The open source OpenXR runtime
0
fork

Configure Feed

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

comp: Transition to visible/focused after xrEndFrame, not xrWaitFrame

The application synchronizes its frame loop by "by calling xrWaitFrame,
xrBeginFrame and xrEndFrame in a loop."

Applications can discard frames by not calling xrEndFrame. If initial
frames are discarded, we should not consider the frame loop synchronized.

Previously a sequence like
xrBeginFrame, xrWaitFrame, xrBeginFrame, xrWaitFrame, xrPollEvent, xrBeginFrame
failed because xrPollEvent the compositor emitted transitions to visible
and focused but they were not emitted in the state tracker, because the
oxr session had not internally tranisitioned to the synchronized state.

+12 -10
+6 -9
src/xrt/compositor/main/comp_compositor.c
··· 210 210 *predicted_display_time = c->last_next_display_time; 211 211 *out_frame_id = c->last_next_display_time; 212 212 213 - if (c->state == COMP_STATE_PREPARED) { 214 - c->state = COMP_STATE_WAITED; 215 - } 216 213 return XRT_SUCCESS; 217 214 } 218 215 ··· 245 242 *out_frame_id = c->last_next_display_time; 246 243 247 244 c->last_next_display_time = next_display_time; 248 - 249 - if (c->state == COMP_STATE_PREPARED) { 250 - c->state = COMP_STATE_WAITED; 251 - } 252 245 return XRT_SUCCESS; 253 246 } 254 247 } ··· 514 507 c->expected_app_duration_ns = 515 508 c->app_profiling.last_end - c->app_profiling.last_begin; 516 509 510 + if (c->state == COMP_STATE_PREPARED) { 511 + c->state = COMP_STATE_COMMITTED; 512 + } 513 + 517 514 // Now is a good point to garbage collect. 518 515 comp_compositor_garbage_collect(c); 519 516 return XRT_SUCCESS; ··· 535 532 case COMP_STATE_PREPARED: 536 533 out_xce->state.type = XRT_COMPOSITOR_EVENT_NONE; 537 534 break; 538 - case COMP_STATE_WAITED: 539 - COMP_DEBUG(c, "WAITED -> VISIBLE"); 535 + case COMP_STATE_COMMITTED: 536 + COMP_DEBUG(c, "COMMITTED -> VISIBLE"); 540 537 out_xce->state.type = XRT_COMPOSITOR_EVENT_STATE_CHANGE; 541 538 out_xce->state.visible = true; 542 539 c->state = COMP_STATE_VISIBLE;
+1 -1
src/xrt/compositor/main/comp_compositor.h
··· 129 129 { 130 130 COMP_STATE_READY = 0, 131 131 COMP_STATE_PREPARED = 1, 132 - COMP_STATE_WAITED = 2, 132 + COMP_STATE_COMMITTED = 2, 133 133 COMP_STATE_VISIBLE = 3, 134 134 COMP_STATE_FOCUSED = 4, 135 135 };
+5
src/xrt/state_trackers/oxr/oxr_session.c
··· 1898 1898 1899 1899 do_synchronize_state_change(log, sess); 1900 1900 1901 + // For emitting state changes, the compositor has to know 1902 + // whether the client is synchronized, i.e. has called 1903 + // xrEndFrame, even with 0 layers. 1904 + CALL_CHK(xrt_comp_layer_commit(xc, -1)); 1905 + 1901 1906 return oxr_session_success_result(sess); 1902 1907 } 1903 1908