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