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

Unified Diff: third_party/WebKit/Source/core/paint/PrePaintTreeWalk.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/PrePaintTreeWalk.cpp
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
index bf339c75be25aa053e7c3c8cf958451a9c1f6024..4f463c5d721e75553b7999f0f666f31a50c90aac 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -49,8 +49,8 @@ void PrePaintTreeWalk::walk(FrameView& rootFrame) {
// GeometryMapper depends on paint properties.
if (rootFrame.needsPaintPropertyUpdate() ||
- (rootFrame.layoutView() &&
- !shouldEndWalkBefore(*rootFrame.layoutView(), initialContext)))
+ (rootFrame.layoutView() && needsWalkForPaintPropertyUpdate(
+ *rootFrame.layoutView(), initialContext)))
m_geometryMapper.clearCache();
walk(rootFrame, initialContext);
@@ -72,6 +72,10 @@ void PrePaintTreeWalk::walk(FrameView& frameView,
context.paintInvalidatorContext);
if (LayoutView* view = frameView.layoutView()) {
+#if DCHECK_IS_ON()
+ context.treeBuilderContext.updatedForSelf = true;
+ context.treeBuilderContext.updatedForChildren = true;
+#endif
walk(*view, context);
#if DCHECK_IS_ON()
view->assertSubtreeClearedPaintInvalidationFlags();
@@ -143,6 +147,10 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded(
if (!object.hasLayer())
return;
+#if DCHECK_IS_ON()
+ DCHECK(context.treeBuilderContext.updatedForChildren);
+#endif
+
PaintLayer& paintLayer = *toLayoutBoxModelObject(object).layer();
if (object.styleRef().hasTransform() ||
&object == context.paintInvalidatorContext.paintInvalidationContainer) {
@@ -215,27 +223,32 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded(
// All subsequences which are contained below this paintLayer must also
// be checked.
context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |=
- PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
+ PaintInvalidatorContext::ForcedSubtreeVisualRectUpdate;
}
paintLayer.setPreviousPaintingClipRects(*clipRects);
}
-bool PrePaintTreeWalk::shouldEndWalkBefore(
+bool PrePaintTreeWalk::needsWalkForPaintPropertyUpdate(
const LayoutObject& object,
const PrePaintTreeWalkContext& context) {
- return (
- !object.needsPaintPropertyUpdate() &&
- !object.descendantNeedsPaintPropertyUpdate() &&
- !context.treeBuilderContext.forceSubtreeUpdate &&
- !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
- !object
- .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState());
+ return object.needsPaintPropertyUpdate() ||
+ object.descendantNeedsPaintPropertyUpdate() ||
+ context.treeBuilderContext.forceSubtreeUpdate ||
+ // If the object needs visual rect update, we should update paint
+ // properties which are needed by visual rect update.
+ m_paintInvalidator.needsVisualRectUpdate(
+ object, context.paintInvalidatorContext);
}
void PrePaintTreeWalk::walk(const LayoutObject& object,
const PrePaintTreeWalkContext& parentContext) {
- if (shouldEndWalkBefore(object, parentContext))
+ // Early out from the treewalk if possible.
+ bool needsWalkForPaintPropertyUpdate =
+ this->needsWalkForPaintPropertyUpdate(object, parentContext);
+ if (!needsWalkForPaintPropertyUpdate &&
+ !object
+ .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState())
return;
// PrePaintTreeWalkContext is large and can lead to stack overflows when
@@ -248,14 +261,47 @@ void PrePaintTreeWalk::walk(const LayoutObject& object,
// some of the state computed here.
updateAuxiliaryObjectProperties(object, *context);
- m_propertyTreeBuilder.updatePropertiesForSelf(object,
- context->treeBuilderContext);
+ if (needsWalkForPaintPropertyUpdate) {
pdr. 2017/03/10 06:21:39 Trying to think of ways to simplify these DCHECKS.
Xianzhu 2017/03/10 17:43:05 This looks a good idea. Will try.
Xianzhu 2017/03/13 19:08:09 I tried the method, but found that we still need t
+#if DCHECK_IS_ON()
+ DCHECK(context->treeBuilderContext.parentUpdated);
+#endif
+ m_propertyTreeBuilder.updatePropertiesForSelf(object,
+ context->treeBuilderContext);
+#if DCHECK_IS_ON()
+ context->treeBuilderContext.updatedForSelf = true;
+#endif
+ } else {
+#if DCHECK_IS_ON()
+ // When DCHECK_IS_ON, always update paint properties so that paint
+ // invalidator can update visual rect for checking missing flags.
+ LayoutPoint oldPaintOffset = object.paintOffset();
+ m_propertyTreeBuilder.updatePropertiesForSelf(object,
+ context->treeBuilderContext);
+ DCHECK(object.paintOffset() == oldPaintOffset)
+ << "Paint offset changed without needsPaintOffsetAndVisualRectUpdate"
+ << " old=" << oldPaintOffset.toString()
+ << " new=" << object.paintOffset().toString();
+#endif
+ }
+
m_paintInvalidator.invalidatePaintIfNeeded(object,
context->paintInvalidatorContext);
- m_propertyTreeBuilder.updatePropertiesForChildren(
- object, context->treeBuilderContext);
- invalidatePaintLayerOptimizationsIfNeeded(object, *context);
+ if (needsWalkForPaintPropertyUpdate) {
+ m_propertyTreeBuilder.updatePropertiesForChildren(
+ object, context->treeBuilderContext);
+#if DCHECK_IS_ON()
+ context->treeBuilderContext.updatedForChildren = true;
+#endif
+ invalidatePaintLayerOptimizationsIfNeeded(object, *context);
+ } else {
+#if DCHECK_IS_ON()
+ // When DCHECK_IS_ON, always update paint properties so that paint
+ // invalidator can update visual rect for checking missing flags.
+ m_propertyTreeBuilder.updatePropertiesForChildren(
+ object, context->treeBuilderContext);
+#endif
+ }
for (const LayoutObject* child = object.slowFirstChild(); child;
child = child->nextSibling()) {

Powered by Google App Engine
This is Rietveld 408576698