diff --git a/scripts/generate_oxr_ext_support.py b/scripts/generate_oxr_ext_support.py index 66c51d634..f38d9a19e 100755 --- a/scripts/generate_oxr_ext_support.py +++ b/scripts/generate_oxr_ext_support.py @@ -34,6 +34,7 @@ def not_(s): # Keep sorted, KHR, EXT, Vendor, experimental (same order). EXTENSIONS = ( ['XR_KHR_android_create_instance', 'XR_USE_PLATFORM_ANDROID'], + ['XR_KHR_android_thread_settings', 'XR_USE_PLATFORM_ANDROID'], ['XR_KHR_binding_modification'], ['XR_KHR_composition_layer_cube', 'XRT_FEATURE_OPENXR_LAYER_CUBE'], ['XR_KHR_composition_layer_cylinder', 'XRT_FEATURE_OPENXR_LAYER_CYLINDER'], diff --git a/src/xrt/state_trackers/oxr/oxr_api_funcs.h b/src/xrt/state_trackers/oxr/oxr_api_funcs.h index 4e33ddd3a..2fa2a47e0 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_funcs.h +++ b/src/xrt/state_trackers/oxr/oxr_api_funcs.h @@ -311,6 +311,12 @@ oxr_xrGetVisibilityMaskKHR(XrSession session, XrVisibilityMaskKHR *visibilityMask); #endif // OXR_HAVE_KHR_visibility_mask +#ifdef OXR_HAVE_KHR_android_thread_settings +//! OpenXR API function @ep{xrSetAndroidApplicationThreadKHR} +XRAPI_ATTR XrResult XRAPI_CALL +oxr_xrSetAndroidApplicationThreadKHR(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId); +#endif // OXR_HAVE_KHR_android_thread_settings + #ifdef OXR_HAVE_EXT_performance_settings //! OpenXR API function @ep{xrPerfSettingsSetPerformanceLevelEXT} XRAPI_ATTR XrResult XRAPI_CALL diff --git a/src/xrt/state_trackers/oxr/oxr_api_negotiate.c b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c index e9ba98aec..a8c03a614 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_negotiate.c +++ b/src/xrt/state_trackers/oxr/oxr_api_negotiate.c @@ -218,6 +218,10 @@ handle_non_null(struct oxr_instance *inst, struct oxr_logger *log, const char *n ENTRY_IF_EXT(xrConvertTimeToWin32PerformanceCounterKHR, KHR_win32_convert_performance_counter_time); #endif // OXR_HAVE_KHR_win32_convert_performance_counter_time +#ifdef OXR_HAVE_KHR_android_thread_settings + ENTRY_IF_EXT(xrSetAndroidApplicationThreadKHR, KHR_android_thread_settings); +#endif // XR_HAVE_KHR_android_thread_settings + #ifdef OXR_HAVE_EXT_performance_settings ENTRY_IF_EXT(xrPerfSettingsSetPerformanceLevelEXT, EXT_performance_settings); #endif // OXR_HAVE_EXT_performance_settings diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c index 5af4545d7..147fc4277 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_session.c +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c @@ -583,3 +583,35 @@ oxr_xrRequestDisplayRefreshRateFB(XrSession session, float displayRefreshRate) } #endif + +/* + * + * XR_KHR_android_thread_settings + * + */ + +#ifdef OXR_HAVE_KHR_android_thread_settings + +XRAPI_ATTR XrResult XRAPI_CALL +oxr_xrSetAndroidApplicationThreadKHR(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId) +{ + OXR_TRACE_MARKER(); + + struct oxr_session *sess = NULL; + struct oxr_logger log; + OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrSetAndroidApplicationThreadKHR"); + OXR_VERIFY_SESSION_NOT_LOST(&log, sess); + + if (threadType != XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR && + threadType != XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR && + threadType != XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR && + threadType != XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR) { + return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, "(threadType == %d) is invalid", threadType); + } + + OXR_VERIFY_EXTENSION(&log, sess->sys->inst, KHR_android_thread_settings); + + return oxr_session_android_thread_settings(&log, sess, threadType, threadId); +} + +#endif diff --git a/src/xrt/state_trackers/oxr/oxr_extension_support.h b/src/xrt/state_trackers/oxr/oxr_extension_support.h index 2bd041d06..8b566528e 100644 --- a/src/xrt/state_trackers/oxr/oxr_extension_support.h +++ b/src/xrt/state_trackers/oxr/oxr_extension_support.h @@ -32,6 +32,17 @@ #endif +/* + * XR_KHR_android_thread_settings + */ +#if defined(XR_KHR_android_thread_settings) && defined(XR_USE_PLATFORM_ANDROID) +#define OXR_HAVE_KHR_android_thread_settings +#define OXR_EXTENSION_SUPPORT_KHR_android_thread_settings(_) _(KHR_android_thread_settings, KHR_ANDROID_THREAD_SETTINGS) +#else +#define OXR_EXTENSION_SUPPORT_KHR_android_thread_settings(_) +#endif + + /* * XR_KHR_binding_modification */ @@ -485,6 +496,7 @@ // clang-format off #define OXR_EXTENSION_SUPPORT_GENERATE(_) \ OXR_EXTENSION_SUPPORT_KHR_android_create_instance(_) \ + OXR_EXTENSION_SUPPORT_KHR_android_thread_settings(_) \ OXR_EXTENSION_SUPPORT_KHR_binding_modification(_) \ OXR_EXTENSION_SUPPORT_KHR_composition_layer_cube(_) \ OXR_EXTENSION_SUPPORT_KHR_composition_layer_cylinder(_) \ diff --git a/src/xrt/state_trackers/oxr/oxr_objects.h b/src/xrt/state_trackers/oxr/oxr_objects.h index 3354301fb..e3fe34b06 100644 --- a/src/xrt/state_trackers/oxr/oxr_objects.h +++ b/src/xrt/state_trackers/oxr/oxr_objects.h @@ -737,6 +737,14 @@ oxr_session_apply_force_feedback(struct oxr_logger *log, struct oxr_hand_tracker *hand_tracker, const XrForceFeedbackCurlApplyLocationsMNDX *locations); +#ifdef OXR_HAVE_KHR_android_thread_settings +XrResult +oxr_session_android_thread_settings(struct oxr_logger *log, + struct oxr_session *sess, + XrAndroidThreadTypeKHR threadType, + uint32_t threadId); +#endif // OXR_HAVE_KHR_android_thread_settings + /* * * oxr_space.c diff --git a/src/xrt/state_trackers/oxr/oxr_session.c b/src/xrt/state_trackers/oxr/oxr_session.c index 03b450f15..b6b2d5eda 100644 --- a/src/xrt/state_trackers/oxr/oxr_session.c +++ b/src/xrt/state_trackers/oxr/oxr_session.c @@ -1120,3 +1120,40 @@ oxr_session_apply_force_feedback(struct oxr_logger *log, return XR_SUCCESS; } + +#ifdef OXR_HAVE_KHR_android_thread_settings +static enum xrt_thread_hint +xr_thread_type_to_thread_hint(XrAndroidThreadTypeKHR type) +{ + switch (type) { + case XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR: return XRT_THREAD_HINT_APPLICATION_MAIN; + case XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR: return XRT_THREAD_HINT_APPLICATION_WORKER; + case XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR: return XRT_THREAD_HINT_RENDERER_MAIN; + case XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR: return XRT_THREAD_HINT_RENDERER_WORKER; + default: assert(false); return 0; + } +} + +XrResult +oxr_session_android_thread_settings(struct oxr_logger *log, + struct oxr_session *sess, + XrAndroidThreadTypeKHR threadType, + uint32_t threadId) +{ + struct xrt_compositor *xc = &sess->xcn->base; + + if (xc == NULL) { + return oxr_error(log, XR_ERROR_FUNCTION_UNSUPPORTED, + "Extension XR_KHR_android_thread_settings not be implemented"); + } + + // Convert. + enum xrt_thread_hint xhint = xr_thread_type_to_thread_hint(threadType); + + // Do the call! + xrt_result_t xret = xrt_comp_set_thread_hint(xc, xhint, threadId); + OXR_CHECK_XRET(log, sess, xret, oxr_session_android_thread_settings); + + return XR_SUCCESS; +} +#endif // OXR_HAVE_KHR_android_thread_settings