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..9b93b77117dcf9d0e5aa062e12998a61d615c0c4 100644 |
--- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
+++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
@@ -47,7 +47,8 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking( |
GeometryMapper& geometryMapper, |
const LayoutObject& object, |
const FloatRect& localRect, |
- const PaintInvalidatorContext& context) { |
+ const PaintInvalidatorContext& context, |
+ bool& coversExtraPixels) { |
// TODO(wkorman): The flip below is required because visual rects are |
// currently in "physical coordinates with flipped block-flow direction" |
// (see LayoutBoxModelObject.h) but we need them to be in physical |
@@ -72,6 +73,14 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking( |
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
// In SPv2, visual rects are in the space of their local transform node. |
rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); |
+ // 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) { |
+ coversExtraPixels = true; |
+ return LayoutRect(intRect); |
+ } |
return LayoutRect(rect); |
} |
@@ -84,6 +93,16 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking( |
result = 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) { |
+ coversExtraPixels = true; |
+ rect = intRect; |
+ } |
+ } |
PropertyTreeState currentTreeState( |
context.treeBuilderContext.current.transform, |
@@ -95,6 +114,9 @@ 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( |
rect, currentTreeState, containerContentsProperties.propertyTreeState, |
@@ -115,28 +137,32 @@ void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( |
const LayoutObject& object, |
LayoutRect& rect) const { |
GeometryMapper geometryMapper; |
- rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, |
- FloatRect(rect), *this); |
+ bool coversExtraPixels; |
+ rect = blink::mapLocalRectToPaintInvalidationBacking( |
+ geometryMapper, object, FloatRect(rect), *this, coversExtraPixels); |
} |
LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( |
const LayoutObject& object, |
const FloatRect& localRect, |
- const PaintInvalidatorContext& context) { |
- return blink::mapLocalRectToPaintInvalidationBacking(m_geometryMapper, object, |
- localRect, context); |
+ const PaintInvalidatorContext& context, |
+ bool& coversExtraPixels) { |
+ return blink::mapLocalRectToPaintInvalidationBacking( |
+ m_geometryMapper, object, localRect, context, coversExtraPixels); |
} |
LayoutRect PaintInvalidator::computePaintInvalidationRectInBacking( |
const LayoutObject& object, |
- const PaintInvalidatorContext& context) { |
+ const PaintInvalidatorContext& context, |
+ bool& coversExtraPixels) { |
FloatRect localRect; |
if (object.isSVG() && !object.isSVGRoot()) |
localRect = SVGLayoutSupport::localOverflowRectForPaintInvalidation(object); |
else |
localRect = FloatRect(object.localOverflowRectForPaintInvalidation()); |
- return mapLocalRectToPaintInvalidationBacking(object, localRect, context); |
+ return mapLocalRectToPaintInvalidationBacking(object, localRect, context, |
+ coversExtraPixels); |
} |
LayoutPoint PaintInvalidator::computeLocationFromPaintInvalidationBacking( |
@@ -311,8 +337,11 @@ void PaintInvalidator::updateContext(const LayoutObject& object, |
PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
context.oldBounds = object.previousPaintInvalidationRect(); |
+ context.oldBoundsCoversExtraPixels = |
+ object.previousPaintInvalidationRectCoversExtraPixels(); |
context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); |
- context.newBounds = computePaintInvalidationRectInBacking(object, context); |
+ context.newBounds = computePaintInvalidationRectInBacking( |
+ object, context, context.newBoundsCoversExtraPixels); |
context.newLocation = |
computeLocationFromPaintInvalidationBacking(object, context); |
@@ -322,7 +351,7 @@ void PaintInvalidator::updateContext(const LayoutObject& object, |
context.newBounds.move(adjustment); |
object.getMutableForPainting().setPreviousPaintInvalidationRect( |
- context.newBounds); |
+ context.newBounds, context.newBoundsCoversExtraPixels); |
object.getMutableForPainting() |
.setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
} |