Firefox (X11) uses software rendering despite hw acceleration being available

Hi all,

Firefox starts with no problems, but subsequent rendering is underperforming :

  • The about:support page shows Mesa – llvmpipe is used for rendering, i.e. software rendering
  • Thunderbird’s about:support page shows hw rendering is used (Thunderbird isn’t in a Snap)
  • glxgears -info shows the GPU is being used
  • xeglgears -info shows the GPU is being used

The snap connections look fine to me :

$ snap connections firefox
Interface               Plug                            Slot                            Notes
alsa                    firefox:alsa                    -                               -
audio-playback          firefox:audio-playback          :audio-playback                 -
audio-record            firefox:audio-record            :audio-record                   -
avahi-observe           firefox:avahi-observe           :avahi-observe                  -
browser-support         firefox:browser-sandbox         :browser-support                -
camera                  firefox:camera                  :camera                         -
content[gnome-42-2204]  firefox:gnome-42-2204           gnome-42-2204:gnome-42-2204     -
content[gtk-3-themes]   firefox:gtk-3-themes            gtk-common-themes:gtk-3-themes  -
content[icon-themes]    firefox:icon-themes             gtk-common-themes:icon-themes   -
content[sound-themes]   firefox:sound-themes            gtk-common-themes:sound-themes  -
cups-control            firefox:cups-control            :cups-control                   -
dbus                    -                               firefox:dbus-daemon             -
desktop                 firefox:desktop                 :desktop                        -
desktop-legacy          firefox:desktop-legacy          :desktop-legacy                 -
gsettings               firefox:gsettings               :gsettings                      -
hardware-observe        firefox:hardware-observe        :hardware-observe               -
home                    firefox:home                    :home                           -
joystick                firefox:joystick                :joystick                       -
mount-control           firefox:host-hunspell           :mount-control                  -
mpris                   -                               firefox:mpris                   -
network                 firefox:network                 :network                        -
network-bind            firefox:network-bind            :network-bind                   -
network-observe         firefox:network-observe         -                               -
opengl                  firefox:opengl                  :opengl                         -
personal-files          firefox:dot-mozilla-firefox     :personal-files                 -
removable-media         firefox:removable-media         :removable-media                -
screen-inhibit-control  firefox:screen-inhibit-control  :screen-inhibit-control         -
system-files            firefox:etc-firefox             :system-files                   -
system-packages-doc     firefox:system-packages-doc     :system-packages-doc            -
u2f-devices             firefox:u2f-devices             :u2f-devices                    -
unity7                  firefox:unity7                  :unity7                         -
upower-observe          firefox:upower-observe          :upower-observe                 -
wayland                 firefox:wayland                 :wayland                        -
x11                     firefox:x11                     :x11                            -

There’s a catch however : I have an Optimus laptop with an Intel iGPU and an Nvidia dGPU, and I don’t use it in the most traditional way :

  • When I don’t use the dGPU, I set prime rendering to intel only (prime-select intel) and remove the dGPU from the PCI database
  • When I intend to use the dGPU, I rescan from the PCI hub connected to the GPU and switch back to nvidia (prime-select nvidia)

This is to ensure the dGPU remains off as much as possible when not needed, as well as to avoid slowdowns of the on-demand mode (prime-select on-demand) which happens too often when some process is waiting for the dGPU despite not needing it, and to avoid rebooting unnecessarily.

So I’m pretty sure it’s linked to me removing and adding hardware from the system database, and something doesn’t get appropriately updated in the process. I tried restarting snapd, but it didn’t change a thing.

Hence my question is : how could I make the Snap system aware of that hardware change ?

My OS is Ubuntu 23.10, and I run Firefox in a pure X11 Gnome 3 session.

Thanks for your insights !

Hi ! @NovHak

I think that, the problem is linked to firefox itself.

You can try the following steps to enable hardware acceleration in Firefox :

1 - Open Firefox and type about:config in the address bar .

2 - Search for layers.acceleration.force-enabled and set it to true .

3 - Search for gfx.webrender.all and set it to true .

4 - Restart Firefox and check if the issue is resolve

I tried that in the past already, but retried anyway, still no dice. I’ve long got past the theory that FF is the problem. The renderer is still Mesa – llvmpipe.

I tried with Thunderbird as I mentioned in my first post because it uses the same engine FF does, but is not “snapified”, and guess what, hw acceleration works. In fact it works everywhere I tried, GLX, EGL, no problem with my games, everything is properly hw-accelerated, except the FF snap.

One thing I didn’t try is running the FF executable outside of the snap system, but I’m 99% sure that all of a sudden hw acceleration will work. No real suspense for me, but I’ll be right back…

EDIT : I’m back and indeed, running Firefox outside of the snap system has it detect the GPU. Two screenshots follow.

  1. Run the normal way, with snap sandboxing :
  2. Run outside of snap sandboxing (/snap/firefox/current/usr/lib/firefox/firefox) :

(sorry for the french description fields, but I hope the meaning is clear enough)

If I go back to intel only prime rendering (prime-select intel), the iGPU is properly detected.

So my question remains the same : how can I have the snap sandboxing system “reload” somehow, so that hardware changes are taken into account ? Without rebooting that is, since yes, snap sandboxing gets it straight after a reboot, but do I hope there is another way around… or could it be AppArmor ?

Does it help to nudge the snapped Firefox with DRI_PRIME environment variable?

For example setting it to 0 or 1 prior to launching Firefox?

It didn’t work either. I tried :

$ DRI_PRIME=1 firefox
$ DRI_PRIME=0 firefox

… but I found a workaround !

How could I not have tried this before :

# snap disable firefox
# snap enable firefox

That being said, I would like to know what was done in that process that put things straight. I noticed a difference in the mounted filesystems, the following was missing while the snap was disabled :

nsfs on /run/snapd/ns/firefox.mnt type nsfs (rw)

EDIT : That is for me the definitive solution :

umount /run/snapd/ns/firefox.mnt

Once that is done, the dGPU is properly detected by FF. A simple, single operation, non-persistent and effective.

From what I understand, Snap sandboxing is achieved by means of :

  1. AppArmor, restricting access to OS resources
  2. Linux namespaces, that maintain a private vision of the OS namespace

A private namespace is deleted once the last process using it has exit()ed, unless it has been mounted beforehand, which is the case here. Snaps maintain their own private vision of the namespace from first execution after boot until OS shutdown.

This is not a bad thing, just that in my very specific case, a hardware change happens that alters the global namespace as it should, but the private namespace retains some information that hides it somehow. In that case, removing it is enough, and a new one is created during the following snap program execution.

1 Like

Hmm !

Although functional, I don’t think it’s the best solution (unless you decide to no longer use the Firefox snap).

AFAIK, it’s the best solution for the specific use case I described. Reinitialising the namespace has been proven sufficient to have FF detect additional hardware. Now of course it’s possible to delve into that private namespace instead, check what needs to be changed and change only that, but that would be much time invested for something that’s trashed on system shutdown anyway.

1 Like