The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

d/rift: Remote timestamps, gravity correction, monotonic samples

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2428>

+90 -11
+31 -10
src/xrt/drivers/rift/rift_hmd.c
··· 21 21 #include "rift_distortion.h" 22 22 23 23 #include "math/m_relation_history.h" 24 + #include "math/m_clock_tracking.h" 24 25 #include "math/m_api.h" 25 26 #include "math/m_vec2.h" 26 27 #include "math/m_mathinclude.h" // IWYU pragma: keep ··· 182 183 if (hmd->sensor_thread.initialized) 183 184 os_thread_helper_stop_and_wait(&hmd->sensor_thread); 184 185 186 + if (hmd->clock_tracker) 187 + m_clock_windowed_skew_tracker_destroy(hmd->clock_tracker); 188 + 185 189 m_relation_history_destroy(&hmd->relation_hist); 186 190 187 191 if (hmd->lens_distortions) ··· 297 301 * We unpack them in the higher 21 bit values first and then shift 298 302 * them down to the lower in order to get the sign bits correct. 299 303 * 300 - * "Inspired" (code copied verbatim) from OpenHMD's rift driver 304 + * Code taken/reformated from OpenHMD's rift driver 301 305 */ 302 306 static void 303 307 rift_decode_sample(const uint8_t *in, int32_t *out) ··· 367 371 return 0; 368 372 } 369 373 374 + int64_t remote_sample_timestamp_ns = (int64_t)report.sample_timestamp * 1000; 375 + 376 + // ignore samples that are behind the latest current sample 377 + if (remote_sample_timestamp_ns < hmd->last_sample_time_ns) { 378 + return 0; 379 + } 380 + 381 + hmd->last_sample_time_ns = remote_sample_timestamp_ns; 382 + 383 + m_clock_windowed_skew_tracker_push(hmd->clock_tracker, os_monotonic_get_ns(), 384 + remote_sample_timestamp_ns); 385 + 386 + int64_t local_timestamp_ns; 387 + // if we havent synchronized our clocks, just do nothing 388 + if (!m_clock_windowed_skew_tracker_to_local(hmd->clock_tracker, remote_sample_timestamp_ns, 389 + &local_timestamp_ns)) { 390 + return 0; 391 + } 392 + 370 393 struct dk2_sample_pack sample_pack = report.samples[report.num_samples >= 2 ? 1 : 0]; 371 394 372 395 int32_t accel_raw[3], gyro_raw[3]; ··· 377 400 rift_sample_to_imu_space(accel_raw, &accel); 378 401 rift_sample_to_imu_space(gyro_raw, &gyro); 379 402 380 - uint64_t sample_timestamp_ns = (uint64_t)report.sample_timestamp * 1000; 381 - 382 - HMD_INFO(hmd, "sample timestamp: %ld", sample_timestamp_ns); 383 - m_imu_3dof_update(&hmd->fusion, sample_timestamp_ns, &accel, &gyro); 403 + m_imu_3dof_update(&hmd->fusion, local_timestamp_ns, &accel, &gyro); 384 404 385 405 struct xrt_space_relation relation = XRT_SPACE_RELATION_ZERO; 386 406 relation.relation_flags = (enum xrt_space_relation_flags)(XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | 387 407 XRT_SPACE_RELATION_ORIENTATION_VALID_BIT); 388 408 relation.pose.orientation = hmd->fusion.rot; 389 - m_relation_history_push(hmd->relation_hist, &relation, os_monotonic_get_ns()); 409 + m_relation_history_push(hmd->relation_hist, &relation, local_timestamp_ns); 390 410 391 411 break; 392 412 } ··· 579 599 580 600 hmd->extra_display_info.icd = info.lens_horizontal_separation_meters; 581 601 582 - for (int i = 0; i < 2; i++) { 583 - info.fov[i] = 93; 584 - } 602 + // hardcode some "okay" values 603 + info.fov[0] = 93; 604 + info.fov[1] = 93; 585 605 586 606 if (!u_device_setup_split_side_by_side(&hmd->base, &info)) { 587 607 HMD_ERROR(hmd, "Failed to setup basic device info"); ··· 619 639 goto error; 620 640 } 621 641 622 - m_imu_3dof_init(&hmd->fusion, 0); 642 + m_imu_3dof_init(&hmd->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_300MS); 643 + hmd->clock_tracker = m_clock_windowed_skew_tracker_alloc(64); 623 644 624 645 result = os_thread_helper_start(&hmd->sensor_thread, sensor_thread, hmd); 625 646
+59 -1
src/xrt/drivers/rift/rift_interface.h
··· 105 105 RIFT_LENS_TYPE_B = 1, 106 106 }; 107 107 108 + #define IN_REPORT_DK2 11 109 + 108 110 #define CATMULL_COEFFICIENTS 11 109 111 #define CHROMATIC_ABBERATION_COEFFEICENT_COUNT 4 110 112 ··· 193 195 } RIFT_PACKED data; 194 196 } RIFT_PACKED; 195 197 196 - #define IN_REPORT_DK2 11 197 198 struct dk2_report_keepalive_mux 198 199 { 199 200 uint16_t command; ··· 201 202 uint16_t interval; 202 203 } RIFT_PACKED; 203 204 205 + enum rift_display_mode 206 + { 207 + RIFT_DISPLAY_MODE_GLOBAL, 208 + RIFT_DISPLAY_MODE_ROLLING_TOP_BOTTOM, 209 + RIFT_DISPLAY_MODE_ROLLING_LEFT_RIGHT, 210 + RIFT_DISPLAY_MODE_ROLLING_RIGHT_LEFT, 211 + }; 212 + 213 + enum rift_display_limit 214 + { 215 + RIFT_DISPLAY_LIMIT_ACL_OFF = 0, 216 + RIFT_DISPLAY_LIMIT_ACL_30 = 1, 217 + RIFT_DISPLAY_LIMIT_ACL_25 = 2, 218 + RIFT_DISPLAY_LIMIT_ACL_50 = 3, 219 + }; 220 + 221 + enum rift_display_flags 222 + { 223 + RIFT_DISPLAY_USE_ROLLING = 1 << 6, 224 + RIFT_DISPLAY_REVERSE_ROLLING = 1 << 7, 225 + RIFT_DISPLAY_HIGH_BRIGHTNESS = 1 << 8, 226 + RIFT_DISPLAY_SELF_REFRESH = 1 << 9, 227 + RIFT_DISPLAY_READ_PIXEL = 1 << 10, 228 + RIFT_DISPLAY_DIRECT_PENTILE = 1 << 11, 229 + }; 230 + 231 + struct rift_display_report 232 + { 233 + uint16_t command_id; 234 + // relative brightness setting independent of pixel persistence, only effective when high brightness is disabled 235 + uint8_t brightness; 236 + // a set of flags, ordered from LSB -> MSB 237 + // - panel mode/shutter type (4 bits), read only, see rift_display_mode 238 + // - current limit (2 bits), see rift_display_limit 239 + // - use rolling (1 bit) 240 + // - reverse rolling (1 bit), unavailable on released DK2 firmware for unknown reason 241 + // - high brightness (1 bit), unavailable on released DK2 firmware for unpublished reason 242 + // - self refresh (1 bit) 243 + // - read pixel (1 bit) 244 + // - direct pentile (1 bit) 245 + uint32_t flags; 246 + // the length of time in rows that the display is lit each frame, defaults to the full size of the display, full 247 + // persistence 248 + uint16_t persistence; 249 + // the offset in rows from vsync that the panel is lit when using global shutter, no effect in rolling shutter, 250 + // disabled on released DK2 firmware for unknown reason 251 + uint16_t lighting_offset; 252 + // the time in microseconds it is estimated for a pixel to settle to one value after it is set, read only 253 + uint16_t pixel_settle; 254 + // the number of rows including active area and blanking period used with persistence and lightingoffset, read 255 + // only 256 + uint16_t total_rows; 257 + } RIFT_PACKED; 258 + 204 259 struct dk2_sensor_sample 205 260 { 206 261 uint8_t data[8]; ··· 328 383 329 384 struct os_hid_device *hid_dev; 330 385 struct os_thread_helper sensor_thread; 386 + int64_t last_sample_time_ns; 387 + 331 388 struct m_imu_3dof fusion; 389 + struct m_clock_windowed_skew_tracker *clock_tracker; 332 390 333 391 int64_t last_keepalive_time; 334 392 enum rift_variant variant;