Chromium Code Reviews| 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())); |
|
Xianzhu
2017/01/06 17:24:39
This is just changed to a shorter form. They are a
| |
| 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 object.isColumnSpanAll()) { | 331 object.isColumnSpanAll()) { |
| 333 context.forcedSubtreeInvalidationFlags |= | 332 context.forcedSubtreeInvalidationFlags |= |
| 334 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; | 333 PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
| 335 } | 334 } |
| 336 | 335 |
| 337 ObjectPaintInvalidator objectPaintInvalidator(object); | 336 ObjectPaintInvalidator objectPaintInvalidator(object); |
| 338 context.oldVisualRect = object.previousVisualRect(); | 337 context.oldVisualRect = object.previousVisualRect(); |
| 339 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); | 338 context.oldLocation = objectPaintInvalidator.previousLocationInBacking(); |
| 340 context.newVisualRect = computeVisualRectInBacking(object, context); | 339 context.newVisualRect = computeVisualRectInBacking(object, context); |
| 341 context.newLocation = computeLocationInBacking(object, context); | 340 context.newLocation = computeLocationInBacking(object, context); |
| 342 context.oldPaintOffset = object.previousPaintOffset(); | |
| 343 context.newPaintOffset = context.treeBuilderContext.current.paintOffset; | |
| 344 | 341 |
| 345 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( | 342 IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( |
| 346 *context.paintInvalidationContainer); | 343 *context.paintInvalidationContainer); |
| 347 context.newLocation.move(adjustment); | 344 context.newLocation.move(adjustment); |
| 348 context.newVisualRect.move(adjustment); | 345 context.newVisualRect.move(adjustment); |
| 349 | 346 |
| 350 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); | 347 object.getMutableForPainting().setPreviousVisualRect(context.newVisualRect); |
| 351 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); | 348 objectPaintInvalidator.setPreviousLocationInBacking(context.newLocation); |
| 352 object.getMutableForPainting().setPreviousPaintOffset(context.newPaintOffset); | |
| 353 } | 349 } |
| 354 | 350 |
| 355 void PaintInvalidator::invalidatePaintIfNeeded( | 351 void PaintInvalidator::invalidatePaintIfNeeded( |
| 356 FrameView& frameView, | 352 FrameView& frameView, |
| 357 PaintInvalidatorContext& context) { | 353 PaintInvalidatorContext& context) { |
| 358 LayoutView* layoutView = frameView.layoutView(); | 354 LayoutView* layoutView = frameView.layoutView(); |
| 359 CHECK(layoutView); | 355 CHECK(layoutView); |
| 360 | 356 |
| 361 context.paintInvalidationContainer = | 357 context.paintInvalidationContainer = |
| 362 context.paintInvalidationContainerForStackedContents = | 358 context.paintInvalidationContainerForStackedContents = |
| 363 &layoutView->containerForPaintInvalidation(); | 359 &layoutView->containerForPaintInvalidation(); |
| 364 context.paintingLayer = layoutView->layer(); | 360 context.paintingLayer = layoutView->layer(); |
| 365 | 361 |
| 366 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 362 if (!RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 367 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); | 363 ScopedUndoFrameViewContentClipAndScroll undo(frameView, context); |
| 368 frameView.invalidatePaintOfScrollControlsIfNeeded(context); | 364 frameView.invalidatePaintOfScrollControlsIfNeeded(context); |
| 369 } | 365 } |
| 370 | 366 |
| 371 if (frameView.frame().selection().isCaretBoundsDirty()) | 367 if (frameView.frame().selection().isCaretBoundsDirty()) |
| 372 frameView.frame().selection().invalidateCaretRect(); | 368 frameView.frame().selection().invalidateCaretRect(); |
| 373 } | 369 } |
| 374 | 370 |
| 375 void PaintInvalidator::invalidatePaintIfNeeded( | 371 void PaintInvalidator::invalidatePaintIfNeeded( |
| 376 const LayoutObject& object, | 372 const LayoutObject& object, |
| 373 const LayoutPoint& oldPaintOffset, | |
| 377 PaintInvalidatorContext& context) { | 374 PaintInvalidatorContext& context) { |
| 378 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); | 375 object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
| 379 | 376 |
| 377 DCHECK(context.treeBuilderContext.current.paintOffset == | |
| 378 object.paintOffset()); | |
| 379 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | |
| 380 object.paintOffset() != oldPaintOffset) { | |
| 381 object.getMutableForPainting().setShouldDoFullPaintInvalidation( | |
| 382 PaintInvalidationLocationChange); | |
| 383 } | |
| 384 | |
| 380 if (!context.forcedSubtreeInvalidationFlags && | 385 if (!context.forcedSubtreeInvalidationFlags && |
| 381 !object | 386 !object |
| 382 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) | 387 .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) |
| 383 return; | 388 return; |
| 384 | 389 |
| 385 updatePaintingLayer(object, context); | 390 updatePaintingLayer(object, context); |
| 386 | 391 |
| 387 if (object.document().printing()) | 392 if (object.document().printing()) |
| 388 return; // Don't invalidate paints if we're printing. | 393 return; // Don't invalidate paints if we're printing. |
| 389 | 394 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 414 ForcedSubtreeFullInvalidationForStackedContents); | 419 ForcedSubtreeFullInvalidationForStackedContents); |
| 415 break; | 420 break; |
| 416 case PaintInvalidationSVGResourceChange: | 421 case PaintInvalidationSVGResourceChange: |
| 417 context.forcedSubtreeInvalidationFlags |= | 422 context.forcedSubtreeInvalidationFlags |= |
| 418 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; | 423 PaintInvalidatorContext::ForcedSubtreeSVGResourceChange; |
| 419 break; | 424 break; |
| 420 default: | 425 default: |
| 421 break; | 426 break; |
| 422 } | 427 } |
| 423 | 428 |
| 424 if (context.oldLocation != context.newLocation || | 429 if (context.oldLocation != context.newLocation) { |
| 425 (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | |
| 426 context.oldPaintOffset != context.newPaintOffset)) { | |
| 427 context.forcedSubtreeInvalidationFlags |= | 430 context.forcedSubtreeInvalidationFlags |= |
| 428 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; | 431 PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| 429 } | 432 } |
| 430 | 433 |
| 431 // TODO(crbug.com/490725): This is a workaround for the bug, to force | 434 // TODO(crbug.com/490725): This is a workaround for the bug, to force |
| 432 // descendant to update visual rects on clipping change. | 435 // descendant to update visual rects on clipping change. |
| 433 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && | 436 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
| 434 context.oldVisualRect != context.newVisualRect | 437 context.oldVisualRect != context.newVisualRect |
| 435 // Note that isLayoutView() below becomes unnecessary after the launch of | 438 // Note that isLayoutView() below becomes unnecessary after the launch of |
| 436 // root layer scrolling. | 439 // root layer scrolling. |
| 437 && (object.hasOverflowClip() || object.isLayoutView()) && | 440 && (object.hasOverflowClip() || object.isLayoutView()) && |
| 438 !toLayoutBox(object).usesCompositedScrolling()) | 441 !toLayoutBox(object).usesCompositedScrolling()) |
| 439 context.forcedSubtreeInvalidationFlags |= | 442 context.forcedSubtreeInvalidationFlags |= |
| 440 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 443 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| 441 } | 444 } |
| 442 | 445 |
| 443 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 446 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
| 444 for (auto target : m_pendingDelayedPaintInvalidations) | 447 for (auto target : m_pendingDelayedPaintInvalidations) |
| 445 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 448 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
| 446 PaintInvalidationDelayedFull); | 449 PaintInvalidationDelayedFull); |
| 447 } | 450 } |
| 448 | 451 |
| 449 } // namespace blink | 452 } // namespace blink |
| OLD | NEW |