moz://gfx newsletter #52

Hello everyone! I know you have been missing your favorite and only newsletter about software engineers staying at home, washing their hands often and fixing strange rendering glitches in Firefox’s graphics engine. In the last two months there has been a heap of fixes and improvements. Before the usual change list I’ll go through a few highlights:

  • A number of us focused on shipping WebRender to a wider range of Intel devices on Windows. This involved quite a bit of testing, profiling, puzzlement about driver behavior and of course heaps of improvements, a lot of which will benefit other configurations as well. See the “WebRender where” page for an overview of WebRender’s deployment.
  • DirectComposition integration with picture caching was a very important part of making this possible, yielding big performance and power usage improvements. It is now enabled by default on windows as of Firefox 75 in some configurations where WebRender is enabled and will expand to more configurations in 76 and 77.
  • In 76 we have improved DirectComposition usage for video playback. This reduces GPU usage during video play a lot. On an Intel HD 530 1080p60 video playback has 65% usage with WebRender on in 75, 40% with Webrender off, and 32% usage with WebRender on in 76.
  • The new vsync implementation on Windows, which improved our results on various benchmarks such as and motionmark, reduced stuttering during video playback and scrolling.
  • Steady progress on WebRender’s software implementation (introduced at the top of the previous episode), codenamed SWGL (pronounced “swigle”), which will in the long run let us move even the most exotic hardware configurations to WebRender.
  • And hardware accelerated GL contexts on Wayland, and pre-optimized shaders, and WebGPU, and… So many other improvements everywhere it is actually quite hard to highlight only a few.

