Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(604)

Unified Diff: third_party/WebKit/Source/core/paint/PaintInvalidator.cpp

Issue 2732573003: Skip paint property update and visual rect update if no geometry change (Closed)
Patch Set: - Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698