| 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 |