Avoid a recursive descendants layer walk sometimes
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 May 2019 05:41:08 +0000 (05:41 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 May 2019 05:41:08 +0000 (05:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197939

Reviewed by Zalan Bujtas.

If a layer got composited post-descendants because it needs to clip, for example, we'd do a recursive
descendant tree walk to add layers to the overlap map. However, all the descendants would already
have contributed to the overlap map if some non-root ancestor was already composited. So we can
skip the addDescendantsToOverlapMapRecursive() if we know, before descendants, whether there's
a non-root composited ancestor.

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::CompositingState::hasNonRootCompositedAncestor const):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):

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

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

index fe85dea..3804d09 100644 (file)
@@ -1,5 +1,22 @@
 2019-05-15  Simon Fraser  <simon.fraser@apple.com>
 
+        Avoid a recursive descendants layer walk sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=197939
+
+        Reviewed by Zalan Bujtas.
+
+        If a layer got composited post-descendants because it needs to clip, for example, we'd do a recursive
+        descendant tree walk to add layers to the overlap map. However, all the descendants would already
+        have contributed to the overlap map if some non-root ancestor was already composited. So we can
+        skip the addDescendantsToOverlapMapRecursive() if we know, before descendants, whether there's
+        a non-root composited ancestor.
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::CompositingState::hasNonRootCompositedAncestor const):
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+
+2019-05-15  Simon Fraser  <simon.fraser@apple.com>
+
         Clean up code related to compositing overlap map maintenance
         https://bugs.webkit.org/show_bug.cgi?id=197936
 
index b5b6c65..b5b8046 100644 (file)
@@ -175,6 +175,11 @@ struct RenderLayerCompositor::CompositingState {
 #endif
     }
 
+    bool hasNonRootCompositedAncestor() const
+    {
+        return compositingAncestor && !compositingAncestor->isRenderViewLayer();
+    }
+
     RenderLayer* compositingAncestor;
     RenderLayer* backingSharingAncestor { nullptr };
     RenderLayer* stackingContextAncestor { nullptr };
@@ -855,6 +860,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     RequiresCompositingData queryData;
     bool willBeComposited = layer.isComposited();
     bool becameCompositedAfterDescendantTraversal = false;
+
     if (layer.needsPostLayoutCompositingUpdate() || compositingState.fullPaintOrderTraversalRequired || compositingState.descendantsRequireCompositingUpdate) {
         layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::None);
         willBeComposited = needsToBeComposited(layer, queryData);
@@ -951,6 +957,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
 #endif
 
     bool anyDescendantHas3DTransform = false;
+    bool descendantsAddedToOverlap = currentState.hasNonRootCompositedAncestor();
 
     for (auto* childLayer : layer.negativeZOrderLayers()) {
         computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform);
@@ -1048,7 +1055,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     compositingState.updateWithDescendantStateAndLayer(currentState, layer, layerExtent);
 
     bool layerContributesToOverlap = currentState.compositingAncestor && !currentState.compositingAncestor->isRenderViewLayer();
-    updateOverlapMap(overlapMap, layer, layerExtent, layerContributesToOverlap, becameCompositedAfterDescendantTraversal);
+    updateOverlapMap(overlapMap, layer, layerExtent, layerContributesToOverlap, becameCompositedAfterDescendantTraversal && !descendantsAddedToOverlap);
 
     // Pop backing/overlap sharing state.
     if ((willBeComposited && !layer.isRenderViewLayer()) || currentState.backingSharingAncestor == &layer) {