Immersive Visualization / IQ-Station Wiki

This site hosts information on virtual reality systems that are geared toward scientific visualization, and as such often toward VR on Linux-based systems. Thus, pages here cover various software (and sometimes hardware) technologies that enable virtual reality operation on Linux.

The original IQ-station effort was to create low-cost (for the time) VR systems making use of 3DTV displays to produce CAVE/Fishtank-style VR displays. That effort pre-dated the rise of the consumer HMD VR systems, however, the realm of midrange-cost large-fishtank systems is still important, and has transitioned from 3DTV-based systems to short-throw projectors.

Difference between revisions of "WebXR Linux"

From IQ-Station Wiki
Jump to navigation Jump to search
(Instructions on how to build the Chromium (Chrome) web-browser on Linux to include WebXR)
 
(Adding more bullet lists that should have been part of the initial page)
 
Line 24: Line 24:
transferred to the HMD due to errors that occur on my OS/GPU interface,
transferred to the HMD due to errors that occur on my OS/GPU interface,
but not necessarily for others.
but not necessarily for others.
In the one case of a working WebXR on Linux environment that I am
award of, the system uses AMD GPU cards, whereas the two machines
at my disposal both use NVIDIA GPUs (of two different generations).


But these instructions can be followed to at least get to the same
That said, these instructions can be followed to at least get to the same
point I have on my machine, and if you're fortunate it might "just work"!
point I have on my machine, and if you're fortunate it might "just work"!


Line 40: Line 43:
older Vive HMD) and Mint Linux (with a Valve Index HMD).
older Vive HMD) and Mint Linux (with a Valve Index HMD).


==Building Chromium with WebXR (on Linux)==
=Building Chromium with WebXR (on Linux)=
The first step of building Chromium with WebXR (on Linux) is of course to just
The first step of building Chromium with WebXR (on Linux) is of course to just
be able to build Chromium on Linux, which turned out to not be as daunting as
be able to build Chromium on Linux, which turned out to not be as daunting as
Line 51: Line 54:
the final build to succeed.
the final build to succeed.


