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