Commit 5e2e7cb8 authored by Tien-Ren Chen's avatar Tien-Ren Chen Committed by Commit Bot

[Blink] Fix oversized foreground layer when a child containment layer exists

Previously we create a child containment layer sized by
LayoutRect::InfiniteIntRect() when a layer has CSS clip-path. This is
because we used object.HasClipRelatedProperty() as the criteria, but the
layer only applies CSS clip and overflow clip. This confuses foreground
layer geometry computation, and resulted in an oversized foreground
layer.

This CL does the following things:

1. Change the criteria so that child containment layer is only created
when either CSS clip or overflow clip is present.

2. Simplify foreground layer and child containment layer geometry
computation, so that subpixel accumulation handling is more correct, and
also infer parameters from the parent graphics layer so the formula is
consistent for different layer hierarchy configuration.

BUG=773536

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: Ic8074ef54270cdd2f628bc73f3bcb6fa929d8881
Reviewed-on: https://chromium-review.googlesource.com/722259
Commit-Queue: Tien-Ren Chen <trchen@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#510003}
parent 99c22804
...@@ -1205,13 +1205,13 @@ IntSize LayoutBox::ScrolledContentOffset() const { ...@@ -1205,13 +1205,13 @@ IntSize LayoutBox::ScrolledContentOffset() const {
return result; return result;
} }
LayoutRect LayoutBox::ClippingRect() const { LayoutRect LayoutBox::ClippingRect(const LayoutPoint& location) const {
LayoutRect result = LayoutRect(LayoutRect::InfiniteIntRect()); LayoutRect result = LayoutRect(LayoutRect::InfiniteIntRect());
if (ShouldClipOverflow()) if (ShouldClipOverflow())
result = OverflowClipRect(LayoutPoint()); result = OverflowClipRect(location);
if (HasClip()) if (HasClip())
result.Intersect(ClipRect(LayoutPoint())); result.Intersect(ClipRect(location));
return result; return result;
} }
...@@ -1332,7 +1332,7 @@ bool LayoutBox::ApplyBoxClips( ...@@ -1332,7 +1332,7 @@ bool LayoutBox::ApplyBoxClips(
// This won't work fully correctly for fixed-position elements, who should // This won't work fully correctly for fixed-position elements, who should
// receive CSS clip but for whom the current object is not in the containing // receive CSS clip but for whom the current object is not in the containing
// block chain. // block chain.
LayoutRect clip_rect = ClippingRect(); LayoutRect clip_rect = ClippingRect(LayoutPoint());
transform_state.Flatten(); transform_state.Flatten();
LayoutRect rect(transform_state.LastPlanarQuad().EnclosingBoundingBox()); LayoutRect rect(transform_state.LastPlanarQuad().EnclosingBoundingBox());
......
...@@ -1067,8 +1067,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject { ...@@ -1067,8 +1067,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutRect ClipRect(const LayoutPoint& location) const; LayoutRect ClipRect(const LayoutPoint& location) const;
// Returns the combination of overflow clip, contain: paint clip and CSS clip // Returns the combination of overflow clip, contain: paint clip and CSS clip
// for this object, in local space. // for this object.
LayoutRect ClippingRect() const; LayoutRect ClippingRect(const LayoutPoint& location) const;
virtual void PaintBoxDecorationBackground(const PaintInfo&, virtual void PaintBoxDecorationBackground(const PaintInfo&,
const LayoutPoint&) const; const LayoutPoint&) const;
......
...@@ -226,9 +226,9 @@ TEST_F(LayoutBoxTest, ControlClip) { ...@@ -226,9 +226,9 @@ TEST_F(LayoutBoxTest, ControlClip) {
EXPECT_TRUE(target->HasClipRelatedProperty()); EXPECT_TRUE(target->HasClipRelatedProperty());
EXPECT_TRUE(target->ShouldClipOverflow()); EXPECT_TRUE(target->ShouldClipOverflow());
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
EXPECT_EQ(LayoutRect(0, 0, 100, 18), target->ClippingRect()); EXPECT_EQ(LayoutRect(0, 0, 100, 18), target->ClippingRect(LayoutPoint()));
#else #else
EXPECT_EQ(LayoutRect(2, 2, 96, 46), target->ClippingRect()); EXPECT_EQ(LayoutRect(2, 2, 96, 46), target->ClippingRect(LayoutPoint()));
#endif #endif
} }
......
...@@ -875,7 +875,7 @@ TEST_F(VisualRectMappingTest, PerspectivePlusScroll) { ...@@ -875,7 +875,7 @@ TEST_F(VisualRectMappingTest, PerspectivePlusScroll) {
transform.FlattenTo2d(); transform.FlattenTo2d();
LayoutRect output(transform.MapRect(FloatRect(originalRect))); LayoutRect output(transform.MapRect(FloatRect(originalRect)));
output.Intersect(container->ClippingRect()); output.Intersect(container->ClippingRect(LayoutPoint()));
CheckVisualRect(*target, *target->View(), originalRect, output, false, false); CheckVisualRect(*target, *target->View(), originalRect, output, false, false);
} }
......
...@@ -351,17 +351,13 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient { ...@@ -351,17 +351,13 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
const PaintLayer* compositing_stacking_context, const PaintLayer* compositing_stacking_context,
const PaintLayer* compositing_container, const PaintLayer* compositing_container,
IntPoint graphics_layer_parent_location); IntPoint graphics_layer_parent_location);
void UpdateChildContainmentLayerGeometry( void UpdateChildContainmentLayerGeometry();
const IntRect& clipping_box,
const IntRect& local_compositing_bounds);
void UpdateChildTransformLayerGeometry(); void UpdateChildTransformLayerGeometry();
void UpdateMaskLayerGeometry(); void UpdateMaskLayerGeometry();
void UpdateTransformGeometry( void UpdateTransformGeometry(
const IntPoint& snapped_offset_from_composited_ancestor, const IntPoint& snapped_offset_from_composited_ancestor,
const IntRect& relative_compositing_bounds); const IntRect& relative_compositing_bounds);
void UpdateForegroundLayerGeometry( void UpdateForegroundLayerGeometry();
const FloatSize& relative_compositing_bounds_size,
const IntRect& clipping_box);
void UpdateBackgroundLayerGeometry( void UpdateBackgroundLayerGeometry(
const FloatSize& relative_compositing_bounds_size); const FloatSize& relative_compositing_bounds_size);
void UpdateDecorationOutlineLayerGeometry( void UpdateDecorationOutlineLayerGeometry(
......
...@@ -2438,4 +2438,40 @@ TEST_P(CompositedLayerMappingTest, ScrollingLayerBackgroundColor) { ...@@ -2438,4 +2438,40 @@ TEST_P(CompositedLayerMappingTest, ScrollingLayerBackgroundColor) {
EXPECT_EQ(Color(0, 0, 255), scrolling_contents_layer->BackgroundColor()); EXPECT_EQ(Color(0, 0, 255), scrolling_contents_layer->BackgroundColor());
} }
TEST_P(CompositedLayerMappingTest, ClipPathNoChildContainmentLayer) {
// This test verifies only the presence of clip path does not induce child
// containment layer.
SetBodyInnerHTML(
"<div id='target' style='width:100px; height:100px; clip-path:circle();'>"
" <div style='will-change:transform; width:200px; height:200px;'></div>"
"</div>");
auto* mapping = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))
->Layer()
->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
ASSERT_FALSE(mapping->ClippingLayer());
}
TEST_P(CompositedLayerMappingTest, ForegroundLayerSizing) {
// This test verifies the foreground layer is sized to the clip rect.
SetBodyInnerHTML(
"<div id='target' style='position:relative; z-index:0; width:100px; "
"height:100px; border:10px solid black; overflow:hidden;'>"
" <div style='width:200px; height:200px; background:green;'></div>"
" <div style='position:relative; z-index:-1; "
"will-change:transform;'></div>"
"</div>");
auto* mapping = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"))
->Layer()
->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
EXPECT_EQ(FloatSize(120, 120), mapping->MainGraphicsLayer()->Size());
ASSERT_TRUE(mapping->ClippingLayer());
EXPECT_EQ(FloatPoint(10, 10), mapping->ClippingLayer()->GetPosition());
EXPECT_EQ(FloatSize(100, 100), mapping->ClippingLayer()->Size());
ASSERT_TRUE(mapping->ForegroundLayer());
EXPECT_EQ(FloatPoint(0, 0), mapping->ForegroundLayer()->GetPosition());
EXPECT_EQ(FloatSize(100, 100), mapping->ForegroundLayer()->Size());
}
} // namespace blink } // namespace blink
...@@ -925,8 +925,12 @@ bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const { ...@@ -925,8 +925,12 @@ bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const {
// z-order hierarchy. // z-order hierarchy.
bool PaintLayerCompositor::ClipsCompositingDescendants( bool PaintLayerCompositor::ClipsCompositingDescendants(
const PaintLayer* layer) const { const PaintLayer* layer) const {
return layer->HasCompositingDescendant() && if (!layer->HasCompositingDescendant())
layer->GetLayoutObject().HasClipRelatedProperty(); return false;
if (!layer->GetLayoutObject().IsBox())
return false;
const LayoutBox& box = ToLayoutBox(layer->GetLayoutObject());
return box.ShouldClipOverflow() || box.HasClip();
} }
// If an element has composited negative z-index children, those children paint // If an element has composited negative z-index children, those children paint
......
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