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

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

Issue 2810503002: Only store previous clip rects for PaintLayers that support subsequences. (Closed)
Patch Set: none Created 3 years, 8 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
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(tree_builder_context.get()), 22 paint_invalidator_context(tree_builder_context.get()),
23 ancestor_overflow_paint_layer(nullptr), 23 ancestor_overflow_paint_layer(nullptr),
24 ancestor_transformed_or_root_paint_layer(nullptr) {} 24 ancestor_transformed_or_root_paint_layer(nullptr),
25 enclosing_paint_layer(nullptr) {}
25 26
26 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context, 27 PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parent_context,
27 bool needs_tree_builder_context) 28 bool needs_tree_builder_context)
28 : tree_builder_context( 29 : tree_builder_context(
29 WTF::WrapUnique(needs_tree_builder_context || DCHECK_IS_ON() 30 WTF::WrapUnique(needs_tree_builder_context || DCHECK_IS_ON()
30 ? new PaintPropertyTreeBuilderContext( 31 ? new PaintPropertyTreeBuilderContext(
31 *parent_context.tree_builder_context) 32 *parent_context.tree_builder_context)
32 : nullptr)), 33 : nullptr)),
33 paint_invalidator_context(tree_builder_context.get(), 34 paint_invalidator_context(tree_builder_context.get(),
34 parent_context.paint_invalidator_context), 35 parent_context.paint_invalidator_context),
35 ancestor_overflow_paint_layer( 36 ancestor_overflow_paint_layer(
36 parent_context.ancestor_overflow_paint_layer), 37 parent_context.ancestor_overflow_paint_layer),
37 ancestor_transformed_or_root_paint_layer( 38 ancestor_transformed_or_root_paint_layer(
38 parent_context.ancestor_transformed_or_root_paint_layer) { 39 parent_context.ancestor_transformed_or_root_paint_layer),
40 enclosing_paint_layer(parent_context.enclosing_paint_layer) {
39 #if DCHECK_IS_ON() 41 #if DCHECK_IS_ON()
40 if (needs_tree_builder_context) 42 if (needs_tree_builder_context)
41 DCHECK(parent_context.tree_builder_context->is_actually_needed); 43 DCHECK(parent_context.tree_builder_context->is_actually_needed);
42 tree_builder_context->is_actually_needed = needs_tree_builder_context; 44 tree_builder_context->is_actually_needed = needs_tree_builder_context;
43 #endif 45 #endif
44 } 46 }
45 47
46 // PaintPropertyTreeBuilderContext is large and can lead to stack overflows 48 // PaintPropertyTreeBuilderContext is large and can lead to stack overflows
47 // when recursion is deep so this context object is allocated on the heap. 49 // when recursion is deep so this context object is allocated on the heap.
48 // See: https://crbug.com/698653. 50 // See: https://crbug.com/698653.
49 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context; 51 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context;
50 52
51 PaintInvalidatorContext paint_invalidator_context; 53 PaintInvalidatorContext paint_invalidator_context;
52 54
53 // The ancestor in the PaintLayer tree which has overflow clip, or 55 // The ancestor in the PaintLayer tree which has overflow clip, or
54 // is the root layer. Note that it is tree ancestor, not containing 56 // is the root layer. Note that it is tree ancestor, not containing
55 // block or stacking ancestor. 57 // block or stacking ancestor.
56 PaintLayer* ancestor_overflow_paint_layer; 58 PaintLayer* ancestor_overflow_paint_layer;
57 PaintLayer* ancestor_transformed_or_root_paint_layer; 59 PaintLayer* ancestor_transformed_or_root_paint_layer;
60 PaintLayer* enclosing_paint_layer;
58 }; 61 };
59 62
60 void PrePaintTreeWalk::Walk(FrameView& root_frame) { 63 void PrePaintTreeWalk::Walk(FrameView& root_frame) {
61 DCHECK(root_frame.GetFrame().GetDocument()->Lifecycle().GetState() == 64 DCHECK(root_frame.GetFrame().GetDocument()->Lifecycle().GetState() ==
62 DocumentLifecycle::kInPrePaint); 65 DocumentLifecycle::kInPrePaint);
63 66
64 PrePaintTreeWalkContext initial_context; 67 PrePaintTreeWalkContext initial_context;
65 initial_context.ancestor_transformed_or_root_paint_layer = 68 initial_context.ancestor_transformed_or_root_paint_layer =
66 root_frame.GetLayoutView()->Layer(); 69 root_frame.GetLayoutView()->Layer();
67 70
68 // GeometryMapper depends on paint properties. 71 // GeometryMapper depends on paint properties.
69 if (NeedsTreeBuilderContextUpdate(root_frame, initial_context)) 72 if (NeedsTreeBuilderContextUpdate(root_frame, initial_context)) {
70 GeometryMapper::ClearCache(); 73 GeometryMapper::ClearCache();
74 }
71 75
72 Walk(root_frame, initial_context); 76 Walk(root_frame, initial_context);
73 paint_invalidator_.ProcessPendingDelayedPaintInvalidations(); 77 paint_invalidator_.ProcessPendingDelayedPaintInvalidations();
74 } 78 }
75 79
76 void PrePaintTreeWalk::Walk(FrameView& frame_view, 80 void PrePaintTreeWalk::Walk(FrameView& frame_view,
77 const PrePaintTreeWalkContext& parent_context) { 81 const PrePaintTreeWalkContext& parent_context) {
78 if (frame_view.ShouldThrottleRendering()) { 82 if (frame_view.ShouldThrottleRendering()) {
79 // Skip the throttled frame. Will update it when it becomes unthrottled. 83 // Skip the throttled frame. Will update it when it becomes unthrottled.
80 return; 84 return;
81 } 85 }
82
83 bool needs_tree_builder_context_update = 86 bool needs_tree_builder_context_update =
84 this->NeedsTreeBuilderContextUpdate(frame_view, parent_context); 87 this->NeedsTreeBuilderContextUpdate(frame_view, parent_context);
85 PrePaintTreeWalkContext context(parent_context, 88 PrePaintTreeWalkContext context(parent_context,
86 needs_tree_builder_context_update); 89 needs_tree_builder_context_update);
87 // ancestorOverflowLayer does not cross frame boundaries. 90 // ancestorOverflowLayer does not cross frame boundaries.
88 context.ancestor_overflow_paint_layer = nullptr; 91 context.ancestor_overflow_paint_layer = nullptr;
89 if (context.tree_builder_context) { 92 if (context.tree_builder_context) {
90 property_tree_builder_.UpdateProperties(frame_view, 93 property_tree_builder_.UpdateProperties(frame_view,
91 *context.tree_builder_context); 94 *context.tree_builder_context);
92 } 95 }
93 paint_invalidator_.InvalidatePaintIfNeeded(frame_view, 96 paint_invalidator_.InvalidatePaintIfNeeded(frame_view,
94 context.paint_invalidator_context); 97 context.paint_invalidator_context);
95 98
96 if (LayoutView* view = frame_view.GetLayoutView()) { 99 if (LayoutView* view = frame_view.GetLayoutView()) {
97 Walk(*view, context); 100 bool ignored;
101 if (!ShouldEarlyOut(*view, context, ignored)) {
102 context.enclosing_paint_layer = view->Layer();
103 if (!context.tree_builder_context) {
104 context.tree_builder_context =
105 WTF::WrapUnique(new PaintPropertyTreeBuilderContext);
chrishtr 2017/04/12 17:31:41 This is a little weird and awkward, let's discuss
106 }
107 #if DCHECK_IS_ON()
108 if (context.tree_builder_context)
109 context.tree_builder_context->is_actually_needed = true;
110 #endif
111 Walk(*view, context);
112 }
98 #if DCHECK_IS_ON() 113 #if DCHECK_IS_ON()
99 view->AssertSubtreeClearedPaintInvalidationFlags(); 114 view->AssertSubtreeClearedPaintInvalidationFlags();
100 #endif 115 #endif
101 } 116 }
102 frame_view.ClearNeedsPaintPropertyUpdate(); 117 frame_view.ClearNeedsPaintPropertyUpdate();
103 } 118 }
104 119
105 static void UpdateAuxiliaryObjectProperties(const LayoutObject& object, 120 static void UpdateAuxiliaryObjectProperties(const LayoutObject& object,
106 PrePaintTreeWalkContext& context) { 121 PrePaintTreeWalkContext& context) {
107 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 122 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled())
(...skipping 11 matching lines...) Expand all
119 134
120 // Sticky position constraints and ancestor overflow scroller affect the 135 // Sticky position constraints and ancestor overflow scroller affect the
121 // sticky layer position, so we need to update it again here. 136 // sticky layer position, so we need to update it again here.
122 // TODO(flackr): This should be refactored in the future to be clearer (i.e. 137 // TODO(flackr): This should be refactored in the future to be clearer (i.e.
123 // update layer position and ancestor inputs updates in the same walk). 138 // update layer position and ancestor inputs updates in the same walk).
124 paint_layer->UpdateLayerPosition(); 139 paint_layer->UpdateLayerPosition();
125 } 140 }
126 141
127 if (paint_layer->IsRootLayer() || object.HasOverflowClip()) 142 if (paint_layer->IsRootLayer() || object.HasOverflowClip())
128 context.ancestor_overflow_paint_layer = paint_layer; 143 context.ancestor_overflow_paint_layer = paint_layer;
144
145 context.enclosing_paint_layer = paint_layer;
129 } 146 }
130 147
131 void PrePaintTreeWalk::ComputeClipRectForContext( 148 void PrePaintTreeWalk::ComputeClipRectForContext(
132 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context, 149 const PaintPropertyTreeBuilderContext::ContainingBlockContext& context,
133 const EffectPaintPropertyNode* effect, 150 const EffectPaintPropertyNode* effect,
134 const PropertyTreeState& ancestor_state, 151 const PropertyTreeState& ancestor_state,
135 const LayoutPoint& ancestor_paint_offset, 152 const LayoutPoint& ancestor_paint_offset,
136 FloatClipRect& clip_rect) { 153 FloatClipRect& clip_rect) {
137 PropertyTreeState local_state(context.transform, context.clip, effect); 154 PropertyTreeState local_state(context.transform, context.clip, effect);
138 155
139 clip_rect = 156 clip_rect =
140 GeometryMapper::SourceToDestinationClipRect(local_state, ancestor_state); 157 GeometryMapper::SourceToDestinationClipRect(local_state, ancestor_state);
141 clip_rect.MoveBy(-FloatPoint(ancestor_paint_offset)); 158 clip_rect.MoveBy(-FloatPoint(ancestor_paint_offset));
142 } 159 }
143 160
144 void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded( 161 void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
145 const LayoutObject& object, 162 const LayoutObject& object,
146 PrePaintTreeWalkContext& context) { 163 PrePaintTreeWalkContext& context) {
147 if (!object.HasLayer()) 164 if (!object.HasLayer())
148 return; 165 return;
149 166
150 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer(); 167 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer();
168 if (!paint_layer.SupportsSubsequenceCaching())
169 return;
170
151 if (object.StyleRef().HasTransform() || 171 if (object.StyleRef().HasTransform() ||
152 &object == 172 &object ==
153 context.paint_invalidator_context.paint_invalidation_container) { 173 context.paint_invalidator_context.paint_invalidation_container) {
154 context.ancestor_transformed_or_root_paint_layer = &paint_layer; 174 context.ancestor_transformed_or_root_paint_layer = &paint_layer;
155 } 175 }
156 176
157 const auto& ancestor = 177 const auto& ancestor =
158 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject(); 178 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject();
159 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties(); 179 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties();
160 180
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 259
240 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( 260 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
241 const LayoutObject& object, 261 const LayoutObject& object,
242 const PrePaintTreeWalkContext& parent_context) { 262 const PrePaintTreeWalkContext& parent_context) {
243 return object.NeedsPaintPropertyUpdate() || 263 return object.NeedsPaintPropertyUpdate() ||
244 object.DescendantNeedsPaintPropertyUpdate() || 264 object.DescendantNeedsPaintPropertyUpdate() ||
245 (parent_context.tree_builder_context && 265 (parent_context.tree_builder_context &&
246 parent_context.tree_builder_context->force_subtree_update) || 266 parent_context.tree_builder_context->force_subtree_update) ||
247 // If the object needs visual rect update, we should update tree 267 // If the object needs visual rect update, we should update tree
248 // builder context which is needed by visual rect update. 268 // builder context which is needed by visual rect update.
249 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object); 269 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(
270 object) ||
271 (parent_context.enclosing_paint_layer &&
pdr. 2017/04/12 18:40:06 Can enclosing_paint_layer ever be null here? Do w
272 parent_context.enclosing_paint_layer
273 ->HasDescendantThatSupportsSubsequenceCaching());
274 }
275
276 bool PrePaintTreeWalk::ShouldEarlyOut(
277 const LayoutObject& object,
278 const PrePaintTreeWalkContext& parent_context,
279 bool& needs_tree_builder_context_update) {
280 // Early out from the tree walk if possible.
281 needs_tree_builder_context_update =
282 this->NeedsTreeBuilderContextUpdate(object, parent_context);
283 return !needs_tree_builder_context_update &&
284 !object.ShouldCheckForPaintInvalidation();
250 } 285 }
251 286
252 void PrePaintTreeWalk::Walk(const LayoutObject& object, 287 void PrePaintTreeWalk::Walk(const LayoutObject& object,
253 const PrePaintTreeWalkContext& parent_context) { 288 const PrePaintTreeWalkContext& parent_context) {
254 // Early out from the tree walk if possible. 289 bool needs_tree_builder_context_update = false;
255 bool needs_tree_builder_context_update = 290 if (ShouldEarlyOut(object, parent_context, needs_tree_builder_context_update))
256 this->NeedsTreeBuilderContextUpdate(object, parent_context);
257 if (!needs_tree_builder_context_update &&
258 !object.ShouldCheckForPaintInvalidation())
259 return; 291 return;
260 292
261 PrePaintTreeWalkContext context(parent_context, 293 PrePaintTreeWalkContext context(parent_context,
262 needs_tree_builder_context_update); 294 needs_tree_builder_context_update);
263 295
264 // This must happen before updatePropertiesForSelf, because the latter reads 296 // This must happen before updatePropertiesForSelf, because the latter reads
265 // some of the state computed here. 297 // some of the state computed here.
266 UpdateAuxiliaryObjectProperties(object, context); 298 UpdateAuxiliaryObjectProperties(object, context);
267 299
268 if (context.tree_builder_context) { 300 if (context.tree_builder_context) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } 334 }
303 Walk(*ToFrameView(frame_view_base), context); 335 Walk(*ToFrameView(frame_view_base), context);
304 } 336 }
305 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 337 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
306 } 338 }
307 339
308 object.GetMutableForPainting().ClearPaintFlags(); 340 object.GetMutableForPainting().ClearPaintFlags();
309 } 341 }
310 342
311 } // namespace blink 343 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698