Chromium Code Reviews| 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 |