OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/PaintLayer.h" | 5 #include "core/paint/PaintLayer.h" |
6 | 6 |
7 #include "core/layout/LayoutBoxModelObject.h" | 7 #include "core/layout/LayoutBoxModelObject.h" |
8 #include "core/layout/LayoutTestHelper.h" | 8 #include "core/layout/LayoutTestHelper.h" |
9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
10 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" | |
10 | 11 |
11 namespace blink { | 12 namespace blink { |
12 | 13 |
13 using PaintLayerTest = RenderingTest; | 14 typedef std::pair<bool, bool> SlimmingPaintAndRootLayerScrolling; |
15 class PaintLayerTest | |
16 : public ::testing::WithParamInterface<SlimmingPaintAndRootLayerScrolling>, | |
17 private ScopedSlimmingPaintV2ForTest, | |
18 private ScopedRootLayerScrollingForTest, | |
19 public RenderingTest { | |
20 public: | |
21 PaintLayerTest() | |
22 : ScopedSlimmingPaintV2ForTest(GetParam().first), | |
23 ScopedRootLayerScrollingForTest(GetParam().second), | |
24 RenderingTest(SingleChildFrameLoaderClient::create()) {} | |
25 }; | |
14 | 26 |
15 TEST_F(PaintLayerTest, CompositedBoundsAbsPosGrandchild) { | 27 SlimmingPaintAndRootLayerScrolling foo[] = { |
28 SlimmingPaintAndRootLayerScrolling(false, false), | |
29 SlimmingPaintAndRootLayerScrolling(true, false), | |
30 SlimmingPaintAndRootLayerScrolling(false, true), | |
31 SlimmingPaintAndRootLayerScrolling(true, true)}; | |
32 | |
33 INSTANTIATE_TEST_CASE_P(All, PaintLayerTest, ::testing::ValuesIn(foo)); | |
34 | |
35 TEST_P(PaintLayerTest, CompositedBoundsAbsPosGrandchild) { | |
36 // TODO(chrishtr): fix this test for SPv2 | |
37 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
38 return; | |
39 | |
16 setBodyInnerHTML( | 40 setBodyInnerHTML( |
17 " <div id='parent'><div id='absposparent'><div id='absposchild'>" | 41 " <div id='parent'><div id='absposparent'><div id='absposchild'>" |
18 " </div></div></div>" | 42 " </div></div></div>" |
19 "<style>" | 43 "<style>" |
20 " #parent { position: absolute; z-index: 0; overflow: hidden;" | 44 " #parent { position: absolute; z-index: 0; overflow: hidden;" |
21 " background: lightgray; width: 150px; height: 150px;" | 45 " background: lightgray; width: 150px; height: 150px;" |
22 " will-change: transform; }" | 46 " will-change: transform; }" |
23 " #absposparent { position: absolute; z-index: 0; }" | 47 " #absposparent { position: absolute; z-index: 0; }" |
24 " #absposchild { position: absolute; top: 0px; left: 0px; height: 200px;" | 48 " #absposchild { position: absolute; top: 0px; left: 0px; height: 200px;" |
25 " width: 200px; background: lightblue; }</style>"); | 49 " width: 200px; background: lightblue; }</style>"); |
26 | 50 |
27 PaintLayer* parentLayer = | 51 PaintLayer* parentLayer = |
28 toLayoutBoxModelObject(getLayoutObjectByElementId("parent"))->layer(); | 52 toLayoutBoxModelObject(getLayoutObjectByElementId("parent"))->layer(); |
29 // Since "absposchild" is clipped by "parent", it should not expand the | 53 // Since "absposchild" is clipped by "parent", it should not expand the |
30 // composited bounds for "parent" beyond its intrinsic size of 150x150. | 54 // composited bounds for "parent" beyond its intrinsic size of 150x150. |
31 EXPECT_EQ(LayoutRect(0, 0, 150, 150), | 55 EXPECT_EQ(LayoutRect(0, 0, 150, 150), |
32 parentLayer->boundingBoxForCompositing()); | 56 parentLayer->boundingBoxForCompositing()); |
33 } | 57 } |
34 | 58 |
35 TEST_F(PaintLayerTest, PaintingExtentReflection) { | 59 TEST_P(PaintLayerTest, PaintingExtentReflection) { |
36 setBodyInnerHTML( | 60 setBodyInnerHTML( |
37 "<div id='target' style='background-color: blue; position: absolute;" | 61 "<div id='target' style='background-color: blue; position: absolute;" |
38 " width: 110px; height: 120px; top: 40px; left: 60px;" | 62 " width: 110px; height: 120px; top: 40px; left: 60px;" |
39 " -webkit-box-reflect: below 3px'>" | 63 " -webkit-box-reflect: below 3px'>" |
40 "</div>"); | 64 "</div>"); |
41 | 65 |
42 PaintLayer* layer = | 66 PaintLayer* layer = |
43 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | 67 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); |
44 EXPECT_EQ( | 68 EXPECT_EQ( |
45 LayoutRect(60, 40, 110, 243), | 69 LayoutRect(60, 40, 110, 243), |
46 layer->paintingExtent(document().layoutView()->layer(), LayoutSize(), 0)); | 70 layer->paintingExtent(document().layoutView()->layer(), LayoutSize(), 0)); |
47 } | 71 } |
48 | 72 |
49 TEST_F(PaintLayerTest, PaintingExtentReflectionWithTransform) { | 73 TEST_P(PaintLayerTest, PaintingExtentReflectionWithTransform) { |
50 setBodyInnerHTML( | 74 setBodyInnerHTML( |
51 "<div id='target' style='background-color: blue; position: absolute;" | 75 "<div id='target' style='background-color: blue; position: absolute;" |
52 " width: 110px; height: 120px; top: 40px; left: 60px;" | 76 " width: 110px; height: 120px; top: 40px; left: 60px;" |
53 " -webkit-box-reflect: below 3px; transform: translateX(30px)'>" | 77 " -webkit-box-reflect: below 3px; transform: translateX(30px)'>" |
54 "</div>"); | 78 "</div>"); |
55 | 79 |
56 PaintLayer* layer = | 80 PaintLayer* layer = |
57 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | 81 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); |
58 EXPECT_EQ( | 82 EXPECT_EQ( |
59 LayoutRect(90, 40, 110, 243), | 83 LayoutRect(90, 40, 110, 243), |
60 layer->paintingExtent(document().layoutView()->layer(), LayoutSize(), 0)); | 84 layer->paintingExtent(document().layoutView()->layer(), LayoutSize(), 0)); |
61 } | 85 } |
62 | 86 |
63 TEST_F(PaintLayerTest, CompositedScrollingNoNeedsRepaint) { | 87 TEST_P(PaintLayerTest, ScrollsWithViewportRelativePosition) { |
88 setBodyInnerHTML("<div id='target' style='position: relative'></div>"); | |
89 | |
90 PaintLayer* layer = | |
91 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | |
92 EXPECT_FALSE(layer->scrollsWithViewport()); | |
93 } | |
94 | |
95 TEST_P(PaintLayerTest, ScrollsWithViewportFixedPosition) { | |
96 setBodyInnerHTML("<div id='target' style='position: fixed'></div>"); | |
97 | |
98 PaintLayer* layer = | |
99 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | |
100 EXPECT_TRUE(layer->scrollsWithViewport()); | |
101 } | |
102 | |
103 TEST_P(PaintLayerTest, ScrollsWithViewportFixedPositionInsideTransform) { | |
104 setBodyInnerHTML( | |
105 "<div style='transform: translateZ(0)'>" | |
pdr.
2016/12/06 04:38:51
This isn't correct for spv2 because the viewport d
chrishtr
2016/12/06 23:56:06
Added here, and also added another test without sc
| |
106 " <div id='target' style='position: fixed'></div>" | |
107 "</div>"); | |
108 | |
109 PaintLayer* layer = | |
110 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | |
111 EXPECT_FALSE(layer->scrollsWithViewport()); | |
112 } | |
113 | |
114 TEST_P(PaintLayerTest, ScrollsWithViewportStickyPosition) { | |
115 setBodyInnerHTML( | |
116 "<div style='transform: translateZ(0)'>" | |
117 " <div id='target' style='position: sticky'></div>" | |
118 "</div>"); | |
119 | |
120 PaintLayer* layer = | |
121 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | |
122 EXPECT_TRUE(layer->scrollsWithViewport()); | |
123 } | |
124 | |
125 TEST_P(PaintLayerTest, ScrollsWithViewportStickyPositionInsideScroller) { | |
126 setBodyInnerHTML( | |
127 "<div style='overflow:scroll; width: 100px; height: 100px;'>" | |
128 " <div id='target' style='position: sticky'></div>" | |
129 " <div style='width: 50px; height: 1000px;'></div>" | |
130 "</div>"); | |
131 | |
132 PaintLayer* layer = | |
133 toLayoutBoxModelObject(getLayoutObjectByElementId("target"))->layer(); | |
134 EXPECT_FALSE(layer->scrollsWithViewport()); | |
135 } | |
136 | |
137 TEST_P(PaintLayerTest, CompositedScrollingNoNeedsRepaint) { | |
pdr.
2016/12/06 04:38:51
Nit: Can you file a bug for this and include it he
| |
138 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
139 return; | |
140 | |
64 enableCompositing(); | 141 enableCompositing(); |
65 setBodyInnerHTML( | 142 setBodyInnerHTML( |
66 "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll;" | 143 "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll;" |
67 " will-change: transform'>" | 144 " will-change: transform'>" |
68 " <div id='content' style='position: relative; background: blue;" | 145 " <div id='content' style='position: relative; background: blue;" |
69 " width: 2000px; height: 2000px'></div>" | 146 " width: 2000px; height: 2000px'></div>" |
70 "</div>"); | 147 "</div>"); |
71 | 148 |
72 PaintLayer* scrollLayer = | 149 PaintLayer* scrollLayer = |
73 toLayoutBoxModelObject(getLayoutObjectByElementId("scroll"))->layer(); | 150 toLayoutBoxModelObject(getLayoutObjectByElementId("scroll"))->layer(); |
74 EXPECT_EQ(PaintsIntoOwnBacking, scrollLayer->compositingState()); | 151 EXPECT_EQ(PaintsIntoOwnBacking, scrollLayer->compositingState()); |
75 | 152 |
76 PaintLayer* contentLayer = | 153 PaintLayer* contentLayer = |
77 toLayoutBoxModelObject(getLayoutObjectByElementId("content"))->layer(); | 154 toLayoutBoxModelObject(getLayoutObjectByElementId("content"))->layer(); |
78 EXPECT_EQ(NotComposited, contentLayer->compositingState()); | 155 EXPECT_EQ(NotComposited, contentLayer->compositingState()); |
79 EXPECT_EQ(LayoutPoint(), contentLayer->location()); | 156 EXPECT_EQ(LayoutPoint(), contentLayer->location()); |
80 | 157 |
81 scrollLayer->getScrollableArea()->setScrollOffset(ScrollOffset(1000, 1000), | 158 scrollLayer->getScrollableArea()->setScrollOffset(ScrollOffset(1000, 1000), |
82 ProgrammaticScroll); | 159 ProgrammaticScroll); |
83 document().view()->updateAllLifecyclePhasesExceptPaint(); | 160 document().view()->updateAllLifecyclePhasesExceptPaint(); |
84 EXPECT_EQ(LayoutPoint(-1000, -1000), contentLayer->location()); | 161 EXPECT_EQ(LayoutPoint(-1000, -1000), contentLayer->location()); |
85 EXPECT_FALSE(contentLayer->needsRepaint()); | 162 EXPECT_FALSE(contentLayer->needsRepaint()); |
86 EXPECT_FALSE(scrollLayer->needsRepaint()); | 163 EXPECT_FALSE(scrollLayer->needsRepaint()); |
87 document().view()->updateAllLifecyclePhases(); | 164 document().view()->updateAllLifecyclePhases(); |
88 } | 165 } |
89 | 166 |
90 TEST_F(PaintLayerTest, NonCompositedScrollingNeedsRepaint) { | 167 TEST_P(PaintLayerTest, NonCompositedScrollingNeedsRepaint) { |
91 setBodyInnerHTML( | 168 setBodyInnerHTML( |
92 "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll'>" | 169 "<div id='scroll' style='width: 100px; height: 100px; overflow: scroll'>" |
93 " <div id='content' style='position: relative; background: blue;" | 170 " <div id='content' style='position: relative; background: blue;" |
94 " width: 2000px; height: 2000px'></div>" | 171 " width: 2000px; height: 2000px'></div>" |
95 "</div>"); | 172 "</div>"); |
96 | 173 |
97 PaintLayer* scrollLayer = | 174 PaintLayer* scrollLayer = |
98 toLayoutBoxModelObject(getLayoutObjectByElementId("scroll"))->layer(); | 175 toLayoutBoxModelObject(getLayoutObjectByElementId("scroll"))->layer(); |
99 EXPECT_EQ(NotComposited, scrollLayer->compositingState()); | 176 EXPECT_EQ(NotComposited, scrollLayer->compositingState()); |
100 | 177 |
101 PaintLayer* contentLayer = | 178 PaintLayer* contentLayer = |
102 toLayoutBoxModelObject(getLayoutObjectByElementId("content"))->layer(); | 179 toLayoutBoxModelObject(getLayoutObjectByElementId("content"))->layer(); |
103 EXPECT_EQ(NotComposited, scrollLayer->compositingState()); | 180 EXPECT_EQ(NotComposited, scrollLayer->compositingState()); |
104 EXPECT_EQ(LayoutPoint(), contentLayer->location()); | 181 EXPECT_EQ(LayoutPoint(), contentLayer->location()); |
105 | 182 |
106 scrollLayer->getScrollableArea()->setScrollOffset(ScrollOffset(1000, 1000), | 183 scrollLayer->getScrollableArea()->setScrollOffset(ScrollOffset(1000, 1000), |
107 ProgrammaticScroll); | 184 ProgrammaticScroll); |
108 document().view()->updateAllLifecyclePhasesExceptPaint(); | 185 document().view()->updateAllLifecyclePhasesExceptPaint(); |
109 EXPECT_EQ(LayoutPoint(-1000, -1000), contentLayer->location()); | 186 EXPECT_EQ(LayoutPoint(-1000, -1000), contentLayer->location()); |
110 EXPECT_TRUE(contentLayer->needsRepaint()); | 187 EXPECT_TRUE(contentLayer->needsRepaint()); |
111 EXPECT_TRUE(scrollLayer->needsRepaint()); | 188 EXPECT_TRUE(scrollLayer->needsRepaint()); |
112 document().view()->updateAllLifecyclePhases(); | 189 document().view()->updateAllLifecyclePhases(); |
113 } | 190 } |
114 | 191 |
115 TEST_F(PaintLayerTest, HasNonIsolatedDescendantWithBlendMode) { | 192 TEST_P(PaintLayerTest, HasNonIsolatedDescendantWithBlendMode) { |
116 setBodyInnerHTML( | 193 setBodyInnerHTML( |
117 "<div id='stacking-grandparent' style='isolation: isolate'>" | 194 "<div id='stacking-grandparent' style='isolation: isolate'>" |
118 " <div id='stacking-parent' style='isolation: isolate'>" | 195 " <div id='stacking-parent' style='isolation: isolate'>" |
119 " <div id='non-stacking-parent' style='position:relative'>" | 196 " <div id='non-stacking-parent' style='position:relative'>" |
120 " <div id='blend-mode' style='mix-blend-mode: overlay'>" | 197 " <div id='blend-mode' style='mix-blend-mode: overlay'>" |
121 " </div>" | 198 " </div>" |
122 " </div>" | 199 " </div>" |
123 " </div>" | 200 " </div>" |
124 "</div>"); | 201 "</div>"); |
125 PaintLayer* stackingGrandparent = | 202 PaintLayer* stackingGrandparent = |
126 toLayoutBoxModelObject(getLayoutObjectByElementId("stacking-grandparent")) | 203 toLayoutBoxModelObject(getLayoutObjectByElementId("stacking-grandparent")) |
127 ->layer(); | 204 ->layer(); |
128 PaintLayer* stackingParent = | 205 PaintLayer* stackingParent = |
129 toLayoutBoxModelObject(getLayoutObjectByElementId("stacking-parent")) | 206 toLayoutBoxModelObject(getLayoutObjectByElementId("stacking-parent")) |
130 ->layer(); | 207 ->layer(); |
131 PaintLayer* parent = | 208 PaintLayer* parent = |
132 toLayoutBoxModelObject(getLayoutObjectByElementId("non-stacking-parent")) | 209 toLayoutBoxModelObject(getLayoutObjectByElementId("non-stacking-parent")) |
133 ->layer(); | 210 ->layer(); |
134 | 211 |
135 EXPECT_TRUE(parent->hasNonIsolatedDescendantWithBlendMode()); | 212 EXPECT_TRUE(parent->hasNonIsolatedDescendantWithBlendMode()); |
136 EXPECT_TRUE(stackingParent->hasNonIsolatedDescendantWithBlendMode()); | 213 EXPECT_TRUE(stackingParent->hasNonIsolatedDescendantWithBlendMode()); |
137 EXPECT_FALSE(stackingGrandparent->hasNonIsolatedDescendantWithBlendMode()); | 214 EXPECT_FALSE(stackingGrandparent->hasNonIsolatedDescendantWithBlendMode()); |
138 | 215 |
139 EXPECT_FALSE(parent->hasDescendantWithClipPath()); | 216 EXPECT_FALSE(parent->hasDescendantWithClipPath()); |
140 EXPECT_TRUE(parent->hasVisibleDescendant()); | 217 EXPECT_TRUE(parent->hasVisibleDescendant()); |
141 } | 218 } |
142 | 219 |
143 TEST_F(PaintLayerTest, HasDescendantWithClipPath) { | 220 TEST_P(PaintLayerTest, HasDescendantWithClipPath) { |
144 setBodyInnerHTML( | 221 setBodyInnerHTML( |
145 "<div id='parent' style='position:relative'>" | 222 "<div id='parent' style='position:relative'>" |
146 " <div id='clip-path' style='clip-path: circle(50px at 0 100px)'>" | 223 " <div id='clip-path' style='clip-path: circle(50px at 0 100px)'>" |
147 " </div>" | 224 " </div>" |
148 "</div>"); | 225 "</div>"); |
149 PaintLayer* parent = | 226 PaintLayer* parent = |
150 toLayoutBoxModelObject(getLayoutObjectByElementId("parent"))->layer(); | 227 toLayoutBoxModelObject(getLayoutObjectByElementId("parent"))->layer(); |
151 PaintLayer* clipPath = | 228 PaintLayer* clipPath = |
152 toLayoutBoxModelObject(getLayoutObjectByElementId("clip-path"))->layer(); | 229 toLayoutBoxModelObject(getLayoutObjectByElementId("clip-path"))->layer(); |
153 | 230 |
154 EXPECT_TRUE(parent->hasDescendantWithClipPath()); | 231 EXPECT_TRUE(parent->hasDescendantWithClipPath()); |
155 EXPECT_FALSE(clipPath->hasDescendantWithClipPath()); | 232 EXPECT_FALSE(clipPath->hasDescendantWithClipPath()); |
156 | 233 |
157 EXPECT_FALSE(parent->hasNonIsolatedDescendantWithBlendMode()); | 234 EXPECT_FALSE(parent->hasNonIsolatedDescendantWithBlendMode()); |
158 EXPECT_TRUE(parent->hasVisibleDescendant()); | 235 EXPECT_TRUE(parent->hasVisibleDescendant()); |
159 } | 236 } |
160 | 237 |
161 TEST_F(PaintLayerTest, HasVisibleDescendant) { | 238 TEST_P(PaintLayerTest, HasVisibleDescendant) { |
162 enableCompositing(); | 239 enableCompositing(); |
163 setBodyInnerHTML( | 240 setBodyInnerHTML( |
164 "<div id='invisible' style='position:relative'>" | 241 "<div id='invisible' style='position:relative'>" |
165 " <div id='visible' style='visibility: visible; position: relative'>" | 242 " <div id='visible' style='visibility: visible; position: relative'>" |
166 " </div>" | 243 " </div>" |
167 "</div>"); | 244 "</div>"); |
168 PaintLayer* invisible = | 245 PaintLayer* invisible = |
169 toLayoutBoxModelObject(getLayoutObjectByElementId("invisible"))->layer(); | 246 toLayoutBoxModelObject(getLayoutObjectByElementId("invisible"))->layer(); |
170 PaintLayer* visible = | 247 PaintLayer* visible = |
171 toLayoutBoxModelObject(getLayoutObjectByElementId("visible"))->layer(); | 248 toLayoutBoxModelObject(getLayoutObjectByElementId("visible"))->layer(); |
172 | 249 |
173 EXPECT_TRUE(invisible->hasVisibleDescendant()); | 250 EXPECT_TRUE(invisible->hasVisibleDescendant()); |
174 EXPECT_FALSE(visible->hasVisibleDescendant()); | 251 EXPECT_FALSE(visible->hasVisibleDescendant()); |
175 | 252 |
176 EXPECT_FALSE(invisible->hasNonIsolatedDescendantWithBlendMode()); | 253 EXPECT_FALSE(invisible->hasNonIsolatedDescendantWithBlendMode()); |
177 EXPECT_FALSE(invisible->hasDescendantWithClipPath()); | 254 EXPECT_FALSE(invisible->hasDescendantWithClipPath()); |
178 } | 255 } |
179 | 256 |
180 } // namespace blink | 257 } // namespace blink |
OLD | NEW |