OpenXR Loader 浅析

下载OpenXR Loader源码,

git clone https://github.com/KhronosGroup/OpenXR-SDK-Source.git

本文是针对Android平台,进入OpenXR-SDK-Source/src/tests/hello_xr目录下,执行

./gradlew clean ./gradlew assembleOpenGLESDebug

可以生成 build/outputs/apk/OpenGLES/debug/hello_xr-OpenGLES-debug.apk

在./build/intermediates/merged_native_libs/OpenGLESDebug/out/lib/目录下也可以找到loader so

Android平台Loader初始化流程:

1.

xrInitializeLoaderKHR -》LoaderXrInitializeLoaderKHR -》InitializeLoader -》LoaderInitData::initialize

这里主要是获取JVM,Application Context。

2.

xrEnumerateInstanceExtensionProperties -》LoaderXrEnumerateInstanceExtensionProperties -》RuntimeInterface::LoadRuntime -》

在这个函数里,有几个步骤,

2.1. 首先是

RuntimeManifestFile::FindManifestFiles -》GetPlatformRuntimeVirtualManifest -》getActiveRuntimeVirtualManifest -》getActiveRuntimeCursor

这里是为了查询当前系统中存在的runtime,获取路径及so名称。并且过程中会检查前面LoaderInitData是否已经初始化过。

在Android上的查询方式,是通过content provider实现的,如果在linux平台上,会在系统里找active_runtime.json 文件。

2.2. 然后是

RuntimeInterface::TryLoadingSingleRuntime -》

XrResult RuntimeInterface::TryLoadingSingleRuntime(const std::string& openxr_command,std::unique_ptr& manifest_file) {
......//在这个函数里,先去dlopen so。LoaderPlatformLibraryHandle runtime_library = LoaderPlatformLibraryOpen(manifest_file->LibraryPath());
......//检查前面LoaderInitData是否已经初始化过if (!LoaderInitData::instance().initialized()) {
......//通过dlsym直接找到xrInitializeLoaderKHR进行调用auto initLoader =reinterpret_cast(LoaderPlatformLibraryGetProcAddr(runtime_library, function_name));
......//再调xrNegotiateLoaderRuntimeInterface,在runtime里主要实现两个功能,一是检查版本是否匹配,二是填充runtime_info.getInstanceProcAddr指针,后续都是用这个指针来查找并调用函数。auto negotiate =reinterpret_cast(LoaderPlatformLibraryGetProcAddr(runtime_library, function_name));
......res = negotiate(&loader_info, &runtime_info);
......//前边xrInitializeLoaderKHR如果不成功,这里会通过xrGetInstanceProcAddr的方式再调一遍,这应该是为了版本兼容设计的,适配不同的runtime实现方式。if (XR_SUCCEEDED(runtime_info.getInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", &initializeVoid))) {
......//之后构建新的RuntimeInterface并重置instance指针,来保存当前的runtime信息。GetInstance().reset(new RuntimeInterface(runtime_library, runtime_info.getInstanceProcAddr));
......//最后还要查询支持的扩展,GetInstanceExtensionProperties,这里边已经是通过xrGetInstanceProcAddr来获取函数指针了,在runtime的实现里是xrEnumerateInstanceExtensionPropertiesGetInstance()->GetInstanceExtensionProperties(extension_properties);
......
}

ApiLayer加载流程:

xrEnumerateApiLayerProperties -> LoaderXrEnumerateApiLayerProperties

-> ApiLayerInterface::GetApiLayerProperties -> ApiLayerManifestFile::FindManifestFiles

在这里会去寻找配置文件,搜索的目录是:

openxr/1/api_layers/implicit.d/

openxr/1/api_layers/explicit.d/

所以应该在工程Assets文件夹下,创建相应的目录,并放入写好的配置文件****.json

以自带的ApiLayer为例,可以修改hello_xr的build.gradle文件,添加编译模块

        externalNativeBuild {cmake {******targets "openxr_loader", "hello_xr", "XrApiLayer_api_dump", "XrApiLayer_core_validation"

这样再编译,就能生成相应的so和json文件。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部