Bonjour, bonjour! Another long overdue episode of your favourite Mozilla gfx team newsletter is here. A few weeks ago, Jessie published a call to help us find steps to reproduce a mysterious glitch. Thanks a ton to everyone who helped out with this one! Glenn landed a fix to an issue that we suspect might be the cause of the issues 🤞. Don’t hesitate to let us know if you are still running into this particular glitch with Firefox Nightly and WebRender enabled.

Other than that there are a number of pretty exciting things going on in WebRender. One of them is Lee and Jeff’s work on a software backend for WebRender. In order to eventually move all Firefox users to WebRender, we need a backend that can accomodate for very old GPUs and very buggy drivers. Ideally this backend would use most of WebRender’s current code and infrastructure to avoid having too much new code (and bugs!) to maintain with our limited resources. One of the avenues that was investigated is using a software emulation layer for OpenGL such as Swift Shader or llvm-pipe as a black box to run our GPU code on the CPU. We unfortunately couldn’t get good enough performance this way so Lee is now experimenting with automatically translating our shaders into SIMD-optimized CPU code while compiling Firefox instead, with SIMD optimizations. These “software shaders” are then run into a simple custom rasterizer that only supports the few OpenGL features that we need and take advantage of the restricted featureset to run as fast as possible. This is still very much experimental but initial results are promising.

A lot of progress was also made towards DirectCompositor integration which I have mentioned a few times in this blog. Glenn, Sotaro and Jeff are ironing out the last few bugs (famous last words!) before the feature can ride the trains to release. A lot of work went into making video playback very efficient in this new compositing mode.

What’s new in gfx

Botond and Ting-Yu collaborated to fix an Android regression where pinch-zooming while text is selected could cause the view to jump to the top-left corner of the page.

Kats fixed a task exhaustion issue with the hit-testing dumping code.

Botond and Decoder fixed a race condition;

Botond fixed some race conditions in APZ caught by thread sanitizer.

Kats reenabled test_group_pointerevents.html for GeckoView.

Martin Stránský avoided passing invalid file descriptors through IPC with dmabuf textures on Wayland.

Bob Owen fixed a crash with canvas remoting.

Kris fixed a crash.

Martin Stránský made the GL compositor backend work with NV12 video textures produced by ffmpeg on Wayland.

Martin Stránský added support for wayland dmabuf textures with WebGL.

Martin Stránský implemented fence synchronization to dmabuf surfaces for WebGL on Wayland.

Sotaro prevented the creation of unnecessary compositor windows.

Sotaro improved the shutdown logic of the VR code.

Markus fixed an invalidation bug with CoreAnimation.

Botond fixed an issue with window.scrollY after maximizing the window.

Martin Stránský implemented dmabuf modifiers.

Tim Nguyen implemented conic gradients with the skia backend.

Nical fixed a crash in the D2D backend.

Jeff Gilbert fixed WebGLSL comment parsing.

Jeff Gilbert optimized GetDrawFetchLimits and vertexAttribPointer in WebGL.

Imanol Fernandez fixed a WebGL crash affecting Firefox reality.

Jeff Gilbert fixed failures in the CTS/conformance2/extensions test suite.

Boris Zbarsky made canvas error handling better match the specification when creating a pattern from an invalid image.

Jeff Gilbert fixed an issue with canvas drawImage and non-premultiplied source images.

Jeff Gilbert improved the performance of the VAO cache under in some cases.

What’s new in WebRender

WebRender is a GPU based 2D rendering engine for the web written in Rust, currently powering Firefox‘s rendering engine as well as Mozilla’s research web browser Servo.

Jamie fixed several bugs in WebRender’s support for scrolling and pinch zooming on Android.

Miko implemented display-list interning.

Glenn made a ton of progress towards efficient video playback with direct composition.

Connor fixed a bug with large blur radii when a scale factor is applied.

Hiro Bug 1510030 running background color animations as WebRender animated properties.

Jamie enabled caching compiled shaders even after statup.

Andrew reduced quantization effects with text.

Andrew prevented quantization effects mismatch between CPU and text shader.

Glenn avoided generating segment instance vectors when there is only a single segment. This was intended as a workaround for running into a limit of segmented primitives which we were hitting in a benchmark, but also gave a nice 10% improvement on the displaylist-mutate benchmark.

Glenn fixed a race condition with memory pressure events causing invalid caches.

Miko made the serialized display list format easier to debug.

Nical made a lot of progress towards unifying the text and brush shading infrastructure.

Nical added a pref to tune batching behavior.

Sotaro fixed an invalidation bug witrh partial present.

Jeff improved render target creation with ANGLE.

Kris fixed a dashed/dotted border issue with Adreno GPUs on Android.

Glenn fixed a crash involving plane-splitting and invalid transform.

Glenn fixed a crash with picture cache dependency building.

Tim Nguyen implemented conic gradients in WebRender.

Glenn added a per-tile valid rect in the picture cache to reduce overdraw in some cases.

Bert improved support for picture cache invalidation debugging and testing.

Jdm removed now unused ipc-channel from WebRender.

Bert [usedd] primitive cluster flags to select picture cache tile size for scroll bars.

Lee fixed an issue causing opaque images to miss the fast image shader.

Nical added a pref to enable/disable rayon in WebRender.

Andrew fixed fixed a stuttering issue involving animated elements with filters.

Jim improved the line decoration shader.

Glenn fixed the invalidation of elements with an inflation factor.

Sotaro made profiler screenshots and frame recording work with DirectComposition integration.

Nical fixed incorrect border-image repetitions.

Nical implemented border-image-repeat: round in WebRender.

Nical reduced the amount of allocations in the render task graph.

Kvark fixed an issue with the solid border shader.

Connor moved the opacity filter to its own shader.

Nical removed accidental string manipulation in performance sensitive code.

Bert avoided using rayon for glyph rasterization unless the number of glyph is high enough to compensate for rayon’s overhead.

Simon Sapin avoided rounded corner paths in some cases where it isn’t needed.

Connor added support for alpha components on the SVG color matrix filter.

Jeff fixed a clipping issue when painting a xul tree.

Timothy fixed an issue with orphanned displaylist with fission and WebRender.

Jamie [ensured](Bug 1613144) the async scroll offset is in the correct coordinate space whilst async zooming.

Jamie fixed position:sticky during pinch-zoom.

Sotaro fixed a glitch with window recording on Windows.

Jeff allowed more blob images to be marked as opaque. This change allowed scrollbars to be marked as opaque on Windows which reduced the GPU utilization in the DWM with DirectComposite enabled from 21% to 17% at 1080p and 29% to 24% at 4k.

To enable WebRender in Firefox, in the about:config page, enable the pref gfx.webrender.all and restart the browser.

WebRender is available under the MPLv2 license as a standalone crate on crates.io (documentation) for use in your own rust projects.

What’s new in WebGPU

Kvark implemented resource binding, compute pass recording, and reworked the asynchronous buffer mapping. All of that has landed now, and Firefox Nightly is able to run the standard compute example :tada: (when the pref is enabled)

Kvark spoke at Fosdem 2020 about our Rust-based WebGPU infrastructure. This presentation was derived from an internal talk about WebGPU that happened at Berlin All Hands, slides from which are also available. It had more focus on the Web API and Firefox architecture.