- 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;