Skip to content

Commit 90c7238

Browse files
committed
Add fix for #2: delete layer context when destroying XrInstance
1 parent aa50d7f commit 90c7238

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ Each function must be registered. To do so, you should add a line similar to thi
7979
functions.emplace_back("xrEndFrame", PFN_xrVoidFunction(thisLayer_xrEndFrame));
8080
```
8181

82+
Due to the lifetime of API layers being tied to the OpenXR instance, we need to be able to initialize and cleaup the layer context when applications create and destroy their OpenXR instance, in case they do it multiple times. One example of an application with that behavior is Microsoft Flight Simulator 2020. Failing to do so causes problems (see issue #2).
83+
84+
Thus, all layers created with this framework will, at miminum, hook the `xrDestroyInstance` function. Please do not remove or disable the hook for this funciton, or you may have created a semi-silent bug that will crashes *some* applications, but not others!
85+
8286
## Layer implemented extensions
8387

8488
API Layers *can* implement OpenXR instance extensions.

src/layer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ void OpenXRLayer::CreateLayerContext(PFN_xrGetInstanceProcAddr getInstanceProcAd
5252
this_layer->functions[shim.functionName] = shim;
5353
}
5454

55+
void OpenXRLayer::DestroyLayerContext()
56+
{
57+
delete this_layer;
58+
this_layer = nullptr;
59+
}
60+
5561
OpenXRLayer& OpenXRLayer::GetLayerContext()
5662
{
5763
if (this_layer)

src/layer.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class OpenXRLayer
3939

4040
static void CreateLayerContext(PFN_xrGetInstanceProcAddr getInstanceProcAddr, const std::vector<ShimFunction>& shims = {});
4141

42+
//This function must be called as part of the instance destruction hook
43+
static void DestroyLayerContext();
44+
4245
static OpenXRLayer& GetLayerContext();
4346
XrResult GetInstanceProcAddr(XrInstance instance, const char* name, PFN_xrVoidFunction* function);
4447
void LoadDispatchTable(XrInstance instance);

src/layer_shims.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,25 @@
55
// Initial Author: Arthur Brainville <ybalrid@ybalrid.info>
66

77
#include "layer_shims.hpp"
8+
9+
#include <cassert>
810
#include <iostream>
911

12+
//IMPORTANT: to allow for multiple instance creation/destruction, the contect of the layer must be re-initialized when the instance is being destroyed.
13+
//Hooking xrDestroyInstance is the best way to do that.
14+
XRAPI_ATTR XrResult XRAPI_CALL thisLayer_xrDestroyInstance(
15+
XrInstance instance)
16+
{
17+
PFN_xrDestroyInstance nextLayer_xrDestroyInstance = GetNextLayerFunction(xrDestroyInstance);
18+
19+
OpenXRLayer::DestroyLayerContext();
20+
21+
assert(nextLayer_xrDestroyInstance != nullptr);
22+
return nextLayer_xrDestroyInstance(instance);
23+
}
24+
25+
26+
1027
//Define the functions implemented in this layer like this:
1128
XRAPI_ATTR XrResult XRAPI_CALL thisLayer_xrEndFrame(XrSession session,
1229
const XrFrameEndInfo* frameEndInfo)
@@ -42,6 +59,7 @@ XRAPI_ATTR XrResult XRAPI_CALL thisLayer_xrTestMeTEST(XrSession session)
4259
std::vector<OpenXRLayer::ShimFunction> ListShims()
4360
{
4461
std::vector<OpenXRLayer::ShimFunction> functions;
62+
functions.emplace_back("xrDestroyInstance", PFN_xrVoidFunction(thisLayer_xrDestroyInstance));
4563

4664
//List every functions that is callable on this API layer
4765
functions.emplace_back("xrEndFrame", PFN_xrVoidFunction(thisLayer_xrEndFrame));

0 commit comments

Comments
 (0)