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

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

Issue 2751753004: Store PaintPropertyTreeBuilderContext inline (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 unified diff | Download patch
« no previous file with comments | « no previous file | 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"
11 #include "core/layout/LayoutPart.h" 11 #include "core/layout/LayoutPart.h"
12 #include "core/layout/LayoutView.h" 12 #include "core/layout/LayoutView.h"
13 #include "core/paint/PaintLayer.h" 13 #include "core/paint/PaintLayer.h"
14 14
15 namespace blink { 15 namespace blink {
16 16
17 struct PrePaintTreeWalkContext { 17 struct PrePaintTreeWalkContext {
18 USING_FAST_MALLOC(PrePaintTreeWalkContext);
19
20 public:
18 PrePaintTreeWalkContext() 21 PrePaintTreeWalkContext()
19 : treeBuilderContext( 22 : treeBuilderContext(),
20 WTF::wrapUnique(new PaintPropertyTreeBuilderContext)), 23 paintInvalidatorContext(treeBuilderContext),
21 paintInvalidatorContext(*treeBuilderContext),
22 ancestorOverflowPaintLayer(nullptr), 24 ancestorOverflowPaintLayer(nullptr),
23 ancestorTransformedOrRootPaintLayer(nullptr) {} 25 ancestorTransformedOrRootPaintLayer(nullptr) {}
24 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) 26 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext)
25 : treeBuilderContext(WTF::wrapUnique(new PaintPropertyTreeBuilderContext( 27 : treeBuilderContext(parentContext.treeBuilderContext),
26 *parentContext.treeBuilderContext))), 28 paintInvalidatorContext(treeBuilderContext,
27 paintInvalidatorContext(*treeBuilderContext,
28 parentContext.paintInvalidatorContext), 29 parentContext.paintInvalidatorContext),
29 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer), 30 ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer),
30 ancestorTransformedOrRootPaintLayer( 31 ancestorTransformedOrRootPaintLayer(
31 parentContext.ancestorTransformedOrRootPaintLayer) {} 32 parentContext.ancestorTransformedOrRootPaintLayer) {}
32 33
33 // PaintPropertyTreeBuilderContext is large and can lead to stack overflows 34 PaintPropertyTreeBuilderContext treeBuilderContext;
34 // when recursion is deep so this context object is allocated on the heap.
35 // See: https://crbug.com/698653.
36 std::unique_ptr<PaintPropertyTreeBuilderContext> treeBuilderContext;
37 35
38 PaintInvalidatorContext paintInvalidatorContext; 36 PaintInvalidatorContext paintInvalidatorContext;
39 37
40 // The ancestor in the PaintLayer tree which has overflow clip, or 38 // The ancestor in the PaintLayer tree which has overflow clip, or
41 // is the root layer. Note that it is tree ancestor, not containing 39 // is the root layer. Note that it is tree ancestor, not containing
42 // block or stacking ancestor. 40 // block or stacking ancestor.
43 PaintLayer* ancestorOverflowPaintLayer; 41 PaintLayer* ancestorOverflowPaintLayer;
44 PaintLayer* ancestorTransformedOrRootPaintLayer; 42 PaintLayer* ancestorTransformedOrRootPaintLayer;
45 }; 43 };
46 44
47 void PrePaintTreeWalk::walk(FrameView& rootFrame) { 45 void PrePaintTreeWalk::walk(FrameView& rootFrame) {
48 DCHECK(rootFrame.frame().document()->lifecycle().state() == 46 DCHECK(rootFrame.frame().document()->lifecycle().state() ==
49 DocumentLifecycle::InPrePaint); 47 DocumentLifecycle::InPrePaint);
50 48
51 PrePaintTreeWalkContext initialContext; 49 PrePaintTreeWalkContext initialContext;
52 m_propertyTreeBuilder.setupInitialContext(*initialContext.treeBuilderContext); 50 m_propertyTreeBuilder.setupInitialContext(initialContext.treeBuilderContext);
53 initialContext.ancestorTransformedOrRootPaintLayer = 51 initialContext.ancestorTransformedOrRootPaintLayer =
54 rootFrame.layoutView()->layer(); 52 rootFrame.layoutView()->layer();
55 53
56 // GeometryMapper depends on paint properties. 54 // GeometryMapper depends on paint properties.
57 if (rootFrame.needsPaintPropertyUpdate() || 55 if (rootFrame.needsPaintPropertyUpdate() ||
58 (rootFrame.layoutView() && 56 (rootFrame.layoutView() &&
59 !shouldEndWalkBefore(*rootFrame.layoutView(), initialContext))) 57 !shouldEndWalkBefore(*rootFrame.layoutView(), initialContext)))
60 m_geometryMapper.clearCache(); 58 m_geometryMapper.clearCache();
61 59
62 walk(rootFrame, initialContext); 60 walk(rootFrame, initialContext);
63 m_paintInvalidator.processPendingDelayedPaintInvalidations(); 61 m_paintInvalidator.processPendingDelayedPaintInvalidations();
64 } 62 }
65 63
66 void PrePaintTreeWalk::walk(FrameView& frameView, 64 void PrePaintTreeWalk::walk(FrameView& frameView,
67 const PrePaintTreeWalkContext& parentContext) { 65 const PrePaintTreeWalkContext& parentContext) {
68 if (frameView.shouldThrottleRendering()) { 66 if (frameView.shouldThrottleRendering()) {
69 // Skip the throttled frame. Will update it when it becomes unthrottled. 67 // Skip the throttled frame. Will update it when it becomes unthrottled.
70 return; 68 return;
71 } 69 }
72 70
73 PrePaintTreeWalkContext context(parentContext); 71 PrePaintTreeWalkContext context(parentContext);
74 // ancestorOverflowLayer does not cross frame boundaries. 72 // ancestorOverflowLayer does not cross frame boundaries.
75 context.ancestorOverflowPaintLayer = nullptr; 73 context.ancestorOverflowPaintLayer = nullptr;
76 m_propertyTreeBuilder.updateProperties(frameView, 74 m_propertyTreeBuilder.updateProperties(frameView, context.treeBuilderContext);
77 *context.treeBuilderContext);
78 m_paintInvalidator.invalidatePaintIfNeeded(frameView, 75 m_paintInvalidator.invalidatePaintIfNeeded(frameView,
79 context.paintInvalidatorContext); 76 context.paintInvalidatorContext);
80 77
81 if (LayoutView* view = frameView.layoutView()) { 78 if (LayoutView* view = frameView.layoutView()) {
82 walk(*view, context); 79 walk(*view, context);
83 #if DCHECK_IS_ON() 80 #if DCHECK_IS_ON()
84 view->assertSubtreeClearedPaintInvalidationFlags(); 81 view->assertSubtreeClearedPaintInvalidationFlags();
85 #endif 82 #endif
86 } 83 }
87 frameView.clearNeedsPaintPropertyUpdate(); 84 frameView.clearNeedsPaintPropertyUpdate();
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 respectOverflowClip, LayoutSize()); 176 respectOverflowClip, LayoutSize());
180 #endif 177 #endif
181 178
182 bool hasClip = false; 179 bool hasClip = false;
183 RefPtr<ClipRects> clipRects = ClipRects::create(); 180 RefPtr<ClipRects> clipRects = ClipRects::create();
184 const LayoutPoint& ancestorPaintOffset = 181 const LayoutPoint& ancestorPaintOffset =
185 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); 182 context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset();
186 183
187 FloatClipRect clipRect; 184 FloatClipRect clipRect;
188 const EffectPaintPropertyNode* effect = 185 const EffectPaintPropertyNode* effect =
189 context.treeBuilderContext->currentEffect; 186 context.treeBuilderContext.currentEffect;
190 computeClipRectForContext(context.treeBuilderContext->current, effect, 187 computeClipRectForContext(context.treeBuilderContext.current, effect,
191 ancestorState, ancestorPaintOffset, hasClip, 188 ancestorState, ancestorPaintOffset, hasClip,
192 clipRect); 189 clipRect);
193 clipRects->setOverflowClipRect(clipRect); 190 clipRects->setOverflowClipRect(clipRect);
194 #ifdef CHECK_CLIP_RECTS 191 #ifdef CHECK_CLIP_RECTS
195 CHECK(!hasClip || 192 CHECK(!hasClip ||
196 clipRects->overflowClipRect() == oldClipRects.overflowClipRect()) 193 clipRects->overflowClipRect() == oldClipRects.overflowClipRect())
197 << "rect= " << clipRects->overflowClipRect().toString(); 194 << "rect= " << clipRects->overflowClipRect().toString();
198 #endif 195 #endif
199 196
200 computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, 197 computeClipRectForContext(context.treeBuilderContext.fixedPosition, effect,
201 ancestorState, ancestorPaintOffset, hasClip, 198 ancestorState, ancestorPaintOffset, hasClip,
202 clipRect); 199 clipRect);
203 clipRects->setFixedClipRect(clipRect); 200 clipRects->setFixedClipRect(clipRect);
204 #ifdef CHECK_CLIP_RECTS 201 #ifdef CHECK_CLIP_RECTS
205 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect()) 202 CHECK(hasClip || clipRects->fixedClipRect() == oldClipRects.fixedClipRect())
206 << " fixed=" << clipRects->fixedClipRect().toString(); 203 << " fixed=" << clipRects->fixedClipRect().toString();
207 #endif 204 #endif
208 205
209 computeClipRectForContext(context.treeBuilderContext->absolutePosition, 206 computeClipRectForContext(context.treeBuilderContext.absolutePosition, effect,
210 effect, ancestorState, ancestorPaintOffset, hasClip, 207 ancestorState, ancestorPaintOffset, hasClip,
211 clipRect); 208 clipRect);
212 clipRects->setPosClipRect(clipRect); 209 clipRects->setPosClipRect(clipRect);
213 #ifdef CHECK_CLIP_RECTS 210 #ifdef CHECK_CLIP_RECTS
214 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect()) 211 CHECK(!hasClip || clipRects->posClipRect() == oldClipRects.posClipRect())
215 << " abs=" << clipRects->posClipRect().toString(); 212 << " abs=" << clipRects->posClipRect().toString();
216 #endif 213 #endif
217 214
218 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects(); 215 ClipRects* previousClipRects = paintLayer.previousPaintingClipRects();
219 216
220 if (!previousClipRects || *clipRects != *previousClipRects) { 217 if (!previousClipRects || *clipRects != *previousClipRects) {
221 paintLayer.setNeedsRepaint(); 218 paintLayer.setNeedsRepaint();
222 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false); 219 paintLayer.setPreviousPaintPhaseDescendantOutlinesEmpty(false);
223 paintLayer.setPreviousPaintPhaseFloatEmpty(false); 220 paintLayer.setPreviousPaintPhaseFloatEmpty(false);
224 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); 221 paintLayer.setPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
225 // All subsequences which are contained below this paintLayer must also 222 // All subsequences which are contained below this paintLayer must also
226 // be checked. 223 // be checked.
227 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |= 224 context.paintInvalidatorContext.forcedSubtreeInvalidationFlags |=
228 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; 225 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate;
229 } 226 }
230 227
231 paintLayer.setPreviousPaintingClipRects(*clipRects); 228 paintLayer.setPreviousPaintingClipRects(*clipRects);
232 } 229 }
233 230
234 bool PrePaintTreeWalk::shouldEndWalkBefore( 231 bool PrePaintTreeWalk::shouldEndWalkBefore(
235 const LayoutObject& object, 232 const LayoutObject& object,
236 const PrePaintTreeWalkContext& context) { 233 const PrePaintTreeWalkContext& context) {
237 return ( 234 return (
238 !object.needsPaintPropertyUpdate() && 235 !object.needsPaintPropertyUpdate() &&
239 !object.descendantNeedsPaintPropertyUpdate() && 236 !object.descendantNeedsPaintPropertyUpdate() &&
240 !context.treeBuilderContext->forceSubtreeUpdate && 237 !context.treeBuilderContext.forceSubtreeUpdate &&
241 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && 238 !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags &&
242 !object 239 !object
243 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) ; 240 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) ;
244 } 241 }
245 242
246 void PrePaintTreeWalk::walk(const LayoutObject& object, 243 void PrePaintTreeWalk::walk(const LayoutObject& object,
247 const PrePaintTreeWalkContext& parentContext) { 244 const PrePaintTreeWalkContext& parentContext) {
248 if (shouldEndWalkBefore(object, parentContext)) 245 if (shouldEndWalkBefore(object, parentContext))
249 return; 246 return;
250 247
251 PrePaintTreeWalkContext context(parentContext); 248 PrePaintTreeWalkContext context(parentContext);
252 249
253 // This must happen before updatePropertiesForSelf, because the latter reads 250 // This must happen before updatePropertiesForSelf, because the latter reads
254 // some of the state computed here. 251 // some of the state computed here.
255 updateAuxiliaryObjectProperties(object, context); 252 updateAuxiliaryObjectProperties(object, context);
256 253
257 m_propertyTreeBuilder.updatePropertiesForSelf(object, 254 m_propertyTreeBuilder.updatePropertiesForSelf(object,
258 *context.treeBuilderContext); 255 context.treeBuilderContext);
259 m_paintInvalidator.invalidatePaintIfNeeded(object, 256 m_paintInvalidator.invalidatePaintIfNeeded(object,
260 context.paintInvalidatorContext); 257 context.paintInvalidatorContext);
261 m_propertyTreeBuilder.updatePropertiesForChildren( 258 m_propertyTreeBuilder.updatePropertiesForChildren(object,
262 object, *context.treeBuilderContext); 259 context.treeBuilderContext);
263 260
264 invalidatePaintLayerOptimizationsIfNeeded(object, context); 261 invalidatePaintLayerOptimizationsIfNeeded(object, context);
265 262
266 for (const LayoutObject* child = object.slowFirstChild(); child; 263 for (const LayoutObject* child = object.slowFirstChild(); child;
267 child = child->nextSibling()) { 264 child = child->nextSibling()) {
268 if (child->isLayoutMultiColumnSpannerPlaceholder()) { 265 if (child->isLayoutMultiColumnSpannerPlaceholder()) {
269 child->getMutableForPainting().clearPaintFlags(); 266 child->getMutableForPainting().clearPaintFlags();
270 continue; 267 continue;
271 } 268 }
272 walk(*child, context); 269 walk(*child, context);
273 } 270 }
274 271
275 if (object.isLayoutPart()) { 272 if (object.isLayoutPart()) {
276 const LayoutPart& layoutPart = toLayoutPart(object); 273 const LayoutPart& layoutPart = toLayoutPart(object);
277 FrameViewBase* frameViewBase = layoutPart.frameViewBase(); 274 FrameViewBase* frameViewBase = layoutPart.frameViewBase();
278 if (frameViewBase && frameViewBase->isFrameView()) { 275 if (frameViewBase && frameViewBase->isFrameView()) {
279 context.treeBuilderContext->current.paintOffset += 276 context.treeBuilderContext.current.paintOffset +=
280 layoutPart.replacedContentRect().location() - 277 layoutPart.replacedContentRect().location() -
281 frameViewBase->frameRect().location(); 278 frameViewBase->frameRect().location();
282 context.treeBuilderContext->current.paintOffset = 279 context.treeBuilderContext.current.paintOffset =
283 roundedIntPoint(context.treeBuilderContext->current.paintOffset); 280 roundedIntPoint(context.treeBuilderContext.current.paintOffset);
284 walk(*toFrameView(frameViewBase), context); 281 walk(*toFrameView(frameViewBase), context);
285 } 282 }
286 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 283 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
287 } 284 }
288 285
289 object.getMutableForPainting().clearPaintFlags(); 286 object.getMutableForPainting().clearPaintFlags();
290 } 287 }
291 288
292 } // namespace blink 289 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698