| 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 99a5ed9e309dd1977f3d5371cc93dafcb64fb835..4fb19f34802e61899841b8a98a6f5d73be080637 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
|
| @@ -27,11 +27,10 @@
|
|
|
| namespace blink {
|
|
|
| -PaintPropertyTreeBuilderContext::PaintPropertyTreeBuilderContext()
|
| - : container_for_absolute_position(nullptr),
|
| - current_effect(EffectPaintPropertyNode::Root()),
|
| - input_clip_of_current_effect(ClipPaintPropertyNode::Root()),
|
| - force_subtree_update(false) {
|
| +PaintPropertyTreeBuilderFragmentContext::
|
| + PaintPropertyTreeBuilderFragmentContext()
|
| + : current_effect(EffectPaintPropertyNode::Root()),
|
| + input_clip_of_current_effect(ClipPaintPropertyNode::Root()) {
|
| current.clip = absolute_position.clip = fixed_position.clip =
|
| ClipPaintPropertyNode::Root();
|
| current.transform = absolute_position.transform = fixed_position.transform =
|
| @@ -130,7 +129,11 @@ static MainThreadScrollingReasons GetMainThreadScrollingReasons(
|
|
|
| void PaintPropertyTreeBuilder::UpdateProperties(
|
| FrameView& frame_view,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderContext& full_context) {
|
| + if (full_context.fragments.IsEmpty())
|
| + full_context.fragments.push_back(PaintPropertyTreeBuilderFragmentContext());
|
| +
|
| + PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0];
|
| if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
|
| // With root layer scrolling, the LayoutView (a LayoutObject) properties are
|
| // updated like other objects (see updatePropertiesAndContextForSelf and
|
| @@ -140,26 +143,28 @@ void PaintPropertyTreeBuilder::UpdateProperties(
|
| context.current.rendering_context_id = 0;
|
| context.current.should_flatten_inherited_transform = true;
|
| context.absolute_position = context.current;
|
| - context.container_for_absolute_position = nullptr;
|
| + full_context.container_for_absolute_position = nullptr;
|
| context.fixed_position = context.current;
|
| return;
|
| }
|
|
|
| #if DCHECK_IS_ON()
|
| - FindFrameViewPropertiesNeedingUpdateScope check_scope(&frame_view, context);
|
| + FindFrameViewPropertiesNeedingUpdateScope check_scope(
|
| + &frame_view, full_context.is_actually_needed);
|
| #endif
|
|
|
| - if (frame_view.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (frame_view.NeedsPaintPropertyUpdate() ||
|
| + full_context.force_subtree_update) {
|
| TransformationMatrix frame_translate;
|
| frame_translate.Translate(
|
| frame_view.X() + context.current.paint_offset.X(),
|
| frame_view.Y() + context.current.paint_offset.Y());
|
| - context.force_subtree_update |= UpdatePreTranslation(
|
| + full_context.force_subtree_update |= UpdatePreTranslation(
|
| frame_view, context.current.transform, frame_translate, FloatPoint3D());
|
|
|
| FloatRoundedRect content_clip(
|
| IntRect(IntPoint(), frame_view.VisibleContentSize()));
|
| - context.force_subtree_update |=
|
| + full_context.force_subtree_update |=
|
| UpdateContentClip(frame_view, context.current.clip,
|
| frame_view.PreTranslation(), content_clip);
|
|
|
| @@ -180,7 +185,7 @@ void PaintPropertyTreeBuilder::UpdateProperties(
|
| auto reasons =
|
| GetMainThreadScrollingReasons(frame_view, ancestor_reasons);
|
|
|
| - context.force_subtree_update |= UpdateScrollTranslation(
|
| + full_context.force_subtree_update |= UpdateScrollTranslation(
|
| frame_view, frame_view.PreTranslation(), frame_scroll, FloatPoint3D(),
|
| context.current.scroll, scroll_clip, scroll_bounds,
|
| user_scrollable_horizontal, user_scrollable_vertical, reasons,
|
| @@ -190,7 +195,7 @@ void PaintPropertyTreeBuilder::UpdateProperties(
|
| // Ensure pre-existing properties are cleared if there is no scrolling.
|
| frame_view.SetScrollTranslation(nullptr);
|
| // Rebuild all descendant properties because a property was removed.
|
| - context.force_subtree_update = true;
|
| + full_context.force_subtree_update = true;
|
| }
|
| }
|
| }
|
| @@ -214,7 +219,7 @@ void PaintPropertyTreeBuilder::UpdateProperties(
|
| context.current.rendering_context_id = 0;
|
| context.current.should_flatten_inherited_transform = true;
|
| context.absolute_position = context.current;
|
| - context.container_for_absolute_position = nullptr;
|
| + full_context.container_for_absolute_position = nullptr;
|
| context.fixed_position = context.current;
|
| context.fixed_position.transform = fixed_transform_node;
|
| context.fixed_position.scroll = fixed_scroll_node;
|
| @@ -243,7 +248,8 @@ static bool NeedsPaintOffsetTranslation(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
|
| const LayoutBoxModelObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| if (NeedsPaintOffsetTranslation(object) &&
|
| // As an optimization, skip these paint offset translation nodes when
|
| // the offset is an identity. An exception is the layout view because root
|
| @@ -264,7 +270,7 @@ void PaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
|
| LayoutPoint fractional_paint_offset =
|
| LayoutPoint(context.current.paint_offset - rounded_paint_offset);
|
|
|
| - context.force_subtree_update |= properties.UpdatePaintOffsetTranslation(
|
| + force_subtree_update |= properties.UpdatePaintOffsetTranslation(
|
| context.current.transform,
|
| TransformationMatrix().Translate(rounded_paint_offset.X(),
|
| rounded_paint_offset.Y()),
|
| @@ -282,7 +288,7 @@ void PaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
|
| }
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearPaintOffsetTranslation();
|
| + force_subtree_update |= properties->ClearPaintOffsetTranslation();
|
| }
|
| }
|
|
|
| @@ -299,24 +305,25 @@ static bool NeedsTransformForNonRootSVG(const LayoutObject& object) {
|
| // creating a transform node for SVG-specific transforms without 3D.
|
| void PaintPropertyTreeBuilder::UpdateTransformForNonRootSVG(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| DCHECK(object.IsSVGChild());
|
| // SVG does not use paint offset internally, except for SVGForeignObject which
|
| // has different SVG and HTML coordinate spaces.
|
| DCHECK(object.IsSVGForeignObject() ||
|
| context.current.paint_offset == LayoutPoint());
|
|
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| AffineTransform transform = object.LocalToSVGParentTransform();
|
| if (NeedsTransformForNonRootSVG(object)) {
|
| // The origin is included in the local transform, so leave origin empty.
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdateTransform(
|
| + force_subtree_update |= properties.UpdateTransform(
|
| context.current.transform, TransformationMatrix(transform),
|
| FloatPoint3D());
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearTransform();
|
| + force_subtree_update |= properties->ClearTransform();
|
| }
|
| }
|
|
|
| @@ -372,13 +379,14 @@ static bool NeedsTransform(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateTransform(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| if (object.IsSVGChild()) {
|
| - UpdateTransformForNonRootSVG(object, context);
|
| + UpdateTransformForNonRootSVG(object, context, force_subtree_update);
|
| return;
|
| }
|
|
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| const ComputedStyle& style = object.StyleRef();
|
|
|
| // A transform node is allocated for transforms, preserves-3d and any
|
| @@ -411,13 +419,13 @@ void PaintPropertyTreeBuilder::UpdateTransform(
|
| : CompositorElementId();
|
|
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdateTransform(
|
| + force_subtree_update |= properties.UpdateTransform(
|
| context.current.transform, matrix, TransformOrigin(box),
|
| context.current.should_flatten_inherited_transform,
|
| rendering_context_id, compositing_reasons, compositor_element_id);
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearTransform();
|
| + force_subtree_update |= properties->ClearTransform();
|
| }
|
| }
|
|
|
| @@ -529,11 +537,12 @@ static bool NeedsEffect(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateEffect(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| const ComputedStyle& style = object.StyleRef();
|
|
|
| // TODO(trchen): Can't omit effect node if we have 3D children.
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| const ClipPaintPropertyNode* output_clip =
|
| context.input_clip_of_current_effect;
|
|
|
| @@ -554,7 +563,7 @@ void PaintPropertyTreeBuilder::UpdateEffect(
|
| bool has_mask = ComputeMaskParameters(
|
| mask_clip, mask_color_filter, object, context.current.paint_offset);
|
| if (has_mask) {
|
| - context.force_subtree_update |= properties.UpdateMaskClip(
|
| + force_subtree_update |= properties.UpdateMaskClip(
|
| context.current.clip, context.current.transform,
|
| FloatRoundedRect(mask_clip));
|
| output_clip = properties.MaskClip();
|
| @@ -565,7 +574,7 @@ void PaintPropertyTreeBuilder::UpdateEffect(
|
| compositing_reasons |= kCompositingReasonIsolateCompositedDescendants;
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearMaskClip();
|
| + force_subtree_update |= properties->ClearMaskClip();
|
| }
|
|
|
| SkBlendMode blend_mode =
|
| @@ -582,7 +591,7 @@ void PaintPropertyTreeBuilder::UpdateEffect(
|
| DCHECK(!style.HasCurrentOpacityAnimation() ||
|
| compositing_reasons != kCompositingReasonNone);
|
|
|
| - context.force_subtree_update |= properties.UpdateEffect(
|
| + force_subtree_update |= properties.UpdateEffect(
|
| context.current_effect, context.current.transform, output_clip,
|
| kColorFilterNone, CompositorFilterOperations(), style.Opacity(),
|
| blend_mode, compositing_reasons, compositor_element_id);
|
| @@ -592,19 +601,19 @@ void PaintPropertyTreeBuilder::UpdateEffect(
|
| // yet. Adding CompositingReasonSquashingDisallowed forces mask not
|
| // getting squashed into a child effect. Have no compositing reason
|
| // otherwise.
|
| - context.force_subtree_update |= properties.UpdateMask(
|
| + force_subtree_update |= properties.UpdateMask(
|
| properties.Effect(), context.current.transform, output_clip,
|
| mask_color_filter, CompositorFilterOperations(), 1.f,
|
| SkBlendMode::kDstIn, kCompositingReasonSquashingDisallowed,
|
| CompositorElementId());
|
| } else {
|
| - context.force_subtree_update |= properties.ClearMask();
|
| + force_subtree_update |= properties.ClearMask();
|
| }
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties()) {
|
| - context.force_subtree_update |= properties->ClearEffect();
|
| - context.force_subtree_update |= properties->ClearMask();
|
| - context.force_subtree_update |= properties->ClearMaskClip();
|
| + force_subtree_update |= properties->ClearEffect();
|
| + force_subtree_update |= properties->ClearMask();
|
| + force_subtree_update |= properties->ClearMaskClip();
|
| }
|
| }
|
| }
|
| @@ -628,10 +637,11 @@ static bool NeedsFilter(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateFilter(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| const ComputedStyle& style = object.StyleRef();
|
|
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (NeedsFilter(object)) {
|
| CompositorFilterOperations filter =
|
| ToLayoutBoxModelObject(object)
|
| @@ -677,13 +687,13 @@ void PaintPropertyTreeBuilder::UpdateFilter(
|
| compositing_reasons != kCompositingReasonNone);
|
|
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdateFilter(
|
| + force_subtree_update |= properties.UpdateFilter(
|
| context.current_effect, context.current.transform, output_clip,
|
| kColorFilterNone, std::move(filter), 1.f, SkBlendMode::kSrcOver,
|
| compositing_reasons, compositor_element_id);
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearFilter();
|
| + force_subtree_update |= properties->ClearFilter();
|
| }
|
| }
|
|
|
| @@ -705,8 +715,9 @@ static bool NeedsCssClip(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateCssClip(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (NeedsCssClip(object)) {
|
| // Create clip node for descendants that are not fixed position.
|
| // We don't have to setup context.absolutePosition.clip here because this
|
| @@ -716,12 +727,12 @@ void PaintPropertyTreeBuilder::UpdateCssClip(
|
| LayoutRect clip_rect =
|
| ToLayoutBox(object).ClipRect(context.current.paint_offset);
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdateCssClip(
|
| + force_subtree_update |= properties.UpdateCssClip(
|
| context.current.clip, context.current.transform,
|
| FloatRoundedRect(FloatRect(clip_rect)));
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearCssClip();
|
| + force_subtree_update |= properties->ClearCssClip();
|
| }
|
| }
|
|
|
| @@ -732,8 +743,9 @@ void PaintPropertyTreeBuilder::UpdateCssClip(
|
|
|
| void PaintPropertyTreeBuilder::UpdateLocalBorderBoxContext(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (!object.NeedsPaintPropertyUpdate() && !context.force_subtree_update)
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (!object.NeedsPaintPropertyUpdate() && !force_subtree_update)
|
| return;
|
|
|
| // We only need to cache the local border box properties for layered objects.
|
| @@ -761,8 +773,9 @@ static bool NeedsScrollbarPaintOffset(const LayoutObject& object) {
|
| // TODO(trchen): Remove this once we bake the paint offset into frameRect.
|
| void PaintPropertyTreeBuilder::UpdateScrollbarPaintOffset(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (!object.NeedsPaintPropertyUpdate() && !context.force_subtree_update)
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (!object.NeedsPaintPropertyUpdate() && !force_subtree_update)
|
| return;
|
|
|
| if (NeedsScrollbarPaintOffset(object)) {
|
| @@ -771,11 +784,11 @@ void PaintPropertyTreeBuilder::UpdateScrollbarPaintOffset(
|
| auto paint_offset = TransformationMatrix().Translate(
|
| rounded_paint_offset.X(), rounded_paint_offset.Y());
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdateScrollbarPaintOffset(
|
| + force_subtree_update |= properties.UpdateScrollbarPaintOffset(
|
| context.current.transform, paint_offset, FloatPoint3D());
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearScrollbarPaintOffset();
|
| + force_subtree_update |= properties->ClearScrollbarPaintOffset();
|
| }
|
| }
|
|
|
| @@ -785,8 +798,9 @@ static bool NeedsOverflowScroll(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateOverflowClip(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (NeedsOverflowScroll(object)) {
|
| const LayoutBox& box = ToLayoutBox(object);
|
| LayoutRect clip_rect;
|
| @@ -798,21 +812,20 @@ void PaintPropertyTreeBuilder::UpdateOverflowClip(
|
| if (box.StyleRef().HasBorderRadius()) {
|
| auto inner_border = box.StyleRef().GetRoundedInnerBorderFor(
|
| LayoutRect(context.current.paint_offset, box.Size()));
|
| - context.force_subtree_update |= properties.UpdateInnerBorderRadiusClip(
|
| + force_subtree_update |= properties.UpdateInnerBorderRadiusClip(
|
| context.current.clip, context.current.transform, inner_border);
|
| current_clip = properties.InnerBorderRadiusClip();
|
| } else {
|
| - context.force_subtree_update |= properties.ClearInnerBorderRadiusClip();
|
| + force_subtree_update |= properties.ClearInnerBorderRadiusClip();
|
| }
|
|
|
| - context.force_subtree_update |=
|
| + force_subtree_update |=
|
| properties.UpdateOverflowClip(current_clip, context.current.transform,
|
| FloatRoundedRect(FloatRect(clip_rect)));
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties()) {
|
| - context.force_subtree_update |=
|
| - properties->ClearInnerBorderRadiusClip();
|
| - context.force_subtree_update |= properties->ClearOverflowClip();
|
| + force_subtree_update |= properties->ClearInnerBorderRadiusClip();
|
| + force_subtree_update |= properties->ClearOverflowClip();
|
| }
|
| return;
|
| }
|
| @@ -840,8 +853,9 @@ static bool NeedsPerspective(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdatePerspective(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (NeedsPerspective(object)) {
|
| const ComputedStyle& style = object.StyleRef();
|
| // The perspective node must not flatten (else nothing will get
|
| @@ -852,13 +866,13 @@ void PaintPropertyTreeBuilder::UpdatePerspective(
|
| FloatPoint3D origin = PerspectiveOrigin(ToLayoutBox(object)) +
|
| ToLayoutSize(context.current.paint_offset);
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |= properties.UpdatePerspective(
|
| + force_subtree_update |= properties.UpdatePerspective(
|
| context.current.transform, matrix, origin,
|
| context.current.should_flatten_inherited_transform,
|
| context.current.rendering_context_id);
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearPerspective();
|
| + force_subtree_update |= properties->ClearPerspective();
|
| }
|
| }
|
|
|
| @@ -875,25 +889,23 @@ static bool NeedsSVGLocalToBorderBoxTransform(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateSvgLocalToBorderBoxTransform(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| if (!object.IsSVGRoot())
|
| return;
|
|
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| AffineTransform transform_to_border_box =
|
| SVGRootPainter(ToLayoutSVGRoot(object))
|
| .TransformToPixelSnappedBorderBox(context.current.paint_offset);
|
| if (!transform_to_border_box.IsIdentity() &&
|
| NeedsSVGLocalToBorderBoxTransform(object)) {
|
| auto& properties = *object.GetMutableForPainting().PaintProperties();
|
| - context.force_subtree_update |=
|
| - properties.UpdateSvgLocalToBorderBoxTransform(
|
| - context.current.transform, transform_to_border_box,
|
| - FloatPoint3D());
|
| + force_subtree_update |= properties.UpdateSvgLocalToBorderBoxTransform(
|
| + context.current.transform, transform_to_border_box, FloatPoint3D());
|
| } else {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties()) {
|
| - context.force_subtree_update |=
|
| - properties->ClearSvgLocalToBorderBoxTransform();
|
| + force_subtree_update |= properties->ClearSvgLocalToBorderBoxTransform();
|
| }
|
| }
|
| }
|
| @@ -935,8 +947,9 @@ static bool NeedsScrollTranslation(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (NeedsScrollTranslation(object)) {
|
| const LayoutBox& box = ToLayoutBox(object);
|
| auto* scrollable_area = box.GetScrollableArea();
|
| @@ -959,14 +972,14 @@ void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation(
|
| if (auto* existing_scroll_translation = properties.ScrollTranslation()) {
|
| auto* existing_scroll_node = existing_scroll_translation->ScrollNode();
|
| if (existing_scroll_node->GetMainThreadScrollingReasons() != reasons)
|
| - context.force_subtree_update = true;
|
| + force_subtree_update = true;
|
| }
|
|
|
| CompositorElementId compositor_element_id =
|
| CreateDomNodeBasedCompositorElementId(object);
|
| TransformationMatrix matrix = TransformationMatrix().Translate(
|
| -scroll_offset.Width(), -scroll_offset.Height());
|
| - context.force_subtree_update |= properties.UpdateScrollTranslation(
|
| + force_subtree_update |= properties.UpdateScrollTranslation(
|
| context.current.transform, matrix, FloatPoint3D(),
|
| context.current.should_flatten_inherited_transform,
|
| context.current.rendering_context_id, kCompositingReasonNone,
|
| @@ -976,7 +989,7 @@ void PaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation(
|
| } else {
|
| // Ensure pre-existing properties are cleared.
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearScrollTranslation();
|
| + force_subtree_update |= properties->ClearScrollTranslation();
|
| }
|
| }
|
|
|
| @@ -995,14 +1008,13 @@ static bool NeedsCssClipFixedPosition(const LayoutObject& object) {
|
|
|
| void PaintPropertyTreeBuilder::UpdateOutOfFlowContext(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| if (object.IsLayoutBlock())
|
| context.paint_offset_for_float = context.current.paint_offset;
|
|
|
| - if (object.CanContainAbsolutePositionObjects()) {
|
| + if (object.CanContainAbsolutePositionObjects())
|
| context.absolute_position = context.current;
|
| - context.container_for_absolute_position = &object;
|
| - }
|
|
|
| if (object.IsLayoutView()) {
|
| if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
|
| @@ -1033,8 +1045,8 @@ void PaintPropertyTreeBuilder::UpdateOutOfFlowContext(
|
| if (context.fixed_position.clip == css_clip->Parent()) {
|
| context.fixed_position.clip = css_clip;
|
| } else {
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| - context.force_subtree_update |= properties.UpdateCssClipFixedPosition(
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| + force_subtree_update |= properties.UpdateCssClipFixedPosition(
|
| context.fixed_position.clip,
|
| const_cast<TransformPaintPropertyNode*>(
|
| css_clip->LocalTransformSpace()),
|
| @@ -1046,15 +1058,16 @@ void PaintPropertyTreeBuilder::UpdateOutOfFlowContext(
|
| }
|
| }
|
|
|
| - if (object.NeedsPaintPropertyUpdate() || context.force_subtree_update) {
|
| + if (object.NeedsPaintPropertyUpdate() || force_subtree_update) {
|
| if (auto* properties = object.GetMutableForPainting().PaintProperties())
|
| - context.force_subtree_update |= properties->ClearCssClipFixedPosition();
|
| + force_subtree_update |= properties->ClearCssClipFixedPosition();
|
| }
|
| }
|
|
|
| void PaintPropertyTreeBuilder::UpdatePaintOffset(
|
| const LayoutBoxModelObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + const LayoutObject* container_for_absolute_position) {
|
| if (object.IsFloating())
|
| context.current.paint_offset = context.paint_offset_for_float;
|
|
|
| @@ -1070,12 +1083,12 @@ void PaintPropertyTreeBuilder::UpdatePaintOffset(
|
| context.current.paint_offset += object.OffsetForInFlowPosition();
|
| break;
|
| case EPosition::kAbsolute: {
|
| - DCHECK(context.container_for_absolute_position == object.Container());
|
| + DCHECK(container_for_absolute_position == object.Container());
|
| context.current = context.absolute_position;
|
|
|
| // Absolutely positioned content in an inline should be positioned
|
| // relative to the inline.
|
| - const LayoutObject* container = context.container_for_absolute_position;
|
| + const LayoutObject* container = container_for_absolute_position;
|
| if (container && container->IsInFlowPositioned() &&
|
| container->IsLayoutInline()) {
|
| DCHECK(object.IsBox());
|
| @@ -1099,7 +1112,7 @@ void PaintPropertyTreeBuilder::UpdatePaintOffset(
|
| // TODO(pdr): Several calls in this function walk back up the tree to
|
| // calculate containers (e.g., physicalLocation, offsetForInFlowPosition*).
|
| // The containing block and other containers can be stored on
|
| - // PaintPropertyTreeBuilderContext instead of recomputing them.
|
| + // PaintPropertyTreeBuilderFragmentContext instead of recomputing them.
|
| context.current.paint_offset.MoveBy(ToLayoutBox(object).PhysicalLocation());
|
| // This is a weird quirk that table cells paint as children of table rows,
|
| // but their location have the row's location baked-in.
|
| @@ -1115,20 +1128,25 @@ void PaintPropertyTreeBuilder::UpdatePaintOffset(
|
|
|
| void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + const LayoutObject* container_for_absolute_position,
|
| + bool& is_actually_needed,
|
| + PaintPropertyTreeBuilderFragmentContext& context,
|
| + bool& force_subtree_update) {
|
| #if DCHECK_IS_ON()
|
| - FindPaintOffsetNeedingUpdateScope check_scope(object, context);
|
| + FindPaintOffsetNeedingUpdateScope check_scope(object, is_actually_needed);
|
| #endif
|
|
|
| if (object.IsBoxModelObject()) {
|
| - UpdatePaintOffset(ToLayoutBoxModelObject(object), context);
|
| - UpdatePaintOffsetTranslation(ToLayoutBoxModelObject(object), context);
|
| + UpdatePaintOffset(ToLayoutBoxModelObject(object), context,
|
| + container_for_absolute_position);
|
| + UpdatePaintOffsetTranslation(ToLayoutBoxModelObject(object), context,
|
| + force_subtree_update);
|
| }
|
|
|
| if (object.PaintOffset() != context.current.paint_offset) {
|
| // Many paint properties depend on paint offset so we force an update of
|
| // the entire subtree on paint offset changes.
|
| - context.force_subtree_update = true;
|
| + force_subtree_update = true;
|
|
|
| if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| object.GetMutableForPainting().SetShouldDoFullPaintInvalidation(
|
| @@ -1164,9 +1182,9 @@ void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
|
| box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
|
| }
|
|
|
| -void PaintPropertyTreeBuilder::UpdatePaintProperties(
|
| +void PaintPropertyTreeBuilder::CollectFragments(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderContext& full_context) {
|
| bool needs_paint_properties =
|
| NeedsPaintOffsetTranslation(object) || NeedsTransform(object) ||
|
| NeedsEffect(object) || NeedsTransformForNonRootSVG(object) ||
|
| @@ -1182,62 +1200,80 @@ void PaintPropertyTreeBuilder::UpdatePaintProperties(
|
| } else {
|
| object.GetMutableForPainting().ClearPaintProperties();
|
| if (had_paint_properties)
|
| - context.force_subtree_update = true;
|
| + full_context.force_subtree_update = true;
|
| }
|
| }
|
|
|
| void PaintPropertyTreeBuilder::UpdatePropertiesForSelf(
|
| const LayoutObject& object,
|
| - PaintPropertyTreeBuilderContext& context) {
|
| + PaintPropertyTreeBuilderContext& full_context) {
|
| + PaintPropertyTreeBuilderFragmentContext& context = full_context.fragments[0];
|
| if (object.IsSVGHiddenContainer()) {
|
| // SVG resources are painted within one or more other locations in the
|
| // SVG during paint, and hence have their own independent paint property
|
| // trees, paint offset, etc.
|
| - context = PaintPropertyTreeBuilderContext();
|
| + context = PaintPropertyTreeBuilderFragmentContext();
|
| }
|
|
|
| - UpdatePaintProperties(object, context);
|
| + CollectFragments(object, full_context);
|
| +
|
| + bool is_actually_needed = false;
|
| +#if DCHECK_IS_ON()
|
| + is_actually_needed = full_context.is_actually_needed;
|
| +#endif
|
|
|
| // This is not in FindObjectPropertiesNeedingUpdateScope because paint offset
|
| // can change without needsPaintPropertyUpdate.
|
| - UpdateForObjectLocationAndSize(object, context);
|
| + UpdateForObjectLocationAndSize(
|
| + object, full_context.container_for_absolute_position, is_actually_needed,
|
| + context, full_context.force_subtree_update);
|
|
|
| #if DCHECK_IS_ON()
|
| - FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(object,
|
| - context);
|
| + FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(
|
| + object, full_context.force_subtree_update);
|
| #endif
|
|
|
| if (object.IsBoxModelObject() || object.IsSVG()) {
|
| - UpdateTransform(object, context);
|
| - UpdateCssClip(object, context);
|
| + UpdateTransform(object, context, full_context.force_subtree_update);
|
| + UpdateCssClip(object, context, full_context.force_subtree_update);
|
| + if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| + UpdateEffect(object, context, full_context.force_subtree_update);
|
| + UpdateFilter(object, context, full_context.force_subtree_update);
|
| + }
|
| + UpdateLocalBorderBoxContext(object, context,
|
| + full_context.force_subtree_update);
|
| if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
|
| - UpdateEffect(object, context);
|
| - UpdateFilter(object, context);
|
| + UpdateScrollbarPaintOffset(object, context,
|
| + full_context.force_subtree_update);
|
| }
|
| - UpdateLocalBorderBoxContext(object, context);
|
| - if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
|
| - UpdateScrollbarPaintOffset(object, context);
|
| }
|
| }
|
|
|
| void PaintPropertyTreeBuilder::UpdatePropertiesForChildren(
|
| const LayoutObject& object,
|
| PaintPropertyTreeBuilderContext& context) {
|
| -#if DCHECK_IS_ON()
|
| - FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(object,
|
| - context);
|
| -#endif
|
| -
|
| if (!object.IsBoxModelObject() && !object.IsSVG())
|
| return;
|
|
|
| - UpdateOverflowClip(object, context);
|
| - UpdatePerspective(object, context);
|
| - UpdateSvgLocalToBorderBoxTransform(object, context);
|
| - UpdateScrollAndScrollTranslation(object, context);
|
| - UpdateOutOfFlowContext(object, context);
|
| + for (auto& fragment_context : context.fragments) {
|
| +#if DCHECK_IS_ON()
|
| + FindObjectPropertiesNeedingUpdateScope check_needs_update_scope(
|
| + object, context.force_subtree_update);
|
| +#endif
|
| + UpdateOverflowClip(object, fragment_context, context.force_subtree_update);
|
| + UpdatePerspective(object, fragment_context, context.force_subtree_update);
|
| + UpdateSvgLocalToBorderBoxTransform(object, fragment_context,
|
| + context.force_subtree_update);
|
| + UpdateScrollAndScrollTranslation(object, fragment_context,
|
| + context.force_subtree_update);
|
| + UpdateOutOfFlowContext(object, fragment_context,
|
| + context.force_subtree_update);
|
| +
|
| + context.force_subtree_update |= object.SubtreeNeedsPaintPropertyUpdate();
|
| + }
|
|
|
| - context.force_subtree_update |= object.SubtreeNeedsPaintPropertyUpdate();
|
| + if (object.CanContainAbsolutePositionObjects())
|
| + context.container_for_absolute_position = &object;
|
| }
|
|
|
| } // namespace blink
|
|
|