An overview of hardware acceleration in Chromium

Hardware accelerated video encoding and decoding in Chromium is coming soon to the stable snap channel. It has been (and continues to be) available for testers in hwacc branches.

Background

Computers usually have at least one Graphics Processing Unit (GPU). Different from the Central Processing Unit (CPU), which is general purpose, a GPU is, as the name suggests, specialized in image manipulation, so media is more efficiently processed by it. In the Chromium snap today all video processing is done by the CPU which is not nearly as efficient as it could be and may result in a more sluggish desktop because the CPU is doing tasks it is not optimized for. Recognising that GPUs are perfect for certain types of tasks we can use “hardware acceleration” to send specific types of tasks to the GPU, freeing up the CPU and resulting in a more efficient system overall. Enabling hardware acceleration in Chromium results in lower energy consumption and also increased overall performance.

Enabling hardware acceleration is more complicated than flipping a switch and in fact a lot of work had to go into the Chromium snap to make this happen. So, here is an overview of the steps we took to enable hardware acceleration in the Chromium snap.

In the snap world we are restricted to using the packages in the series corresponding to the base snap version, which was core20 (so 20.04 series) at the time the project started. Unfortunately, 20.04 does not provide recent enough versions of Libva or the Intel GPU driver to enable hardware accelerationÂą. And so last year we started building Libva and the Intel media driver from source to lay the foundation for hardware acceleration in the Chromium snap.

Such a process generally involves debugging with e.g. correct dependency resolution and environment fine tuning; here is what a typical merge request looked like.

We had hit-or-miss results with those builds; it was clear that we would need time and structure to get reliable results. The original intent to merge this directly into the dev source tree (used to build the main snap on the edge channel) was thus abandoned, and instead the hwacc branches were created to continue those efforts in a staging area that would be used to build opt-in snaps.

With the help of more Canonical’s eyes², Intel’s partnership and automated tests for different hardware configurations, we are now in a much better position to merge our work into the main Chromium snap.

Scope and testing

The scope of the project are machines with Intel GPU. To verify if your machine is covered, go to Settings > About and see if your graphics is Intel HD or UHD Graphics (you can also use the command line: lspci | grep HD\ Graphics).

u1

If yes, your machine will benefit from the hwacc Chromium snap. It is still in testing, but if you want to give it a try, run:

snap install --channel candidate/hwacc chromium

Monitoring whether your Intel GPU is actually used for decoding video is straightforward with intel_gpu_top, provided by the intel-gpu-tools package:

sudo apt install intel-gpu-tools
sudo intel_gpu_top

Then use the browser to play media (video calls are also covered) and verify in intel_gpu_top that the video engine is busy (video demonstration).

For that VP8 video, hwacc Chromium brings the CPU consumption down from roughly 110% to 50% in my experiment — that will vary from machine to machine.

Finally, it must be noted that, although the support for hardware accelerated video encoding is quite broad, not absolutely all codecs are supported, and for video encoding that number is more limited. The exact Intel platform can also be a relevant variable.

Why Intel platforms only

We have to start somewhere and generally speaking Intel provides the best support in drivers and maintenance for Linux.

As such, acceleration in Chromium hwacc snap is currently done via the VA-API over Libva. If you look for kVideoDecoderName in about://media-internals while playing media, it will say VaapiVideoDecoder — if the functionality is actually working.

Where does development happen and how is it organized?

The repository lives in Launchpad and the edge/hwacc snap is built there.

In the main Chromium snap, stable, beta and edge channels map to upstream’s stable, beta and dev channel. The hwacc snap does not follow that routine and edge/hwacc is manually promoted to candidate/hwacc when its ready.

What exactly are the hwacc changes?

By now the changes are merged into the official edge channel, so just see the merge commit.

For example, these are flags enabled by hwacc Chromium:

  • --use-gl=angle --use-angle=gl: select OpenGL renderer.
  • --enable-features=VaapiVideoDecoder,VaapiVideoEncoder,VaapiVideoDecodeLinuxGL, to enable VAAPI video decoding in Linux — upstream only enables that in ChromeOS by default.
  • --enable-features=UseChromeOSDirectVideoDecoder to use VaapiVideoDecoder instead of the legacy VDAVideoDecoder.
  • --video-capture-use-gpu-memory-buffer enables one-copy, observed to slightly reduce power consumption.
  • --ozone-platform-hint=auto to use Wayland Ozone backend if Wayland is detected as the system platform but not if Xorg is detected as the system platform.

If you are giving it a try, let us know your observations. Bug reports are always welcome, you can file one with ubuntu-bug chromium-browser or directly via the Launchpad interface.

ÂąThis is not a problem anymore since Chromium is migrating to core22. In fact, the Gnome 42 extension itself provides the driver now.

²Hector Cao, Bram Stolk, Daniel van Vugt, Sebastien Bacher, Ricardo Martins, Pierre Equoy.

12 Likes

Thank you for the great post!
It helped a lot to me and hw acceleration now works on my GPU also:
Intel® UHD Graphics 620 (verified on two different Intel CPUs)
Also, just to mention that for me I had to use the following arguments, maybe it helps to someone else also:

chromium --enable-features=VaapiVideoDecodeLinuxGL --disable-features=UseChromeOSDirectVideoDecoder --ignore-gpu-blacklist --enable-zero-copy

Question: do you maybe know when this change will land in the stable Chromium branch?
Thanks!

You may actually want to remove the flag --video-capture-use-gpu-memory-buffer from the builds, as it completely breaks webcam input:

ERROR:video_capture_impl.cc(501)] Failed to open GpuMemoryBuffer handle

It can be worked around by creating ~/.chromium-browser.init and adding CHROMIUM_FLAGS="--disable-video-capture-use-gpu-memory-buffer" to it, but that is not exactly user friendly (and rather redundant).

Upstream the Chromium developers say that the --video-capture-use-gpu-memory-buffer flag is broken and that packagers should no longer be using it.

Do the packagers need to be advised to remove this, or should the flags work as intended?

Yes. If you could inform them, please do so. On Chrome M116 that flag got broken, unfortunately. The flag had absolutely no effect before that, actually. In the future it will be enabled automatically when supported. So it’s a good idea to remove that flag from the config for all versions.

I’ve reported this bug on Launchpad as well.

1 Like

@milmilu, sorry for the late reply! Since last month upstream enables VAAPI code paths for building in Linux by default. So next month it should hit stable and then, even if the flags are not passed are not passed by default in the launcher (that will need to be discussed), the user would be able to pass them.

@the7thstranger, thank you for bringing that to our attention.

1 Like