Title: [174356] trunk/Source/WebCore
Revision
174356
Author
simon.fra...@apple.com
Date
2014-10-06 11:57:59 -0700 (Mon, 06 Oct 2014)

Log Message

Some compositing logic cleanup
https://bugs.webkit.org/show_bug.cgi?id=133060

Reviewed by Zalan Bujtas.

Move compositing-related code from RenderLayer::styleChanged() to
RenderLayerCompositor::layerStyleChanged(). Combine various tests
(many clip-related) for changes that require layer rebuilding into
styleChangeRequiresLayerRebuild().

Remove code that calls setBackingNeedsRepaint() after filters change
between being composited or not; I verified that existing "repaint after
style change" code takes care those repaints.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects):
(WebCore::RenderLayer::checkIfDescendantClippingContextNeedsUpdate): Deleted.
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::checkIfDescendantClippingContextNeedsUpdate):
(WebCore::styleChangeRequiresLayerRebuild):
(WebCore::RenderLayerCompositor::layerStyleChanged):
* rendering/RenderLayerCompositor.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (174355 => 174356)


--- trunk/Source/WebCore/ChangeLog	2014-10-06 18:56:44 UTC (rev 174355)
+++ trunk/Source/WebCore/ChangeLog	2014-10-06 18:57:59 UTC (rev 174356)
@@ -1,3 +1,29 @@
+2014-10-06  Simon Fraser  <simon.fra...@apple.com>
+
+        Some compositing logic cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=133060
+
+        Reviewed by Zalan Bujtas.
+
+        Move compositing-related code from RenderLayer::styleChanged() to
+        RenderLayerCompositor::layerStyleChanged(). Combine various tests
+        (many clip-related) for changes that require layer rebuilding into 
+        styleChangeRequiresLayerRebuild().
+        
+        Remove code that calls setBackingNeedsRepaint() after filters change
+        between being composited or not; I verified that existing "repaint after
+        style change" code takes care those repaints.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects):
+        (WebCore::RenderLayer::checkIfDescendantClippingContextNeedsUpdate): Deleted.
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::checkIfDescendantClippingContextNeedsUpdate):
+        (WebCore::styleChangeRequiresLayerRebuild):
+        (WebCore::RenderLayerCompositor::layerStyleChanged):
+        * rendering/RenderLayerCompositor.h:
+
 2014-10-06  Ada Chan  <adac...@apple.com>
 
         Fix the iOS build after https://trac.webkit.org/changeset/174353.

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (174355 => 174356)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-10-06 18:56:44 UTC (rev 174355)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-10-06 18:57:59 UTC (rev 174356)
@@ -1148,21 +1148,6 @@
     }
 }
 
-// Return true if the new clipping behaviour requires layer update.
-bool RenderLayer::checkIfDescendantClippingContextNeedsUpdate(bool isClipping)
-{
-    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
-        RenderLayerBacking* backing = child->backing();
-        // Layer subtree needs update when new clipping is added or existing clipping is removed.
-        if (backing && (isClipping || backing->hasAncestorClippingLayer()))
-            return true;
-
-        if (child->checkIfDescendantClippingContextNeedsUpdate(isClipping))
-            return true;
-    }
-    return false;
-}
-
 void RenderLayer::dirty3DTransformedDescendantStatus()
 {
     RenderLayer* curr = stackingContainer();
@@ -6469,18 +6454,6 @@
     }
 }
 
-inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
-    ASSERT(newStyle);
-    return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip());
-}
-
-inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
-    ASSERT(newStyle);
-    return !isComposited() && oldStyle && (oldStyle->overflowX() != newStyle->overflowX()) && stackingContainer()->hasCompositingDescendant();
-}
-
 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
 {
     bool isNormalFlowOnly = shouldBeNormalFlowOnly();
@@ -6535,28 +6508,9 @@
 
     updateNeedsCompositedScrolling();
 
-    const RenderStyle& newStyle = renderer().style();
-    if (compositor().updateLayerCompositingState(*this)
-        || needsCompositingLayersRebuiltForClip(oldStyle, &newStyle)
-        || needsCompositingLayersRebuiltForOverflow(oldStyle, &newStyle))
-        compositor().setCompositingLayersNeedRebuild();
-    else if (isComposited()) {
-        // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
-        backing()->updateGeometry();
-        backing()->updateAfterDescendants();
-    }
+    compositor().layerStyleChanged(*this, oldStyle);
 
-    if (oldStyle) {
-        // Compositing layers keep track of whether they are clipped by any of the ancestors.
-        // When the current layer's clipping behaviour changes, we need to propagate it to the descendants.
-        const RenderStyle& style = renderer().style();
-        bool wasClipping = oldStyle->hasClip() || oldStyle->overflowX() != OVISIBLE || oldStyle->overflowY() != OVISIBLE;
-        bool isClipping = style.hasClip() || style.overflowX() != OVISIBLE || style.overflowY() != OVISIBLE;
-        if (isClipping != wasClipping) {
-            if (checkIfDescendantClippingContextNeedsUpdate(isClipping))
-                compositor().setCompositingLayersNeedRebuild();
-        }
-    }
+    updateOrRemoveFilterEffectRenderer();
 
 #if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
     if (diff == StyleDifferenceRecompositeLayer || diff >= StyleDifferenceLayoutPositionedMovementOnly)
@@ -6564,14 +6518,6 @@
 #else
     UNUSED_PARAM(diff);
 #endif
-
-    updateOrRemoveFilterEffectRenderer();
-    bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters();
-    if (isComposited() && backingDidCompositeLayers && !backing()->canCompositeFilters()) {
-        // The filters used to be drawn by platform code, but now the platform cannot draw them anymore.
-        // Fallback to drawing them in software.
-        setBackingNeedsRepaint();
-    }
 }
 
 void RenderLayer::updateScrollableAreaSet(bool hasOverflow)
