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

Side by Side Diff: third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp

Issue 2735823005: Implement a non-recursive PrePaint treewalk (Closed)
Patch Set: Faster, cleaner 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/PrePaintTreeWalk.h" 5 #include "core/paint/PrePaintTreeWalk.h"
6 6
7 #include "core/dom/DocumentLifecycle.h" 7 #include "core/dom/DocumentLifecycle.h"
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/frame/LocalFrame.h" 9 #include "core/frame/LocalFrame.h"
10 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" 10 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 if (LayoutView* view = frameView.layoutView()) { 73 if (LayoutView* view = frameView.layoutView()) {
74 walk(*view, context); 74 walk(*view, context);
75 #if DCHECK_IS_ON() 75 #if DCHECK_IS_ON()
76 view->assertSubtreeClearedPaintInvalidationFlags(); 76 view->assertSubtreeClearedPaintInvalidationFlags();
77 #endif 77 #endif
78 } 78 }
79 frameView.clearNeedsPaintPropertyUpdate(); 79 frameView.clearNeedsPaintPropertyUpdate();
80 } 80 }
81 81
82 // |PrePaintTreeWalkContext| is large and can cause stack overflows when used
83 // in a recursive treewalk (see: https://crbug.com/698653). This function
84 // implements an iterative pre-order tree walk of the layout tree where the
85 // stack is maintained using heap allocations in a Vector.
86 void PrePaintTreeWalk::walk(const LayoutView& view,
87 const PrePaintTreeWalkContext& parentContext) {
88 Vector<PrePaintTreeWalkContext> stack;
pdr. 2017/03/08 01:04:59 This has a bug: when the vector resizes, parent po
89 stack.push_back(parentContext);
90
91 const LayoutObject* object = &view;
92 while (object) {
93 if (!shouldEndWalkBefore(*object, stack.back())) {
94 stack.push_back(stack.back());
95 walkObject(*object, stack.back());
96 if (const auto* child = object->slowFirstChild()) {
97 object = child;
98 continue;
99 }
100 stack.pop_back();
101 }
102
103 while (object && !object->nextSibling()) {
104 object->getMutableForPainting().clearPaintFlags();
105 stack.pop_back();
106 object = object->parent();
107 }
108
109 if (object) {
110 object->getMutableForPainting().clearPaintFlags();
111 object = object->nextSibling();
112 }
113 }
114 }
115
82 static void updateAuxiliaryObjectProperties(const LayoutObject& object, 116 static void updateAuxiliaryObjectProperties(const LayoutObject& object,
83 PrePaintTreeWalkContext& context) { 117 PrePaintTreeWalkContext& context) {
84 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 118 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled())
85 return; 119 return;
86 120
87 if (!object.hasLayer()) 121 if (!object.hasLayer())
88 return; 122 return;
89 123
90 PaintLayer* paintLayer = object.enclosingLayer(); 124 PaintLayer* paintLayer = object.enclosingLayer();
91 paintLayer->updateAncestorOverflowLayer(context.ancestorOverflowPaintLayer); 125 paintLayer->updateAncestorOverflowLayer(context.ancestorOverflowPaintLayer);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 const PrePaintTreeWalkContext& context) { 259 const PrePaintTreeWalkContext& context) {
226 return ( 260 return (
227 !object.needsPaintPropertyUpdate() && 261 !object.needsPaintPropertyUpdate() &&
228 !object.descendantNeedsPaintPropertyUpdate() && 262 !object.descendantNeedsPaintPropertyUpdate() &&
229 !context.treeBuilderContext.forceSubtreeUpdate && 263 !context.treeBuilderContext.forceSubtreeUpdate &&
230 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && 264 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
231 !object 265 !object
232 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) ; 266 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) ;
233 } 267 }
234 268
235 void PrePaintTreeWalk::walk(const LayoutObject& object, 269 void PrePaintTreeWalk::walkObject(const LayoutObject& object,
236 const PrePaintTreeWalkContext& parentContext) { 270 PrePaintTreeWalkContext& context) {
237 PrePaintTreeWalkContext context(parentContext); 271 DCHECK(!shouldEndWalkBefore(object, context));
238 272
239 if (shouldEndWalkBefore(object, parentContext)) 273 if (object.isLayoutMultiColumnSpannerPlaceholder())
240 return; 274 return;
241 275
242 // This must happen before updatePropertiesForSelf, because the latter reads 276 // This must happen before updatePropertiesForSelf, because the latter reads
243 // some of the state computed here. 277 // some of the state computed here.
244 updateAuxiliaryObjectProperties(object, context); 278 updateAuxiliaryObjectProperties(object, context);
245 279
246 m_propertyTreeBuilder.updatePropertiesForSelf(object, 280 m_propertyTreeBuilder.updatePropertiesForSelf(object,
247 context.treeBuilderContext); 281 context.treeBuilderContext);
248 m_paintInvalidator.invalidatePaintIfNeeded(object, 282 m_paintInvalidator.invalidatePaintIfNeeded(object,
249 context.paintInvalidatorContext); 283 context.paintInvalidatorContext);
250 m_propertyTreeBuilder.updatePropertiesForChildren(object, 284 m_propertyTreeBuilder.updatePropertiesForChildren(object,
251 context.treeBuilderContext); 285 context.treeBuilderContext);
252 286
253 invalidatePaintLayerOptimizationsIfNeeded(object, context); 287 invalidatePaintLayerOptimizationsIfNeeded(object, context);
254 288
255 for (const LayoutObject* child = object.slowFirstChild(); child;
256 child = child->nextSibling()) {
257 if (child->isLayoutMultiColumnSpannerPlaceholder()) {
258 child->getMutableForPainting().clearPaintFlags();
259 continue;
260 }
261 walk(*child, context);
262 }
263
264 if (object.isLayoutPart()) { 289 if (object.isLayoutPart()) {
265 const LayoutPart& layoutPart = toLayoutPart(object); 290 const LayoutPart& layoutPart = toLayoutPart(object);
266 FrameViewBase* frameViewBase = layoutPart.widget(); 291 FrameViewBase* frameViewBase = layoutPart.widget();
267 if (frameViewBase && frameViewBase->isFrameView()) { 292 if (frameViewBase && frameViewBase->isFrameView()) {
268 context.treeBuilderContext.current.paintOffset += 293 PrePaintTreeWalkContext frameViewContext(context);
294 frameViewContext.treeBuilderContext.current.paintOffset +=
269 layoutPart.replacedContentRect().location() - 295 layoutPart.replacedContentRect().location() -
270 frameViewBase->frameRect().location(); 296 frameViewBase->frameRect().location();
271 context.treeBuilderContext.current.paintOffset = 297 frameViewContext.treeBuilderContext.current.paintOffset = roundedIntPoint(
272 roundedIntPoint(context.treeBuilderContext.current.paintOffset); 298 frameViewContext.treeBuilderContext.current.paintOffset);
273 walk(*toFrameView(frameViewBase), context); 299 walk(*toFrameView(frameViewBase), frameViewContext);
274 } 300 }
275 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 301 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
276 } 302 }
277
278 object.getMutableForPainting().clearPaintFlags();
279 } 303 }
280 304
281 } // namespace blink 305 } // namespace blink
OLDNEW
« 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