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

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

Issue 2888253002: Skip both paint and raster invalidation for LayoutSVGHiddenContainer subtree (Closed)
Patch Set: Rebaseline-cl 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/PaintInvalidator.h" 5 #include "core/paint/PaintInvalidator.h"
6 6
7 #include "core/editing/FrameSelection.h" 7 #include "core/editing/FrameSelection.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/frame/Settings.h" 10 #include "core/frame/Settings.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 // TODO(wkorman): The flip below is required because visual rects are 62 // TODO(wkorman): The flip below is required because visual rects are
63 // currently in "physical coordinates with flipped block-flow direction" 63 // currently in "physical coordinates with flipped block-flow direction"
64 // (see LayoutBoxModelObject.h) but we need them to be in physical 64 // (see LayoutBoxModelObject.h) but we need them to be in physical
65 // coordinates. 65 // coordinates.
66 Rect rect = local_rect; 66 Rect rect = local_rect;
67 // Writing-mode flipping doesn't apply to non-root SVG. 67 // Writing-mode flipping doesn't apply to non-root SVG.
68 if (!is_svg_child) { 68 if (!is_svg_child) {
69 if (object.IsBox()) { 69 if (object.IsBox()) {
70 ToLayoutBox(object).FlipForWritingMode(rect); 70 ToLayoutBox(object).FlipForWritingMode(rect);
71 } else if (!(context.forced_subtree_invalidation_flags & 71 } else if (!(context.subtree_flags &
72 PaintInvalidatorContext::kForcedSubtreeSlowPathRect)) { 72 PaintInvalidatorContext::kSubtreeSlowPathRect)) {
73 // For SPv2 and the GeometryMapper path, we also need to convert the rect 73 // For SPv2 and the GeometryMapper path, we also need to convert the rect
74 // for non-boxes into physical coordinates before applying paint offset. 74 // for non-boxes into physical coordinates before applying paint offset.
75 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires 75 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires
76 // physical coordinates for boxes, but "physical coordinates with flipped 76 // physical coordinates for boxes, but "physical coordinates with flipped
77 // block-flow direction" for non-boxes for which we don't need to flip.) 77 // block-flow direction" for non-boxes for which we don't need to flip.)
78 // TODO(wangxianzhu): Avoid containingBlock(). 78 // TODO(wangxianzhu): Avoid containingBlock().
79 object.ContainingBlock()->FlipForWritingMode(rect); 79 object.ContainingBlock()->FlipForWritingMode(rect);
80 } 80 }
81 } 81 }
82 82
83 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 83 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
84 // In SPv2, visual rects are in the space of their local transform node. 84 // In SPv2, visual rects are in the space of their local transform node.
85 // For SVG, the input rect is in local SVG coordinates in which paint 85 // For SVG, the input rect is in local SVG coordinates in which paint
86 // offset doesn't apply. 86 // offset doesn't apply.
87 if (!is_svg_child) 87 if (!is_svg_child)
88 rect.MoveBy(Point(object.PaintOffset())); 88 rect.MoveBy(Point(object.PaintOffset()));
89 // Use enclosingIntRect to ensure the final visual rect will cover the 89 // Use enclosingIntRect to ensure the final visual rect will cover the
90 // rect in source coordinates no matter if the painting will use pixel 90 // rect in source coordinates no matter if the painting will use pixel
91 // snapping. 91 // snapping.
92 return LayoutRect(EnclosingIntRect(rect)); 92 return LayoutRect(EnclosingIntRect(rect));
93 } 93 }
94 94
95 // If kForcedSubtreeNoRasterInvalidation is set, we map the rect to the
96 // temporary root paint property state instead of the paint invalidation
97 // backing.
98 bool map_to_backing =
99 !(context.forced_subtree_invalidation_flags &
100 PaintInvalidatorContext::kForcedSubtreeNoRasterInvalidation);
101
102 LayoutRect result; 95 LayoutRect result;
103 if (context.forced_subtree_invalidation_flags & 96 if (context.subtree_flags & PaintInvalidatorContext::kSubtreeSlowPathRect) {
104 PaintInvalidatorContext::kForcedSubtreeSlowPathRect) {
105 result = SlowMapToVisualRectInAncestorSpace( 97 result = SlowMapToVisualRectInAncestorSpace(
106 object, *context.paint_invalidation_container, rect); 98 object, *context.paint_invalidation_container, rect);
107 } else if (object == context.paint_invalidation_container) { 99 } else if (object == context.paint_invalidation_container) {
108 DCHECK(map_to_backing);
109 result = LayoutRect(rect); 100 result = LayoutRect(rect);
110 } else { 101 } else {
111 // For non-root SVG, the input rect is in local SVG coordinates in which 102 // For non-root SVG, the input rect is in local SVG coordinates in which
112 // paint offset doesn't apply. 103 // paint offset doesn't apply.
113 if (!is_svg_child) 104 if (!is_svg_child)
114 rect.MoveBy(Point(object.PaintOffset())); 105 rect.MoveBy(Point(object.PaintOffset()));
115 106
116 auto container_contents_properties = 107 auto container_contents_properties =
117 map_to_backing 108 context.paint_invalidation_container->ContentsProperties();
118 ? context.paint_invalidation_container->ContentsProperties()
119 : PropertyTreeState::Root();
120 if (context.tree_builder_context_->current.transform == 109 if (context.tree_builder_context_->current.transform ==
121 container_contents_properties.Transform() && 110 container_contents_properties.Transform() &&
122 context.tree_builder_context_->current.clip == 111 context.tree_builder_context_->current.clip ==
123 container_contents_properties.Clip()) { 112 container_contents_properties.Clip()) {
124 result = LayoutRect(rect); 113 result = LayoutRect(rect);
125 } else { 114 } else {
126 // Use enclosingIntRect to ensure the final visual rect will cover the 115 // Use enclosingIntRect to ensure the final visual rect will cover the
127 // rect in source coordinates no matter if the painting will use pixel 116 // rect in source coordinates no matter if the painting will use pixel
128 // snapping, when transforms are applied. If there is no transform, 117 // snapping, when transforms are applied. If there is no transform,
129 // enclosingIntRect is applied in the last step of paint invalidation 118 // enclosingIntRect is applied in the last step of paint invalidation
130 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()). 119 // (see CompositedLayerMapping::setContentsNeedDisplayInRect()).
131 if (!is_svg_child && context.tree_builder_context_->current.transform != 120 if (!is_svg_child && context.tree_builder_context_->current.transform !=
132 container_contents_properties.Transform()) 121 container_contents_properties.Transform())
133 rect = Rect(EnclosingIntRect(rect)); 122 rect = Rect(EnclosingIntRect(rect));
134 123
135 PropertyTreeState current_tree_state( 124 PropertyTreeState current_tree_state(
136 context.tree_builder_context_->current.transform, 125 context.tree_builder_context_->current.transform,
137 context.tree_builder_context_->current.clip, nullptr); 126 context.tree_builder_context_->current.clip, nullptr);
138 127
139 FloatClipRect float_rect((FloatRect(rect))); 128 FloatClipRect float_rect((FloatRect(rect)));
140 GeometryMapper::SourceToDestinationVisualRect( 129 GeometryMapper::SourceToDestinationVisualRect(
141 current_tree_state, container_contents_properties, float_rect); 130 current_tree_state, container_contents_properties, float_rect);
142 result = LayoutRect(float_rect.Rect()); 131 result = LayoutRect(float_rect.Rect());
143 } 132 }
144 133
145 // Convert the result to the container's contents space. 134 // Convert the result to the container's contents space.
146 if (map_to_backing) 135 result.MoveBy(-context.paint_invalidation_container->PaintOffset());
147 result.MoveBy(-context.paint_invalidation_container->PaintOffset());
148 } 136 }
149 137
150 object.AdjustVisualRectForRasterEffects(result); 138 object.AdjustVisualRectForRasterEffects(result);
151 if (!map_to_backing)
152 return result;
153 139
154 PaintLayer::MapRectInPaintInvalidationContainerToBacking( 140 PaintLayer::MapRectInPaintInvalidationContainerToBacking(
155 *context.paint_invalidation_container, result); 141 *context.paint_invalidation_container, result);
156 142
157 result.Move(object.ScrollAdjustmentForPaintInvalidation( 143 result.Move(object.ScrollAdjustmentForPaintInvalidation(
158 *context.paint_invalidation_container)); 144 *context.paint_invalidation_container));
159 145
160 return result; 146 return result;
161 } 147 }
162 148
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 // This is to exclude some objects (e.g. LayoutText) inheriting 320 // This is to exclude some objects (e.g. LayoutText) inheriting
335 // stacked style from parent but aren't actually stacked. 321 // stacked style from parent but aren't actually stacked.
336 object.HasLayer() && 322 object.HasLayer() &&
337 context.paint_invalidation_container != 323 context.paint_invalidation_container !=
338 context.paint_invalidation_container_for_stacked_contents) { 324 context.paint_invalidation_container_for_stacked_contents) {
339 // The current object is stacked, so we should use 325 // The current object is stacked, so we should use
340 // m_paintInvalidationContainerForStackedContents as its paint invalidation 326 // m_paintInvalidationContainerForStackedContents as its paint invalidation
341 // container on which the current object is painted. 327 // container on which the current object is painted.
342 context.paint_invalidation_container = 328 context.paint_invalidation_container =
343 context.paint_invalidation_container_for_stacked_contents; 329 context.paint_invalidation_container_for_stacked_contents;
344 if (context.forced_subtree_invalidation_flags & 330 if (context.subtree_flags &
345 PaintInvalidatorContext:: 331 PaintInvalidatorContext::kSubtreeFullInvalidationForStackedContents) {
346 kForcedSubtreeFullInvalidationForStackedContents) 332 context.subtree_flags |=
347 context.forced_subtree_invalidation_flags |= 333 PaintInvalidatorContext::kSubtreeFullInvalidation;
348 PaintInvalidatorContext::kForcedSubtreeFullInvalidation; 334 }
349 } 335 }
350 336
351 if (object == context.paint_invalidation_container) { 337 if (object == context.paint_invalidation_container) {
352 // When we hit a new paint invalidation container, we don't need to 338 // When we hit a new paint invalidation container, we don't need to
353 // continue forcing a check for paint invalidation, since we're 339 // continue forcing a check for paint invalidation, since we're
354 // descending into a different invalidation container. (For instance if 340 // descending into a different invalidation container. (For instance if
355 // our parents were moved, the entire container will just move.) 341 // our parents were moved, the entire container will just move.)
356 if (object != context.paint_invalidation_container_for_stacked_contents) { 342 if (object != context.paint_invalidation_container_for_stacked_contents) {
357 // However, we need to keep kForcedSubtreeVisualRectUpdate and 343 // However, we need to keep kSubtreeVisualRectUpdate and
358 // kForcedSubtreeFullInvalidationForStackedContents flags if the current 344 // kSubtreeFullInvalidationForStackedContents flags if the current
359 // object isn't the paint invalidation container of stacked contents. 345 // object isn't the paint invalidation container of stacked contents.
360 context.forced_subtree_invalidation_flags &= 346 context.subtree_flags &=
361 (PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate | 347 (PaintInvalidatorContext::kSubtreeVisualRectUpdate |
362 PaintInvalidatorContext:: 348 PaintInvalidatorContext::kSubtreeFullInvalidationForStackedContents);
363 kForcedSubtreeFullInvalidationForStackedContents);
364 } else { 349 } else {
365 context.forced_subtree_invalidation_flags = 0; 350 context.subtree_flags = 0;
366 } 351 }
367 } 352 }
368 353
369 DCHECK(context.paint_invalidation_container == 354 DCHECK(context.paint_invalidation_container ==
370 object.ContainerForPaintInvalidation()); 355 object.ContainerForPaintInvalidation());
371 DCHECK(context.painting_layer == object.PaintingLayer()); 356 DCHECK(context.painting_layer == object.PaintingLayer());
372 } 357 }
373 358
374 void PaintInvalidator::UpdateVisualRectIfNeeded( 359 void PaintInvalidator::UpdateVisualRectIfNeeded(
375 const LayoutObject& object, 360 const LayoutObject& object,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 447 }
463 448
464 void PaintInvalidator::InvalidatePaint( 449 void PaintInvalidator::InvalidatePaint(
465 const LayoutObject& object, 450 const LayoutObject& object,
466 const PaintPropertyTreeBuilderContext* tree_builder_context, 451 const PaintPropertyTreeBuilderContext* tree_builder_context,
467 PaintInvalidatorContext& context) { 452 PaintInvalidatorContext& context) {
468 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), 453 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
469 "PaintInvalidator::invalidatePaintIfNeeded()", "object", 454 "PaintInvalidator::invalidatePaintIfNeeded()", "object",
470 object.DebugName().Ascii()); 455 object.DebugName().Ascii());
471 456
457 if (object.IsSVGHiddenContainer()) {
458 context.subtree_flags |= PaintInvalidatorContext::kSubtreeNoInvalidation;
459 }
460 if (context.subtree_flags & PaintInvalidatorContext::kSubtreeNoInvalidation)
461 return;
462
472 object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation(); 463 object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation();
473 464
474 UpdatePaintingLayer(object, context); 465 UpdatePaintingLayer(object, context);
475 466
476 if (object.GetDocument().Printing() && 467 if (object.GetDocument().Printing() &&
477 !RuntimeEnabledFeatures::printBrowserEnabled()) 468 !RuntimeEnabledFeatures::printBrowserEnabled())
478 return; // Don't invalidate paints if we're printing. 469 return; // Don't invalidate paints if we're printing.
479 470
480 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter 471 // TODO(crbug.com/637313): Use GeometryMapper which now supports filter
481 // geometry effects, after skia optimizes filter's mapRect operation. 472 // geometry effects, after skia optimizes filter's mapRect operation.
482 // TODO(crbug.com/648274): This is a workaround for multi-column contents. 473 // TODO(crbug.com/648274): This is a workaround for multi-column contents.
483 if (object.HasFilterInducingProperty() || object.IsLayoutFlowThread()) { 474 if (object.HasFilterInducingProperty() || object.IsLayoutFlowThread()) {
484 context.forced_subtree_invalidation_flags |= 475 context.subtree_flags |= PaintInvalidatorContext::kSubtreeSlowPathRect;
485 PaintInvalidatorContext::kForcedSubtreeSlowPathRect;
486 } 476 }
487 477
488 UpdatePaintInvalidationContainer(object, context); 478 UpdatePaintInvalidationContainer(object, context);
489 UpdateVisualRectIfNeeded(object, tree_builder_context, context); 479 UpdateVisualRectIfNeeded(object, tree_builder_context, context);
490 480
491 if (!object.ShouldCheckForPaintInvalidation() && 481 if (!object.ShouldCheckForPaintInvalidation() &&
492 !(context.forced_subtree_invalidation_flags & 482 !(context.subtree_flags &
493 ~PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate)) { 483 ~PaintInvalidatorContext::kSubtreeVisualRectUpdate)) {
494 // We are done updating anything needed. No other paint invalidation work to 484 // We are done updating anything needed. No other paint invalidation work to
495 // do for this object. 485 // do for this object.
496 return; 486 return;
497 } 487 }
498 488
499 if (object.IsSVGHiddenContainer()) {
500 context.forced_subtree_invalidation_flags |=
501 PaintInvalidatorContext::kForcedSubtreeNoRasterInvalidation;
502 }
503
504 PaintInvalidationReason reason = object.InvalidatePaint(context); 489 PaintInvalidationReason reason = object.InvalidatePaint(context);
505 switch (reason) { 490 switch (reason) {
506 case PaintInvalidationReason::kDelayedFull: 491 case PaintInvalidationReason::kDelayedFull:
507 pending_delayed_paint_invalidations_.push_back(&object); 492 pending_delayed_paint_invalidations_.push_back(&object);
508 break; 493 break;
509 case PaintInvalidationReason::kSubtree: 494 case PaintInvalidationReason::kSubtree:
510 context.forced_subtree_invalidation_flags |= 495 context.subtree_flags |=
511 (PaintInvalidatorContext::kForcedSubtreeFullInvalidation | 496 (PaintInvalidatorContext::kSubtreeFullInvalidation |
512 PaintInvalidatorContext:: 497 PaintInvalidatorContext::kSubtreeFullInvalidationForStackedContents);
513 kForcedSubtreeFullInvalidationForStackedContents);
514 break; 498 break;
515 case PaintInvalidationReason::kSVGResource: 499 case PaintInvalidationReason::kSVGResource:
516 context.forced_subtree_invalidation_flags |= 500 context.subtree_flags |=
517 PaintInvalidatorContext::kForcedSubtreeSVGResourceChange; 501 PaintInvalidatorContext::kSubtreeSVGResourceChange;
518 break; 502 break;
519 default: 503 default:
520 break; 504 break;
521 } 505 }
522 506
523 if (object.MayNeedPaintInvalidationSubtree()) { 507 if (object.MayNeedPaintInvalidationSubtree()) {
524 context.forced_subtree_invalidation_flags |= 508 context.subtree_flags |=
525 PaintInvalidatorContext::kForcedSubtreeInvalidationChecking; 509 PaintInvalidatorContext::kSubtreeInvalidationChecking;
526 } 510 }
527 511
528 if (context.old_location != context.new_location && 512 if (context.old_location != context.new_location &&
529 !context.painting_layer->SubtreeIsInvisible()) { 513 !context.painting_layer->SubtreeIsInvisible()) {
530 context.forced_subtree_invalidation_flags |= 514 context.subtree_flags |=
531 PaintInvalidatorContext::kForcedSubtreeInvalidationChecking; 515 PaintInvalidatorContext::kSubtreeInvalidationChecking;
532 } 516 }
533 517
534 if (context.forced_subtree_invalidation_flags && 518 if (context.subtree_flags && context.NeedsVisualRectUpdate(object)) {
535 context.NeedsVisualRectUpdate(object)) {
536 // If any subtree flag is set, we also need to pass needsVisualRectUpdate 519 // If any subtree flag is set, we also need to pass needsVisualRectUpdate
537 // requirement to the subtree. 520 // requirement to the subtree.
538 context.forced_subtree_invalidation_flags |= 521 context.subtree_flags |= PaintInvalidatorContext::kSubtreeVisualRectUpdate;
539 PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
540 } 522 }
541 } 523 }
542 524
543 void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() { 525 void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() {
544 for (auto target : pending_delayed_paint_invalidations_) { 526 for (auto target : pending_delayed_paint_invalidations_) {
545 target->GetMutableForPainting() 527 target->GetMutableForPainting()
546 .SetShouldDoFullPaintInvalidationWithoutGeometryChange( 528 .SetShouldDoFullPaintInvalidationWithoutGeometryChange(
547 PaintInvalidationReason::kDelayedFull); 529 PaintInvalidationReason::kDelayedFull);
548 } 530 }
549 } 531 }
550 532
551 } // namespace blink 533 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintInvalidator.h ('k') | third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698