The open source OpenXR runtime
0
fork

Configure Feed

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

oxr: Implement additional xrWaitFrame/xrBeginFrame call order checks

Relevant CTS tests: https://github.com/KhronosGroup/OpenXR-CTS/pull/7

+49 -1
+5
src/xrt/state_trackers/oxr/oxr_objects.h
··· 1261 1261 bool compositor_visible; 1262 1262 bool compositor_focused; 1263 1263 1264 + // the number of xrWaitFrame calls that did not yet have a corresponding 1265 + // xrEndFrame or xrBeginFrame (discarded frame) call 1266 + int active_wait_frames; 1267 + struct os_mutex active_wait_frames_lock; 1268 + 1264 1269 bool frame_started; 1265 1270 bool exiting; 1266 1271
+44 -1
src/xrt/state_trackers/oxr/oxr_session.c
··· 521 521 return oxr_session_success_result(sess); 522 522 } 523 523 524 - // Before calling wait frame make sure that begin frame has been called. 524 + os_mutex_lock(&sess->active_wait_frames_lock); 525 + sess->active_wait_frames++; 526 + os_mutex_unlock(&sess->active_wait_frames_lock); 527 + 528 + // A subsequent xrWaitFrame call must: block until the previous frame 529 + // has been begun 525 530 os_semaphore_wait(&sess->sem, 0); 526 531 527 532 uint64_t predicted_display_time; ··· 561 566 562 567 struct xrt_compositor *xc = sess->compositor; 563 568 569 + os_mutex_lock(&sess->active_wait_frames_lock); 570 + int active_wait_frames = sess->active_wait_frames; 571 + os_mutex_unlock(&sess->active_wait_frames_lock); 572 + 564 573 XrResult ret; 574 + if (active_wait_frames == 0) { 575 + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, 576 + "xrBeginFrame without xrWaitFrame"); 577 + } 578 + 565 579 if (sess->frame_started) { 580 + // max 2 xrWaitFrame can be in flight so a second xrBeginFrame 581 + // is only valid if we have a second xrWaitFrame in flight 582 + if (active_wait_frames != 2) { 583 + return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID, 584 + "xrBeginFrame without xrWaitFrame"); 585 + } 586 + 587 + 566 588 ret = XR_FRAME_DISCARDED; 567 589 if (xc != NULL) { 568 590 CALL_CHK( 569 591 xrt_comp_discard_frame(xc, sess->frame_id.begun)); 570 592 sess->frame_id.begun = -1; 593 + 594 + os_mutex_lock(&sess->active_wait_frames_lock); 595 + sess->active_wait_frames--; 596 + os_mutex_unlock(&sess->active_wait_frames_lock); 571 597 } 572 598 } else { 573 599 ret = oxr_session_success_result(sess); ··· 1849 1875 if (xc == NULL) { 1850 1876 sess->frame_started = false; 1851 1877 1878 + os_mutex_lock(&sess->active_wait_frames_lock); 1879 + sess->active_wait_frames--; 1880 + os_mutex_unlock(&sess->active_wait_frames_lock); 1881 + 1852 1882 do_synchronize_state_change(log, sess); 1853 1883 1854 1884 return oxr_session_success_result(sess); ··· 1885 1915 * Early out for discarded frame if layer count is 0. 1886 1916 */ 1887 1917 if (frameEndInfo->layerCount == 0) { 1918 + 1919 + sess->active_wait_frames--; 1920 + 1888 1921 CALL_CHK(xrt_comp_discard_frame(xc, sess->frame_id.begun)); 1889 1922 sess->frame_id.begun = -1; 1890 1923 sess->frame_started = false; ··· 2020 2053 2021 2054 sess->frame_started = false; 2022 2055 2056 + os_mutex_lock(&sess->active_wait_frames_lock); 2057 + sess->active_wait_frames--; 2058 + os_mutex_unlock(&sess->active_wait_frames_lock); 2059 + 2023 2060 return oxr_session_success_result(sess); 2024 2061 } 2025 2062 ··· 2048 2085 u_hashmap_int_destroy(&sess->act_attachments_by_key); 2049 2086 2050 2087 xrt_comp_destroy(&sess->compositor); 2088 + 2089 + os_semaphore_destroy(&sess->sem); 2090 + os_mutex_destroy(&sess->active_wait_frames_lock); 2051 2091 2052 2092 free(sess); 2053 2093 ··· 2185 2225 2186 2226 // Init the begin/wait frame semaphore. 2187 2227 os_semaphore_init(&sess->sem, 1); 2228 + 2229 + sess->active_wait_frames = 0; 2230 + os_mutex_init(&sess->active_wait_frames_lock); 2188 2231 2189 2232 struct xrt_compositor *xc = sess->compositor; 2190 2233 if (xc != NULL) {