@@ -6722,7 +6668,7 @@
         // Don't delete the whole filter info here, because we might use it
         // for loading SVG reference filter files.
         if (FilterInfo* filterInfo = FilterInfo::getIfExists(*this))
-            filterInfo->setRenderer(0);
+            filterInfo->setRenderer(nullptr);
 
         // Early-return only if we *don't* have reference filters.
         // For reference filters, we still want the FilterEffect graph built
@@ -6749,7 +6695,7 @@
     // If the filter fails to build, remove it from the layer. It will still attempt to
     // go through regular processing (e.g. compositing), but never apply anything.
     if (!filterInfo.renderer()->build(&renderer(), renderer().style().filter(), FilterProperty))
-        filterInfo.setRenderer(0);
+        filterInfo.setRenderer(nullptr);
 }
 
 void RenderLayer::filterNeedsRepaint()

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (174355 => 174356)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2014-10-06 18:56:44 UTC (rev 174355)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2014-10-06 18:57:59 UTC (rev 174356)
@@ -825,8 +825,6 @@
     virtual GraphicsLayer* layerForScrollCorner() const override;
     virtual bool usesCompositedScrolling() const override;
     WEBCORE_EXPORT bool needsCompositedScrolling() const;
-    bool needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
-    bool needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
 
     bool paintsWithTransparency(PaintBehavior paintBehavior) const
     {
@@ -1099,7 +1097,6 @@
     void setAncestorChainHasVisibleDescendant();
 
     void updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks = nullptr);
-    bool checkIfDescendantClippingContextNeedsUpdate(bool isClipping);
 
     bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
 

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (174355 => 174356)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-10-06 18:56:44 UTC (rev 174355)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-10-06 18:57:59 UTC (rev 174356)
@@ -849,6 +849,54 @@
 }
 #endif
 
+static bool checkIfDescendantClippingContextNeedsUpdate(const RenderLayer& layer, bool isClipping)
+{
+    for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling()) {
+        RenderLayerBacking* backing = child->backing();
+        if (backing && (isClipping || backing->hasAncestorClippingLayer()))
+            return true;
+
+        if (checkIfDescendantClippingContextNeedsUpdate(*child, isClipping))
+            return true;
+    }
+    return false;
+}
+
+static bool styleChangeRequiresLayerRebuild(const RenderLayer& layer, const RenderStyle& oldStyle, const RenderStyle& newStyle)
+{
+    // Clip can affect ancestor compositing bounds, so we need recompute overlap when it changes on a non-composited layer.
+    // FIXME: we should avoid doing this for all clip changes.
+    if (oldStyle.clip() != newStyle.clip() || oldStyle.hasClip() != newStyle.hasClip())
+        return true;
+
+    // When overflow changes, composited layers may need to update their ancestorClipping layers.
+    if (!layer.isComposited() && (oldStyle.overflowX() != newStyle.overflowX()) && layer.stackingContainer()->hasCompositingDescendant())
+        return true;
+
+    // Compositing layers keep track of whether they are clipped by any of the ancestors.
+    // When the current layer's clipping behaviour changes, we need to propagate it to the descendants.
+    bool wasClipping = oldStyle.hasClip() || oldStyle.overflowX() != OVISIBLE || oldStyle.overflowY() != OVISIBLE;
+    bool isClipping = newStyle.hasClip() || newStyle.overflowX() != OVISIBLE || newStyle.overflowY() != OVISIBLE;
+    if (isClipping != wasClipping) {
+        if (checkIfDescendantClippingContextNeedsUpdate(layer, isClipping))
+            return true;
+    }
+
+    return false;
+}
+
+void RenderLayerCompositor::layerStyleChanged(RenderLayer& layer, const RenderStyle* oldStyle)
+{
+    const RenderStyle& newStyle = layer.renderer().style();
+    if (updateLayerCompositingState(layer) || (oldStyle && styleChangeRequiresLayerRebuild(layer, *oldStyle, newStyle)))
+        setCompositingLayersNeedRebuild();
+    else if (layer.isComposited()) {
+        // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
+        layer.backing()->updateGeometry();
+        layer.backing()->updateAfterDescendants();
+    }
+}
+
 bool RenderLayerCompositor::updateBacking(RenderLayer& layer, CompositingChangeRepaint shouldRepaint)
 {
     bool layerChanged = false;

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (174355 => 174356)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-10-06 18:56:44 UTC (rev 174355)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-10-06 18:57:59 UTC (rev 174356)
@@ -171,6 +171,8 @@
     void layerWasAdded(RenderLayer& parent, RenderLayer& child);
     void layerWillBeRemoved(RenderLayer& parent, RenderLayer& child);
 
+    void layerStyleChanged(RenderLayer&, const RenderStyle* oldStyle);
+
     // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context
     RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer&) const;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to