WebRender newsletter #10

Another long overdue newsletter is here (I still consistently underestimate the time it takes to gather information and write these up, oops!).

I have been using Firefox with WebRender enabled as my main browser for a little while now on various computers. It’s great to see that it actually works and on many pages outperforms Firefox without WebRender. Of course we are still hitting pages where WebRender doesn’t perform very well but these tend to highlight specific areas of WebRender with a naive implementation that hasn’t been optimized yet. It’s quite satisfying because these tend to be quickly fixed. We aren’t running into fundamental design flaws which is always a risk when rewriting such a large piece of tech from scratch.

There are some configurations with graphics drivers that play very well with WebRender (intel on linux and nvidia on windows have worked quite well for me so far) and others that don’t (I’ve had a lot of issues with the proprietary nvidia drivers on linux and whatever intel chip is on the low end surface tablets for example). Fine tuning WebRender to play nice with the most common hardware and driver configurations is going to be a big challenge that we’ll have to go through before shipping, and we aren’t quite there yet.

Before I go through some of the code changes, I want to give shout-out for Darkspirit who is helping a lot with testing and triaging on bugzilla and github. Thanks a lot!

Update – What does image.mem.shared do?

This is a popular question in the comments section of this post, let’s see:

Gecko has an internal representation of the page that we call the Display list. When WebRender is disabled we walk through this display list and each display item on the list knows how to paint itself into the destination surface on the content process. WebRender has its own display list format, which is a little different, and we have to turn the Gecko display list into a WebRender display list and send it to the GPU/compositor process where WebRender renders it.

At the early days of WebRender’s integration we started with a rather naïve transformation of the display list that would have each Gecko image display item create a WebRender image object, copy the decoded image into it and create a WebRender image display item that refers to it. This meant that if two display items were referring to the same image, they would each create their own WebRender copy of the image. Ouch! If you have a “sprite sheet” (a big image that has for example all of the icons in the page and many HTML elements refer to portions of that image) in a site, which is fairly common, this would go very wrong very quickly, because the sprite sheet would end up duplicated many times (lots of CPU time, and memory bandwidth spent copying data around, and a lot more memory used as well).

Andrew’s work, in a nutshell, made it so that we can decode the image in shared memory directly (removing an expensive copy) and have all image display items that are using the same image refer to that shared image object instead of creating their own copy (no more duplication). And this will soon be enabled by default but is currently behind the “image.mem.shared” pref. Note that we are (well, Andrew is, single-handedly) still in the process of getting SVG images to work well but it isn’t implemented yet (If you are wondering why your memory usage explodes when adding an emoji in mastdon for example, that’s what is happening, and will soon be fixed).

Notable WebRender changes

  • Glenn is incrementally refactoring WebRender’s frame building and batching architecture to better support segmenting primitives into parts and move as many pixels as possible to the opaque pass. This ongoing work is spread over many pull requests and has already yield great performance improvements.
  • Morris greatly improved the performance of blurs with large radii.
  • Nical fixed a bug in the rendering of dotted borders.
  • Gankro further improved serialization of glyphs.
  • Glenn removed the need to re-build scenes every frame during scrolling (this is a big CPU win).
  • Glenn implemented filtering out render tasks for filters that have no effect such as opacity(1.0).
  • Kvark made it possible for GPU queries to be toggled at runtime.
  • Nical improved the UI of the integrated GPU profiler a bit and exposed the settings to gecko.
  • Kvark investigated some of the remaining performance issues with motion mark.
  • Ethan fixed some issues related to pre-multiplied alpha and filters.
  • Kats fixed a hit testing bug.
  • Nical Implemented rendering common bullet points with webrender display items instead of blob images.
  • Kvark made the depth buffer optional in render passes to save memory bandwidth where it isn’t needed
  • Ethan fixed another rendering error with pre-multiplied alpha.
  • Kvark implemented support for the new document API on the renderer side.
  • Kvark worked around a GLSL compiler bug.
  • Kvark improved the logic that recycles render targets.

