mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-02-05 13:28:16 +00:00
oxr: Implement additional xrWaitFrame/xrBeginFrame call order checks
Relevant CTS tests: https://github.com/KhronosGroup/OpenXR-CTS/pull/7
This commit is contained in:
parent
965fa60bff
commit
7eaa7abb89
|
@ -1261,6 +1261,11 @@ struct oxr_session
|
|||
bool compositor_visible;
|
||||
bool compositor_focused;
|
||||
|
||||
// the number of xrWaitFrame calls that did not yet have a corresponding
|
||||
// xrEndFrame or xrBeginFrame (discarded frame) call
|
||||
int active_wait_frames;
|
||||
struct os_mutex active_wait_frames_lock;
|
||||
|
||||
bool frame_started;
|
||||
bool exiting;
|
||||
|
||||
|
|
|
@ -521,7 +521,12 @@ oxr_session_frame_wait(struct oxr_logger *log,
|
|||
return oxr_session_success_result(sess);
|
||||
}
|
||||
|
||||
// Before calling wait frame make sure that begin frame has been called.
|
||||
os_mutex_lock(&sess->active_wait_frames_lock);
|
||||
sess->active_wait_frames++;
|
||||
os_mutex_unlock(&sess->active_wait_frames_lock);
|
||||
|
||||
// A subsequent xrWaitFrame call must: block until the previous frame
|
||||
// has been begun
|
||||
os_semaphore_wait(&sess->sem, 0);
|
||||
|
||||
uint64_t predicted_display_time;
|
||||
|
@ -561,13 +566,34 @@ oxr_session_frame_begin(struct oxr_logger *log, struct oxr_session *sess)
|
|||
|
||||
struct xrt_compositor *xc = sess->compositor;
|
||||
|
||||
os_mutex_lock(&sess->active_wait_frames_lock);
|
||||
int active_wait_frames = sess->active_wait_frames;
|
||||
os_mutex_unlock(&sess->active_wait_frames_lock);
|
||||
|
||||
XrResult ret;
|
||||
if (active_wait_frames == 0) {
|
||||
return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID,
|
||||
"xrBeginFrame without xrWaitFrame");
|
||||
}
|
||||
|
||||
if (sess->frame_started) {
|
||||
// max 2 xrWaitFrame can be in flight so a second xrBeginFrame
|
||||
// is only valid if we have a second xrWaitFrame in flight
|
||||
if (active_wait_frames != 2) {
|
||||
return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID,
|
||||
"xrBeginFrame without xrWaitFrame");
|
||||
}
|
||||
|
||||
|
||||
ret = XR_FRAME_DISCARDED;
|
||||
if (xc != NULL) {
|
||||
CALL_CHK(
|
||||
xrt_comp_discard_frame(xc, sess->frame_id.begun));
|
||||
sess->frame_id.begun = -1;
|
||||
|
||||
os_mutex_lock(&sess->active_wait_frames_lock);
|
||||
sess->active_wait_frames--;
|
||||
os_mutex_unlock(&sess->active_wait_frames_lock);
|
||||
}
|
||||
} else {
|
||||
ret = oxr_session_success_result(sess);
|
||||
|
@ -1849,6 +1875,10 @@ oxr_session_frame_end(struct oxr_logger *log,
|
|||
if (xc == NULL) {
|
||||
sess->frame_started = false;
|
||||
|
||||
os_mutex_lock(&sess->active_wait_frames_lock);
|
||||
sess->active_wait_frames--;
|
||||
os_mutex_unlock(&sess->active_wait_frames_lock);
|
||||
|
||||
do_synchronize_state_change(log, sess);
|
||||
|
||||
return oxr_session_success_result(sess);
|
||||
|
@ -1885,6 +1915,9 @@ oxr_session_frame_end(struct oxr_logger *log,
|
|||
* Early out for discarded frame if layer count is 0.
|
||||
*/
|
||||
if (frameEndInfo->layerCount == 0) {
|
||||
|
||||
sess->active_wait_frames--;
|
||||
|
||||
CALL_CHK(xrt_comp_discard_frame(xc, sess->frame_id.begun));
|
||||
sess->frame_id.begun = -1;
|
||||
sess->frame_started = false;
|
||||
|
@ -2020,6 +2053,10 @@ oxr_session_frame_end(struct oxr_logger *log,
|
|||
|
||||
sess->frame_started = false;
|
||||
|
||||
os_mutex_lock(&sess->active_wait_frames_lock);
|
||||
sess->active_wait_frames--;
|
||||
os_mutex_unlock(&sess->active_wait_frames_lock);
|
||||
|
||||
return oxr_session_success_result(sess);
|
||||
}
|
||||
|
||||
|
@ -2049,6 +2086,9 @@ oxr_session_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|||
|
||||
xrt_comp_destroy(&sess->compositor);
|
||||
|
||||
os_semaphore_destroy(&sess->sem);
|
||||
os_mutex_destroy(&sess->active_wait_frames_lock);
|
||||
|
||||
free(sess);
|
||||
|
||||
return ret;
|
||||
|
@ -2186,6 +2226,9 @@ oxr_session_create(struct oxr_logger *log,
|
|||
// Init the begin/wait frame semaphore.
|
||||
os_semaphore_init(&sess->sem, 1);
|
||||
|
||||
sess->active_wait_frames = 0;
|
||||
os_mutex_init(&sess->active_wait_frames_lock);
|
||||
|
||||
struct xrt_compositor *xc = sess->compositor;
|
||||
if (xc != NULL) {
|
||||
struct xrt_session_prepare_info xspi = {0};
|
||||
|
|
Loading…
Reference in a new issue