Commit c52d4d72 authored by Philip Rogers's avatar Philip Rogers Committed by Chromium LUCI CQ

Promote fixed/sticky if they can be scrolled

In https://crrev.com/624999, fixed and sticky positioned elements were
promoted if they stick to a scroller. This patch takes that further and
promotes fixed and sticky elements if they stick to a scroller, even if
the scroller is overflow: hidden. This will let us remove the
kHasNonLayerViewportConstrainedObjects main thread scrolling reason in a
followup, which is difficult to support with CompositeAfterPaint.

It is possible to have scroll animations with overflow hidden,
scroll-behavior: smooth, and the root scroller.

This is expected to regress the ie_chalkboard benchmark which now gets
layerized which requires a raster larger than the visible rect. Before
this patch, only the visible rect would be re-rasterized because there
were no layers. This situation should be rare and this patch should be
a small progression overall because it reduces main thread scrolling
reasons.

Bug: 649096
Change-Id: I6b1b15584166ace3dcd9b40d8271b13fb12b6366
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2100113
Commit-Queue: Philip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Auto-Submit: Philip Rogers <pdr@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842312}
parent aa9db65f
...@@ -356,25 +356,28 @@ bool CompositingReasonFinder::RequiresCompositingForRootScroller( ...@@ -356,25 +356,28 @@ bool CompositingReasonFinder::RequiresCompositingForRootScroller(
bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition( bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
const PaintLayer& layer) { const PaintLayer& layer) {
const auto& layout_object = layer.GetLayoutObject();
if (!layout_object.StyleRef().HasViewportConstrainedPosition() &&
!layout_object.StyleRef().HasStickyConstrainedPosition())
return false;
// Don't promote fixed position elements that are descendants of a non-view // Don't promote fixed position elements that are descendants of a non-view
// container, e.g. transformed elements. They will stay fixed wrt the // container, e.g. transformed elements. They will stay fixed wrt the
// container rather than the enclosing frame. // container rather than the enclosing frame.
EPosition position = layout_object.StyleRef().GetPosition(); if (layer.FixedToViewport()) {
if (position == EPosition::kFixed) { // We check for |HasOverflow| instead of |ScrollsOverflow| to ensure fixed
return layer.FixedToViewport() && // position elements are composited under overflow: hidden, which can still
layout_object.GetFrameView()->LayoutViewport()->ScrollsOverflow(); // have smooth scroll animations.
LocalFrameView* frame_view = layer.GetLayoutObject().GetFrameView();
return frame_view->LayoutViewport()->HasOverflow();
} }
DCHECK_EQ(position, EPosition::kSticky);
// Don't promote sticky position elements that cannot move with scrolls. // Don't promote sticky position elements that cannot move with scrolls.
if (!layer.SticksToScroller()) if (layer.SticksToScroller()) {
return false; // We check for |HasOverflow| instead of |ScrollsOverflow| to ensure sticky
return layer.AncestorScrollContainerLayer()->ScrollsOverflow(); // position elements are composited under overflow: hidden, which can still
// have smooth scroll animations.
return layer.AncestorScrollContainerLayer()
->GetScrollableArea()
->HasOverflow();
}
return false;
} }
} // namespace blink } // namespace blink
...@@ -102,9 +102,25 @@ TEST_F(CompositingReasonFinderTest, OnlyAnchoredStickyPositionPromoted) { ...@@ -102,9 +102,25 @@ TEST_F(CompositingReasonFinderTest, OnlyAnchoredStickyPositionPromoted) {
TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) { TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) {
SetBodyInnerHTML(R"HTML( SetBodyInnerHTML(R"HTML(
<style>.scroller {width: 400px; height: 400px; overflow: auto; <style>
will-change: transform;} .scroller {
.sticky { position: sticky; top: 0; width: 10px; height: 10px;} width: 400px;
height: 400px;
overflow: auto;
will-change: transform;
}
.sticky {
position: sticky;
top: 0;
width: 10px;
height: 10px;
}
.overflow-hidden {
width: 400px;
height: 400px;
overflow: hidden;
will-change: transform;
}
</style> </style>
<div class='scroller'> <div class='scroller'>
<div id='sticky-scrolling' class='sticky'></div> <div id='sticky-scrolling' class='sticky'></div>
...@@ -113,14 +129,49 @@ TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) { ...@@ -113,14 +129,49 @@ TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) {
<div class='scroller'> <div class='scroller'>
<div id='sticky-no-scrolling' class='sticky'></div> <div id='sticky-no-scrolling' class='sticky'></div>
</div> </div>
<div class='overflow-hidden'>
<div id='overflow-hidden-scrolling' class='sticky'></div>
<div style='height: 2000px;'></div>
</div>
<div class='overflow-hidden'>
<div id='overflow-hidden-no-scrolling' class='sticky'></div>
</div>
)HTML"); )HTML");
EXPECT_EQ( auto& sticky_scrolling =
kPaintsIntoOwnBacking, *To<LayoutBoxModelObject>(GetLayoutObjectByElementId("sticky-scrolling"));
GetPaintLayerByElementId("sticky-scrolling")->GetCompositingState()); EXPECT_TRUE(
EXPECT_EQ( CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
kNotComposited, *sticky_scrolling.Layer()));
GetPaintLayerByElementId("sticky-no-scrolling")->GetCompositingState());
auto& sticky_no_scrolling = *To<LayoutBoxModelObject>(
GetLayoutObjectByElementId("sticky-no-scrolling"));
EXPECT_FALSE(
CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
*sticky_no_scrolling.Layer()));
auto& overflow_hidden_scrolling = *To<LayoutBoxModelObject>(
GetLayoutObjectByElementId("overflow-hidden-scrolling"));
EXPECT_TRUE(
CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
*overflow_hidden_scrolling.Layer()));
auto& overflow_hidden_no_scrolling = *To<LayoutBoxModelObject>(
GetLayoutObjectByElementId("overflow-hidden-no-scrolling"));
EXPECT_FALSE(
CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
*overflow_hidden_no_scrolling.Layer()));
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(kPaintsIntoOwnBacking,
sticky_scrolling.Layer()->GetCompositingState());
EXPECT_EQ(kNotComposited,
sticky_no_scrolling.Layer()->GetCompositingState());
EXPECT_EQ(kPaintsIntoOwnBacking,
overflow_hidden_scrolling.Layer()->GetCompositingState());
EXPECT_EQ(kNotComposited,
overflow_hidden_no_scrolling.Layer()->GetCompositingState());
}
} }
void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation( void CompositingReasonFinderTest::CheckCompositingReasonsForAnimation(
......
...@@ -5909,7 +5909,7 @@ TEST_P(PaintPropertyTreeBuilderTest, RepeatingFixedPositionInPagedMedia) { ...@@ -5909,7 +5909,7 @@ TEST_P(PaintPropertyTreeBuilderTest, RepeatingFixedPositionInPagedMedia) {
EXPECT_EQ(3u, NumFragments(fixed)); EXPECT_EQ(3u, NumFragments(fixed));
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
const auto& fragment = FragmentAt(fixed, i); const auto& fragment = FragmentAt(fixed, i);
EXPECT_EQ(PhysicalOffset(20, -180 + i * 400), fragment.PaintOffset()); EXPECT_EQ(PhysicalOffset(0, 0), fragment.PaintOffset());
EXPECT_EQ(LayoutUnit(400 * i), fragment.LogicalTopInFlowThread()); EXPECT_EQ(LayoutUnit(400 * i), fragment.LogicalTopInFlowThread());
} }
...@@ -5917,7 +5917,7 @@ TEST_P(PaintPropertyTreeBuilderTest, RepeatingFixedPositionInPagedMedia) { ...@@ -5917,7 +5917,7 @@ TEST_P(PaintPropertyTreeBuilderTest, RepeatingFixedPositionInPagedMedia) {
EXPECT_EQ(3u, NumFragments(fixed_child)); EXPECT_EQ(3u, NumFragments(fixed_child));
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
const auto& fragment = FragmentAt(fixed_child, i); const auto& fragment = FragmentAt(fixed_child, i);
EXPECT_EQ(PhysicalOffset(20, -170 + i * 400), fragment.PaintOffset()); EXPECT_EQ(PhysicalOffset(0, 10), fragment.PaintOffset());
EXPECT_EQ(LayoutUnit(i * 400), fragment.LogicalTopInFlowThread()); EXPECT_EQ(LayoutUnit(i * 400), fragment.LogicalTopInFlowThread());
} }
......
...@@ -5,6 +5,24 @@ ...@@ -5,6 +5,24 @@
"bounds": [800, 4021], "bounds": [800, 4021],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#FFFFFF" "backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
}, },
{ {
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"position": [10, 100],
"bounds": [100, 100], "bounds": [100, 100],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#00FF00" "backgroundColor": "#00FF00",
"transform": 2
} }
], ],
"transforms": [ "transforms": [
...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 100, 0, 1] [10, 100, 0, 1]
] ]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -14,16 +14,52 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -14,16 +14,52 @@ In all iframes, the green fixed-position element should not be composited.
"backgroundColor": "#00FFFF", "backgroundColor": "#00FFFF",
"transform": 1 "transform": 1
}, },
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 2
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
},
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'",
"bounds": [154, 154], "bounds": [154, 154],
"transform": 2 "transform": 4
},
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 5
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 6
}, },
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe3'", "name": "LayoutIFrame (positioned) IFRAME id='iframe3'",
"position": [10, 380], "position": [10, 380],
"bounds": [154, 154] "bounds": [154, 154]
}, },
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 7
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 8
},
{ {
"name": "ContentsLayer for Vertical Scrollbar Layer", "name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [785, 0], "position": [785, 0],
...@@ -43,12 +79,70 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -43,12 +79,70 @@ In all iframes, the green fixed-position element should not be composited.
}, },
{ {
"id": 2, "id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 32, 0, 1]
]
},
{
"id": 3,
"parent": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 4,
"transform": [ "transform": [
[1, 0, 0, 0], [1, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 200, 0, 1] [10, 200, 0, 1]
] ]
},
{
"id": 5,
"parent": 4,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
},
{
"id": 6,
"parent": 5,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 382, 0, 1]
]
},
{
"id": 8,
"parent": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
} }
] ]
} }
......
...@@ -8,10 +8,21 @@ ...@@ -8,10 +8,21 @@
}, },
{ {
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"position": [10, 100],
"bounds": [100, 100], "bounds": [100, 100],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#00FF00" "backgroundColor": "#00FF00",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
}, },
{ {
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'", "name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"position": [10, 100],
"bounds": [100, 100], "bounds": [100, 100],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#00FF00" "backgroundColor": "#00FF00",
"transform": 2
} }
], ],
"transforms": [ "transforms": [
...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 100, 0, 1] [10, 100, 0, 1]
] ]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -14,16 +14,37 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -14,16 +14,37 @@ In all iframes, the green fixed-position element should not be composited.
"backgroundColor": "#00FFFF", "backgroundColor": "#00FFFF",
"transform": 1 "transform": 1
}, },
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
},
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'",
"bounds": [154, 154], "bounds": [154, 154],
"transform": 2 "transform": 4
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 6
}, },
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe3'", "name": "LayoutIFrame (positioned) IFRAME id='iframe3'",
"position": [10, 380], "position": [10, 380],
"bounds": [154, 154] "bounds": [154, 154]
}, },
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 8
},
{ {
"name": "VerticalScrollbar", "name": "VerticalScrollbar",
"position": [785, 0], "position": [785, 0],
...@@ -42,12 +63,70 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -42,12 +63,70 @@ In all iframes, the green fixed-position element should not be composited.
}, },
{ {
"id": 2, "id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 32, 0, 1]
]
},
{
"id": 3,
"parent": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 4,
"transform": [ "transform": [
[1, 0, 0, 0], [1, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 200, 0, 1] [10, 200, 0, 1]
] ]
},
{
"id": 5,
"parent": 4,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
},
{
"id": 6,
"parent": 5,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 382, 0, 1]
]
},
{
"id": 8,
"parent": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
} }
] ]
} }
......
...@@ -9,8 +9,19 @@ TEST ...@@ -9,8 +9,19 @@ TEST
}, },
{ {
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'", "name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"position": [10, 10], "bounds": [39, 20],
"bounds": [39, 20] "transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
} }
] ]
} }
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
}, },
{ {
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed green'", "name": "LayoutNGBlockFlow (positioned) DIV class='fixed green'",
"position": [8, 100],
"bounds": [100, 100], "bounds": [100, 100],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#008000" "backgroundColor": "#008000",
"transform": 2
} }
], ],
"transforms": [ "transforms": [
...@@ -24,6 +24,15 @@ ...@@ -24,6 +24,15 @@
[0, 0, 1, 0], [0, 0, 1, 0],
[0, -100, 0, 1] [0, -100, 0, 1]
] ]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -4,9 +4,31 @@ ...@@ -4,9 +4,31 @@
"name": "Scrolling background of LayoutView #document", "name": "Scrolling background of LayoutView #document",
"bounds": [804, 604], "bounds": [804, 604],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#FF0000",
"invalidations": [
[787, 2, 15, 600],
[779, 2, 15, 592]
]
},
{
"name": "LayoutNGBlockFlow (positioned) DIV id='overlay'",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#008000", "backgroundColor": "#008000",
"invalidations": [ "invalidations": [
[2, 2, 800, 600] [0, 0, 800, 600]
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
] ]
} }
] ]
......
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 4021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
}
]
}
...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -17,10 +17,10 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
}, },
{ {
"name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'", "name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'",
"position": [10, 100],
"bounds": [100, 100], "bounds": [100, 100],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#00FF00" "backgroundColor": "#00FF00",
"transform": 2
} }
], ],
"transforms": [ "transforms": [
...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed- ...@@ -32,6 +32,15 @@ Even though we can opt-out of fixed-position compositing for unscrollable fixed-
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 100, 0, 1] [10, 100, 0, 1]
] ]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
} }
] ]
} }
......
...@@ -14,16 +14,52 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -14,16 +14,52 @@ In all iframes, the green fixed-position element should not be composited.
"backgroundColor": "#00FFFF", "backgroundColor": "#00FFFF",
"transform": 1 "transform": 1
}, },
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 2
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
},
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'", "name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'",
"bounds": [154, 154], "bounds": [154, 154],
"transform": 2 "transform": 4
},
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 5
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 6
}, },
{ {
"name": "LayoutIFrame (positioned) IFRAME id='iframe3'", "name": "LayoutIFrame (positioned) IFRAME id='iframe3'",
"position": [10, 380], "position": [10, 380],
"bounds": [154, 154] "bounds": [154, 154]
}, },
{
"name": "LayoutView #document",
"bounds": [150, 150],
"transform": 7
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed lime box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 8
},
{ {
"name": "ContentsLayer for Vertical Scrollbar Layer", "name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [785, 0], "position": [785, 0],
...@@ -43,12 +79,70 @@ In all iframes, the green fixed-position element should not be composited. ...@@ -43,12 +79,70 @@ In all iframes, the green fixed-position element should not be composited.
}, },
{ {
"id": 2, "id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 32, 0, 1]
]
},
{
"id": 3,
"parent": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 4,
"transform": [ "transform": [
[1, 0, 0, 0], [1, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 0, 1, 0], [0, 0, 1, 0],
[10, 200, 0, 1] [10, 200, 0, 1]
] ]
},
{
"id": 5,
"parent": 4,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
},
{
"id": 6,
"parent": 5,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
},
{
"id": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[12, 382, 0, 1]
]
},
{
"id": 8,
"parent": 7,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
} }
] ]
} }
......
TEST
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 5021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed'",
"bounds": [39, 20],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 2016],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"transform": 1
},
{
"name": "LayoutBlockFlow (positioned) DIV class='fixed green'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 2
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, -100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 100, 0, 1]
]
}
]
}
...@@ -5,11 +5,14 @@ ...@@ -5,11 +5,14 @@
"bounds": [800, 2016], "bounds": [800, 2016],
"contentsOpaque": true, "contentsOpaque": true,
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"invalidations": [
[8, 200, 100, 100],
[8, 100, 100, 100]
],
"transform": 1 "transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed green'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 2
} }
], ],
"transforms": [ "transforms": [
...@@ -21,6 +24,15 @@ ...@@ -21,6 +24,15 @@
[0, 0, 1, 0], [0, 0, 1, 0],
[0, -100, 0, 1] [0, -100, 0, 1]
] ]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 100, 0, 1]
]
} }
] ]
} }
......
TEST
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 5021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [39, 20],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 4021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
}
]
}
Even though we can opt-out of fixed-position compositing for unscrollable fixed-position containers, we still need to composite fixed-position layers that need compositing for other reasons such as overlap.
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 4024],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='absolute composited red box'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#FF0000",
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed lime box'",
"position": [10, 100],
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00"
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 100, 0, 1]
]
}
]
}
In all iframes, the green fixed-position element should not be composited.
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [785, 4016],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='composited box'",
"bounds": [300, 100],
"contentsOpaque": true,
"backgroundColor": "#00FFFF",
"transform": 1
},
{
"name": "LayoutIFrame (positioned) IFRAME id='iframe2' class='composited'",
"bounds": [154, 154],
"transform": 2
},
{
"name": "LayoutIFrame (positioned) IFRAME id='iframe3'",
"position": [10, 380],
"bounds": [154, 154]
},
{
"name": "ContentsLayer for Vertical Scrollbar Layer",
"position": [785, 0],
"bounds": [15, 600],
"contentsOpaque": true
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[50, 360, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 200, 0, 1]
]
}
]
}
Composited box underneath iframe.
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 2016],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"invalidations": [
[8, 200, 100, 100],
[8, 100, 100, 100]
],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, -100, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [804, 604],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"invalidations": [
[10, 2, 769, 592],
[787, 2, 15, 600]
]
},
{
"name": "LayoutView #document",
"bounds": [800, 600],
"backgroundColor": "#FF0000",
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV id='overlay'",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
}
]
}
TEST
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 5021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [38, 18],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [804, 604],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutView #document",
"bounds": [800, 600],
"backgroundColor": "#FF0000",
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV id='overlay'",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
}
]
}
TEST
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [800, 5021],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [36, 20],
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[10, 10, 0, 1]
]
}
]
}
{
"layers": [
{
"name": "Scrolling Contents Layer",
"bounds": [804, 604],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"invalidations": [
[10, 2, 769, 592],
[787, 2, 15, 600]
]
},
{
"name": "LayoutView #document",
"bounds": [800, 600],
"backgroundColor": "#FF0000",
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV id='overlay'",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#008000",
"transform": 1
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[2, 2, 0, 1]
]
}
]
}
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