| 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 |