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.
This commit is contained in:
Christoph Haag 2020-10-31 18:39:16 +01:00
parent 9aeb3f50c5
commit e03ee48dce
3 changed files with 12 additions and 10 deletions

View file

@ -210,9 +210,6 @@ compositor_wait_frame(struct xrt_compositor *xc,
*predicted_display_time = c->last_next_display_time;
*out_frame_id = c->last_next_display_time;
if (c->state == COMP_STATE_PREPARED) {
c->state = COMP_STATE_WAITED;
}
return XRT_SUCCESS;
}
@ -245,10 +242,6 @@ compositor_wait_frame(struct xrt_compositor *xc,
*out_frame_id = c->last_next_display_time;
c->last_next_display_time = next_display_time;
if (c->state == COMP_STATE_PREPARED) {
c->state = COMP_STATE_WAITED;
}
return XRT_SUCCESS;
}
}
@ -514,6 +507,10 @@ compositor_layer_commit(struct xrt_compositor *xc, int64_t frame_id)
c->expected_app_duration_ns =
c->app_profiling.last_end - c->app_profiling.last_begin;
if (c->state == COMP_STATE_PREPARED) {
c->state = COMP_STATE_COMMITTED;
}
// Now is a good point to garbage collect.
comp_compositor_garbage_collect(c);
return XRT_SUCCESS;
@ -535,8 +532,8 @@ compositor_poll_events(struct xrt_compositor *xc,
case COMP_STATE_PREPARED:
out_xce->state.type = XRT_COMPOSITOR_EVENT_NONE;
break;
case COMP_STATE_WAITED:
COMP_DEBUG(c, "WAITED -> VISIBLE");
case COMP_STATE_COMMITTED:
COMP_DEBUG(c, "COMMITTED -> VISIBLE");
out_xce->state.type = XRT_COMPOSITOR_EVENT_STATE_CHANGE;
out_xce->state.visible = true;
c->state = COMP_STATE_VISIBLE;

View file

@ -129,7 +129,7 @@ enum comp_state
{
COMP_STATE_READY = 0,
COMP_STATE_PREPARED = 1,
COMP_STATE_WAITED = 2,
COMP_STATE_COMMITTED = 2,
COMP_STATE_VISIBLE = 3,
COMP_STATE_FOCUSED = 4,
};

View file

@ -1898,6 +1898,11 @@ oxr_session_frame_end(struct oxr_logger *log,
do_synchronize_state_change(log, sess);
// For emitting state changes, the compositor has to know
// whether the client is synchronized, i.e. has called
// xrEndFrame, even with 0 layers.
CALL_CHK(xrt_comp_layer_commit(xc, -1));
return oxr_session_success_result(sess);
}