Make "clips compositing descendants" an indirect compositing reason
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Sep 2019 18:25:27 +0000 (18:25 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Sep 2019 18:25:27 +0000 (18:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201381

Reviewed by Antti Koivisto.

Whether a layer has to composite to clip composited descendants is an "indirect" reason,
just like having to composite for filters if there's a composited descendant. So add
IndirectCompositingReason::Clipping, and have computeIndirectCompositingReason() compute this,
replacing the code that ran in computeCompositingRequirements().

This is some preparatory cleanup for webkit.org/b/201330.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects const):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::requiresCompositingLayer const):
(WebCore::RenderLayerCompositor::reasonsForCompositing const):
(WebCore::RenderLayerCompositor::computeIndirectCompositingReason const):
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const): Deleted.
* rendering/RenderLayerCompositor.h:

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

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

index e3d9139..f2ff828 100644 (file)
@@ -1,3 +1,28 @@
+2019-09-03  Simon Fraser  <simon.fraser@apple.com>
+
+        Make "clips compositing descendants" an indirect compositing reason
+        https://bugs.webkit.org/show_bug.cgi?id=201381
+
+        Reviewed by Antti Koivisto.
+
+        Whether a layer has to composite to clip composited descendants is an "indirect" reason,
+        just like having to composite for filters if there's a composited descendant. So add
+        IndirectCompositingReason::Clipping, and have computeIndirectCompositingReason() compute this,
+        replacing the code that ran in computeCompositingRequirements().
+
+        This is some preparatory cleanup for webkit.org/b/201330.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects const):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::RenderLayerCompositor::requiresCompositingLayer const):
+        (WebCore::RenderLayerCompositor::reasonsForCompositing const):
+        (WebCore::RenderLayerCompositor::computeIndirectCompositingReason const):
+        (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const): Deleted.
+        * rendering/RenderLayerCompositor.h:
+
 2019-09-03  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][Floats] Move FloatingState::constraints to FloatingContext
