Android Extended Reality Bridge.
AXRB is an experimental bridge for running Android OpenXR applications inside a Linux Android container and forwarding their OpenXR runtime calls, tracking, and frame output to a PC OpenXR runtime such as SteamVR or Monado.
The current prototype proves the loader/runtime integration path and a basic CPU frame transport path. It is not production-ready and it is not a 90 FPS renderer yet.
Android OpenXR APK
-> Android OpenXR loader
-> AXRB Android OpenXR runtime APK
-> AXRB bridge protocol
-> AXRB host bridge
-> PC OpenXR runtime
-> headset
Primary development target:
- Linux host
- Waydroid or custom LXC Android container
- Monado or SteamVR as the host OpenXR runtime
- Vulkan external memory and dma-buf for the real frame path
Current test environment:
- Windows host running SteamVR
- WSL/Waydroid for the Android container side
- TCP/local-socket CPU image transport for proof of concept
Implemented:
- Android installable OpenXR runtime package:
com.axrb.openxrruntime - Runtime discovery through Android OpenXR runtime broker provider
- Minimal OpenXR runtime entry points for
hello_xr - HMD and controller pose forwarding from a host OpenXR runtime
- Windows host bridge using
XR_KHR_D3D11_enable - SteamVR projection layer submission
- CPU image readback from Android GLES swapchain images
- Android local socket image proxy in the runtime APK
- TCP image receiver on the host bridge
- 512x512 proof-of-concept frame upload into SteamVR
- Linux dma-buf frame descriptor and Unix FD-passing transport foundation
- UDP encoded-video transport foundation for the Windows/WSL fallback path
Known limitations:
- CPU readback and socket transport are slow.
- The current image path is for validation, not low-latency VR.
- The Windows/WSL path is useful for development, but it is not the right target for zero-copy frame transport.
- WSL/Waydroid currently reports Android Vulkan through SwiftShader/CPU on the tested setup, not hardware Vulkan.
- Real 90 FPS requires the Linux GPU-sharing path: Vulkan external memory, dma-buf, and explicit sync.
android-runtime/ Native Android OpenXR runtime implementation
android-runtime-apk/ Installable Android runtime APK and runtime broker
host-bridge/ Native host bridge talking to PC OpenXR
protocol/ Pose/image protocol structures and transports
container/ Waydroid/WSL helper scripts
tests/ Runtime smoke tests and Android loader probes
Native host/WSL build:
cmake -S . -B build-wsl
cmake --build build-wsl
ctest --test-dir build-wsl --output-on-failureWindows host bridge build:
cmake --build build --config DebugAndroid runtime APK:
bash android-runtime-apk/build_apk.shThe Android APK build expects an Android SDK/NDK available from the environment used to run the script.
Start the Windows host bridge:
.\build\host-bridge\Debug\axrb-host-bridge.exe --serve-openxr 38490Install the Android runtime APK:
adb install -r build-android-runtime-apk/axrb-openxr-runtime-debug.apkForward the prototype ports when using adb/Waydroid:
adb reverse tcp:38490 tcp:38490
adb reverse tcp:38491 tcp:38491Launch an Android OpenXR app, for example Khronos hello_xr:
adb shell am start -n org.khronos.openxr.hello_xr.opengles/android.app.NativeActivityUseful logs:
adb logcat -s AXRB.Image AXRB.ImageProxy AXRB.PoseBroker OpenXR-LoaderHost logs are written to stderr by axrb-host-bridge.
Check whether Waydroid exposes hardware Vulkan to Android:
tools/waydroid_vulkan_probe.shOn native Linux with a real DRM render node, configure Waydroid explicitly:
sudo tools/waydroid_vulkan_probe.sh --configure-waydroid-dri /dev/dri/renderD128See docs/hardware_vulkan_waydroid.md for the WSL versus native Linux hardware
Vulkan findings.
Linux dma-buf descriptor receiver:
./build-wsl/host-bridge/axrb-host-bridge --serve-gpu-fds /tmp/axrb-gpu-frame.sockThis mode currently validates and logs dma-buf descriptors passed over a Unix domain socket. Vulkan import and OpenXR submission are the next steps for this path.
Synthetic encoded-video UDP transport test:
.\build\host-bridge\Debug\axrb-host-bridge.exe --video-recv-udp 38492 180./build-wsl/host-bridge/axrb-host-bridge --video-send-synthetic "$(ip route | awk '/default/ {print $3; exit}')" 38492 180 90Visible UDP video feed into the Windows OpenXR/SteamVR bridge:
.\build\host-bridge\Debug\axrb-host-bridge.exe --serve-openxr 38490./build-wsl/host-bridge/axrb-host-bridge --video-send-rgba "$(ip route | awk '/default/ {print $3; exit}')" 38492 900 90 160 90This currently uses AXRB's debug RGBA video codec over the same UDP transport. It proves the transport and headset submission path, but it is not the final H.264/HEVC hardware encode/decode path yet.
The CPU path currently does this:
GLES texture
-> glReadPixels
-> native local socket
-> runtime APK Java proxy
-> TCP
-> host receive buffer
-> D3D11 texture upload
-> OpenXR projection layer
This is intentionally simple and debuggable, but it will not reach headset-rate rendering.
The intended high-performance Linux path is:
Android/Waydroid Vulkan image
-> exported dma-buf / external memory
-> explicit sync
-> host Vulkan import
-> OpenXR compositor submission
That path should avoid CPU copies and is the correct next major milestone for low-latency rendering.
See docs/linux_gpu_transport.md for the current implementation breakdown.
AXRB is intended for first-party tests, open samples, and owned development APKs. Do not use it to bypass DRM, anti-cheat, platform security, store restrictions, or application license terms.