Merge pull request #65798 from kisg/dynamic_openxr_loader

Dynamic loading of OpenXR Loader on Android
This commit is contained in:
Rémi Verschelde 2022-09-26 08:27:24 +02:00
commit 3472bdd6b6
10 changed files with 358 additions and 119 deletions

View file

@ -41,6 +41,7 @@
#endif
#ifdef ANDROID_ENABLED
#define OPENXR_LOADER_NAME "libopenxr_loader.so"
#include "extensions/openxr_android_extension.h"
#endif
@ -284,6 +285,9 @@ bool OpenXRAPI::create_instance() {
0, // runtimeVersion, from here will be set by our get call
"" // runtimeName
};
OPENXR_API_INIT_XR_FUNC_V(xrGetInstanceProperties);
result = xrGetInstanceProperties(instance, &instanceProps);
if (XR_FAILED(result)) {
// not fatal probably
@ -992,9 +996,94 @@ bool OpenXRAPI::is_running() {
return running;
}
bool OpenXRAPI::openxr_loader_init() {
#ifdef ANDROID_ENABLED
ERR_FAIL_COND_V_MSG(openxr_loader_library_handle != nullptr, false, "OpenXR Loader library is already loaded.");
{
Error error_code = OS::get_singleton()->open_dynamic_library(OPENXR_LOADER_NAME, openxr_loader_library_handle);
ERR_FAIL_COND_V_MSG(error_code != OK, false, "OpenXR loader not found.");
}
{
Error error_code = OS::get_singleton()->get_dynamic_library_symbol_handle(openxr_loader_library_handle, "xrGetInstanceProcAddr", (void *&)xrGetInstanceProcAddr);
ERR_FAIL_COND_V_MSG(error_code != OK, false, "Symbol xrGetInstanceProcAddr not found in OpenXR Loader library.");
}
#endif
// Resolve the symbols that don't require an instance
OPENXR_API_INIT_XR_FUNC_V(xrCreateInstance);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateApiLayerProperties);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateInstanceExtensionProperties);
return true;
}
bool OpenXRAPI::resolve_instance_openxr_symbols() {
ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
OPENXR_API_INIT_XR_FUNC_V(xrAcquireSwapchainImage);
OPENXR_API_INIT_XR_FUNC_V(xrApplyHapticFeedback);
OPENXR_API_INIT_XR_FUNC_V(xrAttachSessionActionSets);
OPENXR_API_INIT_XR_FUNC_V(xrBeginFrame);
OPENXR_API_INIT_XR_FUNC_V(xrBeginSession);
OPENXR_API_INIT_XR_FUNC_V(xrCreateAction);
OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSet);
OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSpace);
OPENXR_API_INIT_XR_FUNC_V(xrCreateReferenceSpace);
OPENXR_API_INIT_XR_FUNC_V(xrCreateSession);
OPENXR_API_INIT_XR_FUNC_V(xrCreateSwapchain);
OPENXR_API_INIT_XR_FUNC_V(xrDestroyAction);
OPENXR_API_INIT_XR_FUNC_V(xrDestroyActionSet);
OPENXR_API_INIT_XR_FUNC_V(xrDestroyInstance);
OPENXR_API_INIT_XR_FUNC_V(xrDestroySession);
OPENXR_API_INIT_XR_FUNC_V(xrDestroySpace);
OPENXR_API_INIT_XR_FUNC_V(xrDestroySwapchain);
OPENXR_API_INIT_XR_FUNC_V(xrEndFrame);
OPENXR_API_INIT_XR_FUNC_V(xrEndSession);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateReferenceSpaces);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateSwapchainFormats);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurations);
OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurationViews);
OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateBoolean);
OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateFloat);
OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateVector2f);
OPENXR_API_INIT_XR_FUNC_V(xrGetCurrentInteractionProfile);
OPENXR_API_INIT_XR_FUNC_V(xrGetSystem);
OPENXR_API_INIT_XR_FUNC_V(xrGetSystemProperties);
OPENXR_API_INIT_XR_FUNC_V(xrLocateViews);
OPENXR_API_INIT_XR_FUNC_V(xrLocateSpace);
OPENXR_API_INIT_XR_FUNC_V(xrPathToString);
OPENXR_API_INIT_XR_FUNC_V(xrPollEvent);
OPENXR_API_INIT_XR_FUNC_V(xrReleaseSwapchainImage);
OPENXR_API_INIT_XR_FUNC_V(xrResultToString);
OPENXR_API_INIT_XR_FUNC_V(xrStringToPath);
OPENXR_API_INIT_XR_FUNC_V(xrSuggestInteractionProfileBindings);
OPENXR_API_INIT_XR_FUNC_V(xrSyncActions);
OPENXR_API_INIT_XR_FUNC_V(xrWaitFrame);
OPENXR_API_INIT_XR_FUNC_V(xrWaitSwapchainImage);
return true;
}
XrResult OpenXRAPI::get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) {
XrResult result = xrGetInstanceProcAddr(instance, p_name, p_addr);
if (result != XR_SUCCESS) {
String error_message = String("Symbol ") + p_name + " not found in OpenXR instance.";
ERR_FAIL_COND_V_MSG(true, result, error_message.utf8().get_data());
}
return result;
}
bool OpenXRAPI::initialize(const String &p_rendering_driver) {
ERR_FAIL_COND_V_MSG(instance != XR_NULL_HANDLE, false, "OpenXR instance was already created");
if (!openxr_loader_init()) {
return false;
}
if (p_rendering_driver == "vulkan") {
#ifdef VULKAN_ENABLED
graphics_extension = memnew(OpenXRVulkanExtension(this));
@ -1017,6 +1106,10 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
}
// initialize
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_before_instance_created();
}
if (!load_layer_properties()) {
destroy_instance();
return false;
@ -1032,6 +1125,11 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
return false;
}
if (!resolve_instance_openxr_symbols()) {
destroy_instance();
return false;
}
if (!get_system_info()) {
destroy_instance();
return false;
@ -1669,6 +1767,13 @@ OpenXRAPI::~OpenXRAPI() {
layer_properties = nullptr;
}
#ifdef ANDROID_ENABLED
if (openxr_loader_library_handle) {
OS::get_singleton()->close_dynamic_library(openxr_loader_library_handle);
openxr_loader_library_handle = nullptr;
}
#endif
singleton = nullptr;
}