Avoid triggering compositing updates when only the root layer is composited
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Nov 2018 00:51:42 +0000 (00:51 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Nov 2018 00:51:42 +0000 (00:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191813

Reviewed by Zalan Bujtas.

If we know that the only composited layer is the root, we can avoid triggering deep
compositing updates sometimes, for example when layout changes size or position,
or when z-order lists change.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::addChild):
(WebCore::RenderLayer::removeChild):
(WebCore::RenderLayer::updateLayerPosition):
(WebCore::RenderLayer::scrollTo):
(WebCore::RenderLayer::updateCompositingLayersAfterScroll):
(WebCore::outputPaintOrderTreeRecursive):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateBackingAndHierarchy): Consult the layer.hasCompositingDescendant()
flag to cut off descendants traversal when possible.
(WebCore::RenderLayerCompositor::layerStyleChanged):

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp

index 2574b82..67e282c 100644 (file)
@@ -1,5 +1,28 @@
 2018-11-17  Simon Fraser  <simon.fraser@apple.com>
 
+        Avoid triggering compositing updates when only the root layer is composited
+        https://bugs.webkit.org/show_bug.cgi?id=191813
+
+        Reviewed by Zalan Bujtas.
+
+        If we know that the only composited layer is the root, we can avoid triggering deep
+        compositing updates sometimes, for example when layout changes size or position,
+        or when z-order lists change.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::addChild):
+        (WebCore::RenderLayer::removeChild):
+        (WebCore::RenderLayer::updateLayerPosition):
+        (WebCore::RenderLayer::scrollTo):
+        (WebCore::RenderLayer::updateCompositingLayersAfterScroll):
+        (WebCore::outputPaintOrderTreeRecursive):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateBackingAndHierarchy): Consult the layer.hasCompositingDescendant()
+        flag to cut off descendants traversal when possible.
+        (WebCore::RenderLayerCompositor::layerStyleChanged):
+
+2018-11-17  Simon Fraser  <simon.fraser@apple.com>
+
         Fix an error in 238354 - !=, not ==.
         
         Fixes test failures.
index 7937d41..ba24169 100644 (file)
@@ -405,7 +405,7 @@ void RenderLayer::addChild(RenderLayer& child, RenderLayer* beforeChild)
     if (child.isSelfPaintingLayer() || child.hasSelfPaintingLayerDescendant())
         setAncestorChainHasSelfPaintingLayerDescendant();
 
-    if (compositor().usesCompositing())
+    if (compositor().hasContentCompositingLayers())
         setDescendantsNeedCompositingRequirementsTraversal();
 
     if (child.hasDescendantNeedingCompositingRequirementsTraversal() || child.needsCompositingRequirementsTraversal())
@@ -451,7 +451,7 @@ void RenderLayer::removeChild(RenderLayer& oldChild)
     if (oldChild.isSelfPaintingLayer() || oldChild.hasSelfPaintingLayerDescendant())
         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 
-    if (compositor().usesCompositing())
+    if (compositor().hasContentCompositingLayers())
         setDescendantsNeedCompositingRequirementsTraversal();
 
 #if ENABLE(CSS_COMPOSITING)
@@ -1577,7 +1577,7 @@ bool RenderLayer::updateLayerPosition()
     positionOrOffsetChanged |= location() != localPoint;
     setLocation(localPoint);
     
