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" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 } | 159 } |
160 | 160 |
161 // This code below checks whether any clips have changed that might: | 161 // This code below checks whether any clips have changed that might: |
162 // (a) invalidate optimizations made for a PaintLayer that supports | 162 // (a) invalidate optimizations made for a PaintLayer that supports |
163 // subsequence caching, or | 163 // subsequence caching, or |
164 // (b) impact clipping of descendant visual rects. | 164 // (b) impact clipping of descendant visual rects. |
165 if (!paint_layer.SupportsSubsequenceCaching() && | 165 if (!paint_layer.SupportsSubsequenceCaching() && |
166 !paint_layer.GetLayoutObject().HasClipRelatedProperty()) | 166 !paint_layer.GetLayoutObject().HasClipRelatedProperty()) |
167 return; | 167 return; |
168 | 168 |
169 FragmentData* fragment_data = object.GetMutableForPainting().FirstFragment(); | |
170 for (auto& fragment : context.tree_builder_context->fragments) { | |
171 DCHECK(fragment_data); | |
172 if (InvalidatePaintLayerOptimizationsForFragment( | |
173 object, context.ancestor_transformed_or_root_paint_layer, fragment, | |
wkorman
2017/05/01 20:29:24
I wondered why this member data name was so long a
chrishtr
2017/05/01 21:43:54
Removed.
chrishtr
2017/05/01 21:54:39
I was wrong, it is needed. It is set on PaintLayer
| |
174 *fragment_data)) { | |
175 context.paint_invalidator_context.forced_subtree_invalidation_flags |= | |
176 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate; | |
177 } | |
178 fragment_data = fragment_data->NextFragment(); | |
179 } | |
180 } | |
181 | |
182 bool PrePaintTreeWalk::InvalidatePaintLayerOptimizationsForFragment( | |
183 const LayoutObject& object, | |
184 const PaintLayer* ancestor_transformed_or_root_paint_layer, | |
185 const PaintPropertyTreeBuilderFragmentContext& context, | |
186 FragmentData& fragment_data) { | |
187 PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer(); | |
188 | |
169 const auto& ancestor = | 189 const auto& ancestor = |
170 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject(); | 190 ancestor_transformed_or_root_paint_layer->GetLayoutObject(); |
171 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties(); | 191 PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties(); |
172 | 192 |
173 #ifdef CHECK_CLIP_RECTS | 193 #ifdef CHECK_CLIP_RECTS |
174 auto respect_overflow_clip = kRespectOverflowClip; | 194 auto respect_overflow_clip = kRespectOverflowClip; |
175 #endif | 195 #endif |
176 if (context.ancestor_transformed_or_root_paint_layer->GetCompositingState() == | 196 if (ancestor_transformed_or_root_paint_layer->GetCompositingState() == |
177 kPaintsIntoOwnBacking) { | 197 kPaintsIntoOwnBacking) { |
178 const auto* ancestor_properties = ancestor.PaintProperties(); | 198 const auto* ancestor_properties = ancestor.PaintProperties(); |
179 if (ancestor_properties && ancestor_properties->OverflowClip()) { | 199 if (ancestor_properties && ancestor_properties->OverflowClip()) { |
180 ancestor_state.SetClip(ancestor_properties->OverflowClip()); | 200 ancestor_state.SetClip(ancestor_properties->OverflowClip()); |
181 #ifdef CHECK_CLIP_RECTS | 201 #ifdef CHECK_CLIP_RECTS |
182 respect_overflow_clip = kIgnoreOverflowClip; | 202 respect_overflow_clip = kIgnoreOverflowClip; |
183 #endif | 203 #endif |
184 } | 204 } |
185 } | 205 } |
186 | 206 |
187 #ifdef CHECK_CLIP_RECTS | 207 #ifdef CHECK_CLIP_RECTS |
188 const auto& old_clip_rects = | 208 const auto& old_clip_rects = |
189 paint_layer.Clipper(PaintLayer::kDoNotUseGeometryMapper) | 209 paint_layer.Clipper(PaintLayer::kDoNotUseGeometryMapper) |
190 .PaintingClipRects(context.ancestor_transformed_or_root_paint_layer, | 210 .PaintingClipRects(ancestor_transformed_or_root_paint_layer, |
191 respect_overflow_clip, LayoutSize()); | 211 respect_overflow_clip, LayoutSize()); |
192 #endif | 212 #endif |
193 | 213 |
194 const LayoutPoint& ancestor_paint_offset = | 214 const LayoutPoint& ancestor_paint_offset = |
195 context.ancestor_transformed_or_root_paint_layer->GetLayoutObject() | 215 ancestor_transformed_or_root_paint_layer->GetLayoutObject().PaintOffset(); |
196 .PaintOffset(); | |
197 | 216 |
198 // TODO(chrishtr): generalize this for multicol. | 217 // TODO(chrishtr): generalize this for multicol. |
199 const auto* effect = | 218 const auto* effect = context.current_effect; |
200 context.tree_builder_context->fragments[0].current_effect; | |
201 auto overflow_clip_rect = ComputeClipRectForContext( | 219 auto overflow_clip_rect = ComputeClipRectForContext( |
202 context.tree_builder_context->fragments[0].current, effect, | 220 context.current, effect, ancestor_state, ancestor_paint_offset); |
203 ancestor_state, ancestor_paint_offset); | |
204 #ifdef CHECK_CLIP_RECTS | 221 #ifdef CHECK_CLIP_RECTS |
205 CHECK(overflow_clip_rect == old_clip_rects.OverflowClipRect().Rect()) | 222 CHECK(overflow_clip_rect == old_clip_rects.OverflowClipRect().Rect()) |
206 << " new=" << overflow_clip_rect.ToString() | 223 << " new=" << overflow_clip_rect.ToString() |
207 << " old=" << old_clip_rects.OverflowClipRect().Rect().ToString(); | 224 << " old=" << old_clip_rects.OverflowClipRect().Rect().ToString(); |
208 #endif | 225 #endif |
209 | 226 |
210 auto fixed_clip_rect = ComputeClipRectForContext( | 227 auto fixed_clip_rect = ComputeClipRectForContext( |
211 context.tree_builder_context->fragments[0].fixed_position, effect, | 228 context.fixed_position, effect, ancestor_state, ancestor_paint_offset); |
212 ancestor_state, ancestor_paint_offset); | |
213 #ifdef CHECK_CLIP_RECTS | 229 #ifdef CHECK_CLIP_RECTS |
214 CHECK(fixed_clip_rect == old_clip_rects.FixedClipRect().Rect()) | 230 CHECK(fixed_clip_rect == old_clip_rects.FixedClipRect().Rect()) |
215 << " new=" << fixed_clip_rect.ToString() | 231 << " new=" << fixed_clip_rect.ToString() |
216 << " old=" << old_clip_rects.FixedClipRect().Rect().ToString(); | 232 << " old=" << old_clip_rects.FixedClipRect().Rect().ToString(); |
217 #endif | 233 #endif |
218 | 234 |
219 auto pos_clip_rect = ComputeClipRectForContext( | 235 auto pos_clip_rect = ComputeClipRectForContext( |
220 context.tree_builder_context->fragments[0].absolute_position, effect, | 236 context.absolute_position, effect, ancestor_state, ancestor_paint_offset); |
221 ancestor_state, ancestor_paint_offset); | |
222 #ifdef CHECK_CLIP_RECTS | 237 #ifdef CHECK_CLIP_RECTS |
223 CHECK(pos_clip_rect == old_clip_rects.PosClipRect().Rect()) | 238 CHECK(pos_clip_rect == old_clip_rects.PosClipRect().Rect()) |
224 << " new=" << pos_clip_rect.ToString() | 239 << " new=" << pos_clip_rect.ToString() |
225 << " old=" << old_clip_rects.PosClipRect().Rect().ToString(); | 240 << " old=" << old_clip_rects.PosClipRect().Rect().ToString(); |
226 #endif | 241 #endif |
227 | 242 |
228 const auto* previous_clip_rects = paint_layer.PreviousPaintingClipRects(); | 243 const auto* previous_clip_rects = fragment_data.PreviousPaintingClipRects(); |
229 if (!previous_clip_rects || | 244 if (!previous_clip_rects || |
230 overflow_clip_rect != previous_clip_rects->OverflowClipRect().Rect() || | 245 overflow_clip_rect != previous_clip_rects->OverflowClipRect().Rect() || |
231 fixed_clip_rect != previous_clip_rects->FixedClipRect().Rect() || | 246 fixed_clip_rect != previous_clip_rects->FixedClipRect().Rect() || |
232 pos_clip_rect != previous_clip_rects->PosClipRect().Rect()) { | 247 pos_clip_rect != previous_clip_rects->PosClipRect().Rect()) { |
233 RefPtr<ClipRects> clip_rects = ClipRects::Create(); | 248 RefPtr<ClipRects> clip_rects = ClipRects::Create(); |
234 clip_rects->SetOverflowClipRect(overflow_clip_rect); | 249 clip_rects->SetOverflowClipRect(overflow_clip_rect); |
235 clip_rects->SetFixedClipRect(fixed_clip_rect); | 250 clip_rects->SetFixedClipRect(fixed_clip_rect); |
236 clip_rects->SetPosClipRect(pos_clip_rect); | 251 clip_rects->SetPosClipRect(pos_clip_rect); |
237 paint_layer.SetPreviousPaintingClipRects(*clip_rects); | 252 fragment_data.SetPreviousPaintingClipRects(*clip_rects); |
238 | 253 |
239 paint_layer.SetNeedsRepaint(); | 254 paint_layer.SetNeedsRepaint(); |
240 paint_layer.SetPreviousPaintPhaseDescendantOutlinesEmpty(false); | 255 paint_layer.SetPreviousPaintPhaseDescendantOutlinesEmpty(false); |
241 paint_layer.SetPreviousPaintPhaseFloatEmpty(false); | 256 paint_layer.SetPreviousPaintPhaseFloatEmpty(false); |
242 paint_layer.SetPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); | 257 paint_layer.SetPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false); |
243 // All subsequences which are contained below this paintLayer must also | 258 // All subsequences which are contained below this paintLayer must also |
244 // be checked. | 259 // be checked. |
245 context.paint_invalidator_context.forced_subtree_invalidation_flags |= | 260 return true; |
246 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate; | |
247 } | 261 } |
262 return false; | |
248 } | 263 } |
249 | 264 |
250 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( | 265 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( |
251 const FrameView& frame_view, | 266 const FrameView& frame_view, |
252 const PrePaintTreeWalkContext& context) { | 267 const PrePaintTreeWalkContext& context) { |
253 return frame_view.NeedsPaintPropertyUpdate() || | 268 return frame_view.NeedsPaintPropertyUpdate() || |
254 (frame_view.GetLayoutView() && | 269 (frame_view.GetLayoutView() && |
255 NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context)); | 270 NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context)); |
256 } | 271 } |
257 | 272 |
258 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( | 273 bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate( |
259 const LayoutObject& object, | 274 const LayoutObject& object, |
260 const PrePaintTreeWalkContext& parent_context) { | 275 const PrePaintTreeWalkContext& parent_context) { |
261 return object.NeedsPaintPropertyUpdate() || | 276 return object.NeedsPaintPropertyUpdate() || |
262 object.DescendantNeedsPaintPropertyUpdate() || | 277 object.DescendantNeedsPaintPropertyUpdate() || |
263 (parent_context.tree_builder_context && | 278 (parent_context.tree_builder_context && |
264 parent_context.tree_builder_context->force_subtree_update) || | 279 parent_context.tree_builder_context->force_subtree_update) || |
265 // If the object needs visual rect update, we should update tree | 280 // If the object needs visual rect update, we should update tree |
266 // builder context which is needed by visual rect update. | 281 // builder context which is needed by visual rect update. |
267 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object); | 282 parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object); |
268 } | 283 } |
269 | 284 |
285 void PrePaintTreeWalk::ClearPreviousPaintingClipRectsForTesting( | |
286 const LayoutObject& object) { | |
287 object.GetMutableForPainting() | |
288 .FirstFragment() | |
289 ->ClearPreviousPaintingClipRects(); | |
290 } | |
291 | |
270 void PrePaintTreeWalk::Walk(const LayoutObject& object, | 292 void PrePaintTreeWalk::Walk(const LayoutObject& object, |
271 const PrePaintTreeWalkContext& parent_context) { | 293 const PrePaintTreeWalkContext& parent_context) { |
272 // Early out from the tree walk if possible. | 294 // Early out from the tree walk if possible. |
273 bool needs_tree_builder_context_update = | 295 bool needs_tree_builder_context_update = |
274 this->NeedsTreeBuilderContextUpdate(object, parent_context); | 296 this->NeedsTreeBuilderContextUpdate(object, parent_context); |
275 if (!needs_tree_builder_context_update && | 297 if (!needs_tree_builder_context_update && |
276 !object.ShouldCheckForPaintInvalidation()) | 298 !object.ShouldCheckForPaintInvalidation()) |
277 return; | 299 return; |
278 | 300 |
279 PrePaintTreeWalkContext context(parent_context, | 301 PrePaintTreeWalkContext context(parent_context, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 } | 342 } |
321 Walk(*frame_view, context); | 343 Walk(*frame_view, context); |
322 } | 344 } |
323 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 345 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
324 } | 346 } |
325 | 347 |
326 object.GetMutableForPainting().ClearPaintFlags(); | 348 object.GetMutableForPainting().ClearPaintFlags(); |
327 } | 349 } |
328 | 350 |
329 } // namespace blink | 351 } // namespace blink |
OLD | NEW |