OLD | NEW |
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 // TODO(wangxianzhu): Avoid containingBlock(). | 67 // TODO(wangxianzhu): Avoid containingBlock(). |
68 object.containingBlock()->flipForWritingMode(rect); | 68 object.containingBlock()->flipForWritingMode(rect); |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 72 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
73 // In SPv2, visual rects are in the space of their local transform node. | 73 // In SPv2, visual rects are in the space of their local transform node. |
74 // For SVG, the input rect is in local SVG coordinates in which paint | 74 // For SVG, the input rect is in local SVG coordinates in which paint |
75 // offset doesn't apply. | 75 // offset doesn't apply. |
76 if (!object.isSVGChild()) | 76 if (!object.isSVGChild()) |
77 rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); | 77 rect.moveBy(FloatPoint(object.paintOffset())); |
78 // Use enclosingIntRect to ensure the final visual rect will cover the | 78 // Use enclosingIntRect to ensure the final visual rect will cover the |
79 // rect in source coordinates no matter if the painting will use pixel | 79 // rect in source coordinates no matter if the painting will use pixel |
80 // snapping. | 80 // snapping. |
81 return LayoutRect(enclosingIntRect(rect)); | 81 return LayoutRect(enclosingIntRect(rect)); |
82 } | 82 } |
83 | 83 |
84 LayoutRect result; | 84 LayoutRect result; |
85 if (context.forcedSubtreeInvalidationFlags & | 85 if (context.forcedSubtreeInvalidationFlags & |
86 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { | 86 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
87 result = slowMapToVisualRectInAncestorSpace( | 87 result = slowMapToVisualRectInAncestorSpace( |
88 object, *context.paintInvalidationContainer, rect); | 88 object, *context.paintInvalidationContainer, rect); |
89 } else if (object == context.paintInvalidationContainer) { | 89 } else if (object == context.paintInvalidationContainer) { |
90 result = LayoutRect(rect); | 90 result = LayoutRect(rect); |
91 } else { | 91 } else { |
92 // For non-root SVG, the input rect is in local SVG coordinates in which | 92 // For non-root SVG, the input rect is in local SVG coordinates in which |
93 // paint offset doesn't apply. | 93 // paint offset doesn't apply. |
94 if (!object.isSVGChild()) { | 94 if (!object.isSVGChild()) { |
95 rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); | 95 rect.moveBy(FloatPoint(object.paintOffset())); |
96 // Use enclosingIntRect to ensure the final visual rect will cover the | 96 // Use enclosingIntRect to ensure the final visual rect will cover the |
97 // rect in source coordinates no matter if the painting will use pixel | 97 // rect in source coordinates no matter if the painting will use pixel |
98 // snapping. | 98 // snapping. |
99 rect = enclosingIntRect(rect); | 99 rect = enclosingIntRect(rect); |
100 } | 100 } |
101 | 101 |
102 PropertyTreeState currentTreeState( | 102 PropertyTreeState currentTreeState( |
103 context.treeBuilderContext.current.transform, | 103 context.treeBuilderContext.current.transform, |
104 context.treeBuilderContext.current.clip, | 104 context.treeBuilderContext.current.clip, |
105 context.treeBuilderContext.currentEffect, | 105 context.treeBuilderContext.currentEffect, |
106 context.treeBuilderContext.current.scroll); | 106 context.treeBuilderContext.current.scroll); |
107 const auto* containerPaintProperties = | 107 const auto* containerPaintProperties = |
108 context.paintInvalidationContainer->paintProperties(); | 108 context.paintInvalidationContainer->paintProperties(); |
109 auto containerContentsProperties = | 109 auto containerContentsProperties = |
110 containerPaintProperties->contentsProperties(); | 110 containerPaintProperties->contentsProperties(); |
111 | 111 |
112 bool success = false; | 112 bool success = false; |
113 result = LayoutRect(geometryMapper.mapToVisualRectInDestinationSpace( | 113 result = LayoutRect(geometryMapper.mapToVisualRectInDestinationSpace( |
114 rect, currentTreeState, containerContentsProperties.propertyTreeState, | 114 rect, currentTreeState, containerContentsProperties, success)); |
115 success)); | |
116 DCHECK(success); | 115 DCHECK(success); |
117 | 116 |
118 // Convert the result to the container's contents space. | 117 // Convert the result to the container's contents space. |
119 result.moveBy(-containerContentsProperties.paintOffset); | 118 result.moveBy(-context.paintInvalidationContainer->paintOffset()); |
120 } | 119 } |
121 | 120 |
122 object.adjustVisualRectForRasterEffects(result); | 121 object.adjustVisualRectForRasterEffects(result); |
123 | 122 |
124 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 123 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
125 *context.paintInvalidationContainer, result); | 124 *context.paintInvalidationContainer, result); |
126 | 125 |
127 return result; | 126 return result; |
128 } | 127 } |
129 | 128 |
(...skipping 28 matching lines...) Expand all Loading... |
158 LayoutPoint PaintInvalidator::computeLocationInBacking( | 157 LayoutPoint PaintInvalidator::computeLocationInBacking( |
159 const LayoutObject& object, | 158 const LayoutObject& object, |
160 const PaintInvalidatorContext& context) { | 159 const PaintInvalidatorContext& context) { |
161 // Use visual rect location for LayoutTexts because it suffices to check | 160 // Use visual rect location for LayoutTexts because it suffices to check |
162 // visual rect change for layout caused invalidation. | 161 // visual rect change for layout caused invalidation. |
163 if (object.isText()) | 162 if (object.isText()) |
164 return context.newVisualRect.location(); | 163 return context.newVisualRect.location(); |
165 | 164 |
166 FloatPoint point; | 165 FloatPoint point; |
167 if (object != context.paintInvalidationContainer) { | 166 if (object != context.paintInvalidationContainer) { |
168 point.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); | 167 point.moveBy(FloatPoint(object.paintOffset())); |
169 | 168 |
170 PropertyTreeState currentTreeState( | 169 PropertyTreeState currentTreeState( |
171 context.treeBuilderContext.current.transform, | 170 context.treeBuilderContext.current.transform, |
172 context.treeBuilderContext.current.clip, | 171 context.treeBuilderContext.current.clip, |
173 context.treeBuilderContext.currentEffect, | 172 context.treeBuilderContext.currentEffect, |
174 context.treeBuilderContext.current.scroll); | 173 context.treeBuilderContext.current.scroll); |
175 const auto* containerPaintProperties = | 174 const auto* containerPaintProperties = |
176 context.paintInvalidationContainer->paintProperties(); | 175 context.paintInvalidationContainer->paintProperties(); |
177 auto containerContentsProperties = | 176 auto containerContentsProperties = |
178 containerPaintProperties->contentsProperties(); | 177 containerPaintProperties->contentsProperties(); |
179 | 178 |
180 bool success = false; | 179 bool success = false; |
181 point = m_geometryMapper | 180 point = m_geometryMapper |
182 .mapRectToDestinationSpace( | 181 .mapRectToDestinationSpace(FloatRect(point, FloatSize()), |
183 FloatRect(point, FloatSize()), currentTreeState, | 182 currentTreeState, |
184 containerContentsProperties.propertyTreeState, success) | 183 containerContentsProperties, success) |
185 .location(); | 184 .location(); |
186 DCHECK(success); | 185 DCHECK(success); |
187 | 186 |
188 // Convert the result to the container's contents space. | 187 // Convert the result to the container's contents space. |
189 point.moveBy(-containerContentsProperties.paintOffset); | 188 point.moveBy(-context.paintInvalidationContainer->paintOffset()); |
190 } | 189 } |
191 | 190 |
192 PaintLayer::mapPointInPaintInvalidationContainerToBacking( | 191 PaintLayer::mapPointInPaintInvalidationContainerToBacking( |
193 *context.paintInvalidationContainer, point); | 192 *context.paintInvalidationContainer, point); |
194 | 193 |
195 return LayoutPoint(point); | 194 return LayoutPoint(point); |
196 } | 195 } |
197 | 196 |
198 void PaintInvalidator::updatePaintingLayer(const LayoutObject& object, | 197 void PaintInvalidator::updatePaintingLayer(const LayoutObject& object, |
199 PaintInvalidatorContext& context) { | 198 PaintInvalidatorContext& context) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 object.isColumnSpanAll()) { | 339 object.isColumnSpanAll()) { |
341 context.forcedSubtreeInvalidationFlags |= | 340 context.forcedSubtreeInvalidationFlags |= |
342 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | 341 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
343 } | 342 } |
344 | 343 |
345 ObjectPaintInvalidator objectPaintInvalidator(object); | 344 ObjectPaintInvalidator objectPaintInvalidator(object); |
346 context.oldVisualRect = object.previousVisualRect(); | 345 context.oldVisualRect = object.previousVisualRect(); |
347 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); | 346 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); |
348 context.newVisualRect = computeVisualRectInBacking(object, context); | 347 context.newVisualRect = computeVisualRectInBacking(object, context); |
349 context.newLocation = computeLocationInBacking(object, context); | 348 context.newLocation = computeLocationInBacking(object, context); |
350 context.oldPaintOffset = object.previousPaintOffset(); | |
351 context.newPaintOffset = context.treeBuilderContext.current.paintOffset; | |
352 | 349 |
353 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( | 350 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( |
354 *context.paintInvalidationContainer); | 351 *context.paintInvalidationContainer); |
355 context.newLocation.move(adjustment); | 352 context.newLocation.move(adjustment); |
356 context.newVisualRect.move(adjustment); | 353 context.newVisualRect.move(adjustment); |
357 | 354 |
358 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); | 355 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); |
359 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); | 356 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); |
360 object.getMutableForPainting().setPreviousPaintOffset(context.newPaintOffset); | |
361 } | 357 } |
362 | 358 |
363 void PaintInvalidator::invalidatePaintIfNeeded( | 359 void PaintInvalidator::invalidatePaintIfNeeded( |
364 FrameView& frameView, | 360 FrameView& frameView, |
365 PaintInvalidatorContext& context) { | 361 PaintInvalidatorContext& context) { |
366 LayoutView* layoutView = frameView.layoutView(); | 362 LayoutView* layoutView = frameView.layoutView(); |
367 CHECK(layoutView); | 363 CHECK(layoutView); |
368 | 364 |
369 context.paintInvalidationContainer = | 365 context.paintInvalidationContainer = |
370 context.paintInvalidationContainerForStackedContents = | 366 context.paintInvalidationContainerForStackedContents = |
371 &layoutView->containerForPaintInvalidation(); | 367 &layoutView->containerForPaintInvalidation(); |
372 context.paintingLayer = layoutView->layer(); | 368 context.paintingLayer = layoutView->layer(); |
373 | 369 |
374 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 370 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
375 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); | 371 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); |
376 frameView.invalidatePaintOfScrollControlsIfNeeded(context); | 372 frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
377 } | 373 } |
378 | 374 |
379 if (frameView.frame().selection().isCaretBoundsDirty()) | 375 if (frameView.frame().selection().isCaretBoundsDirty()) |
380 frameView.frame().selection().invalidateCaretRect(); | 376 frameView.frame().selection().invalidateCaretRect(); |
381 } | 377 } |
382 | 378 |
383 void PaintInvalidator::invalidatePaintIfNeeded( | 379 void PaintInvalidator::invalidatePaintIfNeeded( |
384 const LayoutObject& object, | 380 const LayoutObject& object, |
| 381 const LayoutPoint& oldPaintOffset, |
385 PaintInvalidatorContext& context) { | 382 PaintInvalidatorContext& context) { |
386 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); | 383 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
387 | 384 |
| 385 DCHECK(context.treeBuilderContext.current.paintOffset == |
| 386 object.paintOffset()); |
| 387 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
| 388 object.paintOffset() != oldPaintOffset) { |
| 389 object.getMutableForPainting().setShouldDoFullPaintInvalidation( |
| 390 PaintInvalidationLocationChange); |
| 391 } |
| 392 |
388 if (!context.forcedSubtreeInvalidationFlags && | 393 if (!context.forcedSubtreeInvalidationFlags && |
389 !object | 394 !object |
390 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) | 395 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) |
391 return; | 396 return; |
392 | 397 |
393 updatePaintingLayer(object, context); | 398 updatePaintingLayer(object, context); |
394 | 399 |
395 if (object.document().printing()) | 400 if (object.document().printing()) |
396 return; // Don't invalidate paints if we're printing. | 401 return; // Don't invalidate paints if we're printing. |
397 | 402 |
(...skipping 24 matching lines...) Expand all Loading... |
422 ForcedSubtreeFullInvalidationForStackedContents); | 427 ForcedSubtreeFullInvalidationForStackedContents); |
423 break; | 428 break; |
424 case PaintInvalidationSVGResourceChange: | 429 case PaintInvalidationSVGResourceChange: |
425 context.forcedSubtreeInvalidationFlags |= | 430 context.forcedSubtreeInvalidationFlags |= |
426 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; | 431 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; |
427 break; | 432 break; |
428 default: | 433 default: |
429 break; | 434 break; |
430 } | 435 } |
431 | 436 |
432 if (context.oldLocation != context.newLocation || | 437 if (context.oldLocation != context.newLocation) { |
433 (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | |
434 context.oldPaintOffset != context.newPaintOffset)) { | |
435 context.forcedSubtreeInvalidationFlags |= | 438 context.forcedSubtreeInvalidationFlags |= |
436 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 439 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
437 } | 440 } |
438 | 441 |
439 // TODO(crbug.com/490725): This is a workaround for the bug, to force | 442 // TODO(crbug.com/490725): This is a workaround for the bug, to force |
440 // descendant to update visual rects on clipping change. | 443 // descendant to update visual rects on clipping change. |
441 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 444 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
442 context.oldVisualRect != context.newVisualRect | 445 context.oldVisualRect != context.newVisualRect |
443 // Note that isLayoutView() below becomes unnecessary after the launch of | 446 // Note that isLayoutView() below becomes unnecessary after the launch of |
444 // root layer scrolling. | 447 // root layer scrolling. |
445 && (object.hasOverflowClip() || object.isLayoutView()) && | 448 && (object.hasOverflowClip() || object.isLayoutView()) && |
446 !toLayoutBox(object).usesCompositedScrolling()) | 449 !toLayoutBox(object).usesCompositedScrolling()) |
447 context.forcedSubtreeInvalidationFlags |= | 450 context.forcedSubtreeInvalidationFlags |= |
448 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 451 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
449 } | 452 } |
450 | 453 |
451 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 454 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
452 for (auto target : m_pendingDelayedPaintInvalidations) | 455 for (auto target : m_pendingDelayedPaintInvalidations) |
453 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 456 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
454 PaintInvalidationDelayedFull); | 457 PaintInvalidationDelayedFull); |
455 } | 458 } |
456 | 459 |
457 } // namespace blink | 460 } // namespace blink |
OLD | NEW |