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/HTMLNames.h" | 5 #include "core/HTMLNames.h" |
6 #include "core/frame/FrameView.h" | 6 #include "core/frame/FrameView.h" |
7 #include "core/layout/LayoutTestHelper.h" | 7 #include "core/layout/LayoutTestHelper.h" |
8 #include "core/layout/LayoutView.h" | 8 #include "core/layout/LayoutView.h" |
9 #include "core/paint/PaintLayer.h" | 9 #include "core/paint/PaintLayer.h" |
10 #include "platform/graphics/GraphicsLayer.h" | 10 #include "platform/graphics/GraphicsLayer.h" |
11 #include "platform/graphics/paint/RasterInvalidationTracking.h" | 11 #include "platform/graphics/paint/RasterInvalidationTracking.h" |
12 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" | 12 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" |
13 | 13 |
14 namespace blink { | 14 namespace blink { |
15 | 15 |
16 class BoxPaintInvalidatorTest : public RenderingTest { | 16 class BoxPaintInvalidatorTest : public ::testing::WithParamInterface<bool>, |
| 17 private ScopedRootLayerScrollingForTest, |
| 18 public RenderingTest { |
| 19 public: |
| 20 BoxPaintInvalidatorTest() |
| 21 : ScopedRootLayerScrollingForTest(GetParam()), |
| 22 RenderingTest(SingleChildFrameLoaderClient::create()) {} |
| 23 |
17 protected: | 24 protected: |
18 const RasterInvalidationTracking* getRasterInvalidationTracking() const { | 25 const RasterInvalidationTracking* getRasterInvalidationTracking() const { |
19 // TODO(wangxianzhu): Test SPv2. | 26 // TODO(wangxianzhu): Test SPv2. |
20 return layoutView() | 27 return layoutView() |
21 .layer() | 28 .layer() |
22 ->graphicsLayerBacking() | 29 ->graphicsLayerBackingForScrolling() |
23 ->getRasterInvalidationTracking(); | 30 ->getRasterInvalidationTracking(); |
24 } | 31 } |
25 | 32 |
26 private: | 33 private: |
27 void SetUp() override { | 34 void SetUp() override { |
28 RenderingTest::SetUp(); | 35 RenderingTest::SetUp(); |
29 enableCompositing(); | 36 enableCompositing(); |
30 setBodyInnerHTML( | 37 setBodyInnerHTML( |
31 "<style>" | 38 "<style>" |
32 " body { margin: 0 }" | 39 " body {" |
| 40 " margin: 0;" |
| 41 " height: 0;" |
| 42 " }" |
| 43 " ::-webkit-scrollbar { display: none }" |
33 " #target {" | 44 " #target {" |
34 " width: 50px;" | 45 " width: 50px;" |
35 " height: 100px;" | 46 " height: 100px;" |
| 47 " transform-origin: 0 0;" |
| 48 " }" |
| 49 " .border {" |
36 " border-width: 20px 10px;" | 50 " border-width: 20px 10px;" |
37 " border-style: solid;" | 51 " border-style: solid;" |
38 " border-color: red;" | 52 " border-color: red;" |
39 " transform-origin: 0 0" | 53 " }" |
| 54 " .local-background {" |
| 55 " background-attachment: local;" |
| 56 " overflow: scroll;" |
| 57 " }" |
| 58 " .gradient {" |
| 59 " background-image: linear-gradient(blue, yellow)" |
40 " }" | 60 " }" |
41 "</style>" | 61 "</style>" |
42 "<div id='target'></div>"); | 62 "<div id='target' class='border'></div>"); |
43 } | 63 } |
44 }; | 64 }; |
45 | 65 |
46 TEST_F(BoxPaintInvalidatorTest, IncrementalInvalidationExpand) { | 66 INSTANTIATE_TEST_CASE_P(All, BoxPaintInvalidatorTest, ::testing::Bool()); |
| 67 |
| 68 TEST_P(BoxPaintInvalidatorTest, IncrementalInvalidationExpand) { |
47 document().view()->setTracksPaintInvalidations(true); | 69 document().view()->setTracksPaintInvalidations(true); |
48 Element* target = document().getElementById("target"); | 70 Element* target = document().getElementById("target"); |
49 target->setAttribute(HTMLNames::styleAttr, "width: 100px; height: 200px"); | 71 target->setAttribute(HTMLNames::styleAttr, "width: 100px; height: 200px"); |
50 document().view()->updateAllLifecyclePhases(); | 72 document().view()->updateAllLifecyclePhases(); |
51 const auto& rasterInvalidations = | 73 const auto& rasterInvalidations = |
52 getRasterInvalidationTracking()->trackedRasterInvalidations; | 74 getRasterInvalidationTracking()->trackedRasterInvalidations; |
53 EXPECT_EQ(2u, rasterInvalidations.size()); | 75 ASSERT_EQ(2u, rasterInvalidations.size()); |
54 EXPECT_EQ(IntRect(60, 0, 60, 240), rasterInvalidations[0].rect); | 76 EXPECT_EQ(IntRect(60, 0, 60, 240), rasterInvalidations[0].rect); |
55 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); | 77 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
56 EXPECT_EQ(IntRect(0, 120, 120, 120), rasterInvalidations[1].rect); | 78 EXPECT_EQ(IntRect(0, 120, 120, 120), rasterInvalidations[1].rect); |
57 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); | 79 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); |
58 document().view()->setTracksPaintInvalidations(false); | 80 document().view()->setTracksPaintInvalidations(false); |
59 } | 81 } |
60 | 82 |
61 TEST_F(BoxPaintInvalidatorTest, IncrementalInvalidationShrink) { | 83 TEST_P(BoxPaintInvalidatorTest, IncrementalInvalidationShrink) { |
62 document().view()->setTracksPaintInvalidations(true); | 84 document().view()->setTracksPaintInvalidations(true); |
63 Element* target = document().getElementById("target"); | 85 Element* target = document().getElementById("target"); |
64 target->setAttribute(HTMLNames::styleAttr, "width: 20px; height: 80px"); | 86 target->setAttribute(HTMLNames::styleAttr, "width: 20px; height: 80px"); |
65 document().view()->updateAllLifecyclePhases(); | 87 document().view()->updateAllLifecyclePhases(); |
66 const auto& rasterInvalidations = | 88 const auto& rasterInvalidations = |
67 getRasterInvalidationTracking()->trackedRasterInvalidations; | 89 getRasterInvalidationTracking()->trackedRasterInvalidations; |
68 EXPECT_EQ(2u, rasterInvalidations.size()); | 90 ASSERT_EQ(2u, rasterInvalidations.size()); |
69 EXPECT_EQ(IntRect(30, 0, 40, 140), rasterInvalidations[0].rect); | 91 EXPECT_EQ(IntRect(30, 0, 40, 140), rasterInvalidations[0].rect); |
70 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); | 92 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
71 EXPECT_EQ(IntRect(0, 100, 70, 40), rasterInvalidations[1].rect); | 93 EXPECT_EQ(IntRect(0, 100, 70, 40), rasterInvalidations[1].rect); |
72 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); | 94 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); |
73 document().view()->setTracksPaintInvalidations(false); | 95 document().view()->setTracksPaintInvalidations(false); |
74 } | 96 } |
75 | 97 |
76 TEST_F(BoxPaintInvalidatorTest, IncrementalInvalidationMixed) { | 98 TEST_P(BoxPaintInvalidatorTest, IncrementalInvalidationMixed) { |
77 document().view()->setTracksPaintInvalidations(true); | 99 document().view()->setTracksPaintInvalidations(true); |
78 Element* target = document().getElementById("target"); | 100 Element* target = document().getElementById("target"); |
79 target->setAttribute(HTMLNames::styleAttr, "width: 100px; height: 80px"); | 101 target->setAttribute(HTMLNames::styleAttr, "width: 100px; height: 80px"); |
80 document().view()->updateAllLifecyclePhases(); | 102 document().view()->updateAllLifecyclePhases(); |
81 const auto& rasterInvalidations = | 103 const auto& rasterInvalidations = |
82 getRasterInvalidationTracking()->trackedRasterInvalidations; | 104 getRasterInvalidationTracking()->trackedRasterInvalidations; |
83 EXPECT_EQ(2u, rasterInvalidations.size()); | 105 ASSERT_EQ(2u, rasterInvalidations.size()); |
84 EXPECT_EQ(IntRect(60, 0, 60, 120), rasterInvalidations[0].rect); | 106 EXPECT_EQ(IntRect(60, 0, 60, 120), rasterInvalidations[0].rect); |
85 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); | 107 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
86 EXPECT_EQ(IntRect(0, 100, 70, 40), rasterInvalidations[1].rect); | 108 EXPECT_EQ(IntRect(0, 100, 70, 40), rasterInvalidations[1].rect); |
87 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); | 109 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); |
88 document().view()->setTracksPaintInvalidations(false); | 110 document().view()->setTracksPaintInvalidations(false); |
89 } | 111 } |
90 | 112 |
91 TEST_F(BoxPaintInvalidatorTest, SubpixelVisualRectChagne) { | 113 TEST_P(BoxPaintInvalidatorTest, SubpixelVisualRectChagne) { |
92 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); | 114 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); |
93 | 115 |
94 Element* target = document().getElementById("target"); | 116 Element* target = document().getElementById("target"); |
95 | 117 |
96 // Should do full invalidation if new geometry has subpixels. | 118 // Should do full invalidation if new geometry has subpixels. |
97 document().view()->setTracksPaintInvalidations(true); | 119 document().view()->setTracksPaintInvalidations(true); |
98 target->setAttribute(HTMLNames::styleAttr, "width: 100.6px; height: 70.3px"); | 120 target->setAttribute(HTMLNames::styleAttr, "width: 100.6px; height: 70.3px"); |
99 document().view()->updateAllLifecyclePhases(); | 121 document().view()->updateAllLifecyclePhases(); |
100 const auto* rasterInvalidations = | 122 const auto* rasterInvalidations = |
101 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 123 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
102 EXPECT_EQ(2u, rasterInvalidations->size()); | 124 ASSERT_EQ(2u, rasterInvalidations->size()); |
103 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); | 125 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); |
104 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); | 126 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); |
105 EXPECT_EQ(IntRect(0, 0, 121, 111), (*rasterInvalidations)[1].rect); | 127 EXPECT_EQ(IntRect(0, 0, 121, 111), (*rasterInvalidations)[1].rect); |
106 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[1].reason); | 128 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[1].reason); |
107 document().view()->setTracksPaintInvalidations(false); | 129 document().view()->setTracksPaintInvalidations(false); |
108 | 130 |
109 // Should do full invalidation if old geometry has subpixels. | 131 // Should do full invalidation if old geometry has subpixels. |
110 document().view()->setTracksPaintInvalidations(true); | 132 document().view()->setTracksPaintInvalidations(true); |
111 target->setAttribute(HTMLNames::styleAttr, "width: 50px; height: 100px"); | 133 target->setAttribute(HTMLNames::styleAttr, "width: 50px; height: 100px"); |
112 document().view()->updateAllLifecyclePhases(); | 134 document().view()->updateAllLifecyclePhases(); |
113 rasterInvalidations = | 135 rasterInvalidations = |
114 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 136 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
115 EXPECT_EQ(2u, rasterInvalidations->size()); | 137 ASSERT_EQ(2u, rasterInvalidations->size()); |
116 EXPECT_EQ(IntRect(0, 0, 121, 111), (*rasterInvalidations)[0].rect); | 138 EXPECT_EQ(IntRect(0, 0, 121, 111), (*rasterInvalidations)[0].rect); |
117 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); | 139 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); |
118 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[1].rect); | 140 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[1].rect); |
119 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[1].reason); | 141 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[1].reason); |
120 document().view()->setTracksPaintInvalidations(false); | 142 document().view()->setTracksPaintInvalidations(false); |
121 } | 143 } |
122 | 144 |
123 TEST_F(BoxPaintInvalidatorTest, SubpixelChangeWithoutVisualRectChange) { | 145 TEST_P(BoxPaintInvalidatorTest, SubpixelChangeWithoutVisualRectChange) { |
124 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); | 146 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); |
125 | 147 |
126 Element* target = document().getElementById("target"); | 148 Element* target = document().getElementById("target"); |
127 LayoutObject* targetObject = target->layoutObject(); | 149 LayoutObject* targetObject = target->layoutObject(); |
128 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); | 150 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); |
129 | 151 |
130 // Should do full invalidation if new geometry has subpixels even if the paint | 152 // Should do full invalidation if new geometry has subpixels even if the paint |
131 // invalidation rect doesn't change. | 153 // invalidation rect doesn't change. |
132 document().view()->setTracksPaintInvalidations(true); | 154 document().view()->setTracksPaintInvalidations(true); |
133 target->setAttribute(HTMLNames::styleAttr, | 155 target->setAttribute(HTMLNames::styleAttr, |
134 "margin-top: 0.6px; width: 50px; height: 99.3px"); | 156 "margin-top: 0.6px; width: 50px; height: 99.3px"); |
135 document().view()->updateAllLifecyclePhases(); | 157 document().view()->updateAllLifecyclePhases(); |
136 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); | 158 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); |
137 const auto* rasterInvalidations = | 159 const auto* rasterInvalidations = |
138 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 160 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
139 EXPECT_EQ(1u, rasterInvalidations->size()); | 161 ASSERT_EQ(1u, rasterInvalidations->size()); |
140 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); | 162 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); |
141 EXPECT_EQ(PaintInvalidationLocationChange, (*rasterInvalidations)[0].reason); | 163 EXPECT_EQ(PaintInvalidationLocationChange, (*rasterInvalidations)[0].reason); |
142 document().view()->setTracksPaintInvalidations(false); | 164 document().view()->setTracksPaintInvalidations(false); |
143 | 165 |
144 document().view()->setTracksPaintInvalidations(true); | 166 document().view()->setTracksPaintInvalidations(true); |
145 target->setAttribute(HTMLNames::styleAttr, | 167 target->setAttribute(HTMLNames::styleAttr, |
146 "margin-top: 0.6px; width: 49.3px; height: 98.5px"); | 168 "margin-top: 0.6px; width: 49.3px; height: 98.5px"); |
147 document().view()->updateAllLifecyclePhases(); | 169 document().view()->updateAllLifecyclePhases(); |
148 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); | 170 EXPECT_EQ(LayoutRect(0, 0, 70, 140), targetObject->previousVisualRect()); |
149 rasterInvalidations = | 171 rasterInvalidations = |
150 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 172 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
151 EXPECT_EQ(1u, rasterInvalidations->size()); | 173 ASSERT_EQ(1u, rasterInvalidations->size()); |
152 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); | 174 EXPECT_EQ(IntRect(0, 0, 70, 140), (*rasterInvalidations)[0].rect); |
153 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); | 175 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); |
154 document().view()->setTracksPaintInvalidations(false); | 176 document().view()->setTracksPaintInvalidations(false); |
155 } | 177 } |
156 | 178 |
157 TEST_F(BoxPaintInvalidatorTest, ResizeRotated) { | 179 TEST_P(BoxPaintInvalidatorTest, ResizeRotated) { |
158 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); | 180 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); |
159 | 181 |
160 Element* target = document().getElementById("target"); | 182 Element* target = document().getElementById("target"); |
161 target->setAttribute(HTMLNames::styleAttr, "transform: rotate(45deg)"); | 183 target->setAttribute(HTMLNames::styleAttr, "transform: rotate(45deg)"); |
162 document().view()->updateAllLifecyclePhases(); | 184 document().view()->updateAllLifecyclePhases(); |
163 | 185 |
164 // Should do full invalidation a rotated object is resized. | 186 // Should do full invalidation a rotated object is resized. |
165 document().view()->setTracksPaintInvalidations(true); | 187 document().view()->setTracksPaintInvalidations(true); |
166 target->setAttribute(HTMLNames::styleAttr, | 188 target->setAttribute(HTMLNames::styleAttr, |
167 "transform: rotate(45deg); width: 200px"); | 189 "transform: rotate(45deg); width: 200px"); |
168 document().view()->updateAllLifecyclePhases(); | 190 document().view()->updateAllLifecyclePhases(); |
169 const auto* rasterInvalidations = | 191 const auto* rasterInvalidations = |
170 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 192 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
171 EXPECT_EQ(1u, rasterInvalidations->size()); | 193 ASSERT_EQ(1u, rasterInvalidations->size()); |
172 EXPECT_EQ(IntRect(-99, 0, 255, 255), (*rasterInvalidations)[0].rect); | 194 EXPECT_EQ(IntRect(-99, 0, 255, 255), (*rasterInvalidations)[0].rect); |
173 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); | 195 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); |
174 document().view()->setTracksPaintInvalidations(false); | 196 document().view()->setTracksPaintInvalidations(false); |
175 } | 197 } |
176 | 198 |
177 TEST_F(BoxPaintInvalidatorTest, ResizeRotatedChild) { | 199 TEST_P(BoxPaintInvalidatorTest, ResizeRotatedChild) { |
178 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); | 200 ScopedSlimmingPaintInvalidationForTest scopedSlimmingPaintInvalidation(true); |
179 | 201 |
180 Element* target = document().getElementById("target"); | 202 Element* target = document().getElementById("target"); |
181 target->setAttribute(HTMLNames::styleAttr, | 203 target->setAttribute(HTMLNames::styleAttr, |
182 "transform: rotate(45deg); width: 200px"); | 204 "transform: rotate(45deg); width: 200px"); |
183 target->setInnerHTML( | 205 target->setInnerHTML( |
184 "<div id=child style='width: 50px; height: 50px; background: " | 206 "<div id=child style='width: 50px; height: 50px; background: " |
185 "red'></div>"); | 207 "red'></div>"); |
186 document().view()->updateAllLifecyclePhases(); | 208 document().view()->updateAllLifecyclePhases(); |
187 Element* child = document().getElementById("child"); | 209 Element* child = document().getElementById("child"); |
188 | 210 |
189 // Should do full invalidation a rotated object is resized. | 211 // Should do full invalidation a rotated object is resized. |
190 document().view()->setTracksPaintInvalidations(true); | 212 document().view()->setTracksPaintInvalidations(true); |
191 child->setAttribute(HTMLNames::styleAttr, | 213 child->setAttribute(HTMLNames::styleAttr, |
192 "width: 100px; height: 50px; background: red"); | 214 "width: 100px; height: 50px; background: red"); |
193 document().view()->updateAllLifecyclePhases(); | 215 document().view()->updateAllLifecyclePhases(); |
194 const auto* rasterInvalidations = | 216 const auto* rasterInvalidations = |
195 &getRasterInvalidationTracking()->trackedRasterInvalidations; | 217 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
196 EXPECT_EQ(1u, rasterInvalidations->size()); | 218 ASSERT_EQ(1u, rasterInvalidations->size()); |
197 EXPECT_EQ(IntRect(-43, 21, 107, 107), (*rasterInvalidations)[0].rect); | 219 EXPECT_EQ(IntRect(-43, 21, 107, 107), (*rasterInvalidations)[0].rect); |
198 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); | 220 EXPECT_EQ(PaintInvalidationBorderBoxChange, (*rasterInvalidations)[0].reason); |
199 document().view()->setTracksPaintInvalidations(false); | 221 document().view()->setTracksPaintInvalidations(false); |
200 } | 222 } |
201 | 223 |
| 224 TEST_P(BoxPaintInvalidatorTest, CompositedLayoutViewResize) { |
| 225 enableCompositing(); |
| 226 Element* target = document().getElementById("target"); |
| 227 target->setAttribute(HTMLNames::classAttr, ""); |
| 228 target->setAttribute(HTMLNames::styleAttr, "height: 2000px"); |
| 229 document().view()->updateAllLifecyclePhases(); |
| 230 |
| 231 // Resize the content. |
| 232 document().view()->setTracksPaintInvalidations(true); |
| 233 target->setAttribute(HTMLNames::styleAttr, "height: 3000px"); |
| 234 document().view()->updateAllLifecyclePhases(); |
| 235 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 236 // For now in RootLayerScrolling mode root background is invalidated and |
| 237 // painted on the container layer. No invalidation because the changed part |
| 238 // is clipped. |
| 239 // TODO(skobes): Treat LayoutView in the same way as normal objects having |
| 240 // background-attachment: local. crbug.com/568847. |
| 241 EXPECT_FALSE(layoutView() |
| 242 .layer() |
| 243 ->graphicsLayerBacking() |
| 244 ->getRasterInvalidationTracking()); |
| 245 } else { |
| 246 const auto& rasterInvalidations = |
| 247 getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 248 ASSERT_EQ(1u, rasterInvalidations.size()); |
| 249 EXPECT_EQ(IntRect(0, 2000, 800, 1000), rasterInvalidations[0].rect); |
| 250 EXPECT_EQ(static_cast<const DisplayItemClient*>(&layoutView()), |
| 251 rasterInvalidations[0].client); |
| 252 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
| 253 } |
| 254 document().view()->setTracksPaintInvalidations(false); |
| 255 |
| 256 // Resize the viewport. No paint invalidation. |
| 257 document().view()->setTracksPaintInvalidations(true); |
| 258 document().view()->resize(800, 1000); |
| 259 document().view()->updateAllLifecyclePhases(); |
| 260 EXPECT_FALSE(getRasterInvalidationTracking()); |
| 261 document().view()->setTracksPaintInvalidations(false); |
| 262 } |
| 263 |
| 264 TEST_P(BoxPaintInvalidatorTest, CompositedLayoutViewGradientResize) { |
| 265 enableCompositing(); |
| 266 document().body()->setAttribute(HTMLNames::classAttr, "gradient"); |
| 267 Element* target = document().getElementById("target"); |
| 268 target->setAttribute(HTMLNames::classAttr, ""); |
| 269 target->setAttribute(HTMLNames::styleAttr, "height: 2000px"); |
| 270 document().view()->updateAllLifecyclePhases(); |
| 271 |
| 272 // Resize the content. |
| 273 document().view()->setTracksPaintInvalidations(true); |
| 274 target->setAttribute(HTMLNames::styleAttr, "height: 3000px"); |
| 275 document().view()->updateAllLifecyclePhases(); |
| 276 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 277 // For now in RootLayerScrolling mode root background is invalidated and |
| 278 // painted on the container layer. |
| 279 // TODO(skobes): Treat LayoutView in the same way as normal objects having |
| 280 // background-attachment: local. crbug.com/568847. |
| 281 const auto& rasterInvalidations = layoutView() |
| 282 .layer() |
| 283 ->graphicsLayerBacking() |
| 284 ->getRasterInvalidationTracking() |
| 285 ->trackedRasterInvalidations; |
| 286 ASSERT_EQ(1u, rasterInvalidations.size()); |
| 287 EXPECT_EQ(IntRect(0, 0, 800, 600), rasterInvalidations[0].rect); |
| 288 EXPECT_EQ(static_cast<const DisplayItemClient*>(&layoutView()), |
| 289 rasterInvalidations[0].client); |
| 290 EXPECT_EQ(PaintInvalidationLayoutOverflowBoxChange, |
| 291 rasterInvalidations[0].reason); |
| 292 } else { |
| 293 const auto& rasterInvalidations = |
| 294 getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 295 ASSERT_EQ(1u, rasterInvalidations.size()); |
| 296 EXPECT_EQ(IntRect(0, 0, 800, 3000), rasterInvalidations[0].rect); |
| 297 EXPECT_EQ(static_cast<const DisplayItemClient*>(&layoutView()), |
| 298 rasterInvalidations[0].client); |
| 299 EXPECT_EQ(PaintInvalidationLayoutOverflowBoxChange, |
| 300 rasterInvalidations[0].reason); |
| 301 } |
| 302 document().view()->setTracksPaintInvalidations(false); |
| 303 |
| 304 // Resize the viewport. No paint invalidation. |
| 305 document().view()->setTracksPaintInvalidations(true); |
| 306 document().view()->resize(800, 1000); |
| 307 document().view()->updateAllLifecyclePhases(); |
| 308 EXPECT_FALSE(getRasterInvalidationTracking()); |
| 309 document().view()->setTracksPaintInvalidations(false); |
| 310 } |
| 311 |
| 312 TEST_P(BoxPaintInvalidatorTest, NonCompositedLayoutViewResize) { |
| 313 setBodyInnerHTML( |
| 314 "<style>" |
| 315 " body { margin: 0 }" |
| 316 " iframe { display: block; width: 100px; height: 100px; border: none; }" |
| 317 "</style>" |
| 318 "<iframe id='iframe'></iframe>"); |
| 319 Document& frameDocument = setupChildIframe( |
| 320 "iframe", |
| 321 "<style>" |
| 322 " ::-webkit-scrollbar { display: none }" |
| 323 " body { margin: 0; background: green; height: 0 }" |
| 324 "</style>" |
| 325 "<div id='content' style='width: 200px; height: 200px'></div>"); |
| 326 document().view()->updateAllLifecyclePhases(); |
| 327 Element* iframe = document().getElementById("iframe"); |
| 328 Element* content = frameDocument.getElementById("content"); |
| 329 EXPECT_EQ(layoutView(), |
| 330 content->layoutObject()->containerForPaintInvalidation()); |
| 331 |
| 332 // Resize the content. |
| 333 document().view()->setTracksPaintInvalidations(true); |
| 334 content->setAttribute(HTMLNames::styleAttr, "height: 500px"); |
| 335 document().view()->updateAllLifecyclePhases(); |
| 336 // No invalidation because the changed part of layout overflow is clipped. |
| 337 EXPECT_FALSE(getRasterInvalidationTracking()); |
| 338 document().view()->setTracksPaintInvalidations(false); |
| 339 |
| 340 // Resize the iframe. |
| 341 document().view()->setTracksPaintInvalidations(true); |
| 342 iframe->setAttribute(HTMLNames::styleAttr, "height: 200px"); |
| 343 document().view()->updateAllLifecyclePhases(); |
| 344 const auto& rasterInvalidations = |
| 345 getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 346 ASSERT_EQ(2u, rasterInvalidations.size()); |
| 347 EXPECT_EQ(IntRect(0, 100, 100, 100), rasterInvalidations[0].rect); |
| 348 EXPECT_EQ(static_cast<const DisplayItemClient*>(iframe->layoutObject()), |
| 349 rasterInvalidations[0].client); |
| 350 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
| 351 EXPECT_EQ( |
| 352 static_cast<const DisplayItemClient*>(content->layoutObject()->view()), |
| 353 rasterInvalidations[1].client); |
| 354 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 355 // TODO(skobes): Treat LayoutView in the same way as normal objects having |
| 356 // background-attachment: local. crbug.com/568847. |
| 357 EXPECT_EQ(IntRect(0, 0, 100, 200), rasterInvalidations[1].rect); |
| 358 EXPECT_EQ(PaintInvalidationFull, rasterInvalidations[1].reason); |
| 359 } else { |
| 360 EXPECT_EQ(IntRect(0, 100, 100, 100), rasterInvalidations[1].rect); |
| 361 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[1].reason); |
| 362 } |
| 363 document().view()->setTracksPaintInvalidations(false); |
| 364 } |
| 365 |
| 366 TEST_P(BoxPaintInvalidatorTest, NonCompositedLayoutViewGradientResize) { |
| 367 setBodyInnerHTML( |
| 368 "<style>" |
| 369 " body { margin: 0 }" |
| 370 " iframe { display: block; width: 100px; height: 100px; border: none; }" |
| 371 "</style>" |
| 372 "<iframe id='iframe'></iframe>"); |
| 373 Document& frameDocument = setupChildIframe( |
| 374 "iframe", |
| 375 "<style>" |
| 376 " ::-webkit-scrollbar { display: none }" |
| 377 " body {" |
| 378 " margin: 0;" |
| 379 " height: 0;" |
| 380 " background-image: linear-gradient(blue, yellow);" |
| 381 " }" |
| 382 "</style>" |
| 383 "<div id='content' style='width: 200px; height: 200px'></div>"); |
| 384 document().view()->updateAllLifecyclePhases(); |
| 385 Element* iframe = document().getElementById("iframe"); |
| 386 Element* content = frameDocument.getElementById("content"); |
| 387 LayoutView* frameLayoutView = content->layoutObject()->view(); |
| 388 EXPECT_EQ(layoutView(), |
| 389 content->layoutObject()->containerForPaintInvalidation()); |
| 390 |
| 391 // Resize the content. |
| 392 document().view()->setTracksPaintInvalidations(true); |
| 393 content->setAttribute(HTMLNames::styleAttr, "height: 500px"); |
| 394 document().view()->updateAllLifecyclePhases(); |
| 395 const auto* rasterInvalidations = |
| 396 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 397 ASSERT_EQ(1u, rasterInvalidations->size()); |
| 398 EXPECT_EQ(IntRect(0, 0, 100, 100), (*rasterInvalidations)[0].rect); |
| 399 EXPECT_EQ(static_cast<const DisplayItemClient*>(frameLayoutView), |
| 400 (*rasterInvalidations)[0].client); |
| 401 EXPECT_EQ(PaintInvalidationLayoutOverflowBoxChange, |
| 402 (*rasterInvalidations)[0].reason); |
| 403 document().view()->setTracksPaintInvalidations(false); |
| 404 |
| 405 // Resize the iframe. |
| 406 document().view()->setTracksPaintInvalidations(true); |
| 407 iframe->setAttribute(HTMLNames::styleAttr, "height: 200px"); |
| 408 document().view()->updateAllLifecyclePhases(); |
| 409 rasterInvalidations = |
| 410 &getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 411 ASSERT_EQ(2u, rasterInvalidations->size()); |
| 412 EXPECT_EQ(IntRect(0, 100, 100, 100), (*rasterInvalidations)[0].rect); |
| 413 EXPECT_EQ(static_cast<const DisplayItemClient*>(iframe->layoutObject()), |
| 414 (*rasterInvalidations)[0].client); |
| 415 EXPECT_EQ(PaintInvalidationIncremental, (*rasterInvalidations)[0].reason); |
| 416 EXPECT_EQ(static_cast<const DisplayItemClient*>(frameLayoutView), |
| 417 (*rasterInvalidations)[1].client); |
| 418 EXPECT_EQ(IntRect(0, 0, 100, 200), (*rasterInvalidations)[1].rect); |
| 419 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 420 // TODO(skobes): Treat LayoutView in the same way as normal objects having |
| 421 // background-attachment: local. crbug.com/568847. |
| 422 EXPECT_EQ(PaintInvalidationFull, (*rasterInvalidations)[1].reason); |
| 423 } else { |
| 424 EXPECT_EQ(PaintInvalidationBorderBoxChange, |
| 425 (*rasterInvalidations)[1].reason); |
| 426 } |
| 427 document().view()->setTracksPaintInvalidations(false); |
| 428 } |
| 429 |
| 430 TEST_P(BoxPaintInvalidatorTest, CompositedBackgroundAttachmentLocalResize) { |
| 431 enableCompositing(); |
| 432 |
| 433 Element* target = document().getElementById("target"); |
| 434 target->setAttribute(HTMLNames::classAttr, "border local-background"); |
| 435 target->setAttribute(HTMLNames::styleAttr, "will-change: transform"); |
| 436 target->setInnerHTML( |
| 437 "<div id=child style='width: 500px; height: 500px'></div>", |
| 438 ASSERT_NO_EXCEPTION); |
| 439 Element* child = document().getElementById("child"); |
| 440 document().view()->updateAllLifecyclePhases(); |
| 441 |
| 442 // Resize the content. |
| 443 document().view()->setTracksPaintInvalidations(true); |
| 444 child->setAttribute(HTMLNames::styleAttr, "width: 500px; height: 1000px"); |
| 445 document().view()->updateAllLifecyclePhases(); |
| 446 GraphicsLayer* containerLayer = toLayoutBoxModelObject(target->layoutObject()) |
| 447 ->layer() |
| 448 ->graphicsLayerBacking(); |
| 449 GraphicsLayer* contentsLayer = toLayoutBoxModelObject(target->layoutObject()) |
| 450 ->layer() |
| 451 ->graphicsLayerBackingForScrolling(); |
| 452 // No invalidation on the container layer. |
| 453 EXPECT_FALSE(containerLayer->getRasterInvalidationTracking()); |
| 454 // Incremental invalidation of background on contents layer. |
| 455 const auto& contentsRasterInvalidations = |
| 456 contentsLayer->getRasterInvalidationTracking() |
| 457 ->trackedRasterInvalidations; |
| 458 ASSERT_EQ(1u, contentsRasterInvalidations.size()); |
| 459 EXPECT_EQ(IntRect(0, 500, 500, 500), contentsRasterInvalidations[0].rect); |
| 460 EXPECT_EQ(static_cast<const DisplayItemClient*>(target->layoutObject()), |
| 461 contentsRasterInvalidations[0].client); |
| 462 EXPECT_EQ(PaintInvalidationBackgroundOnScrollingContentsLayer, |
| 463 contentsRasterInvalidations[0].reason); |
| 464 document().view()->setTracksPaintInvalidations(false); |
| 465 |
| 466 // Resize the container. |
| 467 document().view()->setTracksPaintInvalidations(true); |
| 468 target->setAttribute(HTMLNames::styleAttr, |
| 469 "will-change: transform; height: 200px"); |
| 470 document().view()->updateAllLifecyclePhases(); |
| 471 // No invalidation on the contents layer. |
| 472 EXPECT_FALSE(contentsLayer->getRasterInvalidationTracking()); |
| 473 // Incremental invalidation on the container layer. |
| 474 const auto& containerRasterInvalidations = |
| 475 containerLayer->getRasterInvalidationTracking() |
| 476 ->trackedRasterInvalidations; |
| 477 ASSERT_EQ(1u, containerRasterInvalidations.size()); |
| 478 EXPECT_EQ(IntRect(0, 120, 70, 120), containerRasterInvalidations[0].rect); |
| 479 EXPECT_EQ(static_cast<const DisplayItemClient*>(target->layoutObject()), |
| 480 containerRasterInvalidations[0].client); |
| 481 EXPECT_EQ(PaintInvalidationIncremental, |
| 482 containerRasterInvalidations[0].reason); |
| 483 document().view()->setTracksPaintInvalidations(false); |
| 484 } |
| 485 |
| 486 TEST_P(BoxPaintInvalidatorTest, |
| 487 CompositedBackgroundAttachmentLocalGradientResize) { |
| 488 enableCompositing(); |
| 489 |
| 490 Element* target = document().getElementById("target"); |
| 491 target->setAttribute(HTMLNames::classAttr, |
| 492 "border local-background gradient"); |
| 493 target->setAttribute(HTMLNames::styleAttr, "will-change: transform"); |
| 494 target->setInnerHTML( |
| 495 "<div id='child' style='width: 500px; height: 500px'></div>", |
| 496 ASSERT_NO_EXCEPTION); |
| 497 Element* child = document().getElementById("child"); |
| 498 document().view()->updateAllLifecyclePhases(); |
| 499 |
| 500 // Resize the content. |
| 501 document().view()->setTracksPaintInvalidations(true); |
| 502 child->setAttribute(HTMLNames::styleAttr, "width: 500px; height: 1000px"); |
| 503 document().view()->updateAllLifecyclePhases(); |
| 504 GraphicsLayer* containerLayer = toLayoutBoxModelObject(target->layoutObject()) |
| 505 ->layer() |
| 506 ->graphicsLayerBacking(); |
| 507 GraphicsLayer* contentsLayer = toLayoutBoxModelObject(target->layoutObject()) |
| 508 ->layer() |
| 509 ->graphicsLayerBackingForScrolling(); |
| 510 // No invalidation on the container layer. |
| 511 EXPECT_FALSE(containerLayer->getRasterInvalidationTracking()); |
| 512 // Full invalidation of background on contents layer because the gradient |
| 513 // background is resized. |
| 514 const auto& contentsRasterInvalidations = |
| 515 contentsLayer->getRasterInvalidationTracking() |
| 516 ->trackedRasterInvalidations; |
| 517 ASSERT_EQ(1u, contentsRasterInvalidations.size()); |
| 518 EXPECT_EQ(IntRect(0, 0, 500, 1000), contentsRasterInvalidations[0].rect); |
| 519 EXPECT_EQ(static_cast<const DisplayItemClient*>(target->layoutObject()), |
| 520 contentsRasterInvalidations[0].client); |
| 521 EXPECT_EQ(PaintInvalidationBackgroundOnScrollingContentsLayer, |
| 522 contentsRasterInvalidations[0].reason); |
| 523 document().view()->setTracksPaintInvalidations(false); |
| 524 |
| 525 // Resize the container. |
| 526 document().view()->setTracksPaintInvalidations(true); |
| 527 target->setAttribute(HTMLNames::styleAttr, |
| 528 "will-change: transform; height: 200px"); |
| 529 document().view()->updateAllLifecyclePhases(); |
| 530 EXPECT_FALSE(contentsLayer->getRasterInvalidationTracking()); |
| 531 // Full invalidation on the container layer. |
| 532 const auto& containerRasterInvalidations = |
| 533 containerLayer->getRasterInvalidationTracking() |
| 534 ->trackedRasterInvalidations; |
| 535 ASSERT_EQ(1u, containerRasterInvalidations.size()); |
| 536 EXPECT_EQ(IntRect(0, 0, 70, 240), containerRasterInvalidations[0].rect); |
| 537 EXPECT_EQ(static_cast<const DisplayItemClient*>(target->layoutObject()), |
| 538 containerRasterInvalidations[0].client); |
| 539 EXPECT_EQ(PaintInvalidationBorderBoxChange, |
| 540 containerRasterInvalidations[0].reason); |
| 541 document().view()->setTracksPaintInvalidations(false); |
| 542 } |
| 543 |
| 544 TEST_P(BoxPaintInvalidatorTest, NonCompositedBackgroundAttachmentLocalResize) { |
| 545 Element* target = document().getElementById("target"); |
| 546 target->setAttribute(HTMLNames::classAttr, "border local-background"); |
| 547 target->setInnerHTML( |
| 548 "<div id=child style='width: 500px; height: 500px'></div>", |
| 549 ASSERT_NO_EXCEPTION); |
| 550 Element* child = document().getElementById("child"); |
| 551 document().view()->updateAllLifecyclePhases(); |
| 552 EXPECT_EQ(&layoutView(), |
| 553 &target->layoutObject()->containerForPaintInvalidation()); |
| 554 |
| 555 // Resize the content. |
| 556 document().view()->setTracksPaintInvalidations(true); |
| 557 child->setAttribute(HTMLNames::styleAttr, "width: 500px; height: 1000px"); |
| 558 document().view()->updateAllLifecyclePhases(); |
| 559 // No invalidation because the changed part is invisible. |
| 560 EXPECT_FALSE(getRasterInvalidationTracking()); |
| 561 |
| 562 // Resize the container. |
| 563 document().view()->setTracksPaintInvalidations(true); |
| 564 target->setAttribute(HTMLNames::styleAttr, "height: 200px"); |
| 565 document().view()->updateAllLifecyclePhases(); |
| 566 const auto& rasterInvalidations = |
| 567 getRasterInvalidationTracking()->trackedRasterInvalidations; |
| 568 ASSERT_EQ(1u, rasterInvalidations.size()); |
| 569 EXPECT_EQ(IntRect(0, 120, 70, 120), rasterInvalidations[0].rect); |
| 570 EXPECT_EQ(static_cast<const DisplayItemClient*>(target->layoutObject()), |
| 571 rasterInvalidations[0].client); |
| 572 EXPECT_EQ(PaintInvalidationIncremental, rasterInvalidations[0].reason); |
| 573 document().view()->setTracksPaintInvalidations(false); |
| 574 } |
| 575 |
202 } // namespace blink | 576 } // namespace blink |
OLD | NEW |