Chromium Code Reviews| Index: third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp |
| diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp |
| index 10c5d49a581a791a51a0b03be3be41a935da1268..d6e05ed112949823acd0f2522df469b6bab35b3c 100644 |
| --- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp |
| +++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp |
| @@ -16,18 +16,25 @@ namespace blink { |
| struct PrePaintTreeWalkContext { |
| PrePaintTreeWalkContext() |
| - : paintInvalidatorContext(treeBuilderContext), |
| + : treeBuilderContext( |
| + WTF::wrapUnique(new PaintPropertyTreeBuilderContext)), |
| + paintInvalidatorContext(*treeBuilderContext), |
| ancestorOverflowPaintLayer(nullptr), |
| ancestorTransformedOrRootPaintLayer(nullptr) {} |
| PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) |
| - : treeBuilderContext(parentContext.treeBuilderContext), |
| - paintInvalidatorContext(treeBuilderContext, |
| + : treeBuilderContext(WTF::wrapUnique(new PaintPropertyTreeBuilderContext( |
| + *parentContext.treeBuilderContext))), |
| + paintInvalidatorContext(*treeBuilderContext, |
| parentContext.paintInvalidatorContext), |
| ancestorOverflowPaintLayer(parentContext.ancestorOverflowPaintLayer), |
| ancestorTransformedOrRootPaintLayer( |
| parentContext.ancestorTransformedOrRootPaintLayer) {} |
| - PaintPropertyTreeBuilderContext treeBuilderContext; |
| + // PaintPropertyTreeBuilderContext is large and can lead to stack overflows |
|
pdr.
2017/03/10 20:52:39
I think we may still have the issues in https://cr
Xianzhu
2017/03/10 21:54:48
I think 96 bytes is already small enough. It's sma
|
| + // when recursion is deep so this context object is allocated on the heap. |
| + // See: https://crbug.com/698653. |
| + std::unique_ptr<PaintPropertyTreeBuilderContext> treeBuilderContext; |
| + |
| PaintInvalidatorContext paintInvalidatorContext; |
| // The ancestor in the PaintLayer tree which has overflow clip, or |
| @@ -42,8 +49,7 @@ void PrePaintTreeWalk::walk(FrameView& rootFrame) { |
| DocumentLifecycle::InPrePaint); |
| PrePaintTreeWalkContext initialContext; |
| - initialContext.treeBuilderContext = |
| - m_propertyTreeBuilder.setupInitialContext(); |
| + m_propertyTreeBuilder.setupInitialContext(*initialContext.treeBuilderContext); |
| initialContext.ancestorTransformedOrRootPaintLayer = |
| rootFrame.layoutView()->layer(); |
| @@ -67,7 +73,8 @@ void PrePaintTreeWalk::walk(FrameView& frameView, |
| PrePaintTreeWalkContext context(parentContext); |
| // ancestorOverflowLayer does not cross frame boundaries. |
| context.ancestorOverflowPaintLayer = nullptr; |
| - m_propertyTreeBuilder.updateProperties(frameView, context.treeBuilderContext); |
| + m_propertyTreeBuilder.updateProperties(frameView, |
| + *context.treeBuilderContext); |
| m_paintInvalidator.invalidatePaintIfNeeded(frameView, |
| context.paintInvalidatorContext); |
| @@ -152,8 +159,6 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| .paintProperties(); |
| PropertyTreeState ancestorState = |
| *ancestorPaintProperties.localBorderBoxProperties(); |
| - const EffectPaintPropertyNode* effect = |
| - context.treeBuilderContext.currentEffect; |
| #ifdef CHECK_CLIP_RECTS |
| ShouldRespectOverflowClipType respectOverflowClip = RespectOverflowClip; |
| @@ -180,7 +185,9 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| context.ancestorTransformedOrRootPaintLayer->layoutObject().paintOffset(); |
| FloatClipRect clipRect; |
| - computeClipRectForContext(context.treeBuilderContext.current, effect, |
| + const EffectPaintPropertyNode* effect = |
| + context.treeBuilderContext->currentEffect; |
| + computeClipRectForContext(context.treeBuilderContext->current, effect, |
| ancestorState, ancestorPaintOffset, hasClip, |
| clipRect); |
| clipRects->setOverflowClipRect(clipRect); |
| @@ -190,7 +197,7 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| << "rect= " << clipRects->overflowClipRect().toString(); |
| #endif |
| - computeClipRectForContext(context.treeBuilderContext.fixedPosition, effect, |
| + computeClipRectForContext(context.treeBuilderContext->fixedPosition, effect, |
| ancestorState, ancestorPaintOffset, hasClip, |
| clipRect); |
| clipRects->setFixedClipRect(clipRect); |
| @@ -199,8 +206,8 @@ void PrePaintTreeWalk::invalidatePaintLayerOptimizationsIfNeeded( |
| << " fixed=" << clipRects->fixedClipRect().toString(); |
| #endif |
| - computeClipRectForContext(context.treeBuilderContext.absolutePosition, effect, |
| - ancestorState, ancestorPaintOffset, hasClip, |
| + computeClipRectForContext(context.treeBuilderContext->absolutePosition, |
| + effect, ancestorState, ancestorPaintOffset, hasClip, |
| clipRect); |
| clipRects->setPosClipRect(clipRect); |
| #ifdef CHECK_CLIP_RECTS |
| @@ -230,7 +237,7 @@ bool PrePaintTreeWalk::shouldEndWalkBefore( |
| return ( |
| !object.needsPaintPropertyUpdate() && |
| !object.descendantNeedsPaintPropertyUpdate() && |
| - !context.treeBuilderContext.forceSubtreeUpdate && |
| + !context.treeBuilderContext->forceSubtreeUpdate && |
| !context.paintInvalidatorContext.forcedSubtreeInvalidationFlags && |
| !object |
| .shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()); |
| @@ -241,24 +248,20 @@ void PrePaintTreeWalk::walk(const LayoutObject& object, |
| if (shouldEndWalkBefore(object, parentContext)) |
| return; |
| - // PrePaintTreeWalkContext is large and can lead to stack overflows when |
| - // recursion is deep so this context object is allocated on the heap. |
| - // See: https://crbug.com/698653. |
| - std::unique_ptr<PrePaintTreeWalkContext> context = |
| - WTF::wrapUnique(new PrePaintTreeWalkContext(parentContext)); |
| + PrePaintTreeWalkContext context(parentContext); |
| // This must happen before updatePropertiesForSelf, because the latter reads |
| // some of the state computed here. |
| - updateAuxiliaryObjectProperties(object, *context); |
| + updateAuxiliaryObjectProperties(object, context); |
| m_propertyTreeBuilder.updatePropertiesForSelf(object, |
| - context->treeBuilderContext); |
| + *context.treeBuilderContext); |
| m_paintInvalidator.invalidatePaintIfNeeded(object, |
| - context->paintInvalidatorContext); |
| + context.paintInvalidatorContext); |
| m_propertyTreeBuilder.updatePropertiesForChildren( |
| - object, context->treeBuilderContext); |
| + object, *context.treeBuilderContext); |
| - invalidatePaintLayerOptimizationsIfNeeded(object, *context); |
| + invalidatePaintLayerOptimizationsIfNeeded(object, context); |
| for (const LayoutObject* child = object.slowFirstChild(); child; |
| child = child->nextSibling()) { |
| @@ -266,19 +269,19 @@ void PrePaintTreeWalk::walk(const LayoutObject& object, |
| child->getMutableForPainting().clearPaintFlags(); |
| continue; |
| } |
| - walk(*child, *context); |
| + walk(*child, context); |
| } |
| if (object.isLayoutPart()) { |
| const LayoutPart& layoutPart = toLayoutPart(object); |
| FrameViewBase* frameViewBase = layoutPart.frameViewBase(); |
| if (frameViewBase && frameViewBase->isFrameView()) { |
| - context->treeBuilderContext.current.paintOffset += |
| + context.treeBuilderContext->current.paintOffset += |
| layoutPart.replacedContentRect().location() - |
| frameViewBase->frameRect().location(); |
| - context->treeBuilderContext.current.paintOffset = |
| - roundedIntPoint(context->treeBuilderContext.current.paintOffset); |
| - walk(*toFrameView(frameViewBase), *context); |
| + context.treeBuilderContext->current.paintOffset = |
| + roundedIntPoint(context.treeBuilderContext->current.paintOffset); |
| + walk(*toFrameView(frameViewBase), context); |
| } |
| // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| } |