OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |