| 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 fec8cba6013db4eae08b7764975ab388f8cd88b8..126c4eb81d8c5f83cfde9a2dba216fe31051feae 100644
|
| --- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
|
| @@ -54,6 +54,9 @@ struct PrePaintTreeWalkContext {
|
| // is the root layer. Note that it is tree ancestor, not containing
|
| // block or stacking ancestor.
|
| PaintLayer* ancestor_overflow_paint_layer;
|
| +
|
| + // The ancestor in the PaintLayer tree which has a transform or is a root
|
| + // layer for painting (i.e. a paint invalidation container).
|
| PaintLayer* ancestor_transformed_or_root_paint_layer;
|
| };
|
|
|
| @@ -123,7 +126,6 @@ static void UpdateAuxiliaryObjectProperties(const LayoutObject& object,
|
| // update layer position and ancestor inputs updates in the same walk).
|
| paint_layer->UpdateLayerPosition();
|
| }
|
| -
|
| if (paint_layer->IsRootLayer() || object.HasOverflowClip())
|
| context.ancestor_overflow_paint_layer = paint_layer;
|
| }
|
| @@ -166,14 +168,35 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| !paint_layer.GetLayoutObject().HasClipRelatedProperty())
|
| return;
|
|
|
| + FragmentData* fragment_data =
|
| + &object.GetMutableForPainting().EnsureFirstFragment();
|
| + for (auto& fragment : context.tree_builder_context->fragments) {
|
| + DCHECK(fragment_data);
|
| + if (InvalidatePaintLayerOptimizationsForFragment(
|
| + object, context.ancestor_transformed_or_root_paint_layer, fragment,
|
| + *fragment_data)) {
|
| + context.paint_invalidator_context.forced_subtree_invalidation_flags |=
|
| + PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
|
| + }
|
| + fragment_data = fragment_data->NextFragment();
|
| + }
|
| +}
|
| +
|
| +bool PrePaintTreeWalk::InvalidatePaintLayerOptimizationsForFragment(
|
| + const LayoutObject& object,
|
| + const PaintLayer* ancestor_transformed_or_root_paint_layer,
|
| + const PaintPropertyTreeBuilderFragmentContext& context,
|
| + FragmentData& fragment_data) {
|
| + PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer();
|
| +
|
| const auto& ancestor =
|
| - context.ancestor_transformed_or_root_paint_layer->GetLayoutObject();
|
| + ancestor_transformed_or_root_paint_layer->GetLayoutObject();
|
| PropertyTreeState ancestor_state = *ancestor.LocalBorderBoxProperties();
|
|
|
| #ifdef CHECK_CLIP_RECTS
|
| auto respect_overflow_clip = kRespectOverflowClip;
|
| #endif
|
| - if (context.ancestor_transformed_or_root_paint_layer->GetCompositingState() ==
|
| + if (ancestor_transformed_or_root_paint_layer->GetCompositingState() ==
|
| kPaintsIntoOwnBacking) {
|
| const auto* ancestor_properties = ancestor.PaintProperties();
|
| if (ancestor_properties && ancestor_properties->OverflowClip()) {
|
| @@ -187,20 +210,17 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| #ifdef CHECK_CLIP_RECTS
|
| const auto& old_clip_rects =
|
| paint_layer.Clipper(PaintLayer::kDoNotUseGeometryMapper)
|
| - .PaintingClipRects(context.ancestor_transformed_or_root_paint_layer,
|
| + .PaintingClipRects(ancestor_transformed_or_root_paint_layer,
|
| respect_overflow_clip, LayoutSize());
|
| #endif
|
|
|
| const LayoutPoint& ancestor_paint_offset =
|
| - context.ancestor_transformed_or_root_paint_layer->GetLayoutObject()
|
| - .PaintOffset();
|
| + ancestor_transformed_or_root_paint_layer->GetLayoutObject().PaintOffset();
|
|
|
| // TODO(chrishtr): generalize this for multicol.
|
| - const auto* effect =
|
| - context.tree_builder_context->fragments[0].current_effect;
|
| + const auto* effect = context.current_effect;
|
| auto overflow_clip_rect = ComputeClipRectForContext(
|
| - context.tree_builder_context->fragments[0].current, effect,
|
| - ancestor_state, ancestor_paint_offset);
|
| + context.current, effect, ancestor_state, ancestor_paint_offset);
|
| #ifdef CHECK_CLIP_RECTS
|
| CHECK(overflow_clip_rect == old_clip_rects.OverflowClipRect().Rect())
|
| << " new=" << overflow_clip_rect.ToString()
|
| @@ -208,8 +228,7 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| #endif
|
|
|
| auto fixed_clip_rect = ComputeClipRectForContext(
|
| - context.tree_builder_context->fragments[0].fixed_position, effect,
|
| - ancestor_state, ancestor_paint_offset);
|
| + context.fixed_position, effect, ancestor_state, ancestor_paint_offset);
|
| #ifdef CHECK_CLIP_RECTS
|
| CHECK(fixed_clip_rect == old_clip_rects.FixedClipRect().Rect())
|
| << " new=" << fixed_clip_rect.ToString()
|
| @@ -217,15 +236,14 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| #endif
|
|
|
| auto pos_clip_rect = ComputeClipRectForContext(
|
| - context.tree_builder_context->fragments[0].absolute_position, effect,
|
| - ancestor_state, ancestor_paint_offset);
|
| + context.absolute_position, effect, ancestor_state, ancestor_paint_offset);
|
| #ifdef CHECK_CLIP_RECTS
|
| CHECK(pos_clip_rect == old_clip_rects.PosClipRect().Rect())
|
| << " new=" << pos_clip_rect.ToString()
|
| << " old=" << old_clip_rects.PosClipRect().Rect().ToString();
|
| #endif
|
|
|
| - const auto* previous_clip_rects = paint_layer.PreviousPaintingClipRects();
|
| + const auto* previous_clip_rects = fragment_data.PreviousClipRects();
|
| if (!previous_clip_rects ||
|
| overflow_clip_rect != previous_clip_rects->OverflowClipRect().Rect() ||
|
| fixed_clip_rect != previous_clip_rects->FixedClipRect().Rect() ||
|
| @@ -234,7 +252,7 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| clip_rects->SetOverflowClipRect(overflow_clip_rect);
|
| clip_rects->SetFixedClipRect(fixed_clip_rect);
|
| clip_rects->SetPosClipRect(pos_clip_rect);
|
| - paint_layer.SetPreviousPaintingClipRects(*clip_rects);
|
| + fragment_data.SetPreviousClipRects(*clip_rects);
|
|
|
| paint_layer.SetNeedsRepaint();
|
| paint_layer.SetPreviousPaintPhaseDescendantOutlinesEmpty(false);
|
| @@ -242,9 +260,9 @@ void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
|
| paint_layer.SetPreviousPaintPhaseDescendantBlockBackgroundsEmpty(false);
|
| // All subsequences which are contained below this paintLayer must also
|
| // be checked.
|
| - context.paint_invalidator_context.forced_subtree_invalidation_flags |=
|
| - PaintInvalidatorContext::kForcedSubtreeVisualRectUpdate;
|
| + return true;
|
| }
|
| + return false;
|
| }
|
|
|
| bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
|
| @@ -267,6 +285,11 @@ bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
|
| parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object);
|
| }
|
|
|
| +void PrePaintTreeWalk::ClearPreviousClipRectsForTesting(
|
| + const LayoutObject& object) {
|
| + object.GetMutableForPainting().FirstFragment()->ClearPreviousClipRects();
|
| +}
|
| +
|
| void PrePaintTreeWalk::Walk(const LayoutObject& object,
|
| const PrePaintTreeWalkContext& parent_context) {
|
| // Early out from the tree walk if possible.
|
|
|