Index: third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
index c090e7da9c634b1213abb742103762a9d7b1b185..7fb526c8ae31bbf6c1f2f19a165845f8d38d4afe 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
@@ -41,9 +41,9 @@ static LayoutRect slowMapToVisualRectInAncestorSpace( |
} |
// TODO(wangxianzhu): Combine this into |
-// PaintInvalidator::mapLocalRectToPaintInvalidationBacking() when removing |
+// PaintInvalidator::mapLocalRectToBacking() when removing |
// PaintInvalidationState. |
-static LayoutRect mapLocalRectToPaintInvalidationBacking( |
+static PaintInvalidationRectInBacking mapLocalRectToPaintInvalidationBacking( |
GeometryMapper& geometryMapper, |
const LayoutObject& object, |
const FloatRect& localRect, |
@@ -69,21 +69,37 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking( |
} |
} |
+ PaintInvalidationRectInBacking result; |
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
// In SPv2, visual rects are in the space of their local transform node. |
rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); |
- return LayoutRect(rect); |
+ // Use enclosingIntRect to ensure the final visual rect will cover the |
+ // rect in source coordinates no matter if the painting will use pixel |
+ // snapping. |
+ result.rect = LayoutRect(enclosingIntRect(rect)); |
+ if (FloatRect(result.rect) != rect) |
+ result.coversExtraPixels = true; |
+ return result; |
} |
- LayoutRect result; |
if (context.forcedSubtreeInvalidationFlags & |
PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
- result = slowMapToVisualRectInAncestorSpace( |
+ result.rect = slowMapToVisualRectInAncestorSpace( |
object, *context.paintInvalidationContainer, rect); |
} else if (object == context.paintInvalidationContainer) { |
- result = LayoutRect(rect); |
+ result.rect = LayoutRect(rect); |
} else { |
rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); |
+ if ((!object.isSVG() || object.isSVGRoot()) && !rect.isEmpty()) { |
+ // Use enclosingIntRect to ensure the final visual rect will cover the |
+ // rect in source coordinates no matter if the painting will use pixel |
+ // snapping. |
+ IntRect intRect = enclosingIntRect(rect); |
+ if (FloatRect(intRect) != rect) { |
+ result.coversExtraPixels = true; |
+ rect = intRect; |
+ } |
+ } |
PropertyTreeState currentTreeState( |
context.treeBuilderContext.current.transform, |
@@ -95,19 +111,23 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking( |
auto containerContentsProperties = |
containerPaintProperties->contentsProperties(); |
+ // TODO(wangxianzhu): Set coversExtraPixels if there are any non-translate |
+ // transforms. Currently this case is handled in BoxPaintInvalidator by |
+ // checking transforms. |
bool success = false; |
- result = LayoutRect(geometryMapper.mapToVisualRectInDestinationSpace( |
+ result.rect = LayoutRect(geometryMapper.mapToVisualRectInDestinationSpace( |
rect, currentTreeState, containerContentsProperties.propertyTreeState, |
success)); |
DCHECK(success); |
// Convert the result to the container's contents space. |
- result.moveBy(-containerContentsProperties.paintOffset); |
+ result.rect.moveBy(-containerContentsProperties.paintOffset); |
} |
- if (context.paintInvalidationContainer->layer()->groupedMapping()) |
+ if (context.paintInvalidationContainer->layer()->groupedMapping()) { |
PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
- *context.paintInvalidationContainer, result); |
+ *context.paintInvalidationContainer, result.rect); |
+ } |
return result; |
} |
@@ -116,10 +136,12 @@ void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( |
LayoutRect& rect) const { |
GeometryMapper geometryMapper; |
rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, |
- FloatRect(rect), *this); |
+ FloatRect(rect), *this) |
+ .rect; |
} |
-LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( |
+PaintInvalidationRectInBacking |
+PaintInvalidator::mapLocalRectToPaintInvalidationBacking( |
const LayoutObject& object, |
const FloatRect& localRect, |
const PaintInvalidatorContext& context) { |
@@ -127,7 +149,8 @@ LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( |
localRect, context); |
} |
-LayoutRect PaintInvalidator::computePaintInvalidationRectInBacking( |
+PaintInvalidationRectInBacking |
+PaintInvalidator::computePaintInvalidationRectInBacking( |
const LayoutObject& object, |
const PaintInvalidatorContext& context) { |
FloatRect localRect; |
@@ -310,7 +333,9 @@ void PaintInvalidator::updateContext(const LayoutObject& object, |
context.forcedSubtreeInvalidationFlags |= |
PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
- context.oldBounds = object.previousPaintInvalidationRect(); |
+ context.oldBounds.rect = object.previousPaintInvalidationRect(); |
+ context.oldBounds.coversExtraPixels = |
+ object.previousPaintInvalidationRectCoversExtraPixels(); |
context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); |
context.newBounds = computePaintInvalidationRectInBacking(object, context); |
context.newLocation = |
@@ -319,10 +344,10 @@ void PaintInvalidator::updateContext(const LayoutObject& object, |
IntSize adjustment = object.scrollAdjustmentForPaintInvalidation( |
*context.paintInvalidationContainer); |
context.newLocation.move(adjustment); |
- context.newBounds.move(adjustment); |
+ context.newBounds.rect.move(adjustment); |
object.getMutableForPainting().setPreviousPaintInvalidationRect( |
- context.newBounds); |
+ context.newBounds.rect, context.newBounds.coversExtraPixels); |
object.getMutableForPainting() |
.setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
} |
@@ -429,7 +454,7 @@ void PaintInvalidator::invalidatePaintIfNeeded( |
// TODO(crbug.com/490725): This is a workaround for the bug, to force |
// descendant to update paint invalidation rects on clipping change. |
if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && |
- context.oldBounds != context.newBounds |
+ context.oldBounds.rect != context.newBounds.rect |
// Note that isLayoutView() below becomes unnecessary after the launch of |
// root layer scrolling. |
&& (object.hasOverflowClip() || object.isLayoutView()) && |