What’s new in gfx

  • Botond and Micah Tigley added initial support for double-click-to-zoom gestures in Responsive Design Mode
  • Botond and Agi Sferro tracked down and fixed a regression that was causing about:support to load zoomed in on Android.
  • Sotaro re-enabled video frame recycling with the RDD process.
  • Sotaro fixed an issue canvases to not be re-created after GPU context loss.
  • Lee worked around a memory leak.
  • Markus fixed a rendering glitch.
  • Jonathan Kew avoided defaulting to a monospace font as fallback on MacOS.
  • Nical attempted yet another fix at a crash that keeps coming back.
  • Jonathan Kew implemented distinguishing between OS-provided and user-installed fonts in the system font list.
  • Botond fixed non-unified build errors.
  • Kats improved the behavior of momentum scrolling.
  • Jonathan Kew fixed a crash.
  • Kats prevented the viewport clip from clipping position:sticky items.
  • Kris added desktop-zooming information to about:support.
  • Snorp made it possible to disambiguate top-level from other APZ events.
  • Roger Zanoni addressed some static analysis lints.
  • Chris Martin removed some usage of gdi surfaces on windows for sandboxing.
  • Andrew enabled color management for all images and not only tagged ones.
  • Jushua Gahan addressed some static analysis lints.
  • Timothy fixed an invalidation issue with display:none masks.
  • Sotaro fixed a canvas rendering issue when resuming on Android.
  • Jonathan Kew fixed a font metrics related issue.
  • Bob Owen fixed an intermittent issue with canvas remoting.
  • Kats fixed some issues with the dynamic toolbar sticky behavior on Android.
  • Miko fixed an issue with opacity optimization.
  • Bert improved the vsync implementation on Windows.
  • Arash Fotouhi addressed some static analysis lints.
  • Robert Mader implemented creating an OpenGL context with the Wayland backend on Linux.
  • Lee fixed a shutdown crash related to font loading.
  • Jonathan Kew fixed a printing issue with long SVG stroke-dasharray strings.
  • Sam Dalton improved the FPS counter implementation.
  • Kats removed the old android dynamic toolbar implementation.
  • Sotaro improved some OpenGL context debugging utilities.
  • Jonathan Kew fixed a font visibility issue with language-pack fonts on Windows.

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 a regression preventing picture caching from working well on Android.
  • Jamie implemented GLSL shader optimization at build time, resulting in quicker startup times.
  • Glenn added support for the tracy profiler in WebRender.
  • Miko added more items to display item caching.
  • Nical improved texture cache eviction and allocation heuristics to reduce the amount of texture reallocation.
  • Lee implemented a number of shader features in SWGL.
  • Nical prevented the texture cache from deallocating textures if it is about to allocate new ones.
  • Nical reduced the amount of alpha texture reallocations in the texture cache.
  • Connor Brewster fixed the max blur radii to take scale factor into account.
  • Jeff fixed a clipping issue with blob images.
  • Nical fixed clipping issues with shadows.
  • Nical fixed invalid glyph rasterization being requested continuously.
  • Glenn reduced picture cache invalidation with very large rectangles.
  • Miko added memory reporting to the display item cache.
  • Nical made WebRender’s builtin profiling tool more useful.
  • Timothy improved the stacking context scale factor selection to avoid blurriness under certain conditions.
  • Dzmitry fixed a crash caused by picture tasks exceeding the maximum supported texture size.
  • Glenn fixed picture cache tiles being evicted too eagerly.
  • Lee implemented perspective-correct rasterization in SWGL.
  • Glenn fixed a picture caching invalidation bug.
  • Kats and Kris implemented WebRender’s interaction between position:sticky and the dynamic toolbar.
  • Bert added a fast path for more gradient types.
  • Dzmitry fixed missing data in WebRender captures.
  • Kats removed the initial document splitting code.
  • Sotaro made it possible to enable WebRender without GPU process on Windows.
  • Timothy fixed an issue with incomplete SVG masks.
  • Glenn reduced the amount of texture reallocation in the render task target pool.
  • Nical reduced technical debt in WebRender’s message channels.
  • Jamie ensured upload strides are a multiple of 64 pixels on Adreno to avoid driver slow path.
  • Jeff disabled DirectComposition when the resolution is scaled and the compositor does not support stretching, to avoid rendering artifacts.
  • Nical reduced technical debt in the blob image rendering code.
  • Dzmitry fixed a clipping bug.
  • Lee implemented linear filtering for SWGL glBlitFrameBuffer.
  • Andrew fixed a memory leak with off-screen GISs.
  • Sotaro fixed some skipped frames when recving window expose events.
  • Jim added documentation to WebRender’s headless testing scripts.
  • Jim fixed a lot of compiler warnings in SWGL.
  • Sotaro simplified the DirectComposition integration code.
  • Andrew Added support for capturing sequences of frames when debugging WebRender.
  • Nical removed the deprecated recording tool in WebRender.
  • Kats fixed some github CI issues.
  • Glenn fixed a rendering issue involving a combination of blur, drop shadows and video.
  • Glenn simplified the image masking API.
  • Lee fixed a pixel rounding issuel with SWGL.
  • Kats fixed an APZ issue causing some frames to be skipped.
  • Jamie fixed a bug causing black screens on Android.
  • Nical refactored a lot of message passing code in WebRender in preparation for upcoming frame scheduling improvements.

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 (documentation) for use in your own rust projects.

What’s new in WebGPU

WebGPU is a new Web API to access graphics and compute capabilities of the hardware. Firefox and Servo have implementations in progress that are based on wgpu project written in Rust.

  • Dzmitry implemented render passes, samplers, textures, texture views, and other missing pieces of the API.
  • Dzmitry implemented support for presentation based on the CPU readback path.
  • Firefox Nightly is now able to run both Chrome’s WebGPU examples as well as the ones we cross-compiled from Rust to WASM in wgpu-rs.
  • Dzmitry published the article to Mozilla Hacks blog featuring the status of the API as well as our emerging implementation in Firefox (Nightly only).

To enable WebGPU, follow the steps in, which also shows the current implementation status in all browsers.


