Index: third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
index b208df2e9058015007e597387b0e3d6d2f944ccf..9e24a62aca9e79b8eb1639dcd0a037e079d8fa62 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
@@ -9,14 +9,13 @@ |
#include "core/frame/LocalFrame.h" |
#include "core/frame/Settings.h" |
#include "core/layout/LayoutBlockFlow.h" |
-#include "core/layout/LayoutObject.h" |
#include "core/layout/LayoutTable.h" |
#include "core/layout/LayoutView.h" |
#include "core/layout/svg/SVGLayoutSupport.h" |
+#include "core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h" |
#include "core/paint/ObjectPaintProperties.h" |
#include "core/paint/PaintLayer.h" |
#include "core/paint/PaintLayerScrollableArea.h" |
-#include "core/paint/PaintPropertyTreeBuilder.h" |
#include "wtf/Optional.h" |
namespace blink { |
@@ -107,9 +106,9 @@ LayoutRect PaintInvalidator::mapLocalRectToVisualRectInBacking( |
const auto* containerContentsProperties = |
context.paintInvalidationContainer->contentsProperties(); |
- if (context.m_treeBuilderContext.current.transform == |
+ if (context.m_treeBuilderContext->current.transform == |
containerContentsProperties->transform() && |
- context.m_treeBuilderContext.current.clip == |
+ context.m_treeBuilderContext->current.clip == |
containerContentsProperties->clip()) { |
result = LayoutRect(rect); |
} else { |
@@ -118,13 +117,13 @@ LayoutRect PaintInvalidator::mapLocalRectToVisualRectInBacking( |
// snapping, when transforms are applied. If there is no transform, |
// enclosingIntRect is applied in the last step of paint invalidation |
// (see CompositedLayerMapping::setContentsNeedDisplayInRect()). |
- if (!isSVGChild && context.m_treeBuilderContext.current.transform != |
+ if (!isSVGChild && context.m_treeBuilderContext->current.transform != |
containerContentsProperties->transform()) |
rect = Rect(enclosingIntRect(rect)); |
PropertyTreeState currentTreeState( |
- context.m_treeBuilderContext.current.transform, |
- context.m_treeBuilderContext.current.clip, nullptr); |
+ context.m_treeBuilderContext->current.transform, |
+ context.m_treeBuilderContext->current.clip, nullptr); |
FloatRect floatRect(rect); |
context.m_geometryMapper.sourceToDestinationVisualRect( |
@@ -150,6 +149,8 @@ LayoutRect PaintInvalidator::mapLocalRectToVisualRectInBacking( |
void PaintInvalidatorContext::mapLocalRectToVisualRectInBacking( |
const LayoutObject& object, |
LayoutRect& rect) const { |
+ DCHECK(needsVisualRectUpdate(object)); |
+ std::unique_ptr<GeometryMapper> geometryMapper = GeometryMapper::create(); |
rect = PaintInvalidator::mapLocalRectToVisualRectInBacking<LayoutRect, |
LayoutPoint>( |
object, rect, *this); |
@@ -180,10 +181,10 @@ LayoutPoint PaintInvalidator::computeLocationInBacking( |
const auto* containerTransform = |
context.paintInvalidationContainer->contentsProperties()->transform(); |
- if (context.m_treeBuilderContext.current.transform != containerTransform) { |
+ if (context.m_treeBuilderContext->current.transform != containerTransform) { |
FloatRect rect = FloatRect(FloatPoint(point), FloatSize()); |
context.m_geometryMapper.sourceToDestinationRect( |
- context.m_treeBuilderContext.current.transform, containerTransform, |
+ context.m_treeBuilderContext->current.transform, containerTransform, |
rect); |
point = LayoutPoint(rect.location()); |
} |
@@ -329,11 +330,13 @@ void PaintInvalidator::updatePaintInvalidationContainer( |
// descending into a different invalidation container. (For instance if |
// our parents were moved, the entire container will just move.) |
if (object != context.paintInvalidationContainerForStackedContents) { |
- // However, we need to keep the |
- // ForcedSubtreeFullInvalidationForStackedContents flag if the current |
+ // However, we need to keep ForcedSubtreeVisualRectUpdate and |
+ // ForcedSubtreeFullInvalidationForStackedContents flags if the current |
// object isn't the paint invalidation container of stacked contents. |
- context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext:: |
- ForcedSubtreeFullInvalidationForStackedContents; |
+ context.forcedSubtreeInvalidationFlags &= |
+ (PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate | |
+ PaintInvalidatorContext:: |
+ ForcedSubtreeFullInvalidationForStackedContents); |
} else { |
context.forcedSubtreeInvalidationFlags = 0; |
} |
@@ -344,33 +347,44 @@ void PaintInvalidator::updatePaintInvalidationContainer( |
DCHECK(context.paintingLayer == object.paintingLayer()); |
} |
+void PaintInvalidator::updateVisualRectIfNeeded( |
+ const LayoutObject& object, |
+ PaintInvalidatorContext& context) { |
+ context.oldVisualRect = object.visualRect(); |
+ context.oldLocation = ObjectPaintInvalidator(object).locationInBacking(); |
+ |
+#if DCHECK_IS_ON() |
+ FindObjectVisualRectNeedingUpdateScope finder(object, context); |
+#endif |
+ |
+ if (!context.needsVisualRectUpdate(object)) { |
+ context.newLocation = context.oldLocation; |
+ return; |
+ } |
+ |
+ updateVisualRect(object, context); |
+} |
+ |
void PaintInvalidator::updateVisualRect(const LayoutObject& object, |
PaintInvalidatorContext& context) { |
+ // The paint offset should already be updated through |
+ // PaintPropertyTreeBuilder::updatePropertiesForSelf. |
+ DCHECK(context.m_treeBuilderContext); |
+ DCHECK(context.m_treeBuilderContext->current.paintOffset == |
+ object.paintOffset()); |
+ |
Optional<ScopedUndoFrameViewContentClipAndScroll> |
undoFrameViewContentClipAndScroll; |
if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled() && |
object.isLayoutView() && !object.isPaintInvalidationContainer()) { |
undoFrameViewContentClipAndScroll.emplace(*toLayoutView(object).frameView(), |
- context.m_treeBuilderContext); |
+ *context.m_treeBuilderContext); |
} |
- // TODO(crbug.com/637313): Use GeometryMapper which now supports filter |
- // geometry effects, after skia optimizes filter's mapRect operation. |
- // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
- if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { |
- context.forcedSubtreeInvalidationFlags |= |
- PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
- } |
- |
- ObjectPaintInvalidator objectPaintInvalidator(object); |
- context.oldVisualRect = object.visualRect(); |
- context.oldLocation = objectPaintInvalidator.locationInBacking(); |
- |
LayoutRect newVisualRect = computeVisualRectInBacking(object, context); |
if (object.isBoxModelObject()) { |
context.newLocation = computeLocationInBacking(object, context); |
- |
// Location of empty visual rect doesn't affect paint invalidation. Set it |
// to newLocation to avoid saving the previous location separately in |
// ObjectPaintInvalidator. |
@@ -383,7 +397,7 @@ void PaintInvalidator::updateVisualRect(const LayoutObject& object, |
} |
object.getMutableForPainting().setVisualRect(newVisualRect); |
- objectPaintInvalidator.setLocationInBacking(context.newLocation); |
+ ObjectPaintInvalidator(object).setLocationInBacking(context.newLocation); |
} |
void PaintInvalidator::invalidatePaintIfNeeded( |
@@ -398,8 +412,9 @@ void PaintInvalidator::invalidatePaintIfNeeded( |
context.paintingLayer = layoutView->layer(); |
if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
- ScopedUndoFrameViewContentClipAndScroll undo(frameView, |
- context.m_treeBuilderContext); |
+ Optional<ScopedUndoFrameViewContentClipAndScroll> undo; |
+ if (context.m_treeBuilderContext) |
+ undo.emplace(frameView, *context.m_treeBuilderContext); |
frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
} |
} |
@@ -413,47 +428,27 @@ void PaintInvalidator::invalidatePaintIfNeeded( |
object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
- // The paint offset should already be updated through |
- // PaintPropertyTreeBuilder::updatePropertiesForSelf. |
- DCHECK(context.m_treeBuilderContext.current.paintOffset == |
- object.paintOffset()); |
- |
updatePaintingLayer(object, context); |
if (object.document().printing() && |
!RuntimeEnabledFeatures::printBrowserEnabled()) |
return; // Don't invalidate paints if we're printing. |
- updatePaintInvalidationContainer(object, context); |
- |
- bool objectShouldCheckForPaintInvalidation = |
- object.shouldCheckForPaintInvalidation(); |
- if (!context.forcedSubtreeInvalidationFlags && |
- !objectShouldCheckForPaintInvalidation) { |
-#if CHECK_VISUAL_RECT_UPDATE |
- updateVisualRect(object, context); |
- DCHECK( |
- (context.oldVisualRect.isEmpty() && context.newVisualRect.isEmpty()) || |
- enclosingIntRect(context.oldVisualRect) == |
- enclosingIntRect(context.newVisualRect)) |
- << "Visual rect changed without needing paint invalidation:" |
- << " object=" << object.debugName() |
- << " old=" << context.oldVisualRect.toString() |
- << " new=" << context.newVisualRect.toString(); |
- DCHECK(object.isText() || context.oldLocation == context.newLocation) |
- << "Location changed without needing paint invalidation:" |
- << " old=" << context.oldLocation.toString() |
- << " new=" << context.newLocation.toString(); |
-#endif |
- return; |
+ // TODO(crbug.com/637313): Use GeometryMapper which now supports filter |
+ // geometry effects, after skia optimizes filter's mapRect operation. |
+ // TODO(crbug.com/648274): This is a workaround for multi-column contents. |
+ if (object.hasFilterInducingProperty() || object.isLayoutFlowThread()) { |
+ context.forcedSubtreeInvalidationFlags |= |
+ PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
} |
- updateVisualRect(object, context); |
+ updatePaintInvalidationContainer(object, context); |
+ updateVisualRectIfNeeded(object, context); |
- if (!objectShouldCheckForPaintInvalidation && |
- context.forcedSubtreeInvalidationFlags == |
- PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { |
- // We are done updating the visual rect. No other paint invalidation work to |
+ if (!object.shouldCheckForPaintInvalidation() && |
+ !(context.forcedSubtreeInvalidationFlags & |
+ ~PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate)) { |
+ // We are done updating anything needed. No other paint invalidation work to |
// do for this object. |
return; |
} |
@@ -491,12 +486,21 @@ void PaintInvalidator::invalidatePaintIfNeeded( |
context.forcedSubtreeInvalidationFlags |= |
PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
} |
+ |
+ if (context.forcedSubtreeInvalidationFlags && |
+ context.needsVisualRectUpdate(object)) { |
+ // If any subtree flag is set, we also need to pass needsVisualRectUpdate |
+ // requirement to the subtree. |
+ context.forcedSubtreeInvalidationFlags |= |
+ PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate; |
+ } |
} |
void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
- for (auto target : m_pendingDelayedPaintInvalidations) |
+ for (auto target : m_pendingDelayedPaintInvalidations) { |
target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
PaintInvalidationDelayedFull); |
+ } |
} |
} // namespace blink |