index 32dd05f..5deac4b 100644 (file)
@@ -6921,6 +6921,7 @@ TextStream& operator<<(TextStream& ts, IndirectCompositingReason reason)
 {
     switch (reason) {
     case IndirectCompositingReason::None: ts << "none"; break;
+    case IndirectCompositingReason::Clipping: ts << "clipping"; break;
     case IndirectCompositingReason::Stacking: ts << "stacking"; break;
     case IndirectCompositingReason::OverflowScrollPositioning: ts << "overflow positioning"; break;
     case IndirectCompositingReason::Overlap: ts << "overlap"; break;
index 65d4786..cf4289b 100644 (file)
@@ -119,6 +119,7 @@ enum class RequestState {
 
 enum class IndirectCompositingReason {
     None,
+    Clipping,
     Stacking,
     OverflowScrollPositioning,
     Overlap,
@@ -1238,8 +1239,8 @@ private:
     bool m_hasTransformedAncestor : 1;
     bool m_has3DTransformedAncestor : 1;
 
-    unsigned m_indirectCompositingReason : 3;
-    unsigned m_viewportConstrainedNotCompositedReason : 2;
+    unsigned m_indirectCompositingReason : 4; // IndirectCompositingReason
+    unsigned m_viewportConstrainedNotCompositedReason : 2; // ViewportConstrainedNotCompositedReason
 
 #if PLATFORM(IOS_FAMILY)
 #if ENABLE(IOS_TOUCH_EVENTS)
@@ -1257,7 +1258,7 @@ private:
 #endif
 
 #if ENABLE(CSS_COMPOSITING)
-    unsigned m_blendMode : 5;
+    unsigned m_blendMode : 5; // BlendMode
     bool m_hasNotIsolatedCompositedBlendingDescendants : 1;
     bool m_hasNotIsolatedBlendingDescendants : 1;
     bool m_hasNotIsolatedBlendingDescendantsStatusDirty : 1;
index b3537b1..0499223 100644 (file)
@@ -1014,23 +1014,19 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     ASSERT(!layer.hasNotIsolatedCompositedBlendingDescendants() || layer.hasNotIsolatedBlendingDescendants());
 #endif
     // Now check for reasons to become composited that depend on the state of descendant layers.
-    IndirectCompositingReason indirectCompositingReason;
-    if (!willBeComposited && canBeComposited(layer)
-        && requiresCompositingForIndirectReason(layer, currentState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) {
-        layer.setIndirectCompositingReason(indirectCompositingReason);
-        layerWillCompositePostDescendants();
+    if (!willBeComposited && canBeComposited(layer)) {
+        auto indirectReason = computeIndirectCompositingReason(layer, currentState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking);
+        if (indirectReason != IndirectCompositingReason::None) {
+            layer.setIndirectCompositingReason(indirectReason);
+            layerWillCompositePostDescendants();
+        }
     }
-    
+
     if (layer.reflectionLayer()) {
         // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
         layer.reflectionLayer()->setIndirectCompositingReason(willBeComposited ? IndirectCompositingReason::Stacking : IndirectCompositingReason::None);
     }
 
-    // setHasCompositingDescendant() may have changed the answer to needsToBeComposited() when clipping, so test that now.
-    bool isCompositedClippingLayer = canBeComposited(layer) && clipsCompositingDescendants(layer);
-    if (isCompositedClippingLayer & !willBeComposited)
-        layerWillCompositePostDescendants();
-
     // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
     // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
     // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
@@ -2321,7 +2317,6 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer& layer, R
     // The root layer always has a compositing layer, but it may not have backing.
     return requiresCompositingForTransform(renderer)
         || requiresCompositingForAnimation(renderer)
-        || clipsCompositingDescendants(*renderer.layer())
         || requiresCompositingForPosition(renderer, *renderer.layer(), queryData)
         || requiresCompositingForCanvas(renderer)
         || requiresCompositingForFilters(renderer)
@@ -2448,9 +2443,6 @@ OptionSet<CompositingReason> RenderLayerCompositor::reasonsForCompositing(const
     if ((canRender3DTransforms() && renderer.style().backfaceVisibility() == BackfaceVisibility::Hidden))
         reasons.add(CompositingReason::BackfaceVisibilityHidden);
 
-    if (clipsCompositingDescendants(*renderer.layer()))
-        reasons.add(CompositingReason::ClipsCompositingDescendants);
-
     if (requiresCompositingForAnimation(renderer))
         reasons.add(CompositingReason::Animation);
 
@@ -2469,6 +2461,9 @@ OptionSet<CompositingReason> RenderLayerCompositor::reasonsForCompositing(const
     switch (renderer.layer()->indirectCompositingReason()) {
     case IndirectCompositingReason::None:
         break;
+    case IndirectCompositingReason::Clipping:
+        reasons.add(CompositingReason::ClipsCompositingDescendants);
+        break;
     case IndirectCompositingReason::Stacking:
         reasons.add(CompositingReason::Stacking);
         break;
@@ -3042,42 +3037,36 @@ bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const Render
     return layer.hasCompositedScrollableOverflow();
 }
 
-// FIXME: why doesn't this handle the clipping cases?
-bool RenderLayerCompositor::requiresCompositingForIndirectReason(const RenderLayer& layer, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason& reason) const
+IndirectCompositingReason RenderLayerCompositor::computeIndirectCompositingReason(const RenderLayer& layer, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking) const
 {
     // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
     // via compositing so that they also apply to those composited descendants.
     auto& renderer = layer.renderer();
-    if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection())) {
-        reason = IndirectCompositingReason::GraphicalEffect;
-        return true;
-    }
+    if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection()))
+        return IndirectCompositingReason::GraphicalEffect;
 
     // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
     // will be affected by the preserve-3d or perspective.
     if (has3DTransformedDescendants) {
-        if (renderer.style().transformStyle3D() == TransformStyle3D::Preserve3D) {
-            reason = IndirectCompositingReason::Preserve3D;
-            return true;
-        }
+        if (renderer.style().transformStyle3D() == TransformStyle3D::Preserve3D)
+            return IndirectCompositingReason::Preserve3D;
     
-        if (renderer.style().hasPerspective()) {
-            reason = IndirectCompositingReason::Perspective;
-            return true;
-        }
+        if (renderer.style().hasPerspective())
+            return IndirectCompositingReason::Perspective;
     }
 
     // If this layer scrolls independently from the layer that it would paint into, it needs to get composited.
     if (!paintsIntoProvidedBacking && layer.hasCompositedScrollingAncestor()) {
         auto* paintDestination = layer.paintOrderParent();
-        if (paintDestination && layerScrollBehahaviorRelativeToCompositedAncestor(layer, *paintDestination) != ScrollPositioningBehavior::None) {
-            reason = IndirectCompositingReason::OverflowScrollPositioning;
-            return true;
-        }
+        if (paintDestination && layerScrollBehahaviorRelativeToCompositedAncestor(layer, *paintDestination) != ScrollPositioningBehavior::None)
+            return IndirectCompositingReason::OverflowScrollPositioning;
     }
 
-    reason = IndirectCompositingReason::None;
-    return false;
+    // Check for clipping last; if compositing just for clipping, the layer doesn't need its own backing store.
+    if (hasCompositedDescendants && clipsCompositingDescendants(layer))
+        return IndirectCompositingReason::Clipping;
+
+    return IndirectCompositingReason::None;
 }
 
 bool RenderLayerCompositor::styleChangeMayAffectIndirectCompositingReasons(const RenderStyle& oldStyle, const RenderStyle& newStyle)
index 8dd039b..de6c803 100644 (file)
@@ -498,7 +498,7 @@ private:
     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForOverflowScrolling(const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForEditableImage(RenderLayerModelObject&) const;
-    bool requiresCompositingForIndirectReason(const RenderLayer&, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, IndirectCompositingReason&) const;
+    IndirectCompositingReason computeIndirectCompositingReason(const RenderLayer&, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking) const;
 
     static ScrollPositioningBehavior layerScrollBehahaviorRelativeToCompositedAncestor(const RenderLayer&, const RenderLayer& compositedAncestor);