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

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
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3cc8cc1208933e5c5ff79ece7e85c47243cfdc71..c56ecac648d0489273ca0533e08ac78ce1ff38d0 100644
--- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
+++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -18,17 +18,28 @@ struct PrePaintTreeWalkContext {
PrePaintTreeWalkContext(GeometryMapper& geometryMapper)
: treeBuilderContext(
WTF::wrapUnique(new PaintPropertyTreeBuilderContext)),
- paintInvalidatorContext(*treeBuilderContext, geometryMapper),
+ paintInvalidatorContext(treeBuilderContext.get(), geometryMapper),
ancestorOverflowPaintLayer(nullptr),
ancestorTransformedOrRootPaintLayer(nullptr) {}
- PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext)
- : treeBuilderContext(WTF::wrapUnique(new PaintPropertyTreeBuilderContext(
- *parentContext.treeBuilderContext))),
- paintInvalidatorContext(*treeBuilderContext,
+
+ PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext,
+ bool needsTreeBuilderContext)
+ : treeBuilderContext(
+ WTF::wrapUnique(needsTreeBuilderContext || DCHECK_IS_ON()
+ ? new PaintPropertyTreeBuilderContext(
+ *parentContext.treeBuilderContext)
+ : nullptr)),
+ paintInvalidatorContext(treeBuilderContext.get(),
parentContext.paintInvalidatorContext),
ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer),
ancestorTransformedOrRootPaintLayer(
- parentContext.ancestorTransformedOrRootPaintLayer) {}
+ parentContext.ancestorTransformedOrRootPaintLayer) {
+#if DCHECK_IS_ON()
+ if (needsTreeBuilderContext)
+ DCHECK(parentContext.treeBuilderContext->isActuallyNeeded);
+ treeBuilderContext->isActuallyNeeded = needsTreeBuilderContext;
+#endif
+ }
// PaintPropertyTreeBuilderContext is large and can lead to stack overflows
// when recursion is deep so this context object is allocated on the heap.
@@ -53,9 +64,7 @@ void PrePaintTreeWalk::walk(FrameView& rootFrame) {
rootFrame.layoutView()->layer();
// GeometryMapper depends on paint properties.
- if (rootFrame.needsPaintPropertyUpdate() ||
- (rootFrame.layoutView() &&
- !shouldEndWalkBefore(*rootFrame.layoutView(), initialContext)))
+ if (needsTreeBuilderContextUpdate(rootFrame, initialContext))
m_geometryMapper.clearCache();
walk(rootFrame, initialContext);
@@ -69,11 +78,15 @@ void PrePaintTreeWalk::walk(FrameView& frameView,
return;
}
- PrePaintTreeWalkContext context(parentContext);
+ bool needsTreeBuilderContextUpdate =
+ this->needsTreeBuilderContextUpdate(frameView, parentContext);
+ PrePaintTreeWalkContext context(parentContext, needsTreeBuilderContextUpdate);
// ancestorOverflowLayer does not cross frame boundaries.
context.ancestorOverflowPaintLayer = nullptr;
- m_propertyTreeBuilder.updateProperties(frameView,
- *context.treeBuilderContext);
+ if (context.treeBuilderContext) {
+ m_propertyTreeBuilder.updateProperties(frameView,
+ *context.treeBuilderContext);
+ }
m_paintInvalidator.invalidatePaintIfNeeded(frameView,
context.paintInvalidatorContext);
@@ -224,41 +237,61 @@ 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(
- const LayoutObject& object,
+bool PrePaintTreeWalk::needsTreeBuilderContextUpdate(
+ const FrameView& frameView,
const PrePaintTreeWalkContext& context) {
- return !object.needsPaintPropertyUpdate() &&
- !object.descendantNeedsPaintPropertyUpdate() &&
- !context.treeBuilderContext->forceSubtreeUpdate &&
- !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
- !object.shouldCheckForPaintInvalidation();
+ return frameView.needsPaintPropertyUpdate() ||
+ (frameView.layoutView() &&
+ needsTreeBuilderContextUpdate(*frameView.layoutView(), context));
+}
+
+bool PrePaintTreeWalk::needsTreeBuilderContextUpdate(
+ const LayoutObject& object,
+ const PrePaintTreeWalkContext& parentContext) {
+ return object.needsPaintPropertyUpdate() ||
+ object.descendantNeedsPaintPropertyUpdate() ||
+ (parentContext.treeBuilderContext &&
+ parentContext.treeBuilderContext->forceSubtreeUpdate) ||
+ // If the object needs visual rect update, we should update tree
+ // builder context which is needed by visual rect update.
+ parentContext.paintInvalidatorContext.needsVisualRectUpdate(object);
}
void PrePaintTreeWalk::walk(const LayoutObject& object,
const PrePaintTreeWalkContext& parentContext) {
- if (shouldEndWalkBefore(object, parentContext))
+ // Early out from the tree walk if possible.
+ bool needsTreeBuilderContextUpdate =
+ this->needsTreeBuilderContextUpdate(object, parentContext);
+ if (!needsTreeBuilderContextUpdate &&
+ !object.shouldCheckForPaintInvalidation())
return;
- PrePaintTreeWalkContext context(parentContext);
+ PrePaintTreeWalkContext context(parentContext, needsTreeBuilderContextUpdate);
// This must happen before updatePropertiesForSelf, because the latter reads
// some of the state computed here.
updateAuxiliaryObjectProperties(object, context);
- m_propertyTreeBuilder.updatePropertiesForSelf(object,
- *context.treeBuilderContext);
+ if (context.treeBuilderContext) {
+ DCHECK(context.treeBuilderContext);
+ m_propertyTreeBuilder.updatePropertiesForSelf(object,
+ *context.treeBuilderContext);
+ }
+
m_paintInvalidator.invalidatePaintIfNeeded(object,
context.paintInvalidatorContext);
- m_propertyTreeBuilder.updatePropertiesForChildren(
- object, *context.treeBuilderContext);
- invalidatePaintLayerOptimizationsIfNeeded(object, context);
+ if (context.treeBuilderContext) {
+ m_propertyTreeBuilder.updatePropertiesForChildren(
+ object, *context.treeBuilderContext);
+ invalidatePaintLayerOptimizationsIfNeeded(object, context);
+ }
for (const LayoutObject* child = object.slowFirstChild(); child;
child = child->nextSibling()) {
@@ -273,11 +306,13 @@ void PrePaintTreeWalk::walk(const LayoutObject& object,
const LayoutPart& layoutPart = toLayoutPart(object);
FrameViewBase* frameViewBase = layoutPart.frameViewBase();
if (frameViewBase && frameViewBase->isFrameView()) {
- context.treeBuilderContext->current.paintOffset +=
- layoutPart.replacedContentRect().location() -
- frameViewBase->frameRect().location();
- context.treeBuilderContext->current.paintOffset =
- roundedIntPoint(context.treeBuilderContext->current.paintOffset);
+ if (context.treeBuilderContext) {
+ context.treeBuilderContext->current.paintOffset +=
+ layoutPart.replacedContentRect().location() -
+ frameViewBase->frameRect().location();
+ context.treeBuilderContext->current.paintOffset =
+ roundedIntPoint(context.treeBuilderContext->current.paintOffset);
+ }
walk(*toFrameView(frameViewBase), context);
}
// TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698