**Firefox Hacking in Fedora: A New Era for Firefox and Linux**
Last year was a significant milestone for Firefox on Linux, with numerous improvements and bug fixes that pushed the browser to new heights. One of the most exciting developments was the implementation of HDR video playback support, reworked rendering for fractionally scaled displays, and asynchronous rendering.
The progress made possible by advances in the Wayland compositor ecosystem is a testament to the collaborative effort between Mozilla developers and the open-source community. The implementation of HDR support, tracked by Bug 1642854, is particularly noteworthy. While it's currently disabled by default, users can enable it using the gfx.wayland.hdr preference at about:config or by setting gfx.wayland.hdr.force-enabled if they don't have an HDR display.
The HDR mode uses a completely different rendering path, similar to that used on Windows and macOS. This native rendering or composited rendering places specific application layers directly into the Wayland compositor as subsurfaces. The first implementation was done by Robert Mader at FOSDEM, and I unified the implementation for HDR and non-HDR rendering paths using a new WaylandSurface object.
The Firefox application window is actually composed from multiple subsurfaces layered together. This design allows HDR content like video frames to be sent directly to the screen while the rest of the application (controls and HTML page) remains in SDR mode. It also enables power-efficient rendering when video frames are decoded on the graphics card and sent directly to the screen (zero-copy playback). In fullscreen mode, this rendering is similar to mpv or mplayer playback and uses minimal power resources.
I'd like to extend my gratitude to AMD engineers who provided valuable feedback and suggestions for improvements to HDR playback. We removed unnecessary texture creation over decoded video frames and implemented wl_buffer recycling as mpv does. For HDR itself, Firefox on Wayland uses the color-management-v1 protocol to display HDR content on screen, along with BT.2020 video color space and PQ color transfer function. It uses 10-bit color vectors, so you need VP9 version 2 to decode it in hardware.
Firefox also implements software decoding and direct upload to dmabuf frames as a fallback. The basic HDR rendering implementation is complete, and we're now in the testing and bug-fixing phase. Layered rendering is quite tricky, involving rapid wl_surface mapping/unmapping and quick wl_buffer switches, which are difficult to handle properly. HDR rendering of scaled surfaces is still missing – we need fractional-scale-v2 for this (see below), which allows positioning scaled subsurfaces directly in device pixels.
**Fractional Scaling: A Key Innovation**
The next major work done was for fractional scale rendering, which shipped in Firefox 147.0. We updated the rendering pipeline and widget sizing to support fractionally scaled displays (scales like 125%, etc.). This required reworking the widget size code to strictly upscale window/surface sizes and coordinates and never downscale them, as downscaling introduces rounding errors.
Another step was identifying the correct rounding algorithm for Wayland subsurfaces and implementing it. Wayland doesn't define rounding for it, only for top-level windows, so we're in a gray area here. I was directed to Stable rounding by Michel Daenzer. It's used by Mutter and Sway, and Firefox implements it for those two compositors while using a different implementation for KWin.
Fractional scaling is enabled by default, and users should see crisp and clear output regardless of their desktop environment or screen scale. Historically, Firefox disabled and re-enabled the rendering pipeline for scale changes, window create/destroy events, and hide/show sequences. This stems from Wayland's architecture, where a Wayland surface is deleted when a window becomes invisible or is submitted to the compositor with mismatched size/scale.
**Reworking the Wayland Painting Pipeline**
Firefox 149.0 (recent nightly) has a reworked Wayland painting pipeline (Bug 1739232) for both EGL and software rendering. Scale management was moved from wl_buffer fixed scale to wp_viewport, which doesn't cause protocol errors when size/scale doesn't match (producing only blurred output instead of crashes). We also use a clever technique: the rendering wl_surface / wl_buffer / EGLWindow is created right after window creation and before it's shown, allowing us to paint to it offscreen.
When a window becomes visible, we only attach the wl_surface as a subsurface (making it visible) and remove the attachment when it's hidden. This allows us to keep painting and updating the backbuffer regardless of the actual window status, and the synchronized calls can be removed. This brings speed improvements when windows are opened and closed, and Linux rendering is now synchronized with the Windows and macOS implementations.
**Other Improvements and Challenges Ahead**
In addition to these major achievements, we've also implemented a screen lock update for audio playback, which allows the screen to dim but prevents sleep when audio is playing. We added asynchronous Wayland object management to ensure we cleanly remove Wayland objects without pending callbacks, along with various stability fixes.
However, there are still many challenges waiting for us Firefox Linux hackers. As the ecosystem continues to evolve, we must stay vigilant and adapt to new requirements. Ready, Scrum, Go!