From a1c00e14fd9ab26dde6ad354facde46c3c8285fe Mon Sep 17 00:00:00 2001 From: Christoph Haag Date: Sun, 12 Sep 2021 18:47:06 +0200 Subject: [PATCH] st/oxr: Implement a basic version of XR_FB_display_refresh_rate --- src/xrt/compositor/main/comp_compositor.c | 4 ++ src/xrt/include/xrt/xrt_compositor.h | 3 + src/xrt/state_trackers/oxr/oxr_api_funcs.h | 15 +++++ .../state_trackers/oxr/oxr_api_negotiate.c | 6 ++ src/xrt/state_trackers/oxr/oxr_api_session.c | 63 +++++++++++++++++++ 5 files changed, 91 insertions(+) diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c index 86267191c..89ca0d499 100644 --- a/src/xrt/compositor/main/comp_compositor.c +++ b/src/xrt/compositor/main/comp_compositor.c @@ -1276,6 +1276,10 @@ xrt_gfx_provider_create_system(struct xrt_device *xdev, struct xrt_system_compos float target_frame_time_ms = ns_to_ms(c->settings.nominal_frame_interval_ns); + //! @todo: Query all supported refresh rates of the current mode + sys_info->num_refresh_rates = 1; + sys_info->refresh_rates[0] = 1. / time_ns_to_s(c->settings.nominal_frame_interval_ns); + uint64_t now = os_monotonic_get_ns(); for (int i = 0; i < NUM_FRAME_TIMES; i++) { c->compositor_frame_times.times_ns[i] = now + i; diff --git a/src/xrt/include/xrt/xrt_compositor.h b/src/xrt/include/xrt/xrt_compositor.h index 02f40df09..996fcccb6 100644 --- a/src/xrt/include/xrt/xrt_compositor.h +++ b/src/xrt/include/xrt/xrt_compositor.h @@ -1557,6 +1557,9 @@ struct xrt_system_compositor_info //! Number of meaningful elements in xrt_system_compositor_info::supported_blend_modes uint8_t supported_blend_mode_count; + uint32_t num_refresh_rates; + float refresh_rates[1]; + //! The vk device as used by the compositor, never changes. uint8_t compositor_vk_deviceUUID[XRT_GPU_UUID_SIZE]; diff --git a/src/xrt/state_trackers/oxr/oxr_api_funcs.h b/src/xrt/state_trackers/oxr/oxr_api_funcs.h index 59dc680c1..b5f2e2bd5 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_funcs.h +++ b/src/xrt/state_trackers/oxr/oxr_api_funcs.h @@ -515,6 +515,21 @@ oxr_xrLocateHandJointsEXT(XrHandTrackerEXT handTracker, const XrHandJointsLocateInfoEXT *locateInfo, XrHandJointLocationsEXT *locations); +//! OpenXR API function @ep{xrEnumerateDisplayRefreshRatesFB} +XRAPI_ATTR XrResult XRAPI_CALL +oxr_xrEnumerateDisplayRefreshRatesFB(XrSession session, + uint32_t displayRefreshRateCapacityInput, + uint32_t *displayRefreshRateCountOutput, + float *displayRefreshRates); + +//! OpenXR API function @ep{xrGetDisplayRefreshRateFB} +XRAPI_ATTR XrResult XRAPI_CALL +oxr_xrGetDisplayRefreshRateFB(XrSession session, float *displayRefreshRate); + +//! OpenXR API function @ep{xrRequestDisplayRefreshRateFB} +XRAPI_ATTR XrResult XRAPI_CALL +oxr_xrRequestDisplayRefreshRateFB(XrSession session, float displayRefreshRate); + /*! * @} */ diff --git a/src/xrt/state_trackers/oxr/oxr_api_negotiate.c b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c index a97d643c7..5cd1e8cd5 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_negotiate.c +++ b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c @@ -226,6 +226,12 @@ handle_non_null(struct oxr_instance *inst, struct oxr_logger *log, const char *n ENTRY_IF_EXT(xrLocateHandJointsEXT, EXT_hand_tracking); #endif +#ifdef OXR_HAVE_FB_display_refresh_rate + ENTRY_IF_EXT(xrEnumerateDisplayRefreshRatesFB, FB_display_refresh_rate); + ENTRY_IF_EXT(xrGetDisplayRefreshRateFB, FB_display_refresh_rate); + ENTRY_IF_EXT(xrRequestDisplayRefreshRateFB, FB_display_refresh_rate); +#endif + #if 0 #ifdef OXR_HAVE_EXT_debug_utils ENTRY_IF_EXT(xrSetDebugUtilsObjectNameEXT, EXT_debug_utils); diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c index 72c5aae3a..4b8c5888e 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_session.c +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c @@ -441,3 +441,66 @@ oxr_xrLocateHandJointsEXT(XrHandTrackerEXT handTracker, } #endif + +/* + * + * XR_FB_display_refresh_rate + * + */ + +#ifdef XR_FB_display_refresh_rate + +XrResult +oxr_xrEnumerateDisplayRefreshRatesFB(XrSession session, + uint32_t displayRefreshRateCapacityInput, + uint32_t *displayRefreshRateCountOutput, + float *displayRefreshRates) +{ + struct oxr_session *sess = NULL; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEnumerateDisplayRefreshRatesFB"); + + // headless + if (!sess->sys->xsysc) { + *displayRefreshRateCountOutput = 0; + return XR_SUCCESS; + } + + OXR_TWO_CALL_HELPER(&log, displayRefreshRateCapacityInput, displayRefreshRateCountOutput, displayRefreshRates, + sess->sys->xsysc->info.num_refresh_rates, sess->sys->xsysc->info.refresh_rates, XR_SUCCESS); +} + +XrResult +oxr_xrGetDisplayRefreshRateFB(XrSession session, float *displayRefreshRate) +{ + struct oxr_session *sess = NULL; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEnumerateDisplayRefreshRatesFB"); + + // headless + if (!sess->sys->xsysc) { + *displayRefreshRate = 0.0f; + return XR_SUCCESS; + } + + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrGetDisplayRefreshRateFB"); + if (sess->sys->xsysc->info.num_refresh_rates < 1) { + return XR_ERROR_RUNTIME_FAILURE; + } + + *displayRefreshRate = sess->sys->xsysc->info.refresh_rates[0]; + return XR_SUCCESS; +} + +XrResult +oxr_xrRequestDisplayRefreshRateFB(XrSession session, float displayRefreshRate) +{ + struct oxr_session *sess = NULL; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrRequestDisplayRefreshRateFB"); + + //! @todo support for changing refresh rates + return XR_SUCCESS; +} + +#endif