Index: third_party/WebKit/Source/core/layout/LayoutObject.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
index 64ed7a6701663ffb1c70fde8d1096df7ebd9c3d9..5398592e1a7cb200fa15dca13339add280efa47e 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp |
@@ -1317,7 +1317,10 @@ |
PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState); |
clearPaintInvalidationFlags(newPaintInvalidationState); |
- newPaintInvalidationState.updateForChildren(reason); |
+ if (reason == PaintInvalidationDelayedFull) |
+ newPaintInvalidationState.pushDelayedPaintInvalidationTarget(*this); |
+ |
+ newPaintInvalidationState.updateForChildren(); |
invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
} |
@@ -1437,12 +1440,12 @@ |
if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) |
setPreviousPositionFromPaintInvalidationBacking(newLocation); |
- if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { |
- // We are done updating the paint invalidation rect. No other paint invalidation work to do for this object. |
+ if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && !paintInvalidationState.forcedSubtreeInvalidationWithinContainer()) { |
+ ASSERT(paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainer()); |
return PaintInvalidationNone; |
} |
- PaintInvalidationReason invalidationReason = getPaintInvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, newLocation); |
+ PaintInvalidationReason invalidationReason = getPaintInvalidationReason(paintInvalidationContainer, oldBounds, oldLocation, newBounds, newLocation); |
// We need to invalidate the selection before checking for whether we are doing a full invalidation. |
// This is because we need to update the old rect regardless. |
@@ -1463,7 +1466,7 @@ |
// mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based |
// invalidation is issued. See crbug.com/508383 and crbug.com/515977. |
// This is a workaround to force display items to update paint offset. |
- if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paintInvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) |
+ if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paintInvalidationState.forcedSubtreeInvalidationWithinContainer()) |
invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationContainer, paintInvalidationState, invalidationReason); |
return invalidationReason; |
@@ -1478,13 +1481,10 @@ |
return invalidationReason; |
} |
-PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInvalidationState& paintInvalidationState, |
+PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const LayoutBoxModelObject& paintInvalidationContainer, |
const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationBacking, |
const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalidationBacking) const |
{ |
- if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) |
- return PaintInvalidationSubtree; |
- |
if (shouldDoFullPaintInvalidation()) |
return m_bitfields.fullPaintInvalidationReason(); |
@@ -1791,28 +1791,28 @@ |
// Text nodes share style with their parents but transforms don't apply to them, |
// hence the !isText() check. |
if (!isText() && (!hasLayer() || !toLayoutBoxModelObject(this)->layer()->hasStyleDeterminedDirectCompositingReasons())) |
- diff.setNeedsPaintInvalidationSubtree(); |
+ diff.setNeedsPaintInvalidationLayer(); |
} |
// If opacity or zIndex changed, and the layer does not paint into its own separate backing, then we need to invalidate paints (also |
// ignoring text nodes) |
if (diff.opacityChanged() || diff.zIndexChanged()) { |
if (!isText() && (!hasLayer() || !toLayoutBoxModelObject(this)->layer()->hasStyleDeterminedDirectCompositingReasons())) |
- diff.setNeedsPaintInvalidationSubtree(); |
+ diff.setNeedsPaintInvalidationLayer(); |
} |
// If filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to invalidate paints. |
if (diff.filterChanged() && hasLayer()) { |
PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); |
if (!layer->hasStyleDeterminedDirectCompositingReasons() || layer->paintsWithFilters()) |
- diff.setNeedsPaintInvalidationSubtree(); |
+ diff.setNeedsPaintInvalidationLayer(); |
} |
// If backdrop filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to invalidate paints. |
if (diff.backdropFilterChanged() && hasLayer()) { |
PaintLayer* layer = toLayoutBoxModelObject(this)->layer(); |
if (!layer->hasStyleDeterminedDirectCompositingReasons() || layer->paintsWithBackdropFilters()) |
- diff.setNeedsPaintInvalidationSubtree(); |
+ diff.setNeedsPaintInvalidationLayer(); |
} |
// Optimization: for decoration/color property changes, invalidation is only needed if we have style or text affected by these properties. |
@@ -1837,6 +1837,12 @@ |
bool requiresLayer = toLayoutBoxModelObject(this)->layerTypeRequired() != NoPaintLayer; |
if (hasLayer() != requiresLayer) |
diff.setNeedsFullLayout(); |
+ } |
+ |
+ // If we have no layer(), just treat a PaintInvalidationLayer hint as a normal paint invalidation. |
+ if (diff.needsPaintInvalidationLayer() && !hasLayer()) { |
+ diff.clearNeedsPaintInvalidation(); |
+ diff.setNeedsPaintInvalidationObject(); |
} |
return diff; |
@@ -1992,7 +1998,7 @@ |
setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::StyleChange); |
} |
- if (diff.needsPaintInvalidationSubtree() || updatedDiff.needsPaintInvalidationSubtree()) |
+ if (diff.needsPaintInvalidationLayer() || updatedDiff.needsPaintInvalidationLayer()) |
setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants(); |
else if (diff.needsPaintInvalidationObject() || updatedDiff.needsPaintInvalidationObject()) |
setShouldDoFullPaintInvalidation(); |
@@ -3459,7 +3465,7 @@ |
{ |
// paintInvalidationStateIsDirty should be kept in sync with the |
// booleans that are cleared below. |
- ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); |
+ ASSERT(paintInvalidationState.forcedSubtreeInvalidationWithinContainer() || paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainer() || paintInvalidationStateIsDirty()); |
clearShouldDoFullPaintInvalidation(); |
m_bitfields.setChildShouldCheckForPaintInvalidation(false); |
m_bitfields.setNeededLayoutBecauseOfChildren(false); |
@@ -3598,20 +3604,23 @@ |
traverseNonCompositingDescendants(*this, [&paintInvalidationContainer](LayoutObject& object) { |
if (object.hasLayer()) |
toLayoutBoxModelObject(object).layer()->setNeedsRepaint(); |
- object.invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationSubtree); |
+ object.invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationLayer); |
}); |
} |
+// FIXME: If we had a flag to force invalidations in a whole subtree, we could get rid of this function (crbug.com/410097). |
void LayoutObject::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() |
{ |
- // Clear first because PaintInvalidationSubtree overrides other full paint invalidation reasons. |
- clearShouldDoFullPaintInvalidation(); |
- setShouldDoFullPaintInvalidation(PaintInvalidationSubtree); |
+ // Need to access the current compositing status. |
+ DisableCompositingQueryAsserts disabler; |
+ traverseNonCompositingDescendants(*this, [](LayoutObject& object) { |
+ object.setShouldDoFullPaintInvalidation(); |
+ }); |
} |
void LayoutObject::invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(const LayoutBoxModelObject& paintInvalidationContainer) |
{ |
- invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationSubtree); |
+ invalidatePaintOfPreviousPaintInvalidationRect(paintInvalidationContainer, PaintInvalidationLayer); |
for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibling()) { |
if (child->hasLayer()) |
toLayoutBoxModelObject(child)->layer()->setNeedsRepaint(); |