Chromium Code Reviews| 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 d6f93077f10445e3e80dffc43128877addad0fd2..d30a142cd29bc6525cb085b8b325e6d151538602 100644 |
| --- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp |
| @@ -20,6 +20,14 @@ |
| namespace blink { |
| +static void slowMapToVisualRectInAncestorSpace(const LayoutObject& object, const LayoutBoxModelObject& ancestor, LayoutRect& rect) |
| +{ |
| + if (object.isLayoutView()) |
| + toLayoutView(object).mapToVisualRectInAncestorSpace(&ancestor, rect, InputIsInFrameCoordinates, DefaultVisualRectFlags); |
| + else |
| + object.mapToVisualRectInAncestorSpace(&ancestor, rect); |
| +} |
| + |
| // TODO(wangxianzhu): Combine this into PaintInvalidator::mapLocalRectToPaintInvalidationBacking() when removing PaintInvalidationState. |
| static LayoutRect mapLocalRectToPaintInvalidationBacking(GeometryMapper& geometryMapper, const LayoutObject& object, const FloatRect& localRect, const PaintInvalidatorContext& context) |
| { |
| @@ -32,17 +40,22 @@ static LayoutRect mapLocalRectToPaintInvalidationBacking(GeometryMapper& geometr |
| toLayoutBox(object).flipForWritingMode(rect); |
| LayoutRect result; |
| - if (object == context.paintInvalidationContainer) { |
| + if (context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
| + result = LayoutRect(rect); |
| + slowMapToVisualRectInAncestorSpace(object, *context.paintInvalidationContainer, result); |
| + } else if (object == context.paintInvalidationContainer) { |
| result = LayoutRect(rect); |
| } else { |
| - rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); |
| - |
| - bool success = false; |
| PropertyTreeState currentTreeState(context.treeBuilderContext.current.transform, context.treeBuilderContext.current.clip, context.treeBuilderContext.currentEffect); |
| PropertyTreeState containerTreeState; |
| - context.paintInvalidationContainer->objectPaintProperties()->getContentsProperties(containerTreeState); |
| + const ObjectPaintProperties* containerPaintProperties = context.paintInvalidationContainer->objectPaintProperties(); |
| + containerPaintProperties->getContentsProperties(containerTreeState); |
| + |
| + rect.moveBy(FloatPoint(context.treeBuilderContext.current.paintOffset)); |
| + bool success = false; |
| result = LayoutRect(geometryMapper.mapToVisualRectInDestinationSpace(rect, currentTreeState, containerTreeState, success)); |
| DCHECK(success); |
| + result.moveBy(-containerPaintProperties->localBorderBoxProperties()->paintOffset); |
|
chrishtr
2016/09/13 23:30:03
This was a straight-up bug in slimmingPaintInvalid
Xianzhu
2016/09/13 23:47:15
Yes, this was a bug, but didn't notice it because
chrishtr
2016/09/13 23:54:25
Ah yes, makes sense.
|
| } |
| if (context.paintInvalidationContainer->layer()->groupedMapping()) |
| @@ -161,6 +174,10 @@ void PaintInvalidator::updateContext(const LayoutObject& object, PaintInvalidato |
| if (object.mayNeedPaintInvalidationSubtree()) |
| context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| + // TODO(crbug.com/637313): This is temporary before we support filters in paint property tree. |
| + if (object.hasFilterInducingProperty()) |
| + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeSlowPathRect; |
| + |
| context.oldBounds = object.previousPaintInvalidationRect(); |
| context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); |
| context.newBounds = computePaintInvalidationRectInBacking(object, context); |
| @@ -195,6 +212,17 @@ void PaintInvalidator::invalidatePaintIfNeeded(FrameView& frameView, PaintInvali |
| layoutView->sendMediaPositionChangeNotifications(visibleRect); |
| } |
| +static bool hasPercentageTransform(const ComputedStyle& style) |
| +{ |
| + if (TransformOperation* translate = style.translate()) { |
| + if (translate->dependsOnBoxSize()) |
| + return true; |
| + } |
| + return style.transform().dependsOnBoxSize() |
| + || (style.transformOriginX() != Length(50, Percent) && style.transformOriginX().isPercentOrCalc()) |
|
chrishtr
2016/09/13 23:30:03
There's no canonical way to detect non-default tra
Xianzhu
2016/09/13 23:47:15
We only need to check non-default percentage trans
|
| + || (style.transformOriginY() != Length(50, Percent) && style.transformOriginY().isPercentOrCalc()); |
| +} |
| + |
| void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& object, PaintInvalidatorContext& context) |
| { |
| object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); |
| @@ -216,7 +244,8 @@ void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& object, Paint |
| return; |
| } |
| - switch (object.invalidatePaintIfNeeded(context)) { |
| + PaintInvalidationReason reason = object.invalidatePaintIfNeeded(context); |
| + switch (reason) { |
| case PaintInvalidationDelayedFull: |
| m_pendingDelayedPaintInvalidations.append(&object); |
| break; |
| @@ -233,6 +262,19 @@ void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& object, Paint |
| if (context.oldLocation != context.newLocation) |
| context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| + // TODO(crbug.com/533277): This is a workaround for the bug. Remove when we detect paint offset change. |
| + if (reason != PaintInvalidationNone && hasPercentageTransform(object.styleRef())) |
| + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; |
| + |
| + // 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 |
| + // Note that isLayoutView() below becomes unnecessary after the launch of root layer scrolling. |
| + && (object.hasOverflowClip() || object.isLayoutView()) |
| + && !toLayoutBox(object).usesCompositedScrolling()) |
| + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
| + |
| object.getMutableForPainting().clearPaintInvalidationFlags(); |
| } |