The open source OpenXR runtime

st/oxr: Set session state change event time

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

authored by

Christoph Haag and committed by
Jakob Bornecrantz
2c18167f 1f6da677

+67 -24
+55 -19
src/xrt/state_trackers/oxr/oxr_session.c
··· 339 sess->compositor_visible = true; 340 sess->compositor_focused = true; 341 342 // Transition into focused. 343 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 344 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 345 - oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, 0); 346 } 347 XrResult ret = oxr_frame_sync_begin_session(&sess->frame_sync); 348 if (ret != XR_SUCCESS) { ··· 400 sess->compositor_focused = false; 401 } 402 403 - oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, 0); 404 if (sess->exiting) { 405 - oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, 0); 406 } else { 407 #ifndef XRT_OS_ANDROID 408 // @todo In multi-clients scenario with a session being reused, changing session ··· 428 XrResult 429 oxr_session_request_exit(struct oxr_logger *log, struct oxr_session *sess) 430 { 431 if (sess->state == XR_SESSION_STATE_FOCUSED) { 432 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 433 } 434 if (sess->state == XR_SESSION_STATE_VISIBLE) { 435 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 436 } 437 if (!sess->has_ended_once && sess->state != XR_SESSION_STATE_SYNCHRONIZED) { 438 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 439 // Fake the synchronization. 440 sess->has_ended_once = true; 441 } 442 443 //! @todo start fading out the app. 444 - oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0); 445 sess->exiting = true; 446 return oxr_session_success_result(sess); 447 } ··· 477 return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "xrt_session is null"); 478 } 479 480 #ifdef XRT_OS_ANDROID 481 // Most recent Android activity lifecycle event was OnPause: move toward stopping 482 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_PAUSE) { 483 if (sess->state == XR_SESSION_STATE_FOCUSED) { 484 U_LOG_I("Activity paused: changing session state FOCUSED->VISIBLE"); 485 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 486 } 487 488 if (sess->state == XR_SESSION_STATE_VISIBLE) { 489 U_LOG_I("Activity paused: changing session state VISIBLE->SYNCHRONIZED"); 490 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 491 } 492 493 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED) { 494 U_LOG_I("Activity paused: changing session state SYNCHRONIZED->STOPPING"); 495 - oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, 0); 496 } 497 // TODO return here to avoid polling other events? 498 // see https://gitlab.freedesktop.org/monado/monado/-/issues/419 ··· 502 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_RESUME) { 503 if (sess->state == XR_SESSION_STATE_IDLE) { 504 U_LOG_I("Activity resumed: changing session state IDLE->READY"); 505 - oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, 0); 506 } 507 } 508 #endif // XRT_OS_ANDROID ··· 583 } 584 585 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED && sess->compositor_visible) { 586 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 587 } 588 589 if (sess->state == XR_SESSION_STATE_VISIBLE && sess->compositor_focused) { 590 - oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, 0); 591 } 592 593 if (sess->state == XR_SESSION_STATE_FOCUSED && !sess->compositor_focused) { 594 - oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, 0); 595 } 596 597 if (sess->state == XR_SESSION_STATE_VISIBLE && !sess->compositor_visible) { 598 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 599 } 600 601 return XR_SUCCESS; ··· 1402 return ret; 1403 } 1404 1405 // Everything is in order, start the state changes. 1406 - oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, 0); 1407 - oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, 0); 1408 1409 *out_session = sess; 1410
··· 339 sess->compositor_visible = true; 340 sess->compositor_focused = true; 341 342 + int64_t now = os_monotonic_get_ns(); 343 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 344 + if (now_xr <= 0) { 345 + // shouldn't happen but be sure to log if it does 346 + U_LOG_W("Time keeping oddity: XR_SESSION_STATE_SYNCHRONIZED state reached at XrTime %" PRIi64, 347 + now_xr); 348 + } 349 + 350 // Transition into focused. 351 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 352 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 353 + oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, now_xr); 354 } 355 XrResult ret = oxr_frame_sync_begin_session(&sess->frame_sync); 356 if (ret != XR_SUCCESS) { ··· 408 sess->compositor_focused = false; 409 } 410 411 + int64_t now = os_monotonic_get_ns(); 412 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 413 + if (now_xr <= 0) { 414 + // shouldn't happen but be sure to log if it does 415 + U_LOG_W("Time keeping oddity: ending session at XrTime %" PRIi64, now_xr); 416 + } 417 + 418 + oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, now_xr); 419 if (sess->exiting) { 420 + oxr_session_change_state(log, sess, XR_SESSION_STATE_EXITING, now_xr); 421 } else { 422 #ifndef XRT_OS_ANDROID 423 // @todo In multi-clients scenario with a session being reused, changing session ··· 443 XrResult 444 oxr_session_request_exit(struct oxr_logger *log, struct oxr_session *sess) 445 { 446 + int64_t now = os_monotonic_get_ns(); 447 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 448 + if (now_xr <= 0) { 449 + // shouldn't happen but be sure to log if it does 450 + U_LOG_W("Time keeping oddity: Requesting exit at XrTime %" PRIi64, now_xr); 451 + } 452 + 453 if (sess->state == XR_SESSION_STATE_FOCUSED) { 454 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 455 } 456 if (sess->state == XR_SESSION_STATE_VISIBLE) { 457 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 458 } 459 if (!sess->has_ended_once && sess->state != XR_SESSION_STATE_SYNCHRONIZED) { 460 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 461 // Fake the synchronization. 462 sess->has_ended_once = true; 463 } 464 465 //! @todo start fading out the app. 466 + oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr); 467 sess->exiting = true; 468 return oxr_session_success_result(sess); 469 } ··· 499 return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "xrt_session is null"); 500 } 501 502 + int64_t now = os_monotonic_get_ns(); 503 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 504 + if (now_xr <= 0) { 505 + // shouldn't happen but be sure to log if it does 506 + U_LOG_W("Time keeping oddity: Polling session events at XrTime %" PRIi64, now_xr); 507 + } 508 + 509 #ifdef XRT_OS_ANDROID 510 // Most recent Android activity lifecycle event was OnPause: move toward stopping 511 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_PAUSE) { 512 if (sess->state == XR_SESSION_STATE_FOCUSED) { 513 U_LOG_I("Activity paused: changing session state FOCUSED->VISIBLE"); 514 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 515 } 516 517 if (sess->state == XR_SESSION_STATE_VISIBLE) { 518 U_LOG_I("Activity paused: changing session state VISIBLE->SYNCHRONIZED"); 519 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 520 } 521 522 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED) { 523 U_LOG_I("Activity paused: changing session state SYNCHRONIZED->STOPPING"); 524 + oxr_session_change_state(log, sess, XR_SESSION_STATE_STOPPING, now_xr); 525 } 526 // TODO return here to avoid polling other events? 527 // see https://gitlab.freedesktop.org/monado/monado/-/issues/419 ··· 531 if (sess->sys->inst->activity_state == XRT_ANDROID_LIVECYCLE_EVENT_ON_RESUME) { 532 if (sess->state == XR_SESSION_STATE_IDLE) { 533 U_LOG_I("Activity resumed: changing session state IDLE->READY"); 534 + oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, now_xr); 535 } 536 } 537 #endif // XRT_OS_ANDROID ··· 612 } 613 614 if (sess->state == XR_SESSION_STATE_SYNCHRONIZED && sess->compositor_visible) { 615 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 616 } 617 618 if (sess->state == XR_SESSION_STATE_VISIBLE && sess->compositor_focused) { 619 + oxr_session_change_state(log, sess, XR_SESSION_STATE_FOCUSED, now_xr); 620 } 621 622 if (sess->state == XR_SESSION_STATE_FOCUSED && !sess->compositor_focused) { 623 + oxr_session_change_state(log, sess, XR_SESSION_STATE_VISIBLE, now_xr); 624 } 625 626 if (sess->state == XR_SESSION_STATE_VISIBLE && !sess->compositor_visible) { 627 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, now_xr); 628 } 629 630 return XR_SUCCESS; ··· 1431 return ret; 1432 } 1433 1434 + int64_t now = os_monotonic_get_ns(); 1435 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 1436 + if (now_xr <= 0) { 1437 + // shouldn't happen but be sure to log if it does 1438 + U_LOG_W("Time keeping oddity: XR_SESSION_STATE_IDLE reached at XrTime %" PRIi64, now_xr); 1439 + } 1440 + 1441 // Everything is in order, start the state changes. 1442 + oxr_session_change_state(log, sess, XR_SESSION_STATE_IDLE, now_xr); 1443 + oxr_session_change_state(log, sess, XR_SESSION_STATE_READY, now_xr); 1444 1445 *out_session = sess; 1446
+12 -5
src/xrt/state_trackers/oxr/oxr_session_frame_end.c
··· 1551 } 1552 1553 static void 1554 - do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess) 1555 { 1556 if (!sess->has_ended_once && sess->state < XR_SESSION_STATE_VISIBLE) { 1557 - oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, 0); 1558 sess->has_ended_once = true; 1559 } 1560 } ··· 1663 struct xrt_compositor *xc = sess->compositor; 1664 1665 1666 /* 1667 * Early out for headless sessions. 1668 */ ··· 1673 sess->active_wait_frames--; 1674 os_mutex_unlock(&sess->active_wait_frames_lock); 1675 1676 - do_synchronize_state_change(log, sess); 1677 1678 return oxr_session_success_result(sess); 1679 } ··· 1716 sess->frame_id.begun = -1; 1717 sess->frame_started = false; 1718 1719 - do_synchronize_state_change(log, sess); 1720 1721 return oxr_session_success_result(sess); 1722 } ··· 1785 */ 1786 1787 // Do state change if needed. 1788 - do_synchronize_state_change(log, sess); 1789 1790 struct xrt_layer_frame_data data = { 1791 .frame_id = sess->frame_id.begun,
··· 1551 } 1552 1553 static void 1554 + do_synchronize_state_change(struct oxr_logger *log, struct oxr_session *sess, XrTime time) 1555 { 1556 if (!sess->has_ended_once && sess->state < XR_SESSION_STATE_VISIBLE) { 1557 + oxr_session_change_state(log, sess, XR_SESSION_STATE_SYNCHRONIZED, time); 1558 sess->has_ended_once = true; 1559 } 1560 } ··· 1663 struct xrt_compositor *xc = sess->compositor; 1664 1665 1666 + int64_t now = os_monotonic_get_ns(); 1667 + XrTime now_xr = time_state_monotonic_to_ts_ns(sess->sys->inst->timekeeping, now); 1668 + if (now_xr <= 0) { 1669 + // shouldn't happen but be sure to log if it does 1670 + U_LOG_W("Time keeping oddity: frame end at XrTime %" PRIi64, now_xr); 1671 + } 1672 + 1673 /* 1674 * Early out for headless sessions. 1675 */ ··· 1680 sess->active_wait_frames--; 1681 os_mutex_unlock(&sess->active_wait_frames_lock); 1682 1683 + do_synchronize_state_change(log, sess, now_xr); 1684 1685 return oxr_session_success_result(sess); 1686 } ··· 1723 sess->frame_id.begun = -1; 1724 sess->frame_started = false; 1725 1726 + do_synchronize_state_change(log, sess, now_xr); 1727 1728 return oxr_session_success_result(sess); 1729 } ··· 1792 */ 1793 1794 // Do state change if needed. 1795 + do_synchronize_state_change(log, sess, now_xr); 1796 1797 struct xrt_layer_frame_data data = { 1798 .frame_id = sess->frame_id.begun,