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

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

Issue 2873823002: Put PaintInvalidatorContext on the heap, to reduce stack overflows. (Closed)
Patch Set: Merge branch 'master' into fastmallocpaintinvalidator Created 3 years, 7 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/PaintInvalidator.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"
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 #include "platform/graphics/paint/GeometryMapper.h" 14 #include "platform/graphics/paint/GeometryMapper.h"
15 15
16 namespace blink { 16 namespace blink {
17 17
18 struct PrePaintTreeWalkContext { 18 struct PrePaintTreeWalkContext {
19 PrePaintTreeWalkContext() 19 PrePaintTreeWalkContext()
20 : tree_builder_context( 20 : tree_builder_context(
21 WTF::WrapUnique(new PaintPropertyTreeBuilderContext)), 21 WTF::WrapUnique(new PaintPropertyTreeBuilderContext)),
22 paint_invalidator_context(WTF::WrapUnique(new PaintInvalidatorContext)),
22 ancestor_overflow_paint_layer(nullptr), 23 ancestor_overflow_paint_layer(nullptr),
23 ancestor_transformed_or_root_paint_layer(nullptr) {} 24 ancestor_transformed_or_root_paint_layer(nullptr) {}
24 25
25 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context, 26 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context,
26 bool needs_tree_builder_context) 27 bool needs_tree_builder_context)
27 : tree_builder_context( 28 : tree_builder_context(
28 WTF::WrapUnique(needs_tree_builder_context || DCHECK_IS_ON() 29 WTF::WrapUnique(needs_tree_builder_context || DCHECK_IS_ON()
29 ? new PaintPropertyTreeBuilderContext( 30 ? new PaintPropertyTreeBuilderContext(
30 *parent_context.tree_builder_context) 31 *parent_context.tree_builder_context)
31 : nullptr)), 32 : nullptr)),
32 paint_invalidator_context(parent_context.paint_invalidator_context), 33 paint_invalidator_context(WTF::WrapUnique(new PaintInvalidatorContext(
34 *parent_context.paint_invalidator_context))),
33 ancestor_overflow_paint_layer( 35 ancestor_overflow_paint_layer(
34 parent_context.ancestor_overflow_paint_layer), 36 parent_context.ancestor_overflow_paint_layer),
35 ancestor_transformed_or_root_paint_layer( 37 ancestor_transformed_or_root_paint_layer(
36 parent_context.ancestor_transformed_or_root_paint_layer) { 38 parent_context.ancestor_transformed_or_root_paint_layer) {
37 #if DCHECK_IS_ON() 39 #if DCHECK_IS_ON()
38 if (needs_tree_builder_context) 40 if (needs_tree_builder_context)
39 DCHECK(parent_context.tree_builder_context->is_actually_needed); 41 DCHECK(parent_context.tree_builder_context->is_actually_needed);
40 tree_builder_context->is_actually_needed = needs_tree_builder_context; 42 tree_builder_context->is_actually_needed = needs_tree_builder_context;
41 #endif 43 #endif
42 } 44 }
43 45
44 // PaintPropertyTreeBuilderContext is large and can lead to stack overflows 46 // PaintPropertyTreeBuilderContext is large and can lead to stack overflows
45 // when recursion is deep so this context object is allocated on the heap. 47 // when recursion is deep so this context object is allocated on the heap.
46 // See: https://crbug.com/698653. 48 // See: https://crbug.com/698653.
47 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context; 49 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context;
48 50
49 PaintInvalidatorContext paint_invalidator_context; 51 std::unique_ptr<PaintInvalidatorContext> paint_invalidator_context;
50 52
51 // The ancestor in the PaintLayer tree which has overflow clip, or 53 // The ancestor in the PaintLayer tree which has overflow clip, or
52 // is the root layer. Note that it is tree ancestor, not containing 54 // is the root layer. Note that it is tree ancestor, not containing
53 // block or stacking ancestor. 55 // block or stacking ancestor.
54 PaintLayer* ancestor_overflow_paint_layer; 56 PaintLayer* ancestor_overflow_paint_layer;
55 57
56 // The ancestor in the PaintLayer tree which has a transform or is a root 58 // The ancestor in the PaintLayer tree which has a transform or is a root
57 // layer for painting (i.e. a paint invalidation container). 59 // layer for painting (i.e. a paint invalidation container).
58 PaintLayer* ancestor_transformed_or_root_paint_layer; 60 PaintLayer* ancestor_transformed_or_root_paint_layer;
59 }; 61 };
(...skipping 26 matching lines...) Expand all
86 PrePaintTreeWalkContext context(parent_context, 88 PrePaintTreeWalkContext context(parent_context,
87 needs_tree_builder_context_update); 89 needs_tree_builder_context_update);
88 // ancestorOverflowLayer does not cross frame boundaries. 90 // ancestorOverflowLayer does not cross frame boundaries.
89 context.ancestor_overflow_paint_layer = nullptr; 91 context.ancestor_overflow_paint_layer = nullptr;
90 if (context.tree_builder_context) { 92 if (context.tree_builder_context) {
91 property_tree_builder_.UpdateProperties(frame_view, 93 property_tree_builder_.UpdateProperties(frame_view,
92 *context.tree_builder_context); 94 *context.tree_builder_context);
93 } 95 }
94 paint_invalidator_.InvalidatePaint(frame_view, 96 paint_invalidator_.InvalidatePaint(frame_view,
95 context.tree_builder_context.get(), 97 context.tree_builder_context.get(),
96 context.paint_invalidator_context); 98 *context.paint_invalidator_context);
97 99
98 if (LayoutView* view = frame_view.GetLayoutView()) { 100 if (LayoutView* view = frame_view.GetLayoutView()) {
99 Walk(*view, context); 101 Walk(*view, context);
100 #if DCHECK_IS_ON() 102 #if DCHECK_IS_ON()
101 view->AssertSubtreeClearedPaintInvalidationFlags(); 103 view->AssertSubtreeClearedPaintInvalidationFlags();
102 #endif 104 #endif
103 } 105 }
104 frame_view.ClearNeedsPaintPropertyUpdate(); 106 frame_view.ClearNeedsPaintPropertyUpdate();
105 } 107 }
106 108
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 150
149 void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded( 151 void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
150 const LayoutObject& object, 152 const LayoutObject& object,
151 PrePaintTreeWalkContext& context) { 153 PrePaintTreeWalkContext& context) {
152 if (!object.HasLayer()) 154 if (!object.HasLayer())
153 return; 155 return;
154 156
155 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer(); 157 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer();
156 if (object.StyleRef().HasTransform() || 158 if (object.StyleRef().HasTransform() ||
157 &object == 159 &object ==
158 context.paint_invalidator_context.paint_invalidation_container) { 160 context.paint_invalidator_context->paint_invalidation_container) {
159 context.ancestor_transformed_or_root_paint_layer = &paint_layer; 161 context.ancestor_transformed_or_root_paint_layer = &paint_layer;
160 } 162 }
161 163
162 // This code below checks whether any clips have changed that might: 164 // This code below checks whether any clips have changed that might:
163 // (a) invalidate optimizations made for a PaintLayer that supports 165 // (a) invalidate optimizations made for a PaintLayer that supports
164 // subsequence caching, or 166 // subsequence caching, or
165 // (b) impact clipping of descendant visual rects. 167 // (b) impact clipping of descendant visual rects.
166 if (!paint_layer.SupportsSubsequenceCaching() && 168 if (!paint_layer.SupportsSubsequenceCaching() &&
167 !paint_layer.GetLayoutObject().HasClipRelatedProperty()) 169 !paint_layer.GetLayoutObject().HasClipRelatedProperty())
168 return; 170 return;
169 171
170 FragmentData* fragment_data = 172 FragmentData* fragment_data =
171 &object.GetMutableForPainting().EnsureFirstFragment(); 173 &object.GetMutableForPainting().EnsureFirstFragment();
172 for (auto& fragment : context.tree_builder_context->fragments) { 174 for (auto& fragment : context.tree_builder_context->fragments) {
173 DCHECK(fragment_data); 175 DCHECK(fragment_data);
174 if (InvalidatePaintLayerOptimizationsForFragment( 176 if (InvalidatePaintLayerOptimizationsForFragment(
175 object, context.ancestor_transformed_or_root_paint_layer, fragment, 177 object, context.ancestor_transformed_or_root_paint_layer, fragment,
176 *fragment_data)) { 178 *fragment_data)) {
177 context.paint_invalidator_context.forced_subtree_invalidation_flags |= 179 context.paint_invalidator_context->forced_subtree_invalidation_flags |=
178 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate; 180 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
179 } 181 }
180 fragment_data = fragment_data->NextFragment(); 182 fragment_data = fragment_data->NextFragment();
181 } 183 }
182 } 184 }
183 185
184 bool PrePaintTreeWalk::InvalidatePaintLayerOptimizationsForFragment( 186 bool PrePaintTreeWalk::InvalidatePaintLayerOptimizationsForFragment(
185 const LayoutObject& object, 187 const LayoutObject& object,
186 const PaintLayer* ancestor_transformed_or_root_paint_layer, 188 const PaintLayer* ancestor_transformed_or_root_paint_layer,
187 const PaintPropertyTreeBuilderFragmentContext& context, 189 const PaintPropertyTreeBuilderFragmentContext& context,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 276
275 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( 277 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
276 const LayoutObject& object, 278 const LayoutObject& object,
277 const PrePaintTreeWalkContext& parent_context) { 279 const PrePaintTreeWalkContext& parent_context) {
278 return object.NeedsPaintPropertyUpdate() || 280 return object.NeedsPaintPropertyUpdate() ||
279 object.DescendantNeedsPaintPropertyUpdate() || 281 object.DescendantNeedsPaintPropertyUpdate() ||
280 (parent_context.tree_builder_context && 282 (parent_context.tree_builder_context &&
281 parent_context.tree_builder_context->force_subtree_update) || 283 parent_context.tree_builder_context->force_subtree_update) ||
282 // If the object needs visual rect update, we should update tree 284 // If the object needs visual rect update, we should update tree
283 // builder context which is needed by visual rect update. 285 // builder context which is needed by visual rect update.
284 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object); 286 parent_context.paint_invalidator_context->NeedsVisualRectUpdate(
287 object);
285 } 288 }
286 289
287 void PrePaintTreeWalk::ClearPreviousClipRectsForTesting( 290 void PrePaintTreeWalk::ClearPreviousClipRectsForTesting(
288 const LayoutObject& object) { 291 const LayoutObject& object) {
289 object.GetMutableForPainting().FirstFragment()->ClearPreviousClipRects(); 292 object.GetMutableForPainting().FirstFragment()->ClearPreviousClipRects();
290 } 293 }
291 294
292 void PrePaintTreeWalk::Walk(const LayoutObject& object, 295 void PrePaintTreeWalk::Walk(const LayoutObject& object,
293 const PrePaintTreeWalkContext& parent_context) { 296 const PrePaintTreeWalkContext& parent_context) {
294 // Early out from the tree walk if possible. 297 // Early out from the tree walk if possible.
(...skipping 10 matching lines...) Expand all
305 // some of the state computed here. 308 // some of the state computed here.
306 UpdateAuxiliaryObjectProperties(object, context); 309 UpdateAuxiliaryObjectProperties(object, context);
307 310
308 if (context.tree_builder_context) { 311 if (context.tree_builder_context) {
309 DCHECK(context.tree_builder_context); 312 DCHECK(context.tree_builder_context);
310 property_tree_builder_.UpdatePropertiesForSelf( 313 property_tree_builder_.UpdatePropertiesForSelf(
311 object, *context.tree_builder_context); 314 object, *context.tree_builder_context);
312 } 315 }
313 316
314 paint_invalidator_.InvalidatePaint(object, context.tree_builder_context.get(), 317 paint_invalidator_.InvalidatePaint(object, context.tree_builder_context.get(),
315 context.paint_invalidator_context); 318 *context.paint_invalidator_context);
316 319
317 if (context.tree_builder_context) { 320 if (context.tree_builder_context) {
318 property_tree_builder_.UpdatePropertiesForChildren( 321 property_tree_builder_.UpdatePropertiesForChildren(
319 object, *context.tree_builder_context); 322 object, *context.tree_builder_context);
320 InvalidatePaintLayerOptimizationsIfNeeded(object, context); 323 InvalidatePaintLayerOptimizationsIfNeeded(object, context);
321 } 324 }
322 325
323 for (const LayoutObject* child = object.SlowFirstChild(); child; 326 for (const LayoutObject* child = object.SlowFirstChild(); child;
324 child = child->NextSibling()) { 327 child = child->NextSibling()) {
325 if (child->IsLayoutMultiColumnSpannerPlaceholder()) { 328 if (child->IsLayoutMultiColumnSpannerPlaceholder()) {
(...skipping 17 matching lines...) Expand all
343 } 346 }
344 Walk(*frame_view, context); 347 Walk(*frame_view, context);
345 } 348 }
346 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 349 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
347 } 350 }
348 351
349 object.GetMutableForPainting().ClearPaintFlags(); 352 object.GetMutableForPainting().ClearPaintFlags();
350 } 353 }
351 354
352 } // namespace blink 355 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintInvalidator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698