Notable Gecko changes

  • Kats completed the implementation of position:sticky.
  • A collection of motionmark work:
    • jrmuizel landed a change to avoid invalidating blob images on tiny scale changes
    • Kats fixed a bug which was taking about 19% of client side motionmark time
  • Lee optimized the way we send fonts to WR and eliminated font copying as a source of main thread jank.
  • Vincent fixed a crash.
  • Ethan fixed a bug that caused blob images to be missing.
  • Andrew landed scaled image container support which should reduce frequency of fallback rendering (See bugs 1183378, 1368776, 1366097.
  • Andrew made shared surfaces reuse the same image key across display items , need to set the pref “image.mem.shared” to true.
  • Andrew improved the performance of using SVGs as mask-image.
  • Jeff ensured we don’t fall back with -moz-border-*-colors on border sides that don’t have a border (the fallback was hitting us on gmail).
  • Sotaro improved the performance of recompiling shaders by caching the shader binary.
  • Ethan fixed a memory leak.
  • Lee implemented rendering pre-transformed glyphs in WebRender.
  • Sotaro removed a synchronization happening when submitting frames with ANGLE on Windows.
  • Morris and Sotaro fixed pipeline leaks.
  • Nical avoided using blob image serialization for content that must be panted on the content thread (such as native themed widgets).
  • Morris enabled WebRender support for filters (hue-rotate, opacity, saturate).
  • Kats Made APZ use WebRender’s hit testing code and later completed it to work with scroll bars and scroll thumbs.
  • Jerry integrated WebRender’s threads with gecko’s built-in profiler.
  • Markus improved the performance of rendering the title bar on mac.
  • Sotaro fixed some issues with google maps.
  • … and whole lot of other things as shown in the list of bugs closed since the previous newsletter.

Enabling WebRender in Firefox Nightly

In about:config:
– set “gfx.webrender.enabled” to true,
– set “gfx.webrender.blob-images” to true,
– set “image.mem.shared” to true,
– if you are on Linux, set “layers.acceleration.force-enabled” to true.

Note that WebRender can only be enabled in Firefox Nightly.


30 thoughts on “WebRender newsletter #10

  1. Hi Nical.

    I have been using WebRender some time ago on Linux (Fedora) and turned it on again yesterday. I am facing two issues which I am not sure those are bugs, or expected.

    First the address bar drop-down takes long to open for the first time.

    Second any UI popup (e.g. Library or Page actions menu) have a blank frame around, both above the UI and website. May that be connected to Wayland a different painting backend used for UI and content? Should I report it?

    1. The slowness of creating new windows (including the main window, the address bar’s suggestions, etc.) is a know issue. It’s because shaders take a long time to compile. The plan to fix this is to cache shader binaries so that they only need to get compiled once, and also spend some time optimizing shader compilation itself.

      Blank popup UIs is also a know bug, I have seen it somewhere in bugzilla recently but I don’t have the bug number handy.

      1. Yeah, I love the work and publications from the Dolphin folks. I am hopeful that we won’t get to that point though, as our situation is a lot simpler than what they had to deal with (we have a finite and rather small set of shaders to compile). If the lower hanging fruits fail this is indeed an option.

  2. Hello Nical!

    Awesome job you and your team are doing. Love testing out WebRender on Ubuntu.
    Have a minor bug tho, not sure if its on your radar.

    The entire Firefox windows flickers white randomly on some sites.
    It happens on YouTube, reddit and quite randomly.
    Are you aware that this is happening.

    Also the shadows behind text on tab titles are kinda botched.
    And the Main Menu(hamburger has a white rectangle around it)

  3. WebRender performs mostly well for me now, unfortunately the Compositor process often seems to be the cause of performance problems by constantly hanging at over 30 ms in the red zone, even on static pages. It helps to kill the GPU process and let WebRender restart until it hangs again.
    Is this known behaviour or can I work around that somehow?

    1. Don’t hesitate to file a bug for this. This type of behavior tends to be driver specific and it’s good that we know about them if we don’t happen to have hardware that reproduces it handy.

      1. As it’s a Skylake system, which according to Mozilla’s hardware report is very common, I will do that. However I don’t really what information to offer in the ticket. What would help your team in this situation, a performance profile?

      2. You can type about:support in the address bar and copy-paste the content of the graphics section of that page in the bug, it contains info about your hardware and driver versions.

  4. It doesn’t seem ready for me yet, WebRender fails to load according to about:support, so I’d have to wait a bit more. :) (Using Windows 7 with Intel HD graphics)

    1. I don’t have an AMD GPU to test on, we’ll do our best to test on a variety of hardware when there will be less moving parts. A vulkan backend will certainly be a fun thing to work on after we have stabilized the GL backend, but no concrete plans for that yet.

  5. What does image.mem.shared?

    Using Webrender for 3 weeks now. Filled 2-3 bugz. It makes progress. Most visual problems are the black drop-downs and black areas on start (as it was written in comment above).

    I do not see any speed improvements comparing with Firefox. Actually my notebook is betting very hot and freezes. Video playback is sluggish. I have not yet filled a bug for it. Will wait a few weeks. Maybe it is a known issue.

    1. I updated the post with an explanation of the image.mem.shared pref.

      The drop down menus and startup issues are know and we are working on them. Performance is also a big area of focus obviously, although if you are experiencing WebRender to be always slower there may be driver issues at play, and we’ll probably be going through most of those at a later stage in the project.

  6. HI Nical
    I have been using WebRender since WebRender Newsletter 5# when It was first told it could be used.
    Thank you for all you do and for this newsletter because I like it. And I like testing WebRender but I too don’t know what image.mem.shared does? Thanks you

    What does image.mem.shared do? Because I have it set it true and i did restart Firefox Nightly 59 64 bit. Using windows 10 Fall creators up date. And I see no difference. But only drop down menus that I have that show up are… snooze tab and htpps everywhere add-ons. The other add-ons drop down menus not showing up are… Disconnection menu does not show up at all and bandwidth hero menu only show a blank white drop down box and adguard sometimes does not show a drop down menu at all Thank you

    1. Thanks a lot for the kind words. I updated the post with an explanation of the image.mem.shared pref. Also, the drop down menu issues are known and being worked on.

  7. The shared memory image makes me wonder about this possibly stupid question: If I generate something like a 32 bit BMP (where the image data is exactly the same as the texture needed to display it), in a MMAPed file, then send it to the a browser on localhost with sendfile….

    Would the browser display it with 0 copies on the whole route?

    1. For now there is a copy between the the network/file system abstraction that streams the image to the content process and the graphics engine. What image.mem.shared removes is copies between the content process and the compositor/GPU process. I updated the post with some more explanations.

  8. Hi Nicals
    I am not complaining i am just posting my issue that I’m having with my add-ons I use to download for off-line viewing.
    What I wrote in the first about not seeing a difference.. I now do there are two new things different when I use image.mem.shared set to true. The add-on download video and flash does not work at all like it use to, just a gray out. And 1-click Youtube Video Downloader does not show up under any youtube video and work like it use to.

  9. Hi Nical
    I still like the newsletter and all that you do. And I did read the Update – What does image.mem.shared do? It did like it… and it did completely help it answer the question. Thank you I still like testing WebRender.
    I am not complaining I just letting you know about the problems.
    I use Firefox Nightly 59 64 bit… and I don’t know of and see anyway to restart the Firefox Nightly 59 64 bit. And it is needed to… temperately fix the problem and when about:config is used. Because if you close and open Firefox Nightly59 64 bit the restore previous session won’t work and I will loose my previous session. But If I new of away to restart without loosing my previous session that would help until problem got fixed thank you.
    I am not complaining but… I don’t know if you know about this problem but… after some time the time is always different painted layers show up. And they show up on all the tabs, there is a gray square blink over the right arrow on the address bar, and on this website the login icons blink too. And I don’t know what causes it because… when I check about:config gfx.webrender.highlight-painted-layers is not set to true it is set to false like it always was. Thank you

    1. Look in the settings for something like “Show the windows and tabs from last session” (I’m translating from italian).

  10. Hi Nical
    I still like what you do and the newsletter to. And I still like testing WebRender.
    I not complaining i’m just saying but.. I get it WebRender takes alot of time and work. But WebRender still needs to work better then having WebRender disabled. I still like testing WebRender. I not complaining i’m just saying but..
    WebRender is to slow unless you have wifi or anthing else that is fast enough not to be bother by how slow WebRender is. Also when tethered to mobile internet data WebRender if and when your internet connection is to slow WebRender will be.. unusable and disabling WebRender will work better. . What I’Im saying is that WebRender needs to be able to handle all different types of speed from deathly slow to blazing fast and… everything in between and connection types… from mobile data, wifi and anything else there is like Firefox Nightly 59 64 bit can with WebRender disabled can. Thank you I only use Firefox Nightly on my Windows 10 Fall creates update laptop. Thank you

Leave a Reply

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

WordPress.com Logo

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

Twitter picture

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

Facebook photo

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

Connecting to %s