15 thoughts on “moz://gfx newsletter #52

  1. BTW opening PDF in firefox have a font rendering issue. its abnormally bold. and aliased. out of curiosity if PDF rendering done by webrender. and the other question is is webrender actaully rendering the whole graphics on the screen or composing and passing the rendering to libraries like skia?

    1. WebRender does not handle printing/pdf rendering, it goes through a different system. WebRender is actually rendering the whole graphics on the screen as you say, with a few exceptions. When a primitive isn’t supported by WebRender it goes through a fallback system we call “blob images” and these are rendered using skia, turned into images and inserted into the rest of the content. SVG primitives like paths typically go through this fallback.

  2. Why can’t you fix vsync properly as suggested on the “firefox vsync is broken” page on vsynctester?

    I’ve tried with 77.0a1 (2020-05-04) (64-Bit) and it shows lots of jitter with occasional huge spikes, drift, and the test image has visible issues. In the test it scores ~130.

    Chrome has next to no jitter, no drift, the test image is visually perfect, the score is ~520.

    This is on a 1440p, 144 Hz monitor with a Nvidia 2070S GPU.

    1. I think you might still need to toggle `gfx.vsync.use-waitforvblank` to ture in about:config to use the new implementation. Does it work better if you do so?

      1. Didn’t do anything. Also updated to 78.0a1. Score is ~140 now (which may be simply due to a fresh profile without any other tabs open) but all the same problems persist.

    2. Have to agree with this one. The people make compelling arguments as to how the current implementation still has issues. Using Nightly 78.0 2020-05-05 I’m running on a 50hz (yes, 50hz) monitor and though the animation is butter smooth, the reported frame times are EXACTLY 19.0, 20.0, or 21.0 ms. For every single frame. This is bogus, there’s no way these are correct times. Edge frame times are reported with both more random jitter and with a smaller statistical range (+/- ~0.1ms), and because of this I’m inclined to think its implementation is more correct.

      Also the pref I have is called ‘gfx.vsync.force-disable-waitforvblank’ and it’s defaulted to false. So I’m assuming I’m using the new behavior. Flipping it to true and restarting the browser has no discernable effect and exhibits the same behavior.

      1. The reason for these bogus frame times is the reduced JavaScript timer precision. See my other new comment below for the fix :)

        (And yes, ‘gfx.vsync.force-disable-waitforvblank’ should definitely be false :)

      1. That’s why it’s so sad and why I am struggling to understand why firefox devs didn’t properly fix it in the past 4 years.
        I hope you realize that it is still broken, and some of the criticisms on the 4 year old page are sadly still true today.

        I also hope you realize that if this attitude* continues then Firefox will die completely. Usage has dropped from ~33% 9 years ago to not even 5% today.

        *) the devs were made aware of these issues years ago, the devs were made aware that some of the hacks they implemented (instead of fixing it properly) just made things worse, the devs had access to the vsync benchmark over the past years…

        Also, this is not a one-off. There are other areas where Firefox clearly has issues but either devs deem it as “good enough” or they are waiting for their dying user base to get frustrated enough to report in in their crappy bug tracker software.

      1. You don’t understand what you’re talking about.
        The poor measured performance doesn’t change one bit if you change the user agent.

        The warning for firefox being broken is – obviously – only shown to firefox users and the browser is identified through the user agent string.
        There is no warning for chrome because chrome is not broken.

        You say that it’s “working fine” while showing a screenshot of actually quite poor performance with firefox. So I guess it’s fair to call you a blind firefox fanboy, after all you called the site a “firefox hater”, right?

    3. After more testing, I figured out that the bad result here is not accurate, FF is reducing timer precision for security/privacy reasons (as explained on the “FF is broken” page. There’s actually 2 ways you can get around this:

      1. Click the gear on the website, then check “Use rAF time arg as frame time”. This uses a different method of getting the frame times that isn’t affected by the reduced timer precision.
      2. Go into about:config and set “privacy.reduceTimerPrecision” to False and reload vsynctester.

      Interestingly enough, the “Firefox does NOT actually wake up on VSYNC:” part of the “FF is broken” page is exactly what is now fixed in the new version.

      1. (Note that method 2 might be more accurate, as per the “epilogue” of “FF is broken”.)

      2. This is actually the most useful information in this thread. Thank you. I wonder if the improved vsync mark with “privacy.reduceTimerPrecision” disabled has tangible effect on day to day browsing or just for benchmark, because then we can discuss the trade off between privacy and performance and give users a choice.

        Also note that with the ol’ Direct3D backend, I can still see the gray VSYNC indicator stutters to red or cyan even with “privacy.reduceTimerPrecision” disabled. With Webrender, the stutter is completely gone, bringing it to the comparable performance to Chrome. Good job.

  3. Hello Nical,

    Why does my configuration display webrender not allowlist, my Nvidia card is GeForce GTX 950M.
    Firefox version is 77 currently.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s