I am developing an OpenXR streaming application for Linux, https://github.com/Meumeu/WiVRn/ and noticed performance and conformance issues on Wave runtime compared to Oculus runtime.
Composition layer blending
If we don't initialize the alpha channel bit in projection layers, they would not show on the headset, although it would be visible in video.
https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#composition-layer-blending states:
Vulkan validation layers
When running with vulkan validation layers, the runtime generates
xrLocateViews viewCapacityInput
Calling xrLocateViews with a viewCapacityInput set to 0 takes about the same time as with a value of 2. When using generic code that first calls with 0 then uses the right number of views, this doubles the required time.
JNI calls
Many OpenXR functions in the wave runtime perform JNI calls, if AttachCurrentThread was not called by the application for the thread, this has a noticeable performance penalty. OpenXR specification does not require applications to do such a call, and no documentation states it.
xrLocateSpace performance
The xrLocateSpace function performs significantly worse on Wave runtime compared to Meta Quest, a single call is about 30µs on Quest compared to 400 on Wave. Android profiler shows that a significant portion of the time (about 1/6th of xrLocateSpace) is spent in string operations. The same input polling loop is idle 86% of the time (polling rate of 1ms) on Quest, while on Wave, application needs to reduce polling rate up to 5ms for a 50% idle time.
Network consistency
The application requires very consistent network, we acquire the low latency wifi lock using Android API. UDP packets from headset to PC appear to have an irregular pacing and arrive in bursts. Sometimes there is not packet incoming, for durations up to 50ms
Compositor performance
Compared to Oculus Quest 1, at the same display resolution, the predicted display time is about 15ms higher on Vive XR elite.
Overall result
Controller-to-photons latency (ms) over time for Quest 1 (left) and Vive XR elite (right)
Distribution of controller-to-photons for Quest 1 (left) and Vive XR elite (right). x axis is the latency in ms, y axis the number of samples.
From those plots, we can see that total latency is about 15ms more on Vive XR elite, which according to my measurements is mostly in Wave runtime, as a higher predictedDisplayTime value. We also see that large values are both larger and more frequent, which is caused by controller data not reaching the PC, and therefore older predictions are used.
Bonus benchmark
A totally scientific benchmark I used is Beat Saber native on Quest, streamed on Quest and streamed on Vive XR elite, on the same level, scores are 200k (Quest native), 186k (Quest streaming) and 130k (Vive XR elite streaming).
What I am expecting from this post:
Fixes from Vive team on the OpenXR runtime performance and non-conformance issues.
Tweaks if any to reduce the predicted display time at the time of xrWaitFrame.
Help to investigate the network pattern.