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的实现里是xrEnumerateInstanceExtensionProperties
    GetInstance()->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文件。

你可能感兴趣的:(android,图形渲染,xr)