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

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

Issue 2854493002: Store previous painting clip rects on FragmentData. (Closed)
Patch Set: none 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
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"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // 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.
48 // See: https://crbug.com/698653. 48 // See: https://crbug.com/698653.
49 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context; 49 std::unique_ptr<PaintPropertyTreeBuilderContext> tree_builder_context;
50 50
51 PaintInvalidatorContext paint_invalidator_context; 51 PaintInvalidatorContext paint_invalidator_context;
52 52
53 // The ancestor in the PaintLayer tree which has overflow clip, or 53 // The ancestor in the PaintLayer tree which has overflow clip, or
54 // 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
55 // block or stacking ancestor. 55 // block or stacking ancestor.
56 PaintLayer* ancestor_overflow_paint_layer; 56 PaintLayer* ancestor_overflow_paint_layer;
57
58 // The ancestor in the PaintLayer tree which has a transform or is a root
59 // layer for painting (i.e. a paint invalidation container).
57 PaintLayer* ancestor_transformed_or_root_paint_layer; 60 PaintLayer* ancestor_transformed_or_root_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();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 119
117 if (object.StyleRef().GetPosition() == EPosition::kSticky) { 120 if (object.StyleRef().GetPosition() == EPosition::kSticky) {
118 paint_layer->GetLayoutObject().UpdateStickyPositionConstraints(); 121 paint_layer->GetLayoutObject().UpdateStickyPositionConstraints();
119 122
120 // Sticky position constraints and ancestor overflow scroller affect the 123 // Sticky position constraints and ancestor overflow scroller affect the
121 // sticky layer position, so we need to update it again here. 124 // 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. 125 // 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). 126 // update layer position and ancestor inputs updates in the same walk).
124 paint_layer->UpdateLayerPosition(); 127 paint_layer->UpdateLayerPosition();
125 } 128 }
126
127 if (paint_layer->IsRootLayer() || object.HasOverflowClip()) 129 if (paint_layer->IsRootLayer() || object.HasOverflowClip())
128 context.ancestor_overflow_paint_layer = paint_layer; 130 context.ancestor_overflow_paint_layer = paint_layer;
129 } 131 }
130 132
131 LayoutRect PrePaintTreeWalk::ComputeClipRectForContext( 133 LayoutRect PrePaintTreeWalk::ComputeClipRectForContext(
132 const PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext& 134 const PaintPropertyTreeBuilderFragmentContext::ContainingBlockContext&
133 context, 135 context,
134 const EffectPaintPropertyNode* effect, 136 const EffectPaintPropertyNode* effect,
135 const PropertyTreeState& ancestor_state, 137 const PropertyTreeState& ancestor_state,
136 const LayoutPoint& ancestor_paint_offset) { 138 const LayoutPoint& ancestor_paint_offset) {
(...skipping 22 matching lines...) Expand all
159 } 161 }
160 162
161 // This code below checks whether any clips have changed that might: 163 // This code below checks whether any clips have changed that might:
162 // (a) invalidate optimizations made for a PaintLayer that supports 164 // (a) invalidate optimizations made for a PaintLayer that supports
163 // subsequence caching, or 165 // subsequence caching, or
164 // (b) impact clipping of descendant visual rects. 166 // (b) impact clipping of descendant visual rects.
165 if (!paint_layer.SupportsSubsequenceCaching() && 167 if (!paint_layer.SupportsSubsequenceCaching() &&
166 !paint_layer.GetLayoutObject().HasClipRelatedProperty()) 168 !paint_layer.GetLayoutObject().HasClipRelatedProperty())
167 return; 169 return;
168 170
171 FragmentData* fragment_data =
172 &object.GetMutableForPainting().EnsureFirstFragment();
173 for (auto& fragment : context.tree_builder_context->fragments) {
174 DCHECK(fragment_data);
175 if (InvalidatePaintLayerOptimizationsForFragment(
176 object, context.ancestor_transformed_or_root_paint_layer, fragment,
177 *fragment_data)) {
178 context.paint_invalidator_context.forced_subtree_invalidation_flags |=
179 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
180 }
181 fragment_data = fragment_data->NextFragment();
182 }
183 }
184
185 bool PrePaintTreeWalk::InvalidatePaintLayerOptimizationsForFragment(
186 const LayoutObject& object,
187 const PaintLayer* ancestor_transformed_or_root_paint_layer,
188 const PaintPropertyTreeBuilderFragmentContext& context,
189 FragmentData& fragment_data) {
190 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer();
191
169 const auto& ancestor = 192 const auto& ancestor =
170 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject(); 193 ancestor_transformed_or_root_paint_layer->GetLayoutObject();
171 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties(); 194 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties();
172 195
173 #ifdef CHECK_CLIP_RECTS 196 #ifdef CHECK_CLIP_RECTS
174 auto respect_overflow_clip = kRespectOverflowClip; 197 auto respect_overflow_clip = kRespectOverflowClip;
175 #endif 198 #endif
176 if (context.ancestor_transformed_or_root_paint_layer->GetCompositingState() == 199 if (ancestor_transformed_or_root_paint_layer->GetCompositingState() ==
177 kPaintsIntoOwnBacking) { 200 kPaintsIntoOwnBacking) {
178 const auto* ancestor_properties = ancestor.PaintProperties(); 201 const auto* ancestor_properties = ancestor.PaintProperties();
179 if (ancestor_properties && ancestor_properties->OverflowClip()) { 202 if (ancestor_properties && ancestor_properties->OverflowClip()) {
180 ancestor_state.SetClip(ancestor_properties->OverflowClip()); 203 ancestor_state.SetClip(ancestor_properties->OverflowClip());
181 #ifdef CHECK_CLIP_RECTS 204 #ifdef CHECK_CLIP_RECTS
182 respect_overflow_clip = kIgnoreOverflowClip; 205 respect_overflow_clip = kIgnoreOverflowClip;
183 #endif 206 #endif
184 } 207 }
185 } 208 }
186 209
187 #ifdef CHECK_CLIP_RECTS 210 #ifdef CHECK_CLIP_RECTS
188 const auto& old_clip_rects = 211 const auto& old_clip_rects =
189 paint_layer.Clipper(PaintLayer::kDoNotUseGeometryMapper) 212 paint_layer.Clipper(PaintLayer::kDoNotUseGeometryMapper)
190 .PaintingClipRects(context.ancestor_transformed_or_root_paint_layer, 213 .PaintingClipRects(ancestor_transformed_or_root_paint_layer,
191 respect_overflow_clip, LayoutSize()); 214 respect_overflow_clip, LayoutSize());
192 #endif 215 #endif
193 216
194 const LayoutPoint& ancestor_paint_offset = 217 const LayoutPoint& ancestor_paint_offset =
195 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject() 218 ancestor_transformed_or_root_paint_layer->GetLayoutObject().PaintOffset();
196 .PaintOffset();
197 219
198 // TODO(chrishtr): generalize this for multicol. 220 // TODO(chrishtr): generalize this for multicol.
199 const auto* effect = 221 const auto* effect = context.current_effect;
200 context.tree_builder_context->fragments[0].current_effect;
201 auto overflow_clip_rect = ComputeClipRectForContext( 222 auto overflow_clip_rect = ComputeClipRectForContext(
202 context.tree_builder_context->fragments[0].current, effect, 223 context.current, effect, ancestor_state, ancestor_paint_offset);
203 ancestor_state, ancestor_paint_offset);
204 #ifdef CHECK_CLIP_RECTS 224 #ifdef CHECK_CLIP_RECTS
205 CHECK(overflow_clip_rect == old_clip_rects.OverflowClipRect().Rect()) 225 CHECK(overflow_clip_rect == old_clip_rects.OverflowClipRect().Rect())
206 << " new=" << overflow_clip_rect.ToString() 226 << " new=" << overflow_clip_rect.ToString()
207 << " old=" << old_clip_rects.OverflowClipRect().Rect().ToString(); 227 << " old=" << old_clip_rects.OverflowClipRect().Rect().ToString();
208 #endif 228 #endif
209 229
210 auto fixed_clip_rect = ComputeClipRectForContext( 230 auto fixed_clip_rect = ComputeClipRectForContext(
211 context.tree_builder_context->fragments[0].fixed_position, effect, 231 context.fixed_position, effect, ancestor_state, ancestor_paint_offset);
212 ancestor_state, ancestor_paint_offset);
213 #ifdef CHECK_CLIP_RECTS 232 #ifdef CHECK_CLIP_RECTS
214 CHECK(fixed_clip_rect == old_clip_rects.FixedClipRect().Rect()) 233 CHECK(fixed_clip_rect == old_clip_rects.FixedClipRect().Rect())
215 << " new=" << fixed_clip_rect.ToString() 234 << " new=" << fixed_clip_rect.ToString()
216 << " old=" << old_clip_rects.FixedClipRect().Rect().ToString(); 235 << " old=" << old_clip_rects.FixedClipRect().Rect().ToString();
217 #endif 236 #endif
218 237
219 auto pos_clip_rect = ComputeClipRectForContext( 238 auto pos_clip_rect = ComputeClipRectForContext(
220 context.tree_builder_context->fragments[0].absolute_position, effect, 239 context.absolute_position, effect, ancestor_state, ancestor_paint_offset);
221 ancestor_state, ancestor_paint_offset);
222 #ifdef CHECK_CLIP_RECTS 240 #ifdef CHECK_CLIP_RECTS
223 CHECK(pos_clip_rect == old_clip_rects.PosClipRect().Rect()) 241 CHECK(pos_clip_rect == old_clip_rects.PosClipRect().Rect())
224 << " new=" << pos_clip_rect.ToString() 242 << " new=" << pos_clip_rect.ToString()
225 << " old=" << old_clip_rects.PosClipRect().Rect().ToString(); 243 << " old=" << old_clip_rects.PosClipRect().Rect().ToString();
226 #endif 244 #endif
227 245
228 const auto* previous_clip_rects = paint_layer.PreviousPaintingClipRects(); 246 const auto* previous_clip_rects = fragment_data.PreviousClipRects();
229 if (!previous_clip_rects || 247 if (!previous_clip_rects ||
230 overflow_clip_rect != previous_clip_rects->OverflowClipRect().Rect() || 248 overflow_clip_rect != previous_clip_rects->OverflowClipRect().Rect() ||
231 fixed_clip_rect != previous_clip_rects->FixedClipRect().Rect() || 249 fixed_clip_rect != previous_clip_rects->FixedClipRect().Rect() ||
232 pos_clip_rect != previous_clip_rects->PosClipRect().Rect()) { 250 pos_clip_rect != previous_clip_rects->PosClipRect().Rect()) {
233 RefPtr<ClipRects> clip_rects = ClipRects::Create(); 251 RefPtr<ClipRects> clip_rects = ClipRects::Create();
234 clip_rects->SetOverflowClipRect(overflow_clip_rect); 252 clip_rects->SetOverflowClipRect(overflow_clip_rect);
235 clip_rects->SetFixedClipRect(fixed_clip_rect); 253 clip_rects->SetFixedClipRect(fixed_clip_rect);
236 clip_rects->SetPosClipRect(pos_clip_rect); 254 clip_rects->SetPosClipRect(pos_clip_rect);
237 paint_layer.SetPreviousPaintingClipRects(*clip_rects); 255 fragment_data.SetPreviousClipRects(*clip_rects);
238 256
239 paint_layer.SetNeedsRepaint(); 257 paint_layer.SetNeedsRepaint();
240 paint_layer.SetPreviousPaintPhaseDescendantOutlinesEmpty(false); 258 paint_layer.SetPreviousPaintPhaseDescendantOutlinesEmpty(false);
241 paint_layer.SetPreviousPaintPhaseFloatEmpty(false); 259 paint_layer.SetPreviousPaintPhaseFloatEmpty(false);
242 paint_layer.SetPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); 260 paint_layer.SetPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
243 // All subsequences which are contained below this paintLayer must also 261 // All subsequences which are contained below this paintLayer must also
244 // be checked. 262 // be checked.
245 context.paint_invalidator_context.forced_subtree_invalidation_flags |= 263 return true;
246 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
247 } 264 }
265 return false;
248 } 266 }
249 267
250 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( 268 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
251 const FrameView& frame_view, 269 const FrameView& frame_view,
252 const PrePaintTreeWalkContext& context) { 270 const PrePaintTreeWalkContext& context) {
253 return frame_view.NeedsPaintPropertyUpdate() || 271 return frame_view.NeedsPaintPropertyUpdate() ||
254 (frame_view.GetLayoutView() && 272 (frame_view.GetLayoutView() &&
255 NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context)); 273 NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context));
256 } 274 }
257 275
258 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( 276 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
259 const LayoutObject& object, 277 const LayoutObject& object,
260 const PrePaintTreeWalkContext& parent_context) { 278 const PrePaintTreeWalkContext& parent_context) {
261 return object.NeedsPaintPropertyUpdate() || 279 return object.NeedsPaintPropertyUpdate() ||
262 object.DescendantNeedsPaintPropertyUpdate() || 280 object.DescendantNeedsPaintPropertyUpdate() ||
263 (parent_context.tree_builder_context && 281 (parent_context.tree_builder_context &&
264 parent_context.tree_builder_context->force_subtree_update) || 282 parent_context.tree_builder_context->force_subtree_update) ||
265 // If the object needs visual rect update, we should update tree 283 // If the object needs visual rect update, we should update tree
266 // builder context which is needed by visual rect update. 284 // builder context which is needed by visual rect update.
267 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object); 285 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object);
268 } 286 }
269 287
288 void PrePaintTreeWalk::ClearPreviousClipRectsForTesting(
289 const LayoutObject& object) {
290 object.GetMutableForPainting().FirstFragment()->ClearPreviousClipRects();
291 }
292
270 void PrePaintTreeWalk::Walk(const LayoutObject& object, 293 void PrePaintTreeWalk::Walk(const LayoutObject& object,
271 const PrePaintTreeWalkContext& parent_context) { 294 const PrePaintTreeWalkContext& parent_context) {
272 // Early out from the tree walk if possible. 295 // Early out from the tree walk if possible.
273 bool needs_tree_builder_context_update = 296 bool needs_tree_builder_context_update =
274 this->NeedsTreeBuilderContextUpdate(object, parent_context); 297 this->NeedsTreeBuilderContextUpdate(object, parent_context);
275 if (!needs_tree_builder_context_update && 298 if (!needs_tree_builder_context_update &&
276 !object.ShouldCheckForPaintInvalidation()) 299 !object.ShouldCheckForPaintInvalidation())
277 return; 300 return;
278 301
279 PrePaintTreeWalkContext context(parent_context, 302 PrePaintTreeWalkContext context(parent_context,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 } 343 }
321 Walk(*frame_view, context); 344 Walk(*frame_view, context);
322 } 345 }
323 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 346 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
324 } 347 }
325 348
326 object.GetMutableForPainting().ClearPaintFlags(); 349 object.GetMutableForPainting().ClearPaintFlags();
327 } 350 }
328 351
329 } // namespace blink 352 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PrePaintTreeWalk.h ('k') | third_party/WebKit/Source/core/paint/PrePaintTreeWalkTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698