-    if (positionOrOffsetChanged && compositor().usesCompositing()) {
+    if (positionOrOffsetChanged && compositor().hasContentCompositingLayers()) {
         if (isComposited())
             setNeedsCompositingGeometryUpdate();
         // This layer's position can affect the location of a composited descendant (which may be a sibling in z-order),
@@ -2430,7 +2430,7 @@ void RenderLayer::scrollTo(const ScrollPosition& position)
     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
 
     bool requiresRepaint = true;
-    if (compositor().usesCompositing() && usesCompositedScrolling()) {
+    if (usesCompositedScrolling()) {
         setNeedsCompositingGeometryUpdate();
         setDescendantsNeedUpdateBackingAndHierarchyTraversal();
         requiresRepaint = false;
@@ -2580,7 +2580,7 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& absoluteRect, bool insid
 
 void RenderLayer::updateCompositingLayersAfterScroll()
 {
-    if (compositor().usesCompositing()) {
+    if (compositor().hasContentCompositingLayers()) {
         // Our stacking container is guaranteed to contain all of our descendants that may need
         // repositioning, so update compositing layers from there.
         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
@@ -6643,7 +6643,7 @@ void showLayerTree(const WebCore::RenderObject* renderer)
 static void outputPaintOrderTreeLegend(TextStream& stream)
 {
     stream.nextLine();
-    stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited\n"
+    stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited, (c)omposited descendant\n"
         "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
         "Descendant needs overlap (t)raversal, Descendant needs (b)acking or hierarchy update, All descendants need (r)equirements traversal, All (s)ubsequent layers need requirements traversal, All descendants need (h)ierarchy traversal\n"
         "Needs compositing paint order update on (s)ubsequent layers, Needs compositing paint (o)rder children update, "
@@ -6670,6 +6670,7 @@ static void outputPaintOrderTreeRecursive(TextStream& stream, const WebCore::Ren
     stream << (layer.hasFilter() ? "F" : "-");
     stream << (layer.renderer().isFixedPositioned() ? "X" : "-");
     stream << (layer.isComposited() ? "C" : "-");
+    stream << (layer.hasCompositingDescendant() ? "c" : "-");
 
     stream << " ";
 
index 93d4f03..9f3f6e9 100644 (file)
@@ -1170,29 +1170,35 @@ void RenderLayerCompositor::updateBackingAndHierarchy(RenderLayer& layer, Vector
     // to the compositing child list of an enclosing layer.
     Vector<Ref<GraphicsLayer>> layerChildren;
     auto& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
-    // FIXME: why the !layerBacking check?
-    bool requireDescendantTraversal = !layerBacking || layer.needsCompositingLayerConnection() || layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || !updateLevel.isEmpty();
+
+    bool requireDescendantTraversal = layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal()
+        || (layer.hasCompositingDescendant() && (!layerBacking || layer.needsCompositingLayerConnection() || !updateLevel.isEmpty()));
 
 #if !ASSERT_DISABLED
     LayerListMutationDetector mutationChecker(layer);
 #endif
     
-    if (requireDescendantTraversal) {
-        for (auto* renderLayer : layer.negativeZOrderLayers())
-            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
-
-            // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+    auto appendForegroundLayerIfNecessary = [&] {
+        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
         if (layer.negativeZOrderLayers().size()) {
             if (layerBacking && layerBacking->foregroundLayer())
                 childList.append(*layerBacking->foregroundLayer());
         }
+    };
+
+    if (requireDescendantTraversal) {
+        for (auto* renderLayer : layer.negativeZOrderLayers())
+            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
+
+        appendForegroundLayerIfNecessary();
 
         for (auto* renderLayer : layer.normalFlowLayers())
             updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
         
         for (auto* renderLayer : layer.positiveZOrderLayers())
             updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
-    }
+    } else
+        appendForegroundLayerIfNecessary();
 
     if (layerBacking) {
         if (requireDescendantTraversal) {
@@ -1370,7 +1376,7 @@ void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer&
     if (queryData.reevaluateAfterLayout)
         layer.setNeedsPostLayoutCompositingUpdate();
 
-    if (diff >= StyleDifference::LayoutPositionedMovementOnly && usesCompositing()) {
+    if (diff >= StyleDifference::LayoutPositionedMovementOnly && hasContentCompositingLayers()) {
         layer.setNeedsPostLayoutCompositingUpdate();
         layer.setNeedsCompositingGeometryUpdate();
     }