Closed Bug 1491448 Opened 6 years ago Closed 5 years ago

When using the CoreAnimation present path, use opaque layers for opaque parts of the window

Categories

(Core :: Widget: Cocoa, enhancement, P2)

All
macOS
enhancement

Tracking

()

RESOLVED FIXED
mozilla70
Tracking Status
firefox64 --- wontfix
firefox70 --- fixed

People

(Reporter: mstange, Assigned: mstange)

References

Details

Attachments

(3 files)

The initial implementation from bug 1491442 is going to use a single CALayer covering the entire window, and that layer will not be marked as opaque. We can split the window into several CALayers. CALayer has a private method setContentsOpaque that can be used to indicate that the IOSurface passed to setContents is opaque. Then we can mark opaque areas of the window as opaque, which will mean that the window server can skip the blending step for these layers. This should reduce battery usage during compositing. Whether we want to share the same IOSurface between the layers, or whether we want to use different framebuffers + IOSurfaces for the different parts of the window, is still an open question.
Priority: -- → P2
Assignee: nobody → mstange
Status: NEW → ASSIGNED

This can be verified by starting Firefox with the environment variables
CA_LAYER_SURFACE=0 CA_COLOR_OPAQUE=1
Transparent parts of the window will be red, and opaque parts will be green.

With this patch, the main browser window will be opaque except for the vibrant
areas, i.e. the tab bar and any open sidebars, which will be transparent.
Full screen video will be opaque.

Depends on D40554

On my 2013 Macbook Pro, the patches in this bug reduce power usage of a 60fps compositor animation by 3 Watts in a window with a vibrant tab bar. If I switch to the dark theme, which does not use vibrancy in the tab bar, overall power usage is reduced by 7 Watts.

Testcase, run on 10.14.5: data:text/html,<style>div { margin: 100px; width: 200px; height: 200px; background: blue; animation: 1s rotate linear infinite; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }</style><div></div>

Before, with CoreAnimation:
Overall 19.5 W, GPU share: 6.9 W
After, default theme (vibrant tab bar):
Overall: 16.8 W, GPU share: 4.5 W
After, dark theme (no vibrancy):
Overall: 12.3 W, GPU share: 3.0 W

Without CoreAnimation, transparent context:
Overall: 19.0 W, GPU share: 7.9 W
Without CoreAnimation, opaque context:
Overall: 10.4 W, GPU share: 2.6 W

The next step will be to set things up in such a way that the transparent layers don't need to be refreshed for web content animations. This will require creating separate NativeLayerCA objects for the different parts of the window and teaching CompositorOGL and BasicCompositor to draw into those smaller layers separately.

On pages where the compositing is heavy enough that the GPU stays busy at all times anyway, the patch does not make a difference to power usage.

Attachment #9082844 - Attachment description: Bug 1491448 - Add NativeLayer::SetOpaqueRegion and implement it for NativeLayerCA by assembling opaque and transparent sublayers to cover the regions. r?jrmuizel → Bug 1491448 - Add NativeLayer::SetOpaqueRegion and implement it for NativeLayerCA by assembling opaque and transparent sublayers to cover the regions. r=jrmuizel
Blocks: 1574538
Attachment #9082845 - Attachment description: Bug 1491448 - Maintain an internal opaque region in nsChildView that can be accessed from any thread. r?spohl → Bug 1491448 - Maintain an internal opaque region in nsChildView that can be accessed from any thread. r=mattwoodrow
Attachment #9082846 - Attachment description: Bug 1491448 - Set the appropriate opaque region on the native layer. r?spohl → Bug 1491448 - Set the appropriate opaque region on the native layer. r=mattwoodrow
Pushed by mstange@themasta.com: https://hg.mozilla.org/integration/autoland/rev/7e25fc7daf50 Add NativeLayer::SetOpaqueRegion and implement it for NativeLayerCA by assembling opaque and transparent sublayers to cover the regions. r=jrmuizel https://hg.mozilla.org/integration/autoland/rev/1d0a11d0acd1 Maintain an internal opaque region in nsChildView that can be accessed from any thread. r=mattwoodrow https://hg.mozilla.org/integration/autoland/rev/9905ea1c2739 Set the appropriate opaque region on the native layer. r=mattwoodrow
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: