Commit 0e88551c authored by Philip Rogers's avatar Philip Rogers Committed by Commit Bot

Make style & layout containment create a clip-related property

As of https://crrev.com/619964, style & layout containment creates
an isolation boundary which means clip-related subtree updates can be
skipped. PaintLayer::ClippingContainer is used for the clip property
tree state of a squashing layer. This clipping container could be an
ancestor of a style & layout isolation boundary. If a clip changed on
a clipping container ancestor of an isolation boundary, the clip node of
squashing layers below could become stale. This patch ensures
PaintLayer::ClippingContainer stops at style & layout containment
boundaries by making style & layout containment a clip-related property.

Bug: 1044895
Change-Id: I898df21c0f65f79114564938042356b7ef587c19
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2025313
Commit-Queue: Philip Rogers <pdr@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736142}
parent 725d26f6
...@@ -1515,6 +1515,7 @@ TEST_F(DisplayLockContextTest, ...@@ -1515,6 +1515,7 @@ TEST_F(DisplayLockContextTest,
width: 100px; width: 100px;
height: 100px; height: 100px;
contain: style layout; contain: style layout;
will-change: transform;
} }
#composited { #composited {
will-change: transform; will-change: transform;
......
...@@ -470,20 +470,26 @@ LayoutObject* LayoutObject::NextInPreOrder() const { ...@@ -470,20 +470,26 @@ LayoutObject* LayoutObject::NextInPreOrder() const {
} }
bool LayoutObject::HasClipRelatedProperty() const { bool LayoutObject::HasClipRelatedProperty() const {
// TODO(trchen): Refactor / remove this function.
// This function detects a bunch of properties that can potentially affect // This function detects a bunch of properties that can potentially affect
// clip inheritance chain. However such generalization is practially useless // clip inheritance chain. However such generalization is practically useless
// because these properties change clip inheritance in different way that // because these properties change clip inheritance in different way that
// needs to be handled explicitly. // needs to be handled explicitly.
// CSS clip applies clip to the current element and all descendants. // CSS clip applies clip to the current element and all descendants.
// CSS overflow clip applies only to containg-block descendants. // CSS overflow clip applies only to containing-block descendants.
// CSS contain:paint applies to all descendants by making itself a containing // CSS contain:paint applies to all descendants by making itself a containing
// block for all descendants. // block for all descendants.
// CSS clip-path/mask/filter induces a stacking context and applies inherited // CSS clip-path/mask/filter induces a stacking context and applies inherited
// clip to that stacking context, while resetting clip for descendants. This // clip to that stacking context, while resetting clip for descendants. This
// special behavior is already handled elsewhere. // special behavior is already handled elsewhere.
if (HasClip() || HasOverflowClip() || ShouldApplyPaintContainment()) if (HasClip() || HasOverflowClip())
return true; return true;
// Paint containment establishes isolation which creates clip isolation nodes.
// Style & Layout containment also establish isolation (see
// |NeedsIsolationNodes| in PaintPropertyTreeBuilder).
if (ShouldApplyPaintContainment() ||
(ShouldApplyStyleContainment() && ShouldApplyLayoutContainment())) {
return true;
}
if (IsBox() && ToLayoutBox(this)->HasControlClip()) if (IsBox() && ToLayoutBox(this)->HasControlClip())
return true; return true;
return false; return false;
......
...@@ -1803,4 +1803,52 @@ TEST_F(CompositedLayerMappingTest, ...@@ -1803,4 +1803,52 @@ TEST_F(CompositedLayerMappingTest,
EXPECT_TRUE(mapping->NeedsRepaint(*vertical_scrollbar_layer)); EXPECT_TRUE(mapping->NeedsRepaint(*vertical_scrollbar_layer));
} }
TEST_F(CompositedLayerMappingTest, IsolationClippingContainer) {
SetBodyInnerHTML(R"HTML(
<style>
#hideable {
overflow: hidden;
height: 10px;
}
.isolation {
contain: style layout;
height: 100px;
}
.squash-container {
will-change: transform;
}
.squashed {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
}
</style>
<div id="hideable">
<div class="isolation" id="isolation_a">
<div class="squash-container" id="squash_container_a">a</div>
<div class="squashed"></div>
</div>
<div class="isolation">
<div class="squash-container">b</div>
<div class="squashed"></div>
</div>
</div>
)HTML");
Element* hideable = GetDocument().getElementById("hideable");
hideable->SetInlineStyleProperty(CSSPropertyID::kOverflow, "visible");
UpdateAllLifecyclePhasesForTest();
auto* isolation_a = GetDocument().getElementById("isolation_a");
auto* isolation_a_object = isolation_a->GetLayoutObject();
auto* squash_container_a = GetDocument().getElementById("squash_container_a");
PaintLayer* squash_container_a_layer =
ToLayoutBoxModelObject(squash_container_a->GetLayoutObject())->Layer();
EXPECT_EQ(squash_container_a_layer->ClippingContainer(), isolation_a_object);
}
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment