Friday 16 July 2010
Retained Layers
Retained Layers has landed and seems to have stuck.
In a previous post I talked about our layers framework. Up until now we've constructed a new layer tree on every paint. With retained layers, we update our layer tree incrementally as content changes in the window. More importantly, we are able to cache the contents of layers. So for example if you have an element with partial opacity, we can cache the rendering of that element in a layer and every time you paint (perhaps with a different opacity each time), we can paint the cached contents without rerendering the element. This provides noticeable speedups for some kinds of fade effects. When we use layers to render CSS transforms, we'll get speedups there too.
One side effect is that we were able to totally reimplement scrolling. Our current scrolling code relies on shifting pixels around in the window for speed, and that often doesn't work well, for example on pages where scrolling content overlays stationary content or vice versa. It's also prone to visible tearing on some platforms because we can't scroll and repaint in a single atomic paint operation. But now, our retained layer tree effectively contains the entire window contents pre-rendered. We can scroll by just adjusting the offsets of some layers and recompositing the layer tree. (Well, almost ... it's slightly more complicated.) This is a relatively simple approach. It eliminates tearing. It lets us aggressively accelerate the scrolling of nasty scrolling pages with complex contents, because we're able to separate the moving content into different layers from the non-moving content and scrolling becomes a matter of simply repainting the scrolled-into-view strip of the moving content and then blending layers together. We're seeing significant improvements in scrolling many kinds of pages. Soon I hope to blog again with more about how this works, what it can do and what the current limitations are.
Immediate improvements are nice, but the most important benefit of retained layers is that it lays down infrastructure we will be exploiting in all kinds of ways. Our D3D and GL layer implementations benefit from reducing browser rendering and caching more rendered content in layer buffers, since compositing buffers is very cheap with GPUs. With those backends, because scrolling is fully layer-based, it will be accelerated by the GPU! Chris Jones is working on enabling layer composition to be in a dedicated process, at which point we'll be able to scroll without synchronizing with the Web content process --- in particular we'll be able to maintain a constant frame rate of smooth scrolling no matter what the Web content is doing, i.e. super-smooth. This will especially benefit Fennec. Fennec will also benefit because its current tile-caching implementation can be replaced with something layer-based; our layer-based scrolling permits the layer manager to cache prerendered content that's not (yet) visible.
Before we ship the next Firefox release there are a few regressions to work on and some performance and quality knobs to tweak. But I'm feeling quite relieved, since this was one of the long poles for that release and the one I've been most on the hook for.
Comments
But what about memory tradeoff for retained Layers?
I look forward to enjoying the improvements with Firefox 4.
PS:
The "previous post" link is broken and should probably be http://weblogs.mozillazine.org/roc/archives/2010/04/layers.html.
It seems like most everything in Firefox is going to be hardware accelerated and that can't be a bad thing.
But this, Robert, this is different. It's the best thing since sliced bread, really! There might be a bug hidden here or there but this rework resolves issues on all the pages I bookmarked for this kind of issues.
So did already I say I'm pleased and happy? Thanks for all this hard work!
BTW, will this be Gecko 2 only or 1.9.x too?
Will there also be hardware acceleration for Windows XP?
By the way, are we using CGLayers on Mac now? If so, how did you solve the flippedness problem you mentioned in that other blog post?
Stefan: fixed.
Mike Ratcliffe: "It seems like most everything in Firefox is going to be hardware accelerated and that can't be a bad thing." ... well, it can! doing things on the GPU isn't always the best approach.
robome: it'll be in the next Gecko release, which I believe is going to be called Gecko 2.
Alfred: yes, our D3D9 layers backend works on Windows XP.
"even with the hardware acceleration, scrolling is now very smooth in Firefox on Windows XP" --- I think you meant "without". Hardware accelerated browser windows are not enabled yet unless you do something special (and then they probably don't work very well!).
Markus: Yes, we're using CGLayers now. That may account for the 8-9% Tp win we saw. In cairo we flip the Coregraphics transformation matrix to get around those problems.
Livio: yes, our GL backend works on Linux, at least on some hardware and drivers. Fullscreen video uses it already.
I'm curious about layered plugins. On Linux, Flash, VLC, etc. are all rendered always on top of other layers, regardless of their layer's position/order. Will these changes solve this artifact? We're working on a project heavily involved with video streaming and, given the HTML5 real-time video streaming support is still quite buggy for a workaround, the best approach would be to use one of such plugins, but we can't use them as nothing can be rendered on top of it right now :(
Windowless plugins integrate much better with the browser's rendering pipeline because we can get the plugin's rendered pixels and process them any way we need. But for video rendering, windowless doesn't perform as well because current windowless plugin rendering relies on having the plugin draw into an X pixmap, so it's hard for the plugin to use GL for acceleration. We need a new windowless plugin drawing API that lets the plugin use GL and lets us get the GL FBO or whatever and render it in our own GL pipeline. We're still getting our GL pipeline up for regular browser windows (we use it for fullscreen video already); once we've done that, we'll be proposing a GL drawing API for windowless plugins.
Excellent work!
Will GPU-accelerated scrolling use Core Animation on OS X, or are you implementing your own GL code for this?