下载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文件。