[Fullscreen] Do not create composited layers for renderers unless they are part of...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2018 04:02:05 +0000 (04:02 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Jul 2018 04:02:05 +0000 (04:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188087
<rdar://problem/42632124>

Reviewed by Simon Fraser.

Source/WebCore:

Sibling composited layers prevent battery lifetime optimizations when in fullscreen.

Test: compositing/no-compositing-when-fulll-screen-is-present.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::isDescendantOf const):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::isDescendantOfFullScreenLayer):
(WebCore::RenderLayerCompositor::requiresCompositingForWillChange const):
(WebCore::RenderLayerCompositor::requiresCompositingForPosition const):

LayoutTests:

* compositing/no-compositing-when-fulll-screen-is-present-expected.txt: Added.
* compositing/no-compositing-when-fulll-screen-is-present.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234291 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/compositing/no-compositing-when-fulll-screen-is-present-expected.txt [new file with mode: 0644]
LayoutTests/compositing/no-compositing-when-fulll-screen-is-present.html [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerCompositor.cpp

index ee62ad9..85256bc 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-26  Zalan Bujtas  <zalan@apple.com>
+
+        [Fullscreen] Do not create composited layers for renderers unless they are part of the fullscreen subtree.
+        https://bugs.webkit.org/show_bug.cgi?id=188087
+        <rdar://problem/42632124>
+
+        Reviewed by Simon Fraser.
+
+        * compositing/no-compositing-when-fulll-screen-is-present-expected.txt: Added.
+        * compositing/no-compositing-when-fulll-screen-is-present.html: Added.
+
 2018-07-26  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r234281.
diff --git a/LayoutTests/compositing/no-compositing-when-fulll-screen-is-present-expected.txt b/LayoutTests/compositing/no-compositing-when-fulll-screen-is-present-expected.txt
new file mode 100644 (file)
index 0000000..0b3f569
--- /dev/null
@@ -0,0 +1,42 @@
+Test that only elements in fullscreen subtree get layer backed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+full screen content
+foobar
+foobar
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 1
+        (GraphicsLayer
+          (bounds 800.00 600.00)
+          (backingStoreAttached 1)
+          (children 2
+            (GraphicsLayer
+              (anchor 0.00 0.00)
+              (bounds 800.00 600.00)
+              (backingStoreAttached 1)
+            )
+            (GraphicsLayer
+              (bounds 800.00 600.00)
+              (drawsContent 1)
+              (backingStoreAttached 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+Enter fullscreen
diff --git a/LayoutTests/compositing/no-compositing-when-fulll-screen-is-present.html b/LayoutTests/compositing/no-compositing-when-fulll-screen-is-present.html
new file mode 100644 (file)
index 0000000..5d99493
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div id="host">full screen content</div>
+<div style="position: fixed; top: 100px; left: 100px;">foobar</div>
+<div style="will-change: transform;">foobar</div>
+<pre id=layers></pre>
+<button>Enter fullscreen</button>
+<script src="../resources/js-test.js"></script>
+<script>
+
+description("Test that only elements in fullscreen subtree get layer backed.");
+
+function goFullscreen() {
+    host.webkitRequestFullscreen();
+    setTimeout(function () {
+        if (done)
+            return;
+
+        testFailed('webkitfullscreenchange was not fired');
+        finishJSTest();
+    }, 2000);
+}
+
+let done = false;
+function finalizeTest() {
+    if (done)
+        return;
+    done = true;
+
+    if (testRunner)
+        testRunner.dumpAsText();
+
+    if (window.internals)
+        layers.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED);
+
+    finishJSTest();
+}
+
+host.addEventListener('webkitfullscreenchange', finalizeTest);
+
+let button = document.querySelector('button');
+button.onclick = goFullscreen;
+
+if (window.eventSender) {
+    jsTestIsAsync = true;
+    eventSender.mouseMoveTo(button.offsetLeft + 5, button.offsetTop + 5);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+</script>
+</body>
+</html>
index a2a930b..7894958 100644 (file)
@@ -33,6 +33,7 @@ perf/accessibility-title-ui-element.html
 # No fullscreen API on iOS
 fullscreen
 http/tests/fullscreen
+compositing/no-compositing-when-fulll-screen-is-present.html
 
 # WebGPU is not enabled on iOS Simulator.
 fast/canvas/webgpu
index 76b2010..d778670 100644 (file)
@@ -1,3 +1,23 @@
+2018-07-26  Zalan Bujtas  <zalan@apple.com>
+
+        [Fullscreen] Do not create composited layers for renderers unless they are part of the fullscreen subtree.
+        https://bugs.webkit.org/show_bug.cgi?id=188087
+        <rdar://problem/42632124>
+
+        Reviewed by Simon Fraser.
+
+        Sibling composited layers prevent battery lifetime optimizations when in fullscreen.
+
+        Test: compositing/no-compositing-when-fulll-screen-is-present.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::isDescendantOf const):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::isDescendantOfFullScreenLayer):
+        (WebCore::RenderLayerCompositor::requiresCompositingForWillChange const):
+        (WebCore::RenderLayerCompositor::requiresCompositingForPosition const):
+
 2018-07-26  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r234281.
index 8291ef9..6cf1f9c 100644 (file)
@@ -1843,6 +1843,15 @@ void RenderLayer::willBeDestroyed()
 }
 #endif
 
+bool RenderLayer::isDescendantOf(const RenderLayer& layer) const
+{
+    for (auto* ancestor = this; ancestor; ancestor = ancestor->parent()) {
+        if (&layer == ancestor)
+            return true;
+    }
+    return false;
+}
+
 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
 {
     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
index d7fd0a8..47fff65 100644 (file)
@@ -143,6 +143,7 @@ public:
     RenderLayer* nextSibling() const { return m_next; }
     RenderLayer* firstChild() const { return m_first; }
     RenderLayer* lastChild() const { return m_last; }
+    bool isDescendantOf(const RenderLayer&) const;
 
     void addChild(RenderLayer* newChild, RenderLayer* beforeChild = nullptr);
     RenderLayer* removeChild(RenderLayer*);
index 41a6384..2f30688 100644 (file)
@@ -2068,6 +2068,25 @@ bool RenderLayerCompositor::canBeComposited(const RenderLayer& layer) const
     return false;
 }
 
+#if ENABLE(FULLSCREEN_API)
+enum class FullScreenDescendant { Yes, No, NotApplicable };
+static FullScreenDescendant isDescendantOfFullScreenLayer(const RenderLayer& layer)
+{
+    auto& document = layer.renderer().document();
+
+    if (!document.webkitIsFullScreen() || !document.fullScreenRenderer())
+        return FullScreenDescendant::NotApplicable;
+
+    auto* fullScreenLayer = document.fullScreenRenderer()->layer();
+    if (!fullScreenLayer) {
+        ASSERT_NOT_REACHED();
+        return FullScreenDescendant::NotApplicable;
+    }
+
+    return layer.isDescendantOf(*fullScreenLayer) ? FullScreenDescendant::Yes : FullScreenDescendant::No;
+}
+#endif
+
 bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer& layer, const RenderLayer* compositingAncestorLayer, const LayoutRect& layerCompositedBoundsInAncestor, const LayoutRect& ancestorCompositedBounds) const
 {
     auto& renderer = layer.renderer();
@@ -2565,6 +2584,11 @@ bool RenderLayerCompositor::requiresCompositingForWillChange(RenderLayerModelObj
     if (!renderer.style().willChange() || !renderer.style().willChange()->canTriggerCompositing())
         return false;
 
+#if ENABLE(FULLSCREEN_API)
+    if (renderer.layer() && isDescendantOfFullScreenLayer(*renderer.layer()) == FullScreenDescendant::No)
+        return false;
+#endif
+
     if (is<RenderBox>(renderer))
         return true;
 
@@ -2635,6 +2659,11 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderLayerModelObjec
     if (!renderer.isPositioned())
         return false;
     
+#if ENABLE(FULLSCREEN_API)
+    if (isDescendantOfFullScreenLayer(layer) == FullScreenDescendant::No)
+        return false;
+#endif
+
     auto position = renderer.style().position();
     bool isFixed = renderer.isOutOfFlowPositioned() && position == PositionType::Fixed;
     if (isFixed && !layer.isStackingContainer())