===Package Dependencies===
==Package Dependencies==
The [https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md Building Chromium instructions]
The official [https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md Building Chromium instructions]
has a lengthy list of dependencies, which for Ubuntu-based systems is ensconced in a bash script designed to load all of them.
has a lengthy list of dependencies, which for Ubuntu-based systems is ensconced in a bash script designed to load all of them.
This is a problem both for people who don't have root/administrative access to their computer, and thus can't just willy-nilly
This is a problem both for people who don't have root/administrative access to their computer, and thus can't just willy-nilly
be running bash scripts that require "sudo", but also for people who want to know what they are installing on their computer.
be running bash scripts that require "sudo", but also for people who want to know what they are installing on their computer.
On the other hand, for other Linux varients, there is a list of packages given as a single command line installation (again
On the other hand, for other Linux varients, there is a list of packages given as a single command line installation (again
requiring root privileges!). I am not 100% convinced that all the listed packages are absolutely necessary (especially some
requiring root privileges!).
that specifically install for an i686 chipset rather than x86_64. Also, some of these may be only needed for add-ons that I'm
I am not 100% convinced that all the listed packages are absolutely necessary
not interested in.
(especially some that specifically install for an i686 chipset rather than x86_64).
Also, some of these may be only needed for add-ons that I'm not interested in.


So unlike most of my build instructions, here is a list of packages that '''I am not installing on my systems(!)''':
So unlike most of my build instructions, here is a list of packages that '''I am not installing on my systems(!)''':
Line 67: Line 71:
* pciutils-devel
* pciutils-devel
* zlib.i686 — not sure why it wants the i686!
* zlib.i686 — not sure why it wants the i686!
* python-psutil — vs. the "python3-0psutil" which is installed
: (I actually did install the following on Mint)
* mod_ssl
* mod_ssl
* php & php-cli
* php & php-cli
* python-psutil — vs. the "python3-0psutil" which is installed
* wdiff — a tool that does word-by-word difference comparisons
* wdiff — a tool that does word-by-word difference comparisons


===RHEL/Rocky Linux===
What I did install on my Rocky system (and your mileage may vary depending on what you already have installed on your system) was:
What I did install on my Rocky system (and your mileage may vary depending on what you already have installed on your system) was:
* gperf
* gperf
* Google's "depot_tools" — which requires Python3.9 at a minimum
* Google's [https://chromium.googlesource.com/chromium/tools/depot_tools.git ''"depot_tools"''] — which requires Python3.8 at a minimum
** Because "depot_tools" requires Python3.8, and version "3.6.8" is the default on my system, I had to make a softlink to use the correct Python:
** Because "depot_tools" requires Python3.8, and version "3.6.8" is the default on my system, I had to make a softlink to use the correct Python:
<syntaxhighlight>
<syntaxhighlight>
Line 81: Line 87:
</syntaxhighlight>
</syntaxhighlight>


===Mint/Ubuntu Linux===
What I installed on my Linux Mint system was:
What I installed on my Linux Mint system was:
* gperf
* gperf
Line 94: Line 101:
built as a ''"third_party"'' contribution.
built as a ''"third_party"'' contribution.


===Chromium Source Code===
==Chromium Source Code==
The next step is to get the Chromium source code itself, and then do the build process.
The next step is to get the Chromium source code itself, and then do the build process.
These steps are an amalgamation of the official
These steps are an amalgamation of the official
Line 139: Line 146:
Second, if you had to create the Python3.9 softlink, some of these steps will remove that link
Second, if you had to create the Python3.9 softlink, some of these steps will remove that link
and you'll have to make the link again.
and you'll have to make the link again.
==Additional (manual) Patches to the Code==


At this point, we need to do some manual tweaks to the now-patched code:
At this point, we need to do some manual tweaks to the now-patched code:
Line 167: Line 176:
%  
%  
</syntaxhighlight>
</syntaxhighlight>
==Configuring and Building==


And here, the official instructions use <CODE>Default</CODE> as the name of the build
And here, the official instructions use <CODE>Default</CODE> as the name of the build
Line 176: Line 187:
% gn gen out/WebXR
% gn gen out/WebXR
% gn args out/WebXR
% gn args out/WebXR
NOTE: an editor will open, and here you can put arguments for the build.  Put the output from the next step as your arguments.
% echo NOTE: an editor will open, and here you can put arguments for the build.  Put the output from the next step as your arguments.
% cat out/WebXR/args.gn
% cat out/WebXR/args.gn
# Set build arguments here. See `gn help buildargs`.                 
# Set build arguments here. See `gn help buildargs`.                 
Line 185: Line 196:
enable_vulkan=true             
enable_vulkan=true             
enable_openxr=true
enable_openxr=true
% autoninja -C out/WebXR chrome
% autoninja -C out/WebXR chrome
% echo Some sanity checks:
% nm out/WebXR/chrome | grep -i openxr
0000000001466706 r _ZN17flag_descriptions25kWebXrRuntimeChoiceOpenXRE
                U _ZN8switches19kWebXrRuntimeOpenXrE
% nm out/WebXR/chrome | grep -i webxr | wc -l
171
% ldd out/WebXR/chrome | grep -i webxr | wc -l
457
</syntaxhighlight>
</syntaxhighlight>


And the <CODE>autoninja</CODE> command will probably take a few hours!
And the <CODE>autoninja</CODE> command will probably take a few hours!


==Running Chromium with WebXR on Linux==
=Running Chromium with WebXR on Linux=
Because of how Chromium works, there is a need to "un-sandbox" it such that it
Because of how Chromium works, there is a need to "un-sandbox" it such that it
can access files needed for OpenXR, so the <CODE>--no-sandbox</CODE> option is
can access files needed for OpenXR, so the <CODE>--no-sandbox</CODE> option is
Line 217: Line 238:
* <CODE>--enable-features=Vulkan,WebXRIncubations</CODE>
* <CODE>--enable-features=Vulkan,WebXRIncubations</CODE>


==See Also==
And here are options that can be enabled via the <CODE>chrome://flags</CODE> web interface:
* <CODE>Vulkan</CODE> &mdash; enabled
* <CODE>Default ANGLE Vulkan</CODE> &mdash; ??
* <CODE>Vulkan from ANGLE</CODE> &mdash; ??
* <CODE>WebXR Internals Debugging Page</CODE> &mdash; Enables the webxr-internals developer page
* <CODE>WebXR Incubations</CODE> &mdash; Enables experimental features for WebXR
* <CODE>WebXR Hand Input</CODE> &mdash; I have disabled because my environment doesn't have hand-tracking
* <CODE>Force WebXr Runtime</CODE> &mdash; Override whatever runtime the browser decides on (Default; No Runtime; OpenXR; Orientation Sensors)
* <CODE>GPU rasterization</CODE>
 
==Test URLs==
Here are some URLs (both Chrome-internal, and WWW) that are helpful for testing and diagnosing a WebXR configuration:
* ''[chrome://flags]'' internal page to change Chromium properties
* ''[chrome://webxr-internals]'' internal feedback page (Note: <CODE>WebXR Internals Debugging Page</CODE> flag must be <CODE>Enabled</CODE>)
* ''[chrome://gpu]'' information about the system's GPU and graphics environment
:
* [https://freevr.org/SimpleVRWorld.htmlh '''https://freevr.org/SimpleVRWorld.html'''] Cube world with head position
* [https://immersive-web.github.io/webxr-samples '''https://immersive-web.github.io/webxr-samples'''] Immersive-Web test page
** [https://immersive-web.github.io/webxr-samples/immersive-vr-session.html https://immersive-web.github.io/webxr-samples/immersive-vr-session.html] Basic Immersive-Web sample world #1
* [https://maxmystere.github.io/moonrider '''https://maxmystere.github.io/moonrider'''] Moonrider immersive game
 
=Future work=
* Progress the WebXR path to work on a newer version of Chromium
* Look for <CODE>//TODO:</CODE> in the patched WebXR code, and address the issue
* (Perhaps) Change the name and icon to keep it separate from daily-use Chromium
 
=See Also=
* [https://immersiveweb.dev WebXR]
* [https://github.com/immersive-web/webxr/blob/master/explainer.md WebXR Device API Explaination]
* [https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md Google's Chromium Build Instructions]
* [https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md Google's Chromium Build Instructions]
* [https://github.com/rcelyte/webxr-linux/tree/main/chromium rcelyte's WebXR patches to Chromium]
* [https://github.com/rcelyte/webxr-linux/tree/main/chromium rcelyte's WebXR patches to Chromium]

Latest revision as of 20:50, 29 January 2025

WebXR on Linux

WebXR is an API that allows XR experiences to be conveyed to users via a web browser interface. This can be an extremely convenient way to deliver certain immersive experiences to many end-users, both to all-in-one headsets such as the Meta-Quest series, or to PC-connected headsets.

Unfortunately, the only reliably available browsers that are capable of delivering WebXR experiences are on Microsoft-Windows and Android-based systems (phones and all-in-one headsets). This page describes efforts to remedy that situation as far as Linux browsers are concerned.

Note that this is largely possible, now that Monado has become a fully-functioning OpenXR runtime — especially for those of us that use HMDs/headsets that make use of Lighthouse tracking.

Current Status

While there are individuals who are known to have WebXR working with Chromium on their Linux system, I have not yet been able to fully attain that success, but there are glimmers of hope, including evidence that head position tracking data is received. What's not happening (for me) is that the graphics are not being transferred to the HMD due to errors that occur on my OS/GPU interface, but not necessarily for others. In the one case of a working WebXR on Linux environment that I am award of, the system uses AMD GPU cards, whereas the two machines at my disposal both use NVIDIA GPUs (of two different generations).

That said, these instructions can be followed to at least get to the same point I have on my machine, and if you're fortunate it might "just work"!

For me, I don't intend to actually use the self-compiled version of Chromium for my day-to-day browsing, but to restrict using it for when I'm doing WebXR work, so I'm freer to experiment with the code.

Executive Summary

The core of this effort is based on the Chromium patches made available by Github users mrxz and rcetyle, and the general open-source nature of Chromium itself. For testing on Linux, I am using the Monado OpenXR Runtime, which I have successfully built and configured to run on both Rocky Linux (with an older Vive HMD) and Mint Linux (with a Valve Index HMD).

Building Chromium with WebXR (on Linux)

The first step of building Chromium with WebXR (on Linux) is of course to just be able to build Chromium on Linux, which turned out to not be as daunting as it might first seem, though depending on the capabilities of the system, it has taken me as much as 8 hours to do the initial build.

Another issue is getting to the same branch of the Chromium source that matches the WebXR patches that are available. Doing that is one of the services of this document, along with a handful of additional patching that I have added to get the final build to succeed.

Package Dependencies

The official Building Chromium instructions has a lengthy list of dependencies, which for Ubuntu-based systems is ensconced in a bash script designed to load all of them. This is a problem both for people who don't have root/administrative access to their computer, and thus can't just willy-nilly be running bash scripts that require "sudo", but also for people who want to know what they are installing on their computer. On the other hand, for other Linux varients, there is a list of packages given as a single command line installation (again requiring root privileges!). I am not 100% convinced that all the listed packages are absolutely necessary (especially some that specifically install for an i686 chipset rather than x86_64). Also, some of these may be only needed for add-ons that I'm not interested in.

So unlike most of my build instructions, here is a list of packages that I am not installing on my systems(!):

  • bluez-libs-devel
  • libgcc.i686 — not sure why it wants the i686!
  • libxkbcommon-x11-devel
  • pciutils-devel
  • zlib.i686 — not sure why it wants the i686!
  • python-psutil — vs. the "python3-0psutil" which is installed
(I actually did install the following on Mint)
  • mod_ssl
  • php & php-cli
  • wdiff — a tool that does word-by-word difference comparisons

RHEL/Rocky Linux

What I did install on my Rocky system (and your mileage may vary depending on what you already have installed on your system) was:

  • gperf
  • Google's "depot_tools" — which requires Python3.8 at a minimum
    • Because "depot_tools" requires Python3.8, and version "3.6.8" is the default on my system, I had to make a softlink to use the correct Python:
% cd .../depot_tools
% ln -s /usr/bin/python3.9 python3

Mint/Ubuntu Linux

What I installed on my Linux Mint system was:

  • gperf
  • generate-ninja — perhaps in lieu of pre-installing Google's "depot_tools" (which do get included as "third_party" code)
  • apache2-ssl-dev
  • php8.1-cli
  • wdiff

Note that I already had OpenXR installed on my system, and I was hoping that that would be sufficient for the Chromium build, however, it was getting overly complicated in altering the Chromium configuration files (BUILD.gn), so in the end it was just easier to have OpenXR built as a "third_party" contribution.

Chromium Source Code

The next step is to get the Chromium source code itself, and then do the build process. These steps are an amalgamation of the official Building Chromium instructions along with the instructions on adding the WebXR patch instructions from the README.md, plus a handful of additional steps that I had to add.

Note that the WebXR patch was created from Chromium version 130.0.6692, so after the Chromium source is downloaded, one must change to that tagged branch, and then update the source code. (And because of this, using the --no-history flag to save time and space in downloading the source should NOT be used.)

% cd Chromium
% fetch --nohooks chromium
% cd src
% git fetch origin 130.0.6692.0 --depth=1
% git checkout refs/tags/130.0.6692.0
% ls -lR third_party/openxr/ | grep $USER | wc -l
12

So far so good. The 12 count means only 12 files dealing with OpenXR to this point, and this is where applying the WebXR patch expands the code:

% pushd ..
% wget https://raw.githubusercontent.com/rcelyte/webxr-linux/refs/heads/chromium/chromium/webxr-linux-vulkan.patch
% popd
% git apply --verbose ../webxr-linux-vulkan.patch
% gclient runhooks
% ls -lR third_party/openxr/ | grep $USER | wc -l
12
% gclient sync
% ls -lR third_party/openxr/ | grep $USER | wc -l
408

And two things to note. First, the OpenXR code went from 12 files to 408, but I wouldn't be concerned if these numbers don't match exactly — only that it would be a concern if there were only a handful of files for OpenXR. Second, if you had to create the Python3.9 softlink, some of these steps will remove that link and you'll have to make the link again.

Additional (manual) Patches to the Code

At this point, we need to do some manual tweaks to the now-patched code:

% cp -p device/vr/BUILD.gn{,_orig}
% vi device/vr/BUILD.gn
[After the line: "//third_party/openxr", add these 4 lines:
        "//gpu/vulkan",                        # Vulkan support                                      
        "//gpu/command_buffer/service",        # Command buffer                                      
        "//gpu/ipc/service",                   # GPU IPC                                             
        "//third_party/vulkan-headers:vulkan_headers",        # Vulkan headers
]
% diff device/vr/BUILD.gn{,_orig}
295,298d293
<         "//gpu/vulkan",                        # Vulkan support
<         "//gpu/command_buffer/service",        # Command buffer
<         "//gpu/ipc/service",                   # GPU IPC
<         "//third_party/vulkan-headers:vulkan_headers",        # Vulkan headers
% cat > third_party/vulkan-headers/BUILD.gn
import("//build/config/linux/pkg_config.gni")                

group("vulkan_headers") {                
  include_dirs = [                
    "include",                
  ]                
}
^D
%

Configuring and Building

And here, the official instructions use Default as the name of the build they are creating, but I use WebXR instead. You just need to be consistent, but if you see Default in the original directions, this is why mine is different.

Continuing:

% gn gen out/WebXR
% gn args out/WebXR
% echo NOTE: an editor will open, and here you can put arguments for the build.  Put the output from the next step as your arguments.
% cat out/WebXR/args.gn
# Set build arguments here. See `gn help buildargs`.                
symbol_level=0                
blink_symbol_level=0                
v8_symbol_level=0                
enable_nacl=false                
enable_vulkan=true            
enable_openxr=true

% autoninja -C out/WebXR chrome

% echo Some sanity checks:
% nm out/WebXR/chrome | grep -i openxr
0000000001466706 r _ZN17flag_descriptions25kWebXrRuntimeChoiceOpenXRE
                 U _ZN8switches19kWebXrRuntimeOpenXrE
% nm out/WebXR/chrome | grep -i webxr | wc -l
171
% ldd out/WebXR/chrome | grep -i webxr | wc -l
457

And the autoninja command will probably take a few hours!

Running Chromium with WebXR on Linux

Because of how Chromium works, there is a need to "un-sandbox" it such that it can access files needed for OpenXR, so the --no-sandbox option is required for use. There are other options as well, though given that I do not yet have it fully functioning, it is not clear what other command-line options are required.

Likewise, there are "flags" that will need to be set, some of which can be indicated on the command line, or configured in the settings URL.

Here is how I am currently running my build of Chromium (from the same directory I was in when running autoninja above:

% out/WebXR/chrome --enable-features=OpenXR --enable-webxr --use-vulkan --no-sandbox

Here is a list of options that are required and/or possibly useful (or, until I know better, possibly detrimental):

  • --no-sandbox — absolutely necessary
  • --enable-features=OpenXR
  • --enable-webxr
  • --use-vulkan
  • --use-gl=egl
  • --use-cmd-decoder=passthrough
  • --ozone-platform-hint=auto
  • --enable-features=Vulkan,WebXRIncubations

And here are options that can be enabled via the chrome://flags web interface:

  • Vulkan — enabled
  • Default ANGLE Vulkan — ??
  • Vulkan from ANGLE — ??
  • WebXR Internals Debugging Page — Enables the webxr-internals developer page
  • WebXR Incubations — Enables experimental features for WebXR
  • WebXR Hand Input — I have disabled because my environment doesn't have hand-tracking
  • Force WebXr Runtime — Override whatever runtime the browser decides on (Default; No Runtime; OpenXR; Orientation Sensors)
  • GPU rasterization

Test URLs

Here are some URLs (both Chrome-internal, and WWW) that are helpful for testing and diagnosing a WebXR configuration:

  • [chrome://flags] internal page to change Chromium properties
  • [chrome://webxr-internals] internal feedback page (Note: WebXR Internals Debugging Page flag must be Enabled)
  • [chrome://gpu] information about the system's GPU and graphics environment

Future work

  • Progress the WebXR path to work on a newer version of Chromium
  • Look for //TODO: in the patched WebXR code, and address the issue
  • (Perhaps) Change the name and icon to keep it separate from daily-use Chromium

See Also