Dramatically reduced power usage in Firefox 70 on macOS with Core Animation
mozillagfx.wordpress.com
mozillagfx.wordpress.com
We do quite a lot of work on a trading website that has heavy use of Canvas and CSS animations, and the latter really kills performance. Two runs on our production website from Intel Power Gadget, pre and post upgrade, show decreased temperature, a lot fewer power spikes, less DRAM wattage, lower GFX clocks, and about 40% less power overall:
Before: https://i.imgur.com/WkdWaHx.jpg
Even better is the news that it's going to improve even further, and the plans to include a Metal backend to WebRender...
Same here, until one of the people responsible for the patches replied to tell me that he fixed it. I've been running nightly builds of Firefox ever since.
Firefox with NoScript runs fast and cool. I love it.
Celebration aside, one particular note (that was known, but still) makes me sad:
> It’s worth noting that the ability to assign an IOSurface to the CALayer contents property is not properly documented. Nevertheless, all major browsers on macOS now make use of this API.
So we end up in a situation where using the most efficient way to display contents now relies on undocumented/private APIs. At any point Apple can break them, or punish us for using them.
CALayer accepts a number of different data types for its contents property, IOSurface being one of them.
Another tip: CAShapeLayer draws on the GPU so simple shapes/strokes can be insanely faster drawn that way vs CoreGraphics.
One thing that is not documented is that the IOSurface must have been created with the 'BGRA' pixel format, or it will silently render as black instead.
Unless Apple wants to break all browsers, that is. At least Chrome and now Firefox use it.
The docs call out using images specifically because that's the 99% use-case; they need to be updated saying that `IOSurfaceRef`s can be used as layer content as well.
`IOSurfaceRef` itself was actually private at one point, IIRC, but isn't anymore.
>This proposal is a bit hacky. The more pure solution would be to teach the compositor to create CoreAnimation layers for Gecko layers, so that for example the throbber animation gets one CoreAnimation layer that contains all the animation frames in a film strip, plus an offset and clip that only shows the current frame. (That's how the Gecko layers are set up for the throbber animation.) Such a solution would be preferable but it would require much more work in the compositor. The tiling solution that I'm proposing in this bug is easier to implement and a bit more generic, because it treats CompositorOGL compositing as a black box that just produces a framebuffer filled with pixels, along with an invalid region.
https://bugzilla.mozilla.org/show_bug.cgi?id=1491456
If I am following this correctly, when dealing with a small on-screen animation, they are moving from having to repaint the whole window to only repainting a largish chunk of the window.
Adopting CALayers at a deeper level in Gekko would allow them to only update the animation itself.
Doing so would require a good deal of additional work.
I can see where it would make more sense to do the deeper integration work "where the puck is going" so to speak.
I appreciate the work you and your comrades are doing.
Do you think 100million is nothing?
Firefox has been my daily driver for well over a year now and I've been extremely happy with it. The gripe I've had has been the heat/power consumption.
Props to the dev team!
Not sure whats going on. 2018 Retina MBP with dedicated GPU running Catalina.
Why are the defaults set this way???
Here's a good post: https://emersion.fr/blog/2019/intro-to-damage-tracking/
To do this with EGL, you need to eglSwapBuffersWithDamage(KHR|EXT) instead of just eglSwapBuffers: https://gitlab.freedesktop.org/wayland/weston/blob/23d01c67a... (isn't it nice to have a GL API that's not terrible? :D)
I think I know how to do it, going to try soon. Bugzilled: https://bugzilla.mozilla.org/show_bug.cgi?id=1590586
And, well, then you are probably still using X server with various terrible extensions that are either polluting the graphics card with constantly composing windows as fast as it will go or, not entirely unlikely, doing CPU blits of window buffers. Just to produce an artifact-riddled not-Vsynced mess.
Sigh.
The state of OpenGL on OSX is terrible.
Yay for proprietary APIs.
https://developer.apple.com/documentation/quartzcore/calayer
Taking advantage of this would require deeper changes in Gekko than this initial change.
https://bugzilla.mozilla.org/show_bug.cgi?id=1491456
Perhaps WebRender will do a better job of leveraging the possibilities of the native platform APIs for the various lesser used platforms?
In any event, it's a huge amount of work to land a change which makes such a huge difference in battery life, and that work is appreciated.
Partial window updates have been available in Windows since long ago (in non-accelerated GDI). Why don't others just copy Windows API instead of inventing their own poor API?
Maybe there is no partial updates because an application can write directly to GPU textures and GPU will redraw entire screen anyway?
Also I am not sure that browser needs OpenGL, because you cannot render text efficiently on GPU anyway and the main content of web pages is text.
> Whenever a layer is mutated in any way, the window manager will redraw an area that includes the bounds of that layer, rather than the bounds of the entire window.
Then the problem still isn't solved because a layer can be much larger than changed pixels.
I agree that browsers using OpenGL is...a design you could reach when measuring for graphics throughput at the expense of all else.
"Vulkan" flag on Android too.
(Post mentioned they plan on implementing metal backend)
Are there any plans to move of off this API?