Path: blob/master/thirdparty/openxr/src/loader/loader_init_data.cpp
20879 views
// Copyright (c) 2017-2025 The Khronos Group Inc.1// Copyright (c) 2017-2019 Valve Corporation2// Copyright (c) 2017-2019 LunarG, Inc.3//4// SPDX-License-Identifier: Apache-2.0 OR MIT5//6// Initial Author: Mark Young <[email protected]>7//89#include "loader_logger.hpp"10#include "runtime_interface.hpp"11#include "loader_instance.hpp"12#include "loader_init_data.hpp"13#include "loader_properties.hpp"1415XrResult LoaderInitData::initialize(const XrLoaderInitInfoBaseHeaderKHR* info) {16// We iterate the chain per struct type, so we only pick the first of each type in the chain.1718XrResult result = initializeProperties(info);19if (result != XR_SUCCESS) {20return result;21}2223#if defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)24result = initializePlatform(info);25if (result != XR_SUCCESS) {26return result;27}28#endif // defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)2930_initialized = true;31return XR_SUCCESS;32}3334XrResult LoaderInitData::initializeProperties(const XrLoaderInitInfoBaseHeaderKHR* info) {35while (info != nullptr) {36if (info->type == XR_TYPE_LOADER_INIT_INFO_PROPERTIES_EXT) {37const auto* propertyInfo = reinterpret_cast<XrLoaderInitInfoPropertiesEXT const*>(info);3839// Validate the inputs first.40for (uint32_t i = 0; i < propertyInfo->propertyValueCount; i++) {41if (propertyInfo->propertyValues[i].name == nullptr) {42return XR_ERROR_VALIDATION_FAILURE;43}44if (propertyInfo->propertyValues[i].value == nullptr) {45return XR_ERROR_VALIDATION_FAILURE;46}47std::string view{propertyInfo->propertyValues[i].name};48if (view.size() == 0) {49return XR_ERROR_VALIDATION_FAILURE;50}51}5253// Inject provided properties into the loader property store.54LoaderProperty::ClearOverrides();55for (uint32_t i = 0; i < propertyInfo->propertyValueCount; i++) {56LoaderProperty::SetOverride(propertyInfo->propertyValues[i].name, propertyInfo->propertyValues[i].value);57}58// Take only the first such struct.59return XR_SUCCESS;60}61info = reinterpret_cast<const XrLoaderInitInfoBaseHeaderKHR*>(info->next);62}6364// fine if we don't find this.65return XR_SUCCESS;66}6768#if defined(XR_USE_PLATFORM_ANDROID) && defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)69XrResult LoaderInitData::initializePlatform(const XrLoaderInitInfoBaseHeaderKHR* info) {70// Check and copy the Android-specific init data.71while (info != nullptr) {72if (info->type == XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR) {73auto cast_info = reinterpret_cast<XrLoaderInitInfoAndroidKHR const*>(info);7475if (cast_info->applicationVM == nullptr) {76return XR_ERROR_VALIDATION_FAILURE;77}78if (cast_info->applicationContext == nullptr) {79return XR_ERROR_VALIDATION_FAILURE;80}8182// Copy and store the JVM pointer and Android Context, ensuring the JVM is initialised.83_platform_info = *cast_info;84_platform_info.next = nullptr; // Not safe to store next pointer since the memory may not exist later.8586if (_platform_info.applicationVM == nullptr) {87return XR_ERROR_VALIDATION_FAILURE;88}89if (_platform_info.applicationContext == nullptr) {90return XR_ERROR_VALIDATION_FAILURE;91}92jni::init(static_cast<jni::JavaVM*>(_platform_info.applicationVM));93const jni::Object context = jni::Object{static_cast<jni::jobject>(_platform_info.applicationContext)};9495// Retrieve a reference to the Android AssetManager.96const auto assetManager = context.call<jni::Object>("getAssets()Landroid/content/res/AssetManager;");97_android_asset_manager = AAssetManager_fromJava(jni::env(), assetManager.getHandle());9899// Retrieve the path to the native libraries.100const auto applicationContext = context.call<jni::Object>("getApplicationContext()Landroid/content/Context;");101const auto applicationInfo = context.call<jni::Object>("getApplicationInfo()Landroid/content/pm/ApplicationInfo;");102_android_native_library_path = applicationInfo.get<std::string>("nativeLibraryDir");103104// Take only the first such struct.105return XR_SUCCESS;106}107info = reinterpret_cast<const XrLoaderInitInfoBaseHeaderKHR*>(info->next);108}109110// We didn't find one.111return XR_ERROR_VALIDATION_FAILURE;112}113#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)114115XrResult InitializeLoaderInitData(const XrLoaderInitInfoBaseHeaderKHR* loaderInitInfo) {116if (!ActiveLoaderInstance::IsAvailable()) {117LoaderLogger::LogVerboseMessage("InitializeLoaderInitData", "Unloading any previously loaded runtime");118// This will not shutdown the runtime, only unload the library.119RuntimeInterface::UnloadRuntime("InitializeLoaderInitData");120} else {121LoaderLogger::LogErrorMessage("InitializeLoaderInitData",122"An active instance currently exists while trying to reinitialize the loader");123return XR_ERROR_INITIALIZATION_FAILED;124}125return LoaderInitData::instance().initialize(loaderInitInfo);126}127128#if defined(XR_USE_PLATFORM_ANDROID) && defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)129std::string GetAndroidNativeLibraryDir() { return LoaderInitData::instance()._android_native_library_path; }130131void* GetAndroidAssetManager() { return LoaderInitData::instance()._android_asset_manager; }132#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_HAS_REQUIRED_PLATFORM_LOADER_INIT_STRUCT)133134135