Chromium Code Reviews| Index: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| index 1ba7d67924f3bbf8c97a2b8277f6702940aad4cc..0f1d935b08fcd089f6abfab5d5bf1c6aab8b153b 100644 |
| --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp |
| @@ -34,21 +34,23 @@ PaintPropertyTreeBuilder::setupInitialContext() { |
| return context; |
| } |
| -void updateFrameViewPreTranslation( |
| - FrameView& frameView, |
| - PassRefPtr<const TransformPaintPropertyNode> parent, |
| - const TransformationMatrix& matrix, |
| - const FloatPoint3D& origin) { |
| +// True if a new property was created, false if an existing one was updated. |
| +bool updatePreTranslation(FrameView& frameView, |
| + PassRefPtr<const TransformPaintPropertyNode> parent, |
| + const TransformationMatrix& matrix, |
| + const FloatPoint3D& origin) { |
| DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| if (auto* existingPreTranslation = frameView.preTranslation()) { |
| existingPreTranslation->update(std::move(parent), matrix, origin); |
| - } else { |
| - frameView.setPreTranslation( |
| - TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); |
| + return false; |
| } |
| + frameView.setPreTranslation( |
| + TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); |
| + return true; |
| } |
| -void updateFrameViewContentClip( |
| +// True if a new property was created, false if an existing one was updated. |
| +bool updateContentClip( |
| FrameView& frameView, |
| PassRefPtr<const ClipPaintPropertyNode> parent, |
| PassRefPtr<const TransformPaintPropertyNode> localTransformSpace, |
| @@ -57,13 +59,15 @@ void updateFrameViewContentClip( |
| if (auto* existingContentClip = frameView.contentClip()) { |
| existingContentClip->update(std::move(parent), |
| std::move(localTransformSpace), clipRect); |
| - } else { |
| - frameView.setContentClip(ClipPaintPropertyNode::create( |
| - std::move(parent), std::move(localTransformSpace), clipRect)); |
| + return false; |
| } |
| + frameView.setContentClip(ClipPaintPropertyNode::create( |
| + std::move(parent), std::move(localTransformSpace), clipRect)); |
| + return true; |
| } |
| -void updateFrameViewScrollTranslation( |
| +// True if a new property was created, false if an existing one was updated. |
| +bool updateScrollTranslation( |
| FrameView& frameView, |
| PassRefPtr<const TransformPaintPropertyNode> parent, |
| const TransformationMatrix& matrix, |
| @@ -71,32 +75,34 @@ void updateFrameViewScrollTranslation( |
| DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| if (auto* existingScrollTranslation = frameView.scrollTranslation()) { |
| existingScrollTranslation->update(std::move(parent), matrix, origin); |
| - } else { |
| - frameView.setScrollTranslation( |
| - TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); |
| + return false; |
| } |
| + frameView.setScrollTranslation( |
| + TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); |
| + return true; |
| } |
| -void updateFrameViewScroll( |
| - FrameView& frameView, |
| - PassRefPtr<const ScrollPaintPropertyNode> parent, |
| - PassRefPtr<const TransformPaintPropertyNode> scrollOffset, |
| - const IntSize& clip, |
| - const IntSize& bounds, |
| - bool userScrollableHorizontal, |
| - bool userScrollableVertical, |
| - MainThreadScrollingReasons mainThreadScrollingReasons) { |
| +// True if a new property was created, false if an existing one was updated. |
| +bool updateScroll(FrameView& frameView, |
| + PassRefPtr<const ScrollPaintPropertyNode> parent, |
| + PassRefPtr<const TransformPaintPropertyNode> scrollOffset, |
| + const IntSize& clip, |
| + const IntSize& bounds, |
| + bool userScrollableHorizontal, |
| + bool userScrollableVertical, |
| + MainThreadScrollingReasons mainThreadScrollingReasons) { |
| DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| if (auto* existingScroll = frameView.scroll()) { |
| existingScroll->update(std::move(parent), std::move(scrollOffset), clip, |
| bounds, userScrollableHorizontal, |
| userScrollableVertical, mainThreadScrollingReasons); |
| - } else { |
| - frameView.setScroll(ScrollPaintPropertyNode::create( |
| - std::move(parent), std::move(scrollOffset), clip, bounds, |
| - userScrollableHorizontal, userScrollableVertical, |
| - mainThreadScrollingReasons)); |
| + return false; |
| } |
| + frameView.setScroll(ScrollPaintPropertyNode::create( |
| + std::move(parent), std::move(scrollOffset), clip, bounds, |
| + userScrollableHorizontal, userScrollableVertical, |
| + mainThreadScrollingReasons)); |
| + return true; |
| } |
| void PaintPropertyTreeBuilder::updateProperties( |
| @@ -116,28 +122,32 @@ void PaintPropertyTreeBuilder::updateProperties( |
| return; |
| } |
| + if (context.forceSubtreeUpdate) |
| + frameView.setNeedsPaintPropertyUpdateWithoutMarkingAncestors(); |
| + |
| #if DCHECK_IS_ON() |
| - FindFrameViewPropertiesNeedingUpdateScope checkNeedsUpdateScope(&frameView); |
| + FindFrameViewPropertiesNeedingUpdateScope checkScope(&frameView, context); |
| #endif |
| if (frameView.needsPaintPropertyUpdate()) { |
| TransformationMatrix frameTranslate; |
| frameTranslate.translate(frameView.x() + context.current.paintOffset.x(), |
| frameView.y() + context.current.paintOffset.y()); |
| - updateFrameViewPreTranslation(frameView, context.current.transform, |
| - frameTranslate, FloatPoint3D()); |
| + context.forceSubtreeUpdate |= updatePreTranslation( |
| + frameView, context.current.transform, frameTranslate, FloatPoint3D()); |
| FloatRoundedRect contentClip( |
| IntRect(IntPoint(), frameView.visibleContentSize())); |
| - updateFrameViewContentClip(frameView, context.current.clip, |
| - frameView.preTranslation(), contentClip); |
| + context.forceSubtreeUpdate |= |
| + updateContentClip(frameView, context.current.clip, |
| + frameView.preTranslation(), contentClip); |
| ScrollOffset scrollOffset = frameView.scrollOffset(); |
| if (frameView.isScrollable() || !scrollOffset.isZero()) { |
| TransformationMatrix frameScroll; |
| frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); |
| - updateFrameViewScrollTranslation(frameView, frameView.preTranslation(), |
| - frameScroll, FloatPoint3D()); |
| + context.forceSubtreeUpdate |= updateScrollTranslation( |
| + frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); |
| IntSize scrollClip = frameView.visibleContentSize(); |
| IntSize scrollBounds = frameView.contentsSize(); |
| @@ -153,14 +163,19 @@ void PaintPropertyTreeBuilder::updateProperties( |
| reasons |= |
| MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
| } |
| - updateFrameViewScroll(frameView, context.current.scroll, |
| - frameView.scrollTranslation(), scrollClip, |
| - scrollBounds, userScrollableHorizontal, |
| - userScrollableVertical, reasons); |
| + context.forceSubtreeUpdate |= updateScroll( |
| + frameView, context.current.scroll, frameView.scrollTranslation(), |
| + scrollClip, scrollBounds, userScrollableHorizontal, |
| + userScrollableVertical, reasons); |
| } else { |
| - // Ensure pre-existing properties are cleared when there is no scrolling. |
| - frameView.setScrollTranslation(nullptr); |
| - frameView.setScroll(nullptr); |
| + if (frameView.scrollTranslation() || frameView.scroll()) { |
| + // Ensure pre-existing properties are cleared if there is no scrolling. |
| + frameView.setScrollTranslation(nullptr); |
| + frameView.setScroll(nullptr); |
| + |
| + // Rebuild all descendant properties because a property was removed. |
| + context.forceSubtreeUpdate = true; |
| + } |
| } |
| } |
| @@ -224,17 +239,16 @@ void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( |
| if (object.needsPaintPropertyUpdate()) { |
| if (usesPaintOffsetTranslation) { |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updatePaintOffsetTranslation( |
| - context.current.transform, |
| - TransformationMatrix().translate(roundedPaintOffset.x(), |
| - roundedPaintOffset.y()), |
| - FloatPoint3D(), context.current.shouldFlattenInheritedTransform, |
| - context.current.renderingContextID); |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updatePaintOffsetTranslation( |
| + context.current.transform, |
| + TransformationMatrix().translate(roundedPaintOffset.x(), |
| + roundedPaintOffset.y()), |
| + FloatPoint3D(), context.current.shouldFlattenInheritedTransform, |
| + context.current.renderingContextID); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearPaintOffsetTranslation(); |
| + context.forceSubtreeUpdate |= properties->clearPaintOffsetTranslation(); |
| } |
| } |
| @@ -279,12 +293,13 @@ void PaintPropertyTreeBuilder::updateTransformForNonRootSVG( |
| // identity matrix. |
| if (!transform.isIdentity()) { |
| // The origin is included in the local transform, so leave origin empty. |
| - object.getMutableForPainting().ensurePaintProperties().updateTransform( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateTransform( |
| context.current.transform, TransformationMatrix(transform), |
| FloatPoint3D()); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearTransform(); |
| + context.forceSubtreeUpdate |= properties->clearTransform(); |
| } |
| } |
| @@ -321,13 +336,14 @@ void PaintPropertyTreeBuilder::updateTransform( |
| if (style.preserves3D() && !renderingContextID) |
| renderingContextID = PtrHash<const LayoutObject>::hash(&object); |
| - object.getMutableForPainting().ensurePaintProperties().updateTransform( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateTransform( |
| context.current.transform, matrix, |
| transformOrigin(toLayoutBox(object)), |
| context.current.shouldFlattenInheritedTransform, renderingContextID); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearTransform(); |
| + context.forceSubtreeUpdate |= properties->clearTransform(); |
| } |
| } |
| @@ -353,7 +369,7 @@ void PaintPropertyTreeBuilder::updateEffect( |
| if (!style.isStackingContext()) { |
| if (object.needsPaintPropertyUpdate()) { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearEffect(); |
| + context.forceSubtreeUpdate |= properties->clearEffect(); |
| } |
| return; |
| } |
| @@ -404,12 +420,13 @@ void PaintPropertyTreeBuilder::updateEffect( |
| } |
| if (effectNodeNeeded) { |
| - object.getMutableForPainting().ensurePaintProperties().updateEffect( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateEffect( |
| context.currentEffect, context.current.transform, outputClip, |
| std::move(filter), opacity); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearEffect(); |
| + context.forceSubtreeUpdate |= properties->clearEffect(); |
| } |
| } |
| @@ -439,12 +456,13 @@ void PaintPropertyTreeBuilder::updateCssClip( |
| DCHECK(object.canContainAbsolutePositionObjects()); |
| LayoutRect clipRect = |
| toLayoutBox(object).clipRect(context.current.paintOffset); |
| - object.getMutableForPainting().ensurePaintProperties().updateCssClip( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateCssClip( |
| context.current.clip, context.current.transform, |
| FloatRoundedRect(FloatRect(clipRect))); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearCssClip(); |
| + context.forceSubtreeUpdate |= properties->clearCssClip(); |
| } |
| } |
| @@ -481,7 +499,7 @@ void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( |
| // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( |
| const LayoutObject& object, |
| - const PaintPropertyTreeBuilderContext& context) { |
| + PaintPropertyTreeBuilderContext& context) { |
| if (!object.needsPaintPropertyUpdate()) |
| return; |
| @@ -492,10 +510,10 @@ void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( |
| if (area->horizontalScrollbar() || area->verticalScrollbar()) { |
| auto paintOffset = TransformationMatrix().translate( |
| roundedPaintOffset.x(), roundedPaintOffset.y()); |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updateScrollbarPaintOffset(context.current.transform, paintOffset, |
| - FloatPoint3D()); |
| + auto& properties = |
| + object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateScrollbarPaintOffset( |
| + context.current.transform, paintOffset, FloatPoint3D()); |
| needsScrollbarPaintOffset = true; |
| } |
| } |
| @@ -503,7 +521,7 @@ void PaintPropertyTreeBuilder::updateScrollbarPaintOffset( |
| auto* properties = object.getMutableForPainting().paintProperties(); |
| if (!needsScrollbarPaintOffset && properties) |
| - properties->clearScrollbarPaintOffset(); |
| + context.forceSubtreeUpdate |= properties->clearScrollbarPaintOffset(); |
| } |
| void PaintPropertyTreeBuilder::updateOverflowClip( |
| @@ -529,29 +547,27 @@ void PaintPropertyTreeBuilder::updateOverflowClip( |
| box.overflowClipRect(context.current.paintOffset))); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) { |
| - properties->clearInnerBorderRadiusClip(); |
| - properties->clearOverflowClip(); |
| + context.forceSubtreeUpdate |= properties->clearInnerBorderRadiusClip(); |
| + context.forceSubtreeUpdate |= properties->clearOverflowClip(); |
| } |
| return; |
| } |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| const auto* currentClip = context.current.clip; |
| if (box.styleRef().hasBorderRadius()) { |
| auto innerBorder = box.styleRef().getRoundedInnerBorderFor( |
| LayoutRect(context.current.paintOffset, box.size())); |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updateInnerBorderRadiusClip(context.current.clip, |
| - context.current.transform, innerBorder); |
| - currentClip = object.paintProperties()->innerBorderRadiusClip(); |
| - } else if (auto* properties = |
| - object.getMutableForPainting().paintProperties()) { |
| - properties->clearInnerBorderRadiusClip(); |
| + context.forceSubtreeUpdate |= properties.updateInnerBorderRadiusClip( |
| + context.current.clip, context.current.transform, innerBorder); |
| + currentClip = properties.innerBorderRadiusClip(); |
| + } else { |
| + context.forceSubtreeUpdate |= properties.clearInnerBorderRadiusClip(); |
| } |
| - object.getMutableForPainting().ensurePaintProperties().updateOverflowClip( |
| - currentClip, context.current.transform, |
| - FloatRoundedRect(FloatRect(clipRect))); |
| + context.forceSubtreeUpdate |= |
| + properties.updateOverflowClip(currentClip, context.current.transform, |
| + FloatRoundedRect(FloatRect(clipRect))); |
| } |
| const auto* properties = object.paintProperties(); |
| @@ -580,13 +596,14 @@ void PaintPropertyTreeBuilder::updatePerspective( |
| TransformationMatrix().applyPerspective(style.perspective()); |
| FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + |
| toLayoutSize(context.current.paintOffset); |
| - object.getMutableForPainting().ensurePaintProperties().updatePerspective( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updatePerspective( |
| context.current.transform, matrix, origin, |
| context.current.shouldFlattenInheritedTransform, |
| context.current.renderingContextID); |
| } else { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearPerspective(); |
| + context.forceSubtreeUpdate |= properties->clearPerspective(); |
| } |
| } |
| @@ -608,13 +625,15 @@ void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( |
| SVGRootPainter(toLayoutSVGRoot(object)) |
| .transformToPixelSnappedBorderBox(context.current.paintOffset); |
| if (!transformToBorderBox.isIdentity()) { |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updateSvgLocalToBorderBoxTransform( |
| + auto& properties = object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= |
| + properties.updateSvgLocalToBorderBoxTransform( |
| context.current.transform, transformToBorderBox, FloatPoint3D()); |
| } else { |
| - if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearSvgLocalToBorderBoxTransform(); |
| + if (auto* properties = object.getMutableForPainting().paintProperties()) { |
| + context.forceSubtreeUpdate |= |
| + properties->clearSvgLocalToBorderBoxTransform(); |
| + } |
| } |
| } |
| @@ -638,14 +657,14 @@ void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( |
| const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); |
| IntSize scrollOffset = box.scrolledContentOffset(); |
| if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { |
| + auto& properties = |
| + object.getMutableForPainting().ensurePaintProperties(); |
| TransformationMatrix matrix = TransformationMatrix().translate( |
| -scrollOffset.width(), -scrollOffset.height()); |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updateScrollTranslation( |
| - context.current.transform, matrix, FloatPoint3D(), |
| - context.current.shouldFlattenInheritedTransform, |
| - context.current.renderingContextID); |
| + context.forceSubtreeUpdate |= properties.updateScrollTranslation( |
| + context.current.transform, matrix, FloatPoint3D(), |
| + context.current.shouldFlattenInheritedTransform, |
| + context.current.renderingContextID); |
| IntSize scrollClip = scrollableArea->visibleContentRect().size(); |
| IntSize scrollBounds = scrollableArea->contentsSize(); |
| @@ -667,9 +686,8 @@ void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( |
| reasons |= |
| MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
| } |
| - object.getMutableForPainting().ensurePaintProperties().updateScroll( |
| - context.current.scroll, |
| - object.paintProperties()->scrollTranslation(), scrollClip, |
| + context.forceSubtreeUpdate |= properties.updateScroll( |
| + context.current.scroll, properties.scrollTranslation(), scrollClip, |
| scrollBounds, userScrollableHorizontal, userScrollableVertical, |
| reasons); |
| } else { |
| @@ -677,8 +695,8 @@ void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( |
| // scrolling. |
| auto* properties = object.getMutableForPainting().paintProperties(); |
| if (properties) { |
| - properties->clearScrollTranslation(); |
| - properties->clearScroll(); |
| + context.forceSubtreeUpdate |= properties->clearScrollTranslation(); |
| + context.forceSubtreeUpdate |= properties->clearScroll(); |
| } |
| } |
| } |
| @@ -728,12 +746,12 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext( |
| context.fixedPosition.clip = cssClip; |
| } else { |
| if (object.needsPaintPropertyUpdate()) { |
| - object.getMutableForPainting() |
| - .ensurePaintProperties() |
| - .updateCssClipFixedPosition(context.fixedPosition.clip, |
| - const_cast<TransformPaintPropertyNode*>( |
| + auto& properties = |
| + object.getMutableForPainting().ensurePaintProperties(); |
| + context.forceSubtreeUpdate |= properties.updateCssClipFixedPosition( |
| + context.fixedPosition.clip, const_cast<TransformPaintPropertyNode*>( |
| cssClip->localTransformSpace()), |
| - cssClip->clipRect()); |
| + cssClip->clipRect()); |
| } |
| const auto* properties = object.paintProperties(); |
| if (properties && properties->cssClipFixedPosition()) |
| @@ -744,7 +762,7 @@ void PaintPropertyTreeBuilder::updateOutOfFlowContext( |
| if (object.needsPaintPropertyUpdate()) { |
| if (auto* properties = object.getMutableForPainting().paintProperties()) |
| - properties->clearCssClipFixedPosition(); |
| + context.forceSubtreeUpdate |= properties->clearCssClipFixedPosition(); |
| } |
| } |
| @@ -875,8 +893,13 @@ void PaintPropertyTreeBuilder::updatePropertiesForSelf( |
| if (!object.isBoxModelObject() && !object.isSVG()) |
| return; |
| + if (context.forceSubtreeUpdate) { |
| + object.getMutableForPainting() |
| + .setNeedsPaintPropertyUpdateWithoutMarkingAncestors(); |
|
chrishtr
2016/12/01 02:36:35
This is kind of an odd way to do forced subtree up
pdr.
2016/12/01 09:35:35
This is a great idea. Done.
|
| + } |
| + |
| #if DCHECK_IS_ON() |
| - FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object); |
| + FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context); |
| #endif |
| deriveBorderBoxFromContainerContext(object, context); |
| @@ -895,8 +918,13 @@ void PaintPropertyTreeBuilder::updatePropertiesForChildren( |
| if (!object.isBoxModelObject() && !object.isSVG()) |
| return; |
| + if (context.forceSubtreeUpdate) { |
| + // This should have been set by |updatePropertiesForSelf|. |
| + DCHECK(object.needsPaintPropertyUpdate()); |
| + } |
| + |
| #if DCHECK_IS_ON() |
| - FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object); |
| + FindObjectPropertiesNeedingUpdateScope checkNeedsUpdateScope(object, context); |
| #endif |
| updateOverflowClip(object, context); |