OLD | NEW |
| (Empty) |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 | |
7 #include "CCLayerTreeHostCommon.h" | |
8 | |
9 #include "CCAnimationTestCommon.h" | |
10 #include "CCGeometryTestUtils.h" | |
11 #include "CCLayerAnimationController.h" | |
12 #include "CCLayerImpl.h" | |
13 #include "CCLayerSorter.h" | |
14 #include "CCMathUtil.h" | |
15 #include "CCProxy.h" | |
16 #include "CCSingleThreadProxy.h" | |
17 #include "CCThread.h" | |
18 #include "ContentLayerChromium.h" | |
19 #include "ContentLayerChromiumClient.h" | |
20 #include "LayerChromium.h" | |
21 | |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 #include <public/WebTransformationMatrix.h> | |
25 | |
26 using namespace cc; | |
27 using namespace WebKitTests; | |
28 using WebKit::WebTransformationMatrix; | |
29 | |
30 namespace { | |
31 | |
32 template<typename LayerType> | |
33 void setLayerPropertiesForTesting(LayerType* layer, const WebTransformationMatri
x& transform, const WebTransformationMatrix& sublayerTransform, const FloatPoint
& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D) | |
34 { | |
35 layer->setTransform(transform); | |
36 layer->setSublayerTransform(sublayerTransform); | |
37 layer->setAnchorPoint(anchor); | |
38 layer->setPosition(position); | |
39 layer->setBounds(bounds); | |
40 layer->setPreserves3D(preserves3D); | |
41 } | |
42 | |
43 void setLayerPropertiesForTesting(LayerChromium* layer, const WebTransformationM
atrix& transform, const WebTransformationMatrix& sublayerTransform, const FloatP
oint& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3
D) | |
44 { | |
45 setLayerPropertiesForTesting<LayerChromium>(layer, transform, sublayerTransf
orm, anchor, position, bounds, preserves3D); | |
46 } | |
47 | |
48 void setLayerPropertiesForTesting(CCLayerImpl* layer, const WebTransformationMat
rix& transform, const WebTransformationMatrix& sublayerTransform, const FloatPoi
nt& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D) | |
49 { | |
50 setLayerPropertiesForTesting<CCLayerImpl>(layer, transform, sublayerTransfor
m, anchor, position, bounds, preserves3D); | |
51 layer->setContentBounds(bounds); | |
52 } | |
53 | |
54 void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer, float
deviceScaleFactor = 1) | |
55 { | |
56 WebTransformationMatrix identityMatrix; | |
57 std::vector<scoped_refptr<LayerChromium> > dummyRenderSurfaceLayerList; | |
58 int dummyMaxTextureSize = 512; | |
59 IntSize deviceViewportSize = IntSize(rootLayer->bounds().width() * deviceSca
leFactor, rootLayer->bounds().height() * deviceScaleFactor); | |
60 | |
61 // We are probably not testing what is intended if the rootLayer bounds are
empty. | |
62 ASSERT(!rootLayer->bounds().isEmpty()); | |
63 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize
, deviceScaleFactor, dummyMaxTextureSize, dummyRenderSurfaceLayerList); | |
64 } | |
65 | |
66 void executeCalculateDrawTransformsAndVisibility(CCLayerImpl* rootLayer, float d
eviceScaleFactor = 1) | |
67 { | |
68 // Note: this version skips layer sorting. | |
69 | |
70 WebTransformationMatrix identityMatrix; | |
71 std::vector<CCLayerImpl*> dummyRenderSurfaceLayerList; | |
72 int dummyMaxTextureSize = 512; | |
73 IntSize deviceViewportSize = IntSize(rootLayer->bounds().width() * deviceSca
leFactor, rootLayer->bounds().height() * deviceScaleFactor); | |
74 | |
75 // We are probably not testing what is intended if the rootLayer bounds are
empty. | |
76 ASSERT(!rootLayer->bounds().isEmpty()); | |
77 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize
, deviceScaleFactor, 0, dummyMaxTextureSize, dummyRenderSurfaceLayerList); | |
78 } | |
79 | |
80 WebTransformationMatrix remove3DComponentOfMatrix(const WebTransformationMatrix&
mat) | |
81 { | |
82 WebTransformationMatrix ret = mat; | |
83 ret.setM13(0); | |
84 ret.setM23(0); | |
85 ret.setM31(0); | |
86 ret.setM32(0); | |
87 ret.setM33(1); | |
88 ret.setM34(0); | |
89 ret.setM43(0); | |
90 return ret; | |
91 } | |
92 | |
93 scoped_ptr<CCLayerImpl> createTreeForFixedPositionTests() | |
94 { | |
95 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
96 scoped_ptr<CCLayerImpl> child = CCLayerImpl::create(2); | |
97 scoped_ptr<CCLayerImpl> grandChild = CCLayerImpl::create(3); | |
98 scoped_ptr<CCLayerImpl> greatGrandChild = CCLayerImpl::create(4); | |
99 | |
100 WebTransformationMatrix IdentityMatrix; | |
101 FloatPoint anchor(0, 0); | |
102 FloatPoint position(0, 0); | |
103 IntSize bounds(100, 100); | |
104 setLayerPropertiesForTesting(root.get(), IdentityMatrix, IdentityMatrix, anc
hor, position, bounds, false); | |
105 setLayerPropertiesForTesting(child.get(), IdentityMatrix, IdentityMatrix, an
chor, position, bounds, false); | |
106 setLayerPropertiesForTesting(grandChild.get(), IdentityMatrix, IdentityMatri
x, anchor, position, bounds, false); | |
107 setLayerPropertiesForTesting(greatGrandChild.get(), IdentityMatrix, Identity
Matrix, anchor, position, bounds, false); | |
108 | |
109 grandChild->addChild(greatGrandChild.Pass()); | |
110 child->addChild(grandChild.Pass()); | |
111 root->addChild(child.Pass()); | |
112 | |
113 return root.Pass(); | |
114 } | |
115 | |
116 class LayerChromiumWithForcedDrawsContent : public LayerChromium { | |
117 public: | |
118 LayerChromiumWithForcedDrawsContent() | |
119 : LayerChromium() | |
120 { | |
121 } | |
122 | |
123 virtual bool drawsContent() const OVERRIDE { return true; } | |
124 | |
125 private: | |
126 virtual ~LayerChromiumWithForcedDrawsContent() | |
127 { | |
128 } | |
129 }; | |
130 | |
131 class MockContentLayerChromiumClient : public ContentLayerChromiumClient { | |
132 public: | |
133 MockContentLayerChromiumClient() { } | |
134 virtual ~MockContentLayerChromiumClient() { } | |
135 virtual void paintContents(SkCanvas*, const IntRect& clip, FloatRect& opaque
) OVERRIDE { } | |
136 }; | |
137 | |
138 scoped_refptr<ContentLayerChromium> createDrawableContentLayerChromium(ContentLa
yerChromiumClient* delegate) | |
139 { | |
140 scoped_refptr<ContentLayerChromium> toReturn = ContentLayerChromium::create(
delegate); | |
141 toReturn->setIsDrawable(true); | |
142 return toReturn; | |
143 } | |
144 | |
145 TEST(CCLayerTreeHostCommonTest, verifyTransformsForNoOpLayer) | |
146 { | |
147 // Sanity check: For layers positioned at zero, with zero size, | |
148 // and with identity transforms, then the drawTransform, | |
149 // screenSpaceTransform, and the hierarchy passed on to children | |
150 // layers should also be identity transforms. | |
151 | |
152 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
153 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
154 scoped_refptr<LayerChromium> grandChild = LayerChromium::create(); | |
155 parent->addChild(child); | |
156 child->addChild(grandChild); | |
157 | |
158 WebTransformationMatrix identityMatrix; | |
159 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
160 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false); | |
161 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false); | |
162 | |
163 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
164 | |
165 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform()); | |
166 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform(
)); | |
167 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform())
; | |
168 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTrans
form()); | |
169 } | |
170 | |
171 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleLayer) | |
172 { | |
173 WebTransformationMatrix identityMatrix; | |
174 scoped_refptr<LayerChromium> layer = LayerChromium::create(); | |
175 | |
176 // Case 1: setting the sublayer transform should not affect this layer's dra
w transform or screen-space transform. | |
177 WebTransformationMatrix arbitraryTranslation; | |
178 arbitraryTranslation.translate(10, 20); | |
179 setLayerPropertiesForTesting(layer.get(), identityMatrix, arbitraryTranslati
on, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
180 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
181 WebTransformationMatrix expectedDrawTransform = identityMatrix; | |
182 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedDrawTransform, layer->drawTransform(
)); | |
183 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform(
)); | |
184 | |
185 // Case 2: Setting the bounds of the layer should not affect either the draw
transform or the screenspace transform. | |
186 WebTransformationMatrix translationToCenter; | |
187 translationToCenter.translate(5, 6); | |
188 setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false); | |
189 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
190 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform()); | |
191 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform(
)); | |
192 | |
193 // Case 3: The anchor point by itself (without a layer transform) should hav
e no effect on the transforms. | |
194 setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, Fl
oatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
195 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
196 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform()); | |
197 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform(
)); | |
198 | |
199 // Case 4: A change in actual position affects both the draw transform and s
creen space transform. | |
200 WebTransformationMatrix positionTransform; | |
201 positionTransform.translate(0, 1.2); | |
202 setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, Fl
oatPoint(0.25, 0.25), FloatPoint(0, 1.2f), IntSize(10, 12), false); | |
203 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
204 EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->drawTransform()); | |
205 EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->screenSpaceTransfo
rm()); | |
206 | |
207 // Case 5: In the correct sequence of transforms, the layer transform should
pre-multiply the translationToCenter. This is easily tested by | |
208 // using a scale transform, because scale and translation are not co
mmutative. | |
209 WebTransformationMatrix layerTransform; | |
210 layerTransform.scale3d(2, 2, 1); | |
211 setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false); | |
212 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
213 EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->drawTransform()); | |
214 EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->screenSpaceTransform(
)); | |
215 | |
216 // Case 6: The layer transform should occur with respect to the anchor point
. | |
217 WebTransformationMatrix translationToAnchor; | |
218 translationToAnchor.translate(5, 0); | |
219 WebTransformationMatrix expectedResult = translationToAnchor * layerTransfor
m * translationToAnchor.inverse(); | |
220 setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, Fl
oatPoint(0.5, 0), FloatPoint(0, 0), IntSize(10, 12), false); | |
221 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
222 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->drawTransform()); | |
223 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform(
)); | |
224 | |
225 // Case 7: Verify that position pre-multiplies the layer transform. | |
226 // The current implementation of calculateDrawTransforms does this i
mplicitly, but it is | |
227 // still worth testing to detect accidental regressions. | |
228 expectedResult = positionTransform * translationToAnchor * layerTransform *
translationToAnchor.inverse(); | |
229 setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, Fl
oatPoint(0.5, 0), FloatPoint(0, 1.2f), IntSize(10, 12), false); | |
230 executeCalculateDrawTransformsAndVisibility(layer.get()); | |
231 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->drawTransform()); | |
232 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform(
)); | |
233 } | |
234 | |
235 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy) | |
236 { | |
237 WebTransformationMatrix identityMatrix; | |
238 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
239 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
240 scoped_refptr<LayerChromium> grandChild = LayerChromium::create(); | |
241 parent->addChild(child); | |
242 child->addChild(grandChild); | |
243 | |
244 // Case 1: parent's anchorPoint should not affect child or grandChild. | |
245 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
246 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
247 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false); | |
248 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
249 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform()); | |
250 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform(
)); | |
251 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform())
; | |
252 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTrans
form()); | |
253 | |
254 // Case 2: parent's position affects child and grandChild. | |
255 WebTransformationMatrix parentPositionTransform; | |
256 parentPositionTransform.translate(0, 1.2); | |
257 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0.25, 0.25), FloatPoint(0, 1.2f), IntSize(10, 12), false); | |
258 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
259 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false); | |
260 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
261 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->drawTransfor
m()); | |
262 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->screenSpaceT
ransform()); | |
263 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->drawTra
nsform()); | |
264 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->screenS
paceTransform()); | |
265 | |
266 // Case 3: parent's local transform affects child and grandchild | |
267 WebTransformationMatrix parentLayerTransform; | |
268 parentLayerTransform.scale3d(2, 2, 1); | |
269 WebTransformationMatrix parentTranslationToAnchor; | |
270 parentTranslationToAnchor.translate(2.5, 3); | |
271 WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor
* parentLayerTransform * parentTranslationToAnchor.inverse(); | |
272 setLayerPropertiesForTesting(parent.get(), parentLayerTransform, identityMat
rix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
273 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
274 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false); | |
275 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
276 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransfo
rm()); | |
277 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpace
Transform()); | |
278 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->drawTr
ansform()); | |
279 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screen
SpaceTransform()); | |
280 | |
281 // Case 4: parent's sublayerMatrix affects child and grandchild | |
282 // scaling is used here again so that the correct sequence of transf
orms is properly tested. | |
283 // Note that preserves3D is false, but the sublayer matrix should re
tain its 3D properties when given to child. | |
284 // But then, the child also does not preserve3D. When it gives its h
ierarchy to the grandChild, it should be flattened to 2D. | |
285 WebTransformationMatrix parentSublayerMatrix; | |
286 parentSublayerMatrix.scale3d(10, 10, 3.3); | |
287 WebTransformationMatrix parentTranslationToCenter; | |
288 parentTranslationToCenter.translate(5, 6); | |
289 // Sublayer matrix is applied to the center of the parent layer. | |
290 parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform
* parentTranslationToAnchor.inverse() | |
291 * parentTranslationToCenter * parentSublayerMatrix * parentTranslati
onToCenter.inverse(); | |
292 WebTransformationMatrix flattenedCompositeTransform = remove3DComponentOfMat
rix(parentCompositeTransform); | |
293 setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSubla
yerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
294 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
295 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false); | |
296 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
297 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransfo
rm()); | |
298 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpace
Transform()); | |
299 EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->dra
wTransform()); | |
300 EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->scr
eenSpaceTransform()); | |
301 | |
302 // Case 5: same as Case 4, except that child does preserve 3D, so the grandC
hild should receive the non-flattened composite transform. | |
303 // | |
304 setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSubla
yerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
305 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), true); | |
306 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false); | |
307 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
308 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransfo
rm()); | |
309 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpace
Transform()); | |
310 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->drawTr
ansform()); | |
311 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screen
SpaceTransform()); | |
312 } | |
313 | |
314 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface) | |
315 { | |
316 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
317 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
318 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild = make_scoped_
refptr(new LayerChromiumWithForcedDrawsContent()); | |
319 parent->addChild(child); | |
320 child->addChild(grandChild); | |
321 | |
322 // Child is set up so that a new render surface should be created. | |
323 child->setOpacity(0.5); | |
324 | |
325 WebTransformationMatrix identityMatrix; | |
326 WebTransformationMatrix parentLayerTransform; | |
327 parentLayerTransform.scale3d(1, 0.9, 1); | |
328 WebTransformationMatrix parentTranslationToAnchor; | |
329 parentTranslationToAnchor.translate(25, 30); | |
330 WebTransformationMatrix parentSublayerMatrix; | |
331 parentSublayerMatrix.scale3d(0.9, 1, 3.3); | |
332 WebTransformationMatrix parentTranslationToCenter; | |
333 parentTranslationToCenter.translate(50, 60); | |
334 WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor
* parentLayerTransform * parentTranslationToAnchor.inverse() | |
335 * parentTranslationToCenter * parentSublayerMatrix * parentTranslati
onToCenter.inverse(); | |
336 | |
337 // Child's render surface should not exist yet. | |
338 ASSERT_FALSE(child->renderSurface()); | |
339 | |
340 setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSubla
yerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(100, 120), false); | |
341 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
342 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(8, 10), false); | |
343 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
344 | |
345 // Render surface should have been created now. | |
346 ASSERT_TRUE(child->renderSurface()); | |
347 ASSERT_EQ(child, child->renderTarget()); | |
348 | |
349 // The child layer's draw transform should refer to its new render surface. | |
350 // The screen-space transform, however, should still refer to the root. | |
351 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform()); | |
352 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpace
Transform()); | |
353 | |
354 // Because the grandChild is the only drawable content, the child's renderSu
rface will tighten its bounds to the grandChild. | |
355 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarge
t()->renderSurface()->drawTransform()); | |
356 | |
357 // The screen space is the same as the target since the child surface draws
into the root. | |
358 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarge
t()->renderSurface()->screenSpaceTransform()); | |
359 } | |
360 | |
361 TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica) | |
362 { | |
363 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
364 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
365 scoped_refptr<LayerChromium> childReplica = LayerChromium::create(); | |
366 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild = make_scoped_
refptr(new LayerChromiumWithForcedDrawsContent()); | |
367 parent->addChild(child); | |
368 child->addChild(grandChild); | |
369 child->setReplicaLayer(childReplica.get()); | |
370 | |
371 // Child is set up so that a new render surface should be created. | |
372 child->setOpacity(0.5); | |
373 | |
374 WebTransformationMatrix identityMatrix; | |
375 WebTransformationMatrix parentLayerTransform; | |
376 parentLayerTransform.scale3d(2, 2, 1); | |
377 WebTransformationMatrix parentTranslationToAnchor; | |
378 parentTranslationToAnchor.translate(2.5, 3); | |
379 WebTransformationMatrix parentSublayerMatrix; | |
380 parentSublayerMatrix.scale3d(10, 10, 3.3); | |
381 WebTransformationMatrix parentTranslationToCenter; | |
382 parentTranslationToCenter.translate(5, 6); | |
383 WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor
* parentLayerTransform * parentTranslationToAnchor.inverse() | |
384 * parentTranslationToCenter * parentSublayerMatrix * parentTranslati
onToCenter.inverse(); | |
385 WebTransformationMatrix childTranslationToCenter; | |
386 childTranslationToCenter.translate(8, 9); | |
387 WebTransformationMatrix replicaLayerTransform; | |
388 replicaLayerTransform.scale3d(3, 3, 1); | |
389 WebTransformationMatrix replicaCompositeTransform = parentCompositeTransform
* replicaLayerTransform; | |
390 | |
391 // Child's render surface should not exist yet. | |
392 ASSERT_FALSE(child->renderSurface()); | |
393 | |
394 setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSubla
yerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false); | |
395 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false); | |
396 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(-0.5, -0.5), IntSize(1, 1), false); | |
397 setLayerPropertiesForTesting(childReplica.get(), replicaLayerTransform, iden
tityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false); | |
398 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
399 | |
400 // Render surface should have been created now. | |
401 ASSERT_TRUE(child->renderSurface()); | |
402 ASSERT_EQ(child, child->renderTarget()); | |
403 | |
404 EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->renderTarg
et()->renderSurface()->replicaDrawTransform()); | |
405 EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->renderTarg
et()->renderSurface()->replicaScreenSpaceTransform()); | |
406 } | |
407 | |
408 TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) | |
409 { | |
410 // This test creates a more complex tree and verifies it all at once. This c
overs the following cases: | |
411 // - layers that are described w.r.t. a render surface: should have draw t
ransforms described w.r.t. that surface | |
412 // - A render surface described w.r.t. an ancestor render surface: should
have a draw transform described w.r.t. that ancestor surface | |
413 // - Replicas of a render surface are described w.r.t. the replica's trans
form around its anchor, along with the surface itself. | |
414 // - Sanity check on recursion: verify transforms of layers described w.r.
t. a render surface that is described w.r.t. an ancestor render surface. | |
415 // - verifying that each layer has a reference to the correct renderSurfac
e and renderTarget values. | |
416 | |
417 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
418 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
419 scoped_refptr<LayerChromium> renderSurface2 = LayerChromium::create(); | |
420 scoped_refptr<LayerChromium> childOfRoot = LayerChromium::create(); | |
421 scoped_refptr<LayerChromium> childOfRS1 = LayerChromium::create(); | |
422 scoped_refptr<LayerChromium> childOfRS2 = LayerChromium::create(); | |
423 scoped_refptr<LayerChromium> replicaOfRS1 = LayerChromium::create(); | |
424 scoped_refptr<LayerChromium> replicaOfRS2 = LayerChromium::create(); | |
425 scoped_refptr<LayerChromium> grandChildOfRoot = LayerChromium::create(); | |
426 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
427 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
428 parent->addChild(renderSurface1); | |
429 parent->addChild(childOfRoot); | |
430 renderSurface1->addChild(childOfRS1); | |
431 renderSurface1->addChild(renderSurface2); | |
432 renderSurface2->addChild(childOfRS2); | |
433 childOfRoot->addChild(grandChildOfRoot); | |
434 childOfRS1->addChild(grandChildOfRS1); | |
435 childOfRS2->addChild(grandChildOfRS2); | |
436 renderSurface1->setReplicaLayer(replicaOfRS1.get()); | |
437 renderSurface2->setReplicaLayer(replicaOfRS2.get()); | |
438 | |
439 // In combination with descendantDrawsContent, opacity != 1 forces the layer
to have a new renderSurface. | |
440 renderSurface1->setOpacity(0.5); | |
441 renderSurface2->setOpacity(0.33f); | |
442 | |
443 // All layers in the tree are initialized with an anchor at .25 and a size o
f (10,10). | |
444 // matrix "A" is the composite layer transform used in all layers, centered
about the anchor point | |
445 // matrix "B" is the sublayer transform used in all layers, centered about t
he center position of the layer. | |
446 // matrix "R" is the composite replica transform used in all replica layers. | |
447 // | |
448 // x component tests that layerTransform and sublayerTransform are done in t
he right order (translation and scale are noncommutative). | |
449 // y component has a translation by 1 for every ancestor, which indicates th
e "depth" of the layer in the hierarchy. | |
450 WebTransformationMatrix translationToAnchor; | |
451 translationToAnchor.translate(2.5, 0); | |
452 WebTransformationMatrix translationToCenter; | |
453 translationToCenter.translate(5, 5); | |
454 WebTransformationMatrix layerTransform; | |
455 layerTransform.translate(1, 1); | |
456 WebTransformationMatrix sublayerTransform; | |
457 sublayerTransform.scale3d(10, 1, 1); | |
458 WebTransformationMatrix replicaLayerTransform; | |
459 replicaLayerTransform.scale3d(-2, 5, 1); | |
460 | |
461 WebTransformationMatrix A = translationToAnchor * layerTransform * translati
onToAnchor.inverse(); | |
462 WebTransformationMatrix B = translationToCenter * sublayerTransform * transl
ationToCenter.inverse(); | |
463 WebTransformationMatrix R = A * translationToAnchor * replicaLayerTransform
* translationToAnchor.inverse(); | |
464 WebTransformationMatrix identityMatrix; | |
465 | |
466 setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
467 setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerT
ransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
468 setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerT
ransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
469 setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTran
sform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
470 setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTrans
form, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
471 setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTrans
form, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
472 setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublaye
rTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
473 setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayer
Transform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
474 setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayer
Transform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
475 setLayerPropertiesForTesting(replicaOfRS1.get(), replicaLayerTransform, subl
ayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false); | |
476 setLayerPropertiesForTesting(replicaOfRS2.get(), replicaLayerTransform, subl
ayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false); | |
477 | |
478 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
479 | |
480 // Only layers that are associated with render surfaces should have an actua
l renderSurface() value. | |
481 // | |
482 ASSERT_TRUE(parent->renderSurface()); | |
483 ASSERT_FALSE(childOfRoot->renderSurface()); | |
484 ASSERT_FALSE(grandChildOfRoot->renderSurface()); | |
485 | |
486 ASSERT_TRUE(renderSurface1->renderSurface()); | |
487 ASSERT_FALSE(childOfRS1->renderSurface()); | |
488 ASSERT_FALSE(grandChildOfRS1->renderSurface()); | |
489 | |
490 ASSERT_TRUE(renderSurface2->renderSurface()); | |
491 ASSERT_FALSE(childOfRS2->renderSurface()); | |
492 ASSERT_FALSE(grandChildOfRS2->renderSurface()); | |
493 | |
494 // Verify all renderTarget accessors | |
495 // | |
496 EXPECT_EQ(parent, parent->renderTarget()); | |
497 EXPECT_EQ(parent, childOfRoot->renderTarget()); | |
498 EXPECT_EQ(parent, grandChildOfRoot->renderTarget()); | |
499 | |
500 EXPECT_EQ(renderSurface1, renderSurface1->renderTarget()); | |
501 EXPECT_EQ(renderSurface1, childOfRS1->renderTarget()); | |
502 EXPECT_EQ(renderSurface1, grandChildOfRS1->renderTarget()); | |
503 | |
504 EXPECT_EQ(renderSurface2, renderSurface2->renderTarget()); | |
505 EXPECT_EQ(renderSurface2, childOfRS2->renderTarget()); | |
506 EXPECT_EQ(renderSurface2, grandChildOfRS2->renderTarget()); | |
507 | |
508 // Verify layer draw transforms | |
509 // note that draw transforms are described with respect to the nearest ance
stor render surface | |
510 // but screen space transforms are described with respect to the root. | |
511 // | |
512 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->drawTransform()); | |
513 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->drawTransform()); | |
514 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->drawTra
nsform()); | |
515 | |
516 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, renderSurface1->drawTransfor
m()); | |
517 EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, childOfRS1->drawTransform()); | |
518 EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A, grandChildOfRS1->drawTransfor
m()); | |
519 | |
520 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, renderSurface2->drawTransfor
m()); | |
521 EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, childOfRS2->drawTransform()); | |
522 EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A, grandChildOfRS2->drawTransfor
m()); | |
523 | |
524 // Verify layer screen-space transforms | |
525 // | |
526 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screenSpaceTransform()); | |
527 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->screenSpaceTransform
()); | |
528 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->screenS
paceTransform()); | |
529 | |
530 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->screenSpaceTransf
orm()); | |
531 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, childOfRS1->screenSpaceTr
ansform()); | |
532 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, grandChildOfRS1->
screenSpaceTransform()); | |
533 | |
534 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->screenSpa
ceTransform()); | |
535 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, childOfRS2->scree
nSpaceTransform()); | |
536 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A, grandChil
dOfRS2->screenSpaceTransform()); | |
537 | |
538 // Verify render surface transforms. | |
539 // | |
540 // Draw transform of render surface 1 is described with respect to root. | |
541 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->
drawTransform()); | |
542 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->
replicaDrawTransform()); | |
543 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->
screenSpaceTransform()); | |
544 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->
replicaScreenSpaceTransform()); | |
545 // Draw transform of render surface 2 is described with respect to render su
rface 2. | |
546 EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, renderSurface2->renderSurface()->draw
Transform()); | |
547 EXPECT_TRANSFORMATION_MATRIX_EQ(B * R, renderSurface2->renderSurface()->repl
icaDrawTransform()); | |
548 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->renderSur
face()->screenSpaceTransform()); | |
549 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R, renderSurface2->renderSur
face()->replicaScreenSpaceTransform()); | |
550 | |
551 // Sanity check. If these fail there is probably a bug in the test itself. | |
552 // It is expected that we correctly set up transforms so that the y-componen
t of the screen-space transform | |
553 // encodes the "depth" of the layer in the tree. | |
554 EXPECT_FLOAT_EQ(1, parent->screenSpaceTransform().m42()); | |
555 EXPECT_FLOAT_EQ(2, childOfRoot->screenSpaceTransform().m42()); | |
556 EXPECT_FLOAT_EQ(3, grandChildOfRoot->screenSpaceTransform().m42()); | |
557 | |
558 EXPECT_FLOAT_EQ(2, renderSurface1->screenSpaceTransform().m42()); | |
559 EXPECT_FLOAT_EQ(3, childOfRS1->screenSpaceTransform().m42()); | |
560 EXPECT_FLOAT_EQ(4, grandChildOfRS1->screenSpaceTransform().m42()); | |
561 | |
562 EXPECT_FLOAT_EQ(3, renderSurface2->screenSpaceTransform().m42()); | |
563 EXPECT_FLOAT_EQ(4, childOfRS2->screenSpaceTransform().m42()); | |
564 EXPECT_FLOAT_EQ(5, grandChildOfRS2->screenSpaceTransform().m42()); | |
565 } | |
566 | |
567 TEST(CCLayerTreeHostCommonTest, verifyTransformsForFlatteningLayer) | |
568 { | |
569 // For layers that flatten their subtree, there should be an orthographic pr
ojection | |
570 // (for x and y values) in the middle of the transform sequence. Note that t
he way the | |
571 // code is currently implemented, it is not expected to use a canonical orth
ographic | |
572 // projection. | |
573 | |
574 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
575 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
576 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild = make_scoped_
refptr(new LayerChromiumWithForcedDrawsContent()); | |
577 | |
578 WebTransformationMatrix rotationAboutYAxis; | |
579 rotationAboutYAxis.rotate3d(0, 30, 0); | |
580 | |
581 const WebTransformationMatrix identityMatrix; | |
582 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint::zero(), FloatPoint::zero(), IntSize(100, 100), false); | |
583 setLayerPropertiesForTesting(child.get(), rotationAboutYAxis, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
584 setLayerPropertiesForTesting(grandChild.get(), rotationAboutYAxis, identityM
atrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
585 | |
586 root->addChild(child); | |
587 child->addChild(grandChild); | |
588 child->setForceRenderSurface(true); | |
589 | |
590 // No layers in this test should preserve 3d. | |
591 ASSERT_FALSE(root->preserves3D()); | |
592 ASSERT_FALSE(child->preserves3D()); | |
593 ASSERT_FALSE(grandChild->preserves3D()); | |
594 | |
595 WebTransformationMatrix expectedChildDrawTransform = rotationAboutYAxis; | |
596 WebTransformationMatrix expectedChildScreenSpaceTransform = rotationAboutYAx
is; | |
597 WebTransformationMatrix expectedGrandChildDrawTransform = rotationAboutYAxis
; // draws onto child's renderSurface | |
598 WebTransformationMatrix expectedGrandChildScreenSpaceTransform = rotationAbo
utYAxis.to2dTransform() * rotationAboutYAxis; | |
599 | |
600 executeCalculateDrawTransformsAndVisibility(root.get()); | |
601 | |
602 // The child's drawTransform should have been taken by its surface. | |
603 ASSERT_TRUE(child->renderSurface()); | |
604 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildDrawTransform, child->renderSur
face()->drawTransform()); | |
605 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform, child->re
nderSurface()->screenSpaceTransform()); | |
606 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform()); | |
607 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform, child->sc
reenSpaceTransform()); | |
608 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildDrawTransform, grandChild-
>drawTransform()); | |
609 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildScreenSpaceTransform, gran
dChild->screenSpaceTransform()); | |
610 } | |
611 | |
612 TEST(CCLayerTreeHostCommonTest, verifyTransformsForDegenerateIntermediateLayer) | |
613 { | |
614 // A layer that is empty in one axis, but not the other, was accidentally sk
ipping a necessary translation. | |
615 // Without that translation, the coordinate space of the layer's drawTransfo
rm is incorrect. | |
616 // | |
617 // Normally this isn't a problem, because the layer wouldn't be drawn anyway
, but if that layer becomes a renderSurface, then | |
618 // its drawTransform is implicitly inherited by the rest of the subtree, whi
ch then is positioned incorrectly as a result. | |
619 | |
620 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
621 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
622 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild = make_scoped_
refptr(new LayerChromiumWithForcedDrawsContent()); | |
623 | |
624 // The child height is zero, but has non-zero width that should be accounted
for while computing drawTransforms. | |
625 const WebTransformationMatrix identityMatrix; | |
626 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint::zero(), FloatPoint::zero(), IntSize(100, 100), false); | |
627 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint::zero(), FloatPoint::zero(), IntSize(10, 0), false); | |
628 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
629 | |
630 root->addChild(child); | |
631 child->addChild(grandChild); | |
632 child->setForceRenderSurface(true); | |
633 | |
634 executeCalculateDrawTransformsAndVisibility(root.get()); | |
635 | |
636 ASSERT_TRUE(child->renderSurface()); | |
637 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->renderSurface()->draw
Transform()); // This is the real test, the rest are sanity checks. | |
638 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform()); | |
639 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform())
; | |
640 } | |
641 | |
642 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForRenderSurfaceWithClipp
edLayer) | |
643 { | |
644 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
645 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
646 scoped_refptr<LayerChromiumWithForcedDrawsContent> child = make_scoped_refpt
r(new LayerChromiumWithForcedDrawsContent()); | |
647 | |
648 const WebTransformationMatrix identityMatrix; | |
649 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
650 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
651 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false); | |
652 | |
653 parent->addChild(renderSurface1); | |
654 parent->setMasksToBounds(true); | |
655 renderSurface1->addChild(child); | |
656 renderSurface1->setForceRenderSurface(true); | |
657 | |
658 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
659 int dummyMaxTextureSize = 512; | |
660 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
661 | |
662 // The child layer's content is entirely outside the parent's clip rect, so
the intermediate | |
663 // render surface should not be listed here, even if it was forced to be cre
ated. Render surfaces without children or visible | |
664 // content are unexpected at draw time (e.g. we might try to create a conten
t texture of size 0). | |
665 ASSERT_TRUE(parent->renderSurface()); | |
666 ASSERT_FALSE(renderSurface1->renderSurface()); | |
667 EXPECT_EQ(1U, renderSurfaceLayerList.size()); | |
668 } | |
669 | |
670 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild) | |
671 { | |
672 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
673 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
674 scoped_refptr<LayerChromiumWithForcedDrawsContent> child = make_scoped_refpt
r(new LayerChromiumWithForcedDrawsContent()); | |
675 | |
676 const WebTransformationMatrix identityMatrix; | |
677 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
678 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
679 | |
680 parent->addChild(renderSurface1); | |
681 renderSurface1->addChild(child); | |
682 renderSurface1->setForceRenderSurface(true); | |
683 renderSurface1->setOpacity(0); | |
684 | |
685 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
686 int dummyMaxTextureSize = 512; | |
687 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
688 | |
689 // Since the layer is transparent, renderSurface1->renderSurface() should no
t have gotten added anywhere. | |
690 // Also, the drawable content rect should not have been extended by the chil
dren. | |
691 ASSERT_TRUE(parent->renderSurface()); | |
692 EXPECT_EQ(0U, parent->renderSurface()->layerList().size()); | |
693 EXPECT_EQ(1U, renderSurfaceLayerList.size()); | |
694 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
695 EXPECT_EQ(IntRect(), parent->drawableContentRect()); | |
696 } | |
697 | |
698 TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface) | |
699 { | |
700 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
701 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
702 scoped_refptr<LayerChromiumWithForcedDrawsContent> child = make_scoped_refpt
r(new LayerChromiumWithForcedDrawsContent()); | |
703 renderSurface1->setForceRenderSurface(true); | |
704 | |
705 const WebTransformationMatrix identityMatrix; | |
706 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
707 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
708 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false); | |
709 | |
710 parent->addChild(renderSurface1); | |
711 renderSurface1->addChild(child); | |
712 | |
713 // Sanity check before the actual test | |
714 EXPECT_FALSE(parent->renderSurface()); | |
715 EXPECT_FALSE(renderSurface1->renderSurface()); | |
716 | |
717 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
718 int dummyMaxTextureSize = 512; | |
719 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
720 | |
721 // The root layer always creates a renderSurface | |
722 EXPECT_TRUE(parent->renderSurface()); | |
723 EXPECT_TRUE(renderSurface1->renderSurface()); | |
724 EXPECT_EQ(2U, renderSurfaceLayerList.size()); | |
725 | |
726 renderSurfaceLayerList.clear(); | |
727 renderSurface1->setForceRenderSurface(false); | |
728 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
729 EXPECT_TRUE(parent->renderSurface()); | |
730 EXPECT_FALSE(renderSurface1->renderSurface()); | |
731 EXPECT_EQ(1U, renderSurfaceLayerList.size()); | |
732 } | |
733 | |
734 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hDirectContainer) | |
735 { | |
736 // This test checks for correct scroll compensation when the fixed-position
container | |
737 // is the direct parent of the fixed-position layer. | |
738 | |
739 DebugScopedSetImplThread scopedImplThread; | |
740 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
741 CCLayerImpl* child = root->children()[0]; | |
742 CCLayerImpl* grandChild = child->children()[0]; | |
743 | |
744 child->setIsContainerForFixedPositionLayers(true); | |
745 grandChild->setFixedToContainerLayer(true); | |
746 | |
747 // Case 1: scrollDelta of 0, 0 | |
748 child->setScrollDelta(IntSize(0, 0)); | |
749 executeCalculateDrawTransformsAndVisibility(root.get()); | |
750 | |
751 WebTransformationMatrix expectedChildTransform; | |
752 WebTransformationMatrix expectedGrandChildTransform = expectedChildTransform
; | |
753 | |
754 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
755 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
756 | |
757 // Case 2: scrollDelta of 10, 10 | |
758 child->setScrollDelta(IntSize(10, 10)); | |
759 executeCalculateDrawTransformsAndVisibility(root.get()); | |
760 | |
761 // Here the child is affected by scrollDelta, but the fixed position grandCh
ild should not be affected. | |
762 expectedChildTransform.makeIdentity(); | |
763 expectedChildTransform.translate(-10, -10); | |
764 | |
765 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
766 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
767 } | |
768 | |
769 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hTransformedDirectContainer) | |
770 { | |
771 // This test checks for correct scroll compensation when the fixed-position
container | |
772 // is the direct parent of the fixed-position layer, but that container is t
ransformed. | |
773 // In this case, the fixed position element inherits the container's transfo
rm, | |
774 // but the scrollDelta that has to be undone should not be affected by that
transform. | |
775 // | |
776 // Transforms are in general non-commutative; using something like a non-uni
form scale | |
777 // helps to verify that translations and non-uniform scales are applied in t
he correct | |
778 // order. | |
779 | |
780 DebugScopedSetImplThread scopedImplThread; | |
781 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
782 CCLayerImpl* child = root->children()[0]; | |
783 CCLayerImpl* grandChild = child->children()[0]; | |
784 | |
785 // This scale will cause child and grandChild to be effectively 200 x 800 wi
th respect to the renderTarget. | |
786 WebTransformationMatrix nonUniformScale; | |
787 nonUniformScale.scaleNonUniform(2, 8); | |
788 child->setTransform(nonUniformScale); | |
789 | |
790 child->setIsContainerForFixedPositionLayers(true); | |
791 grandChild->setFixedToContainerLayer(true); | |
792 | |
793 // Case 1: scrollDelta of 0, 0 | |
794 child->setScrollDelta(IntSize(0, 0)); | |
795 executeCalculateDrawTransformsAndVisibility(root.get()); | |
796 | |
797 WebTransformationMatrix expectedChildTransform; | |
798 expectedChildTransform.multiply(nonUniformScale); | |
799 | |
800 WebTransformationMatrix expectedGrandChildTransform = expectedChildTransform
; | |
801 | |
802 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
803 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
804 | |
805 // Case 2: scrollDelta of 10, 20 | |
806 child->setScrollDelta(IntSize(10, 20)); | |
807 executeCalculateDrawTransformsAndVisibility(root.get()); | |
808 | |
809 // The child should be affected by scrollDelta, but the fixed position grand
Child should not be affected. | |
810 expectedChildTransform.makeIdentity(); | |
811 expectedChildTransform.translate(-10, -20); // scrollDelta | |
812 expectedChildTransform.multiply(nonUniformScale); | |
813 | |
814 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
815 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
816 } | |
817 | |
818 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hDistantContainer) | |
819 { | |
820 // This test checks for correct scroll compensation when the fixed-position
container | |
821 // is NOT the direct parent of the fixed-position layer. | |
822 DebugScopedSetImplThread scopedImplThread; | |
823 | |
824 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
825 CCLayerImpl* child = root->children()[0]; | |
826 CCLayerImpl* grandChild = child->children()[0]; | |
827 CCLayerImpl* greatGrandChild = grandChild->children()[0]; | |
828 | |
829 child->setIsContainerForFixedPositionLayers(true); | |
830 grandChild->setPosition(FloatPoint(8, 6)); | |
831 greatGrandChild->setFixedToContainerLayer(true); | |
832 | |
833 // Case 1: scrollDelta of 0, 0 | |
834 child->setScrollDelta(IntSize(0, 0)); | |
835 executeCalculateDrawTransformsAndVisibility(root.get()); | |
836 | |
837 WebTransformationMatrix expectedChildTransform; | |
838 WebTransformationMatrix expectedGrandChildTransform; | |
839 expectedGrandChildTransform.translate(8, 6); | |
840 | |
841 WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChil
dTransform; | |
842 | |
843 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
844 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
845 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
846 | |
847 // Case 2: scrollDelta of 10, 10 | |
848 child->setScrollDelta(IntSize(10, 10)); | |
849 executeCalculateDrawTransformsAndVisibility(root.get()); | |
850 | |
851 // Here the child and grandChild are affected by scrollDelta, but the fixed
position greatGrandChild should not be affected. | |
852 expectedChildTransform.makeIdentity(); | |
853 expectedChildTransform.translate(-10, -10); | |
854 expectedGrandChildTransform.makeIdentity(); | |
855 expectedGrandChildTransform.translate(-2, -4); | |
856 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
857 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
858 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
859 } | |
860 | |
861 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hDistantContainerAndTransforms) | |
862 { | |
863 // This test checks for correct scroll compensation when the fixed-position
container | |
864 // is NOT the direct parent of the fixed-position layer, and the hierarchy h
as various | |
865 // transforms that have to be processed in the correct order. | |
866 DebugScopedSetImplThread scopedImplThread; | |
867 | |
868 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
869 CCLayerImpl* child = root->children()[0]; | |
870 CCLayerImpl* grandChild = child->children()[0]; | |
871 CCLayerImpl* greatGrandChild = grandChild->children()[0]; | |
872 | |
873 WebTransformationMatrix rotationAboutZ; | |
874 rotationAboutZ.rotate3d(0, 0, 90); | |
875 | |
876 child->setIsContainerForFixedPositionLayers(true); | |
877 child->setTransform(rotationAboutZ); | |
878 grandChild->setPosition(FloatPoint(8, 6)); | |
879 grandChild->setTransform(rotationAboutZ); | |
880 greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is posit
ioned upside-down with respect to the renderTarget. | |
881 | |
882 // Case 1: scrollDelta of 0, 0 | |
883 child->setScrollDelta(IntSize(0, 0)); | |
884 executeCalculateDrawTransformsAndVisibility(root.get()); | |
885 | |
886 WebTransformationMatrix expectedChildTransform; | |
887 expectedChildTransform.multiply(rotationAboutZ); | |
888 | |
889 WebTransformationMatrix expectedGrandChildTransform; | |
890 expectedGrandChildTransform.multiply(rotationAboutZ); // child's local trans
form is inherited | |
891 expectedGrandChildTransform.translate(8, 6); // translation because of posit
ion occurs before layer's local transform. | |
892 expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local
transform | |
893 | |
894 WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChil
dTransform; | |
895 | |
896 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
897 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
898 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
899 | |
900 // Case 2: scrollDelta of 10, 20 | |
901 child->setScrollDelta(IntSize(10, 20)); | |
902 executeCalculateDrawTransformsAndVisibility(root.get()); | |
903 | |
904 // Here the child and grandChild are affected by scrollDelta, but the fixed
position greatGrandChild should not be affected. | |
905 expectedChildTransform.makeIdentity(); | |
906 expectedChildTransform.translate(-10, -20); // scrollDelta | |
907 expectedChildTransform.multiply(rotationAboutZ); | |
908 | |
909 expectedGrandChildTransform.makeIdentity(); | |
910 expectedGrandChildTransform.translate(-10, -20); // child's scrollDelta is i
nherited | |
911 expectedGrandChildTransform.multiply(rotationAboutZ); // child's local trans
form is inherited | |
912 expectedGrandChildTransform.translate(8, 6); // translation because of posit
ion occurs before layer's local transform. | |
913 expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local
transform | |
914 | |
915 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
916 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
917 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
918 } | |
919 | |
920 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hMultipleScrollDeltas) | |
921 { | |
922 // This test checks for correct scroll compensation when the fixed-position
container | |
923 // has multiple ancestors that have nonzero scrollDelta before reaching the
space where the layer is fixed. | |
924 // In this test, each scrollDelta occurs in a different space because of eac
h layer's local transform. | |
925 // This test checks for correct scroll compensation when the fixed-position
container | |
926 // is NOT the direct parent of the fixed-position layer, and the hierarchy h
as various | |
927 // transforms that have to be processed in the correct order. | |
928 DebugScopedSetImplThread scopedImplThread; | |
929 | |
930 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
931 CCLayerImpl* child = root->children()[0]; | |
932 CCLayerImpl* grandChild = child->children()[0]; | |
933 CCLayerImpl* greatGrandChild = grandChild->children()[0]; | |
934 | |
935 WebTransformationMatrix rotationAboutZ; | |
936 rotationAboutZ.rotate3d(0, 0, 90); | |
937 | |
938 child->setIsContainerForFixedPositionLayers(true); | |
939 child->setTransform(rotationAboutZ); | |
940 grandChild->setPosition(FloatPoint(8, 6)); | |
941 grandChild->setTransform(rotationAboutZ); | |
942 greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is posit
ioned upside-down with respect to the renderTarget. | |
943 | |
944 // Case 1: scrollDelta of 0, 0 | |
945 child->setScrollDelta(IntSize(0, 0)); | |
946 executeCalculateDrawTransformsAndVisibility(root.get()); | |
947 | |
948 WebTransformationMatrix expectedChildTransform; | |
949 expectedChildTransform.multiply(rotationAboutZ); | |
950 | |
951 WebTransformationMatrix expectedGrandChildTransform; | |
952 expectedGrandChildTransform.multiply(rotationAboutZ); // child's local trans
form is inherited | |
953 expectedGrandChildTransform.translate(8, 6); // translation because of posit
ion occurs before layer's local transform. | |
954 expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local
transform | |
955 | |
956 WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChil
dTransform; | |
957 | |
958 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
959 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
960 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
961 | |
962 // Case 2: scrollDelta of 10, 20 | |
963 child->setScrollDelta(IntSize(10, 0)); | |
964 grandChild->setScrollDelta(IntSize(5, 0)); | |
965 executeCalculateDrawTransformsAndVisibility(root.get()); | |
966 | |
967 // Here the child and grandChild are affected by scrollDelta, but the fixed
position greatGrandChild should not be affected. | |
968 expectedChildTransform.makeIdentity(); | |
969 expectedChildTransform.translate(-10, 0); // scrollDelta | |
970 expectedChildTransform.multiply(rotationAboutZ); | |
971 | |
972 expectedGrandChildTransform.makeIdentity(); | |
973 expectedGrandChildTransform.translate(-10, 0); // child's scrollDelta is inh
erited | |
974 expectedGrandChildTransform.multiply(rotationAboutZ); // child's local trans
form is inherited | |
975 expectedGrandChildTransform.translate(-5, 0); // grandChild's scrollDelta | |
976 expectedGrandChildTransform.translate(8, 6); // translation because of posit
ion occurs before layer's local transform. | |
977 expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local
transform | |
978 | |
979 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
980 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
981 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
982 } | |
983 | |
984 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hIntermediateSurfaceAndTransforms) | |
985 { | |
986 // This test checks for correct scroll compensation when the fixed-position
container | |
987 // contributes to a different renderSurface than the fixed-position layer. I
n this | |
988 // case, the surface drawTransforms also have to be accounted for when check
ing the | |
989 // scrollDelta. | |
990 DebugScopedSetImplThread scopedImplThread; | |
991 | |
992 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
993 CCLayerImpl* child = root->children()[0]; | |
994 CCLayerImpl* grandChild = child->children()[0]; | |
995 CCLayerImpl* greatGrandChild = grandChild->children()[0]; | |
996 | |
997 child->setIsContainerForFixedPositionLayers(true); | |
998 grandChild->setPosition(FloatPoint(8, 6)); | |
999 grandChild->setForceRenderSurface(true); | |
1000 greatGrandChild->setFixedToContainerLayer(true); | |
1001 greatGrandChild->setDrawsContent(true); | |
1002 | |
1003 WebTransformationMatrix rotationAboutZ; | |
1004 rotationAboutZ.rotate3d(0, 0, 90); | |
1005 grandChild->setTransform(rotationAboutZ); | |
1006 | |
1007 // Case 1: scrollDelta of 0, 0 | |
1008 child->setScrollDelta(IntSize(0, 0)); | |
1009 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1010 | |
1011 WebTransformationMatrix expectedChildTransform; | |
1012 WebTransformationMatrix expectedSurfaceDrawTransform; | |
1013 expectedSurfaceDrawTransform.translate(8, 6); | |
1014 expectedSurfaceDrawTransform.multiply(rotationAboutZ); | |
1015 WebTransformationMatrix expectedGrandChildTransform; | |
1016 WebTransformationMatrix expectedGreatGrandChildTransform; | |
1017 ASSERT_TRUE(grandChild->renderSurface()); | |
1018 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1019 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, grandChild->re
nderSurface()->drawTransform()); | |
1020 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1021 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
1022 | |
1023 // Case 2: scrollDelta of 10, 30 | |
1024 child->setScrollDelta(IntSize(10, 30)); | |
1025 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1026 | |
1027 // Here the grandChild remains unchanged, because it scrolls along with the | |
1028 // renderSurface, and the translation is actually in the renderSurface. But,
the fixed | |
1029 // position greatGrandChild is more awkward: its actually being drawn with r
espect to | |
1030 // the renderSurface, but it needs to remain fixed with resepct to a contain
er beyond | |
1031 // that surface. So, the net result is that, unlike previous tests where the
fixed | |
1032 // position layer's transform remains unchanged, here the fixed position lay
er's | |
1033 // transform explicitly contains the translation that cancels out the scroll
. | |
1034 expectedChildTransform.makeIdentity(); | |
1035 expectedChildTransform.translate(-10, -30); // scrollDelta | |
1036 | |
1037 expectedSurfaceDrawTransform.makeIdentity(); | |
1038 expectedSurfaceDrawTransform.translate(-10, -30); // scrollDelta | |
1039 expectedSurfaceDrawTransform.translate(8, 6); | |
1040 expectedSurfaceDrawTransform.multiply(rotationAboutZ); | |
1041 | |
1042 // The rotation and its inverse are needed to place the scrollDelta compensa
tion in | |
1043 // the correct space. This test will fail if the rotation/inverse are backwa
rds, too, | |
1044 // so it requires perfect order of operations. | |
1045 expectedGreatGrandChildTransform.makeIdentity(); | |
1046 expectedGreatGrandChildTransform.multiply(rotationAboutZ.inverse()); | |
1047 expectedGreatGrandChildTransform.translate(10, 30); // explicit canceling ou
t the scrollDelta that gets embedded in the fixed position layer's surface. | |
1048 expectedGreatGrandChildTransform.multiply(rotationAboutZ); | |
1049 | |
1050 ASSERT_TRUE(grandChild->renderSurface()); | |
1051 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1052 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, grandChild->re
nderSurface()->drawTransform()); | |
1053 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1054 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
1055 } | |
1056 | |
1057 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hMultipleIntermediateSurfaces) | |
1058 { | |
1059 // This test checks for correct scroll compensation when the fixed-position
container | |
1060 // contributes to a different renderSurface than the fixed-position layer, w
ith | |
1061 // additional renderSurfaces in-between. This checks that the conversion to
ancestor | |
1062 // surfaces is accumulated properly in the final matrix transform. | |
1063 DebugScopedSetImplThread scopedImplThread; | |
1064 | |
1065 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
1066 CCLayerImpl* child = root->children()[0]; | |
1067 CCLayerImpl* grandChild = child->children()[0]; | |
1068 CCLayerImpl* greatGrandChild = grandChild->children()[0]; | |
1069 | |
1070 // Add one more layer to the test tree for this scenario. | |
1071 { | |
1072 WebTransformationMatrix identity; | |
1073 scoped_ptr<CCLayerImpl> fixedPositionChild = CCLayerImpl::create(5); | |
1074 setLayerPropertiesForTesting(fixedPositionChild.get(), identity, identit
y, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
1075 greatGrandChild->addChild(fixedPositionChild.Pass()); | |
1076 } | |
1077 CCLayerImpl* fixedPositionChild = greatGrandChild->children()[0]; | |
1078 | |
1079 // Actually set up the scenario here. | |
1080 child->setIsContainerForFixedPositionLayers(true); | |
1081 grandChild->setPosition(FloatPoint(8, 6)); | |
1082 grandChild->setForceRenderSurface(true); | |
1083 greatGrandChild->setPosition(FloatPoint(40, 60)); | |
1084 greatGrandChild->setForceRenderSurface(true); | |
1085 fixedPositionChild->setFixedToContainerLayer(true); | |
1086 fixedPositionChild->setDrawsContent(true); | |
1087 | |
1088 // The additional rotations, which are non-commutative with translations, he
lp to | |
1089 // verify that we have correct order-of-operations in the final scroll compe
nsation. | |
1090 // Note that rotating about the center of the layer ensures we do not accide
ntally | |
1091 // clip away layers that we want to test. | |
1092 WebTransformationMatrix rotationAboutZ; | |
1093 rotationAboutZ.translate(50, 50); | |
1094 rotationAboutZ.rotate3d(0, 0, 90); | |
1095 rotationAboutZ.translate(-50, -50); | |
1096 grandChild->setTransform(rotationAboutZ); | |
1097 greatGrandChild->setTransform(rotationAboutZ); | |
1098 | |
1099 // Case 1: scrollDelta of 0, 0 | |
1100 child->setScrollDelta(IntSize(0, 0)); | |
1101 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1102 | |
1103 WebTransformationMatrix expectedChildTransform; | |
1104 | |
1105 WebTransformationMatrix expectedGrandChildSurfaceDrawTransform; | |
1106 expectedGrandChildSurfaceDrawTransform.translate(8, 6); | |
1107 expectedGrandChildSurfaceDrawTransform.multiply(rotationAboutZ); | |
1108 | |
1109 WebTransformationMatrix expectedGrandChildTransform; | |
1110 | |
1111 WebTransformationMatrix expectedGreatGrandChildSurfaceDrawTransform; | |
1112 expectedGreatGrandChildSurfaceDrawTransform.translate(40, 60); | |
1113 expectedGreatGrandChildSurfaceDrawTransform.multiply(rotationAboutZ); | |
1114 | |
1115 WebTransformationMatrix expectedGreatGrandChildTransform; | |
1116 | |
1117 WebTransformationMatrix expectedFixedPositionChildTransform; | |
1118 | |
1119 ASSERT_TRUE(grandChild->renderSurface()); | |
1120 ASSERT_TRUE(greatGrandChild->renderSurface()); | |
1121 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1122 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform, gran
dChild->renderSurface()->drawTransform()); | |
1123 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1124 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform,
greatGrandChild->renderSurface()->drawTransform()); | |
1125 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
1126 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform, fixedPo
sitionChild->drawTransform()); | |
1127 | |
1128 // Case 2: scrollDelta of 10, 30 | |
1129 child->setScrollDelta(IntSize(10, 30)); | |
1130 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1131 | |
1132 expectedChildTransform.makeIdentity(); | |
1133 expectedChildTransform.translate(-10, -30); // scrollDelta | |
1134 | |
1135 expectedGrandChildSurfaceDrawTransform.makeIdentity(); | |
1136 expectedGrandChildSurfaceDrawTransform.translate(-10, -30); // scrollDelta | |
1137 expectedGrandChildSurfaceDrawTransform.translate(8, 6); | |
1138 expectedGrandChildSurfaceDrawTransform.multiply(rotationAboutZ); | |
1139 | |
1140 // grandChild, greatGrandChild, and greatGrandChild's surface are not expect
ed to | |
1141 // change, since they are all not fixed, and they are all drawn with respect
to | |
1142 // grandChild's surface that already has the scrollDelta accounted for. | |
1143 | |
1144 // But the great-great grandchild, "fixedPositionChild", should have a trans
form that explicitly cancels out the scrollDelta. | |
1145 // The expected transform is: | |
1146 // compoundDrawTransform.inverse() * translate(positive scrollDelta) * com
poundOriginTransform | |
1147 WebTransformationMatrix compoundDrawTransform; // transform from greatGrandC
hildSurface's origin to the root surface. | |
1148 compoundDrawTransform.translate(8, 6); // origin translation of grandChild | |
1149 compoundDrawTransform.multiply(rotationAboutZ); // rotation of grandChild | |
1150 compoundDrawTransform.translate(40, 60); // origin translation of greatGrand
Child | |
1151 compoundDrawTransform.multiply(rotationAboutZ); // rotation of greatGrandChi
ld | |
1152 | |
1153 expectedFixedPositionChildTransform.makeIdentity(); | |
1154 expectedFixedPositionChildTransform.multiply(compoundDrawTransform.inverse()
); | |
1155 expectedFixedPositionChildTransform.translate(10, 30); // explicit canceling
out the scrollDelta that gets embedded in the fixed position layer's surface. | |
1156 expectedFixedPositionChildTransform.multiply(compoundDrawTransform); | |
1157 | |
1158 ASSERT_TRUE(grandChild->renderSurface()); | |
1159 ASSERT_TRUE(greatGrandChild->renderSurface()); | |
1160 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1161 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform, gran
dChild->renderSurface()->drawTransform()); | |
1162 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1163 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform,
greatGrandChild->renderSurface()->drawTransform()); | |
1164 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrand
Child->drawTransform()); | |
1165 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform, fixedPo
sitionChild->drawTransform()); | |
1166 } | |
1167 | |
1168 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWit
hContainerLayerThatHasSurface) | |
1169 { | |
1170 // This test checks for correct scroll compensation when the fixed-position
container | |
1171 // itself has a renderSurface. In this case, the container layer should be t
reated | |
1172 // like a layer that contributes to a renderTarget, and that renderTarget | |
1173 // is completely irrelevant; it should not affect the scroll compensation. | |
1174 DebugScopedSetImplThread scopedImplThread; | |
1175 | |
1176 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
1177 CCLayerImpl* child = root->children()[0]; | |
1178 CCLayerImpl* grandChild = child->children()[0]; | |
1179 | |
1180 child->setIsContainerForFixedPositionLayers(true); | |
1181 child->setForceRenderSurface(true); | |
1182 grandChild->setFixedToContainerLayer(true); | |
1183 grandChild->setDrawsContent(true); | |
1184 | |
1185 // Case 1: scrollDelta of 0, 0 | |
1186 child->setScrollDelta(IntSize(0, 0)); | |
1187 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1188 | |
1189 WebTransformationMatrix expectedSurfaceDrawTransform; | |
1190 expectedSurfaceDrawTransform.translate(0, 0); | |
1191 WebTransformationMatrix expectedChildTransform; | |
1192 WebTransformationMatrix expectedGrandChildTransform; | |
1193 ASSERT_TRUE(child->renderSurface()); | |
1194 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, child->renderS
urface()->drawTransform()); | |
1195 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1196 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1197 | |
1198 // Case 2: scrollDelta of 10, 10 | |
1199 child->setScrollDelta(IntSize(10, 10)); | |
1200 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1201 | |
1202 // The surface is translated by scrollDelta, the child transform doesn't cha
nge | |
1203 // because it scrolls along with the surface, but the fixed position grandCh
ild | |
1204 // needs to compensate for the scroll translation. | |
1205 expectedSurfaceDrawTransform.makeIdentity(); | |
1206 expectedSurfaceDrawTransform.translate(-10, -10); | |
1207 expectedGrandChildTransform.makeIdentity(); | |
1208 expectedGrandChildTransform.translate(10, 10); | |
1209 | |
1210 ASSERT_TRUE(child->renderSurface()); | |
1211 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, child->renderS
urface()->drawTransform()); | |
1212 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1213 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1214 } | |
1215 | |
1216 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerTha
tIsAlsoFixedPositionContainer) | |
1217 { | |
1218 // This test checks the scenario where a fixed-position layer also happens t
o be a | |
1219 // container itself for a descendant fixed position layer. In particular, th
e layer | |
1220 // should not accidentally be fixed to itself. | |
1221 DebugScopedSetImplThread scopedImplThread; | |
1222 | |
1223 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
1224 CCLayerImpl* child = root->children()[0]; | |
1225 CCLayerImpl* grandChild = child->children()[0]; | |
1226 | |
1227 child->setIsContainerForFixedPositionLayers(true); | |
1228 grandChild->setFixedToContainerLayer(true); | |
1229 | |
1230 // This should not confuse the grandChild. If correct, the grandChild would
still be considered fixed to its container (i.e. "child"). | |
1231 grandChild->setIsContainerForFixedPositionLayers(true); | |
1232 | |
1233 // Case 1: scrollDelta of 0, 0 | |
1234 child->setScrollDelta(IntSize(0, 0)); | |
1235 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1236 | |
1237 WebTransformationMatrix expectedChildTransform; | |
1238 WebTransformationMatrix expectedGrandChildTransform; | |
1239 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1240 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1241 | |
1242 // Case 2: scrollDelta of 10, 10 | |
1243 child->setScrollDelta(IntSize(10, 10)); | |
1244 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1245 | |
1246 // Here the child is affected by scrollDelta, but the fixed position grandCh
ild should not be affected. | |
1247 expectedChildTransform.makeIdentity(); | |
1248 expectedChildTransform.translate(-10, -10); | |
1249 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1250 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1251 } | |
1252 | |
1253 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerTha
tHasNoContainer) | |
1254 { | |
1255 // This test checks scroll compensation when a fixed-position layer does not
find any | |
1256 // ancestor that is a "containerForFixedPositionLayers". In this situation,
the layer should | |
1257 // be fixed to the viewport -- not the rootLayer, which may have transforms
of its own. | |
1258 DebugScopedSetImplThread scopedImplThread; | |
1259 | |
1260 scoped_ptr<CCLayerImpl> root = createTreeForFixedPositionTests(); | |
1261 CCLayerImpl* child = root->children()[0]; | |
1262 CCLayerImpl* grandChild = child->children()[0]; | |
1263 | |
1264 WebTransformationMatrix rotationByZ; | |
1265 rotationByZ.rotate3d(0, 0, 90); | |
1266 | |
1267 root->setTransform(rotationByZ); | |
1268 grandChild->setFixedToContainerLayer(true); | |
1269 | |
1270 // Case 1: root scrollDelta of 0, 0 | |
1271 root->setScrollDelta(IntSize(0, 0)); | |
1272 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1273 | |
1274 WebTransformationMatrix expectedChildTransform; | |
1275 expectedChildTransform.multiply(rotationByZ); | |
1276 | |
1277 WebTransformationMatrix expectedGrandChildTransform; | |
1278 expectedGrandChildTransform.multiply(rotationByZ); | |
1279 | |
1280 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1281 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1282 | |
1283 // Case 2: root scrollDelta of 10, 10 | |
1284 root->setScrollDelta(IntSize(10, 10)); | |
1285 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1286 | |
1287 // Here the child is affected by scrollDelta, but the fixed position grandCh
ild should not be affected. | |
1288 expectedChildTransform.makeIdentity(); | |
1289 expectedChildTransform.translate(-10, -10); // the scrollDelta | |
1290 expectedChildTransform.multiply(rotationByZ); | |
1291 | |
1292 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
1293 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->dra
wTransform()); | |
1294 } | |
1295 | |
1296 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces) | |
1297 { | |
1298 // The entire subtree of layers that are outside the clipRect should be cull
ed away, | |
1299 // and should not affect the renderSurfaceLayerList. | |
1300 // | |
1301 // The test tree is set up as follows: | |
1302 // - all layers except the leafNodes are forced to be a new renderSurface t
hat have something to draw. | |
1303 // - parent is a large container layer. | |
1304 // - child has masksToBounds=true to cause clipping. | |
1305 // - grandChild is positioned outside of the child's bounds | |
1306 // - greatGrandChild is also kept outside child's bounds. | |
1307 // | |
1308 // In this configuration, grandChild and greatGrandChild are completely outs
ide the | |
1309 // clipRect, and they should never get scheduled on the list of renderSurfac
es. | |
1310 // | |
1311 | |
1312 const WebTransformationMatrix identityMatrix; | |
1313 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
1314 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
1315 scoped_refptr<LayerChromium> grandChild = LayerChromium::create(); | |
1316 scoped_refptr<LayerChromium> greatGrandChild = LayerChromium::create(); | |
1317 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode1 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1318 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode2 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1319 parent->addChild(child); | |
1320 child->addChild(grandChild); | |
1321 grandChild->addChild(greatGrandChild); | |
1322 | |
1323 // leafNode1 ensures that parent and child are kept on the renderSurfaceLaye
rList, | |
1324 // even though grandChild and greatGrandChild should be clipped. | |
1325 child->addChild(leafNode1); | |
1326 greatGrandChild->addChild(leafNode2); | |
1327 | |
1328 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false); | |
1329 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false); | |
1330 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false); | |
1331 setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identity
Matrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1332 setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false); | |
1333 setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false); | |
1334 | |
1335 child->setMasksToBounds(true); | |
1336 child->setOpacity(0.4f); | |
1337 grandChild->setOpacity(0.5); | |
1338 greatGrandChild->setOpacity(0.4f); | |
1339 | |
1340 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
1341 int dummyMaxTextureSize = 512; | |
1342 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
1343 | |
1344 ASSERT_EQ(2U, renderSurfaceLayerList.size()); | |
1345 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
1346 EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id()); | |
1347 } | |
1348 | |
1349 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent) | |
1350 { | |
1351 // When a renderSurface has a clipRect, it is used to clip the contentRect | |
1352 // of the surface. When the renderSurface is animating its transforms, then | |
1353 // the contentRect's position in the clipRect is not defined on the main | |
1354 // thread, and its contentRect should not be clipped. | |
1355 | |
1356 // The test tree is set up as follows: | |
1357 // - parent is a container layer that masksToBounds=true to cause clipping. | |
1358 // - child is a renderSurface, which has a clipRect set to the bounds of th
e parent. | |
1359 // - grandChild is a renderSurface, and the only visible content in child.
It is positioned outside of the clipRect from parent. | |
1360 | |
1361 // In this configuration, grandChild should be outside the clipped | |
1362 // contentRect of the child, making grandChild not appear in the | |
1363 // renderSurfaceLayerList. However, when we place an animation on the child, | |
1364 // this clipping should be avoided and we should keep the grandChild | |
1365 // in the renderSurfaceLayerList. | |
1366 | |
1367 const WebTransformationMatrix identityMatrix; | |
1368 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
1369 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
1370 scoped_refptr<LayerChromium> grandChild = LayerChromium::create(); | |
1371 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode = make_scoped_re
fptr(new LayerChromiumWithForcedDrawsContent()); | |
1372 parent->addChild(child); | |
1373 child->addChild(grandChild); | |
1374 grandChild->addChild(leafNode); | |
1375 | |
1376 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
1377 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false); | |
1378 setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatri
x, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false); | |
1379 setLayerPropertiesForTesting(leafNode.get(), identityMatrix, identityMatrix,
FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1380 | |
1381 parent->setMasksToBounds(true); | |
1382 child->setOpacity(0.4f); | |
1383 grandChild->setOpacity(0.4f); | |
1384 | |
1385 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
1386 int dummyMaxTextureSize = 512; | |
1387 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
1388 | |
1389 // Without an animation, we should cull child and grandChild from the render
SurfaceLayerList. | |
1390 ASSERT_EQ(1U, renderSurfaceLayerList.size()); | |
1391 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
1392 | |
1393 // Now put an animating transform on child. | |
1394 addAnimatedTransformToController(*child->layerAnimationController(), 10, 30,
0); | |
1395 | |
1396 parent->clearRenderSurface(); | |
1397 child->clearRenderSurface(); | |
1398 grandChild->clearRenderSurface(); | |
1399 renderSurfaceLayerList.clear(); | |
1400 | |
1401 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
1402 | |
1403 // With an animating transform, we should keep child and grandChild in the r
enderSurfaceLayerList. | |
1404 ASSERT_EQ(3U, renderSurfaceLayerList.size()); | |
1405 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
1406 EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id()); | |
1407 EXPECT_EQ(grandChild->id(), renderSurfaceLayerList[2]->id()); | |
1408 } | |
1409 | |
1410 TEST(CCLayerTreeHostCommonTest, verifyDrawableContentRectForLayers) | |
1411 { | |
1412 // Verify that layers get the appropriate drawableContentRect when their par
ent masksToBounds is true. | |
1413 // | |
1414 // grandChild1 - completely inside the region; drawableContentRect should
be the layer rect expressed in target space. | |
1415 // grandChild2 - partially clipped but NOT masksToBounds; the clipRect wil
l be the intersection of layerBounds and the mask region. | |
1416 // grandChild3 - partially clipped and masksToBounds; the drawableContentR
ect will still be the intersection of layerBounds and the mask region. | |
1417 // grandChild4 - outside parent's clipRect; the drawableContentRect should
be empty. | |
1418 // | |
1419 | |
1420 const WebTransformationMatrix identityMatrix; | |
1421 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
1422 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
1423 scoped_refptr<LayerChromium> grandChild1 = LayerChromium::create(); | |
1424 scoped_refptr<LayerChromium> grandChild2 = LayerChromium::create(); | |
1425 scoped_refptr<LayerChromium> grandChild3 = LayerChromium::create(); | |
1426 scoped_refptr<LayerChromium> grandChild4 = LayerChromium::create(); | |
1427 | |
1428 parent->addChild(child); | |
1429 child->addChild(grandChild1); | |
1430 child->addChild(grandChild2); | |
1431 child->addChild(grandChild3); | |
1432 child->addChild(grandChild4); | |
1433 | |
1434 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false); | |
1435 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false); | |
1436 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false); | |
1437 setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false); | |
1438 setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false); | |
1439 setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false); | |
1440 | |
1441 child->setMasksToBounds(true); | |
1442 grandChild3->setMasksToBounds(true); | |
1443 | |
1444 // Force everyone to be a render surface. | |
1445 child->setOpacity(0.4f); | |
1446 grandChild1->setOpacity(0.5); | |
1447 grandChild2->setOpacity(0.5); | |
1448 grandChild3->setOpacity(0.5); | |
1449 grandChild4->setOpacity(0.5); | |
1450 | |
1451 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
1452 int dummyMaxTextureSize = 512; | |
1453 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
1454 | |
1455 EXPECT_RECT_EQ(IntRect(IntPoint(5, 5), IntSize(10, 10)), grandChild1->drawab
leContentRect()); | |
1456 EXPECT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->drawab
leContentRect()); | |
1457 EXPECT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->drawab
leContentRect()); | |
1458 EXPECT_TRUE(grandChild4->drawableContentRect().isEmpty()); | |
1459 } | |
1460 | |
1461 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces) | |
1462 { | |
1463 // Verify that renderSurfaces (and their layers) get the appropriate clipRec
ts when their parent masksToBounds is true. | |
1464 // | |
1465 // Layers that own renderSurfaces (at least for now) do not inherit any clip
ping; | |
1466 // instead the surface will enforce the clip for the entire subtree. They ma
y still | |
1467 // have a clipRect of their own layer bounds, however, if masksToBounds was
true. | |
1468 // | |
1469 | |
1470 const WebTransformationMatrix identityMatrix; | |
1471 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
1472 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
1473 scoped_refptr<LayerChromium> grandChild1 = LayerChromium::create(); | |
1474 scoped_refptr<LayerChromium> grandChild2 = LayerChromium::create(); | |
1475 scoped_refptr<LayerChromium> grandChild3 = LayerChromium::create(); | |
1476 scoped_refptr<LayerChromium> grandChild4 = LayerChromium::create(); | |
1477 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode1 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1478 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode2 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1479 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode3 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1480 scoped_refptr<LayerChromiumWithForcedDrawsContent> leafNode4 = make_scoped_r
efptr(new LayerChromiumWithForcedDrawsContent()); | |
1481 | |
1482 parent->addChild(child); | |
1483 child->addChild(grandChild1); | |
1484 child->addChild(grandChild2); | |
1485 child->addChild(grandChild3); | |
1486 child->addChild(grandChild4); | |
1487 | |
1488 // the leaf nodes ensure that these grandChildren become renderSurfaces for
this test. | |
1489 grandChild1->addChild(leafNode1); | |
1490 grandChild2->addChild(leafNode2); | |
1491 grandChild3->addChild(leafNode3); | |
1492 grandChild4->addChild(leafNode4); | |
1493 | |
1494 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false); | |
1495 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false); | |
1496 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false); | |
1497 setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false); | |
1498 setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false); | |
1499 setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false); | |
1500 setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1501 setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1502 setLayerPropertiesForTesting(leafNode3.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1503 setLayerPropertiesForTesting(leafNode4.get(), identityMatrix, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false); | |
1504 | |
1505 child->setMasksToBounds(true); | |
1506 grandChild3->setMasksToBounds(true); | |
1507 grandChild4->setMasksToBounds(true); | |
1508 | |
1509 // Force everyone to be a render surface. | |
1510 child->setOpacity(0.4f); | |
1511 grandChild1->setOpacity(0.5); | |
1512 grandChild2->setOpacity(0.5); | |
1513 grandChild3->setOpacity(0.5); | |
1514 grandChild4->setOpacity(0.5); | |
1515 | |
1516 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
1517 int dummyMaxTextureSize = 512; | |
1518 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
1519 | |
1520 ASSERT_TRUE(grandChild1->renderSurface()); | |
1521 ASSERT_TRUE(grandChild2->renderSurface()); | |
1522 ASSERT_TRUE(grandChild3->renderSurface()); | |
1523 EXPECT_FALSE(grandChild4->renderSurface()); // Because grandChild4 is entire
ly clipped, it is expected to not have a renderSurface. | |
1524 | |
1525 // Surfaces are clipped by their parent, but un-affected by the owning layer
's masksToBounds. | |
1526 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1->render
Surface()->clipRect()); | |
1527 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2->render
Surface()->clipRect()); | |
1528 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3->render
Surface()->clipRect()); | |
1529 } | |
1530 | |
1531 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy) | |
1532 { | |
1533 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
1534 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
1535 scoped_refptr<LayerChromium> renderSurface2 = LayerChromium::create(); | |
1536 scoped_refptr<LayerChromium> childOfRoot = LayerChromium::create(); | |
1537 scoped_refptr<LayerChromium> childOfRS1 = LayerChromium::create(); | |
1538 scoped_refptr<LayerChromium> childOfRS2 = LayerChromium::create(); | |
1539 scoped_refptr<LayerChromium> grandChildOfRoot = LayerChromium::create(); | |
1540 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
1541 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
1542 parent->addChild(renderSurface1); | |
1543 parent->addChild(childOfRoot); | |
1544 renderSurface1->addChild(childOfRS1); | |
1545 renderSurface1->addChild(renderSurface2); | |
1546 renderSurface2->addChild(childOfRS2); | |
1547 childOfRoot->addChild(grandChildOfRoot); | |
1548 childOfRS1->addChild(grandChildOfRS1); | |
1549 childOfRS2->addChild(grandChildOfRS2); | |
1550 | |
1551 // Make our render surfaces. | |
1552 renderSurface1->setForceRenderSurface(true); | |
1553 renderSurface2->setForceRenderSurface(true); | |
1554 | |
1555 // Put an animated opacity on the render surface. | |
1556 addOpacityTransitionToController(*renderSurface1->layerAnimationController()
, 10, 1, 0, false); | |
1557 | |
1558 // Also put an animated opacity on a layer without descendants. | |
1559 addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController
(), 10, 1, 0, false); | |
1560 | |
1561 WebTransformationMatrix layerTransform; | |
1562 layerTransform.translate(1, 1); | |
1563 WebTransformationMatrix sublayerTransform; | |
1564 sublayerTransform.scale3d(10, 1, 1); | |
1565 | |
1566 // Put a transform animation on the render surface. | |
1567 addAnimatedTransformToController(*renderSurface2->layerAnimationController()
, 10, 30, 0); | |
1568 | |
1569 // Also put transform animations on grandChildOfRoot, and grandChildOfRS2 | |
1570 addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController
(), 10, 30, 0); | |
1571 addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(
), 10, 30, 0); | |
1572 | |
1573 setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1574 setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerT
ransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1575 setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerT
ransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1576 setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTran
sform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1577 setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTrans
form, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1578 setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTrans
form, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1579 setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublaye
rTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1580 setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayer
Transform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1581 setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayer
Transform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false); | |
1582 | |
1583 executeCalculateDrawTransformsAndVisibility(parent.get()); | |
1584 | |
1585 // Only layers that are associated with render surfaces should have an actua
l renderSurface() value. | |
1586 // | |
1587 ASSERT_TRUE(parent->renderSurface()); | |
1588 ASSERT_FALSE(childOfRoot->renderSurface()); | |
1589 ASSERT_FALSE(grandChildOfRoot->renderSurface()); | |
1590 | |
1591 ASSERT_TRUE(renderSurface1->renderSurface()); | |
1592 ASSERT_FALSE(childOfRS1->renderSurface()); | |
1593 ASSERT_FALSE(grandChildOfRS1->renderSurface()); | |
1594 | |
1595 ASSERT_TRUE(renderSurface2->renderSurface()); | |
1596 ASSERT_FALSE(childOfRS2->renderSurface()); | |
1597 ASSERT_FALSE(grandChildOfRS2->renderSurface()); | |
1598 | |
1599 // Verify all renderTarget accessors | |
1600 // | |
1601 EXPECT_EQ(parent, parent->renderTarget()); | |
1602 EXPECT_EQ(parent, childOfRoot->renderTarget()); | |
1603 EXPECT_EQ(parent, grandChildOfRoot->renderTarget()); | |
1604 | |
1605 EXPECT_EQ(renderSurface1, renderSurface1->renderTarget()); | |
1606 EXPECT_EQ(renderSurface1, childOfRS1->renderTarget()); | |
1607 EXPECT_EQ(renderSurface1, grandChildOfRS1->renderTarget()); | |
1608 | |
1609 EXPECT_EQ(renderSurface2, renderSurface2->renderTarget()); | |
1610 EXPECT_EQ(renderSurface2, childOfRS2->renderTarget()); | |
1611 EXPECT_EQ(renderSurface2, grandChildOfRS2->renderTarget()); | |
1612 | |
1613 // Verify drawOpacityIsAnimating values | |
1614 // | |
1615 EXPECT_FALSE(parent->drawOpacityIsAnimating()); | |
1616 EXPECT_FALSE(childOfRoot->drawOpacityIsAnimating()); | |
1617 EXPECT_TRUE(grandChildOfRoot->drawOpacityIsAnimating()); | |
1618 EXPECT_FALSE(renderSurface1->drawOpacityIsAnimating()); | |
1619 EXPECT_TRUE(renderSurface1->renderSurface()->drawOpacityIsAnimating()); | |
1620 EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating()); | |
1621 EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating()); | |
1622 EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating()); | |
1623 EXPECT_FALSE(renderSurface2->renderSurface()->drawOpacityIsAnimating()); | |
1624 EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating()); | |
1625 EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating()); | |
1626 | |
1627 // Verify drawTransformsAnimatingInTarget values | |
1628 // | |
1629 EXPECT_FALSE(parent->drawTransformIsAnimating()); | |
1630 EXPECT_FALSE(childOfRoot->drawTransformIsAnimating()); | |
1631 EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating()); | |
1632 EXPECT_FALSE(renderSurface1->drawTransformIsAnimating()); | |
1633 EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnim
ating()); | |
1634 EXPECT_FALSE(childOfRS1->drawTransformIsAnimating()); | |
1635 EXPECT_FALSE(grandChildOfRS1->drawTransformIsAnimating()); | |
1636 EXPECT_FALSE(renderSurface2->drawTransformIsAnimating()); | |
1637 EXPECT_TRUE(renderSurface2->renderSurface()->targetSurfaceTransformsAreAnima
ting()); | |
1638 EXPECT_FALSE(childOfRS2->drawTransformIsAnimating()); | |
1639 EXPECT_TRUE(grandChildOfRS2->drawTransformIsAnimating()); | |
1640 | |
1641 // Verify drawTransformsAnimatingInScreen values | |
1642 // | |
1643 EXPECT_FALSE(parent->screenSpaceTransformIsAnimating()); | |
1644 EXPECT_FALSE(childOfRoot->screenSpaceTransformIsAnimating()); | |
1645 EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating()); | |
1646 EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating()); | |
1647 EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimat
ing()); | |
1648 EXPECT_FALSE(childOfRS1->screenSpaceTransformIsAnimating()); | |
1649 EXPECT_FALSE(grandChildOfRS1->screenSpaceTransformIsAnimating()); | |
1650 EXPECT_TRUE(renderSurface2->screenSpaceTransformIsAnimating()); | |
1651 EXPECT_TRUE(renderSurface2->renderSurface()->screenSpaceTransformsAreAnimati
ng()); | |
1652 EXPECT_TRUE(childOfRS2->screenSpaceTransformIsAnimating()); | |
1653 EXPECT_TRUE(grandChildOfRS2->screenSpaceTransformIsAnimating()); | |
1654 | |
1655 | |
1656 // Sanity check. If these fail there is probably a bug in the test itself. | |
1657 // It is expected that we correctly set up transforms so that the y-componen
t of the screen-space transform | |
1658 // encodes the "depth" of the layer in the tree. | |
1659 EXPECT_FLOAT_EQ(1, parent->screenSpaceTransform().m42()); | |
1660 EXPECT_FLOAT_EQ(2, childOfRoot->screenSpaceTransform().m42()); | |
1661 EXPECT_FLOAT_EQ(3, grandChildOfRoot->screenSpaceTransform().m42()); | |
1662 | |
1663 EXPECT_FLOAT_EQ(2, renderSurface1->screenSpaceTransform().m42()); | |
1664 EXPECT_FLOAT_EQ(3, childOfRS1->screenSpaceTransform().m42()); | |
1665 EXPECT_FLOAT_EQ(4, grandChildOfRS1->screenSpaceTransform().m42()); | |
1666 | |
1667 EXPECT_FLOAT_EQ(3, renderSurface2->screenSpaceTransform().m42()); | |
1668 EXPECT_FLOAT_EQ(4, childOfRS2->screenSpaceTransform().m42()); | |
1669 EXPECT_FLOAT_EQ(5, grandChildOfRS2->screenSpaceTransform().m42()); | |
1670 } | |
1671 | |
1672 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForIdentityTransform) | |
1673 { | |
1674 // Test the calculateVisibleRect() function works correctly for identity tra
nsforms. | |
1675 | |
1676 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1677 WebTransformationMatrix layerToSurfaceTransform; | |
1678 | |
1679 // Case 1: Layer is contained within the surface. | |
1680 IntRect layerContentRect = IntRect(IntPoint(10, 10), IntSize(30, 30)); | |
1681 IntRect expected = IntRect(IntPoint(10, 10), IntSize(30, 30)); | |
1682 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1683 EXPECT_RECT_EQ(expected, actual); | |
1684 | |
1685 // Case 2: Layer is outside the surface rect. | |
1686 layerContentRect = IntRect(IntPoint(120, 120), IntSize(30, 30)); | |
1687 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1688 EXPECT_TRUE(actual.isEmpty()); | |
1689 | |
1690 // Case 3: Layer is partially overlapping the surface rect. | |
1691 layerContentRect = IntRect(IntPoint(80, 80), IntSize(30, 30)); | |
1692 expected = IntRect(IntPoint(80, 80), IntSize(20, 20)); | |
1693 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1694 EXPECT_RECT_EQ(expected, actual); | |
1695 } | |
1696 | |
1697 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForTranslations) | |
1698 { | |
1699 // Test the calculateVisibleRect() function works correctly for scaling tran
sforms. | |
1700 | |
1701 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1702 IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30)); | |
1703 WebTransformationMatrix layerToSurfaceTransform; | |
1704 | |
1705 // Case 1: Layer is contained within the surface. | |
1706 layerToSurfaceTransform.makeIdentity(); | |
1707 layerToSurfaceTransform.translate(10, 10); | |
1708 IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30)); | |
1709 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1710 EXPECT_RECT_EQ(expected, actual); | |
1711 | |
1712 // Case 2: Layer is outside the surface rect. | |
1713 layerToSurfaceTransform.makeIdentity(); | |
1714 layerToSurfaceTransform.translate(120, 120); | |
1715 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1716 EXPECT_TRUE(actual.isEmpty()); | |
1717 | |
1718 // Case 3: Layer is partially overlapping the surface rect. | |
1719 layerToSurfaceTransform.makeIdentity(); | |
1720 layerToSurfaceTransform.translate(80, 80); | |
1721 expected = IntRect(IntPoint(0, 0), IntSize(20, 20)); | |
1722 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1723 EXPECT_RECT_EQ(expected, actual); | |
1724 } | |
1725 | |
1726 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor2DRotations) | |
1727 { | |
1728 // Test the calculateVisibleRect() function works correctly for rotations ab
out z-axis (i.e. 2D rotations). | |
1729 // Remember that calculateVisibleRect() should return the visible rect in th
e layer's space. | |
1730 | |
1731 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1732 IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30)); | |
1733 WebTransformationMatrix layerToSurfaceTransform; | |
1734 | |
1735 // Case 1: Layer is contained within the surface. | |
1736 layerToSurfaceTransform.makeIdentity(); | |
1737 layerToSurfaceTransform.translate(50, 50); | |
1738 layerToSurfaceTransform.rotate(45); | |
1739 IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30)); | |
1740 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1741 EXPECT_RECT_EQ(expected, actual); | |
1742 | |
1743 // Case 2: Layer is outside the surface rect. | |
1744 layerToSurfaceTransform.makeIdentity(); | |
1745 layerToSurfaceTransform.translate(-50, 0); | |
1746 layerToSurfaceTransform.rotate(45); | |
1747 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1748 EXPECT_TRUE(actual.isEmpty()); | |
1749 | |
1750 // Case 3: The layer is rotated about its top-left corner. In surface space,
the layer | |
1751 // is oriented diagonally, with the left half outside of the renderS
urface. In | |
1752 // this case, the visible rect should still be the entire layer (rem
ember the | |
1753 // visible rect is computed in layer space); both the top-left and | |
1754 // bottom-right corners of the layer are still visible. | |
1755 layerToSurfaceTransform.makeIdentity(); | |
1756 layerToSurfaceTransform.rotate(45); | |
1757 expected = IntRect(IntPoint(0, 0), IntSize(30, 30)); | |
1758 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1759 EXPECT_RECT_EQ(expected, actual); | |
1760 | |
1761 // Case 4: The layer is rotated about its top-left corner, and translated up
wards. In | |
1762 // surface space, the layer is oriented diagonally, with only the to
p corner | |
1763 // of the surface overlapping the layer. In layer space, the render
surface | |
1764 // overlaps the right side of the layer. The visible rect should be
the | |
1765 // layer's right half. | |
1766 layerToSurfaceTransform.makeIdentity(); | |
1767 layerToSurfaceTransform.translate(0, -sqrt(2.0) * 15); | |
1768 layerToSurfaceTransform.rotate(45); | |
1769 expected = IntRect(IntPoint(15, 0), IntSize(15, 30)); // right half of layer
bounds. | |
1770 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1771 EXPECT_RECT_EQ(expected, actual); | |
1772 } | |
1773 | |
1774 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicTransform) | |
1775 { | |
1776 // Test that the calculateVisibleRect() function works correctly for 3d tran
sforms. | |
1777 | |
1778 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1779 IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1780 WebTransformationMatrix layerToSurfaceTransform; | |
1781 | |
1782 // Case 1: Orthographic projection of a layer rotated about y-axis by 45 deg
rees, should be fully contained in the renderSurface. | |
1783 layerToSurfaceTransform.makeIdentity(); | |
1784 layerToSurfaceTransform.rotate3d(0, 45, 0); | |
1785 IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1786 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1787 EXPECT_RECT_EQ(expected, actual); | |
1788 | |
1789 // Case 2: Orthographic projection of a layer rotated about y-axis by 45 deg
rees, but | |
1790 // shifted to the side so only the right-half the layer would be vis
ible on | |
1791 // the surface. | |
1792 double halfWidthOfRotatedLayer = (100 / sqrt(2.0)) * 0.5; // 100 is the un-r
otated layer width; divided by sqrt(2) is the rotated width. | |
1793 layerToSurfaceTransform.makeIdentity(); | |
1794 layerToSurfaceTransform.translate(-halfWidthOfRotatedLayer, 0); | |
1795 layerToSurfaceTransform.rotate3d(0, 45, 0); // rotates about the left edge o
f the layer | |
1796 expected = IntRect(IntPoint(50, 0), IntSize(50, 100)); // right half of the
layer. | |
1797 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1798 EXPECT_RECT_EQ(expected, actual); | |
1799 } | |
1800 | |
1801 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveTransform) | |
1802 { | |
1803 // Test the calculateVisibleRect() function works correctly when the layer h
as a | |
1804 // perspective projection onto the target surface. | |
1805 | |
1806 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1807 IntRect layerContentRect = IntRect(IntPoint(-50, -50), IntSize(200, 200)); | |
1808 WebTransformationMatrix layerToSurfaceTransform; | |
1809 | |
1810 // Case 1: Even though the layer is twice as large as the surface, due to pe
rspective | |
1811 // foreshortening, the layer will fit fully in the surface when its
translated | |
1812 // more than the perspective amount. | |
1813 layerToSurfaceTransform.makeIdentity(); | |
1814 | |
1815 // The following sequence of transforms applies the perspective about the ce
nter of the surface. | |
1816 layerToSurfaceTransform.translate(50, 50); | |
1817 layerToSurfaceTransform.applyPerspective(9); | |
1818 layerToSurfaceTransform.translate(-50, -50); | |
1819 | |
1820 // This translate places the layer in front of the surface's projection plan
e. | |
1821 layerToSurfaceTransform.translate3d(0, 0, -27); | |
1822 | |
1823 IntRect expected = IntRect(IntPoint(-50, -50), IntSize(200, 200)); | |
1824 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1825 EXPECT_RECT_EQ(expected, actual); | |
1826 | |
1827 // Case 2: same projection as before, except that the layer is also translat
ed to the | |
1828 // side, so that only the right half of the layer should be visible. | |
1829 // | |
1830 // Explanation of expected result: | |
1831 // The perspective ratio is (z distance between layer and camera origin) / (
z distance between projection plane and camera origin) == ((-27 - 9) / 9) | |
1832 // Then, by similar triangles, if we want to move a layer by translating -50
units in projected surface units (so that only half of it is | |
1833 // visible), then we would need to translate by (-36 / 9) * -50 == -200 in t
he layer's units. | |
1834 // | |
1835 layerToSurfaceTransform.translate3d(-200, 0, 0); | |
1836 expected = IntRect(IntPoint(50, -50), IntSize(100, 200)); // The right half
of the layer's bounding rect. | |
1837 actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, laye
rContentRect, layerToSurfaceTransform); | |
1838 EXPECT_RECT_EQ(expected, actual); | |
1839 } | |
1840 | |
1841 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicIsNotClippedBe
hindSurface) | |
1842 { | |
1843 // There is currently no explicit concept of an orthographic projection plan
e in our | |
1844 // code (nor in the CSS spec to my knowledge). Therefore, layers that are te
chnically | |
1845 // behind the surface in an orthographic world should not be clipped when th
ey are | |
1846 // flattened to the surface. | |
1847 | |
1848 IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1849 IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1850 WebTransformationMatrix layerToSurfaceTransform; | |
1851 | |
1852 // This sequence of transforms effectively rotates the layer about the y-axi
s at the | |
1853 // center of the layer. | |
1854 layerToSurfaceTransform.makeIdentity(); | |
1855 layerToSurfaceTransform.translate(50, 0); | |
1856 layerToSurfaceTransform.rotate3d(0, 45, 0); | |
1857 layerToSurfaceTransform.translate(-50, 0); | |
1858 | |
1859 IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100)); | |
1860 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1861 EXPECT_RECT_EQ(expected, actual); | |
1862 } | |
1863 | |
1864 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveWhenClippedByW) | |
1865 { | |
1866 // Test the calculateVisibleRect() function works correctly when projecting
a surface | |
1867 // onto a layer, but the layer is partially behind the camera (not just behi
nd the | |
1868 // projection plane). In this case, the cartesian coordinates may seem to be
valid, | |
1869 // but actually they are not. The visibleRect needs to be properly clipped b
y the | |
1870 // w = 0 plane in homogeneous coordinates before converting to cartesian coo
rdinates. | |
1871 | |
1872 IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100)); | |
1873 IntRect layerContentRect = IntRect(IntPoint(-10, -1), IntSize(20, 2)); | |
1874 WebTransformationMatrix layerToSurfaceTransform; | |
1875 | |
1876 // The layer is positioned so that the right half of the layer should be in
front of | |
1877 // the camera, while the other half is behind the surface's projection plane
. The | |
1878 // following sequence of transforms applies the perspective and rotation abo
ut the | |
1879 // center of the layer. | |
1880 layerToSurfaceTransform.makeIdentity(); | |
1881 layerToSurfaceTransform.applyPerspective(1); | |
1882 layerToSurfaceTransform.translate3d(-2, 0, 1); | |
1883 layerToSurfaceTransform.rotate3d(0, 45, 0); | |
1884 | |
1885 // Sanity check that this transform does indeed cause w < 0 when applying th
e | |
1886 // transform, otherwise this code is not testing the intended scenario. | |
1887 bool clipped = false; | |
1888 CCMathUtil::mapQuad(layerToSurfaceTransform, FloatQuad(FloatRect(layerConten
tRect)), clipped); | |
1889 ASSERT_TRUE(clipped); | |
1890 | |
1891 int expectedXPosition = 0; | |
1892 int expectedWidth = 10; | |
1893 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1894 EXPECT_EQ(expectedXPosition, actual.x()); | |
1895 EXPECT_EQ(expectedWidth, actual.width()); | |
1896 } | |
1897 | |
1898 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection) | |
1899 { | |
1900 // To determine visibleRect in layer space, there needs to be an un-projecti
on from | |
1901 // surface space to layer space. When the original transform was a perspecti
ve | |
1902 // projection that was clipped, it returns a rect that encloses the clipped
bounds. | |
1903 // Un-projecting this new rect may require clipping again. | |
1904 | |
1905 // This sequence of transforms causes one corner of the layer to protrude ac
ross the w = 0 plane, and should be clipped. | |
1906 IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100)); | |
1907 IntRect layerContentRect = IntRect(IntPoint(-10, -10), IntSize(20, 20)); | |
1908 WebTransformationMatrix layerToSurfaceTransform; | |
1909 layerToSurfaceTransform.makeIdentity(); | |
1910 layerToSurfaceTransform.applyPerspective(1); | |
1911 layerToSurfaceTransform.translate3d(0, 0, -5); | |
1912 layerToSurfaceTransform.rotate3d(0, 45, 0); | |
1913 layerToSurfaceTransform.rotate3d(80, 0, 0); | |
1914 | |
1915 // Sanity check that un-projection does indeed cause w < 0, otherwise this c
ode is not | |
1916 // testing the intended scenario. | |
1917 bool clipped = false; | |
1918 FloatRect clippedRect = CCMathUtil::mapClippedRect(layerToSurfaceTransform,
layerContentRect); | |
1919 CCMathUtil::projectQuad(layerToSurfaceTransform.inverse(), FloatQuad(clipped
Rect), clipped); | |
1920 ASSERT_TRUE(clipped); | |
1921 | |
1922 // Only the corner of the layer is not visible on the surface because of bei
ng | |
1923 // clipped. But, the net result of rounding visible region to an axis-aligne
d rect is | |
1924 // that the entire layer should still be considered visible. | |
1925 IntRect expected = IntRect(IntPoint(-10, -10), IntSize(20, 20)); | |
1926 IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRe
ct, layerContentRect, layerToSurfaceTransform); | |
1927 EXPECT_RECT_EQ(expected, actual); | |
1928 } | |
1929 | |
1930 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForSimpleLay
ers) | |
1931 { | |
1932 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
1933 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
1934 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
1935 scoped_refptr<LayerChromiumWithForcedDrawsContent> child3 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
1936 root->addChild(child1); | |
1937 root->addChild(child2); | |
1938 root->addChild(child3); | |
1939 | |
1940 WebTransformationMatrix identityMatrix; | |
1941 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
1942 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false); | |
1943 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
1944 setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
1945 | |
1946 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1947 | |
1948 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
1949 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
1950 | |
1951 // Layers that do not draw content should have empty visibleContentRects. | |
1952 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
1953 | |
1954 // layer visibleContentRects are clipped by their targetSurface | |
1955 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); | |
1956 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), child2->visibleContentRect()); | |
1957 EXPECT_TRUE(child3->visibleContentRect().isEmpty()); | |
1958 | |
1959 // layer drawableContentRects are not clipped. | |
1960 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->drawableContentRect()); | |
1961 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); | |
1962 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); | |
1963 } | |
1964 | |
1965 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersCli
ppedByLayer) | |
1966 { | |
1967 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
1968 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
1969 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild1 = make_scoped
_refptr(new LayerChromiumWithForcedDrawsContent()); | |
1970 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild2 = make_scoped
_refptr(new LayerChromiumWithForcedDrawsContent()); | |
1971 scoped_refptr<LayerChromiumWithForcedDrawsContent> grandChild3 = make_scoped
_refptr(new LayerChromiumWithForcedDrawsContent()); | |
1972 root->addChild(child); | |
1973 child->addChild(grandChild1); | |
1974 child->addChild(grandChild2); | |
1975 child->addChild(grandChild3); | |
1976 | |
1977 WebTransformationMatrix identityMatrix; | |
1978 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
1979 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
1980 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); | |
1981 setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
1982 setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatr
ix, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
1983 | |
1984 child->setMasksToBounds(true); | |
1985 executeCalculateDrawTransformsAndVisibility(root.get()); | |
1986 | |
1987 ASSERT_FALSE(child->renderSurface()); | |
1988 | |
1989 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
1990 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
1991 | |
1992 // Layers that do not draw content should have empty visibleContentRects. | |
1993 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
1994 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), child->visibleContentRect()); | |
1995 | |
1996 // All grandchild visibleContentRects should be clipped by child. | |
1997 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), grandChild1->visibleContentRect()); | |
1998 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), grandChild2->visibleContentRect()); | |
1999 EXPECT_TRUE(grandChild3->visibleContentRect().isEmpty()); | |
2000 | |
2001 // All grandchild drawableContentRects should also be clipped by child. | |
2002 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), grandChild1->drawableContentRect()); | |
2003 EXPECT_RECT_EQ(IntRect(75, 75, 25, 25), grandChild2->drawableContentRect()); | |
2004 EXPECT_TRUE(grandChild3->drawableContentRect().isEmpty()); | |
2005 } | |
2006 | |
2007 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersInU
nclippedRenderSurface) | |
2008 { | |
2009 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2010 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
2011 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2012 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2013 scoped_refptr<LayerChromiumWithForcedDrawsContent> child3 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2014 root->addChild(renderSurface1); | |
2015 renderSurface1->addChild(child1); | |
2016 renderSurface1->addChild(child2); | |
2017 renderSurface1->addChild(child3); | |
2018 | |
2019 WebTransformationMatrix identityMatrix; | |
2020 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2021 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); | |
2022 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); | |
2023 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
2024 setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
2025 | |
2026 renderSurface1->setForceRenderSurface(true); | |
2027 executeCalculateDrawTransformsAndVisibility(root.get()); | |
2028 | |
2029 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2030 | |
2031 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
2032 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
2033 | |
2034 // Layers that do not draw content should have empty visibleContentRects. | |
2035 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
2036 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); | |
2037 | |
2038 // An unclipped surface grows its drawableContentRect to include all drawabl
e regions of the subtree. | |
2039 EXPECT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface1->renderSurface()->dra
wableContentRect()); | |
2040 | |
2041 // All layers that draw content into the unclipped surface are also unclippe
d. | |
2042 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); | |
2043 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child2->visibleContentRect()); | |
2044 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child3->visibleContentRect()); | |
2045 | |
2046 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); | |
2047 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); | |
2048 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); | |
2049 } | |
2050 | |
2051 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForLayersInC
lippedRenderSurface) | |
2052 { | |
2053 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2054 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
2055 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2056 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2057 scoped_refptr<LayerChromiumWithForcedDrawsContent> child3 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2058 root->addChild(renderSurface1); | |
2059 renderSurface1->addChild(child1); | |
2060 renderSurface1->addChild(child2); | |
2061 renderSurface1->addChild(child3); | |
2062 | |
2063 WebTransformationMatrix identityMatrix; | |
2064 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2065 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); | |
2066 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); | |
2067 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
2068 setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
2069 | |
2070 root->setMasksToBounds(true); | |
2071 renderSurface1->setForceRenderSurface(true); | |
2072 executeCalculateDrawTransformsAndVisibility(root.get()); | |
2073 | |
2074 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2075 | |
2076 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
2077 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
2078 | |
2079 // Layers that do not draw content should have empty visibleContentRects. | |
2080 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
2081 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); | |
2082 | |
2083 // A clipped surface grows its drawableContentRect to include all drawable r
egions of the subtree, | |
2084 // but also gets clamped by the ancestor's clip. | |
2085 EXPECT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1->renderSurface()->drawa
bleContentRect()); | |
2086 | |
2087 // All layers that draw content into the surface have their visibleContentRe
ct clipped by the surface clipRect. | |
2088 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); | |
2089 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), child2->visibleContentRect()); | |
2090 EXPECT_TRUE(child3->visibleContentRect().isEmpty()); | |
2091 | |
2092 // But the drawableContentRects are unclipped. | |
2093 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); | |
2094 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); | |
2095 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); | |
2096 } | |
2097 | |
2098 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsForSurfaceHi
erarchy) | |
2099 { | |
2100 // Check that clipping does not propagate down surfaces. | |
2101 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2102 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
2103 scoped_refptr<LayerChromium> renderSurface2 = LayerChromium::create(); | |
2104 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2105 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2106 scoped_refptr<LayerChromiumWithForcedDrawsContent> child3 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2107 root->addChild(renderSurface1); | |
2108 renderSurface1->addChild(renderSurface2); | |
2109 renderSurface2->addChild(child1); | |
2110 renderSurface2->addChild(child2); | |
2111 renderSurface2->addChild(child3); | |
2112 | |
2113 WebTransformationMatrix identityMatrix; | |
2114 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2115 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); | |
2116 setLayerPropertiesForTesting(renderSurface2.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(7, 13), false); | |
2117 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); | |
2118 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
2119 setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
2120 | |
2121 root->setMasksToBounds(true); | |
2122 renderSurface1->setForceRenderSurface(true); | |
2123 renderSurface2->setForceRenderSurface(true); | |
2124 executeCalculateDrawTransformsAndVisibility(root.get()); | |
2125 | |
2126 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2127 ASSERT_TRUE(renderSurface2->renderSurface()); | |
2128 | |
2129 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
2130 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
2131 | |
2132 // Layers that do not draw content should have empty visibleContentRects. | |
2133 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
2134 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); | |
2135 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface2->visibleContentRect()); | |
2136 | |
2137 // A clipped surface grows its drawableContentRect to include all drawable r
egions of the subtree, | |
2138 // but also gets clamped by the ancestor's clip. | |
2139 EXPECT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1->renderSurface()->drawa
bleContentRect()); | |
2140 | |
2141 // renderSurface1 lives in the "unclipped universe" of renderSurface1, and i
s only | |
2142 // implicitly clipped by renderSurface1's contentRect. So, renderSurface2 gr
ows to | |
2143 // enclose all drawable content of its subtree. | |
2144 EXPECT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface2->renderSurface()->dra
wableContentRect()); | |
2145 | |
2146 // All layers that draw content into renderSurface2 think they are unclipped
. | |
2147 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); | |
2148 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child2->visibleContentRect()); | |
2149 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child3->visibleContentRect()); | |
2150 | |
2151 // drawableContentRects are also unclipped. | |
2152 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1->drawableContentRect()); | |
2153 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2->drawableContentRect()); | |
2154 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3->drawableContentRect()); | |
2155 } | |
2156 | |
2157 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsWithTransfor
mOnUnclippedSurface) | |
2158 { | |
2159 // Layers that have non-axis aligned bounds (due to transforms) have an expa
nded, | |
2160 // axis-aligned drawableContentRect and visibleContentRect. | |
2161 | |
2162 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2163 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
2164 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2165 root->addChild(renderSurface1); | |
2166 renderSurface1->addChild(child1); | |
2167 | |
2168 WebTransformationMatrix identityMatrix; | |
2169 WebTransformationMatrix childRotation; | |
2170 childRotation.rotate(45); | |
2171 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2172 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); | |
2173 setLayerPropertiesForTesting(child1.get(), childRotation, identityMatrix, Fl
oatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false); | |
2174 | |
2175 renderSurface1->setForceRenderSurface(true); | |
2176 executeCalculateDrawTransformsAndVisibility(root.get()); | |
2177 | |
2178 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2179 | |
2180 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->renderSurface()->drawableConte
ntRect()); | |
2181 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root->drawableContentRect()); | |
2182 | |
2183 // Layers that do not draw content should have empty visibleContentRects. | |
2184 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
2185 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1->visibleContentRect()); | |
2186 | |
2187 // The unclipped surface grows its drawableContentRect to include all drawab
le regions of the subtree. | |
2188 int diagonalRadius = ceil(sqrt(2.0) * 25); | |
2189 IntRect expectedSurfaceDrawableContent = IntRect(50 - diagonalRadius, 50 - d
iagonalRadius, diagonalRadius * 2, diagonalRadius * 2); | |
2190 EXPECT_RECT_EQ(expectedSurfaceDrawableContent, renderSurface1->renderSurface
()->drawableContentRect()); | |
2191 | |
2192 // All layers that draw content into the unclipped surface are also unclippe
d. | |
2193 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1->visibleContentRect()); | |
2194 EXPECT_RECT_EQ(expectedSurfaceDrawableContent, child1->drawableContentRect()
); | |
2195 } | |
2196 | |
2197 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsWithTransfor
mOnClippedSurface) | |
2198 { | |
2199 // Layers that have non-axis aligned bounds (due to transforms) have an expa
nded, | |
2200 // axis-aligned drawableContentRect and visibleContentRect. | |
2201 | |
2202 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2203 scoped_refptr<LayerChromium> renderSurface1 = LayerChromium::create(); | |
2204 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2205 root->addChild(renderSurface1); | |
2206 renderSurface1->addChild(child1); | |
2207 | |
2208 WebTransformationMatrix identityMatrix; | |
2209 WebTransformationMatrix childRotation; | |
2210 childRotation.rotate(45); | |
2211 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false); | |
2212 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false); | |
2213 setLayerPropertiesForTesting(child1.get(), childRotation, identityMatrix, Fl
oatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false); | |
2214 | |
2215 root->setMasksToBounds(true); | |
2216 renderSurface1->setForceRenderSurface(true); | |
2217 executeCalculateDrawTransformsAndVisibility(root.get()); | |
2218 | |
2219 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2220 | |
2221 // The clipped surface clamps the drawableContentRect that encloses the rota
ted layer. | |
2222 int diagonalRadius = ceil(sqrt(2.0) * 25); | |
2223 IntRect unclippedSurfaceContent = IntRect(50 - diagonalRadius, 50 - diagonal
Radius, diagonalRadius * 2, diagonalRadius * 2); | |
2224 IntRect expectedSurfaceDrawableContent = intersection(unclippedSurfaceConten
t, IntRect(0, 0, 50, 50)); | |
2225 EXPECT_RECT_EQ(expectedSurfaceDrawableContent, renderSurface1->renderSurface
()->drawableContentRect()); | |
2226 | |
2227 // On the clipped surface, only a quarter of the child1 is visible, but whe
n rotating | |
2228 // it back to child1's content space, the actual enclosing rect ends up cov
ering the | |
2229 // full left half of child1. | |
2230 EXPECT_RECT_EQ(IntRect(0, 0, 26, 50), child1->visibleContentRect()); | |
2231 | |
2232 // The child's drawableContentRect is unclipped. | |
2233 EXPECT_RECT_EQ(unclippedSurfaceContent, child1->drawableContentRect()); | |
2234 } | |
2235 | |
2236 TEST(CCLayerTreeHostCommonTest, verifyDrawableAndVisibleContentRectsInHighDPI) | |
2237 { | |
2238 MockContentLayerChromiumClient client; | |
2239 | |
2240 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
2241 scoped_refptr<ContentLayerChromium> renderSurface1 = createDrawableContentLa
yerChromium(&client); | |
2242 scoped_refptr<ContentLayerChromium> renderSurface2 = createDrawableContentLa
yerChromium(&client); | |
2243 scoped_refptr<ContentLayerChromium> child1 = createDrawableContentLayerChrom
ium(&client); | |
2244 scoped_refptr<ContentLayerChromium> child2 = createDrawableContentLayerChrom
ium(&client); | |
2245 scoped_refptr<ContentLayerChromium> child3 = createDrawableContentLayerChrom
ium(&client); | |
2246 root->addChild(renderSurface1); | |
2247 renderSurface1->addChild(renderSurface2); | |
2248 renderSurface2->addChild(child1); | |
2249 renderSurface2->addChild(child2); | |
2250 renderSurface2->addChild(child3); | |
2251 | |
2252 WebTransformationMatrix identityMatrix; | |
2253 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2254 setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(3, 4), false); | |
2255 setLayerPropertiesForTesting(renderSurface2.get(), identityMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(7, 13), false); | |
2256 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false); | |
2257 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false); | |
2258 setLayerPropertiesForTesting(child3.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false); | |
2259 | |
2260 const double deviceScaleFactor = 2; | |
2261 root->setContentsScale(deviceScaleFactor); | |
2262 renderSurface1->setContentsScale(deviceScaleFactor); | |
2263 renderSurface2->setContentsScale(deviceScaleFactor); | |
2264 child1->setContentsScale(deviceScaleFactor); | |
2265 child2->setContentsScale(deviceScaleFactor); | |
2266 child3->setContentsScale(deviceScaleFactor); | |
2267 | |
2268 root->setMasksToBounds(true); | |
2269 renderSurface1->setForceRenderSurface(true); | |
2270 renderSurface2->setForceRenderSurface(true); | |
2271 executeCalculateDrawTransformsAndVisibility(root.get(), deviceScaleFactor); | |
2272 | |
2273 ASSERT_TRUE(renderSurface1->renderSurface()); | |
2274 ASSERT_TRUE(renderSurface2->renderSurface()); | |
2275 | |
2276 // DrawableContentRects for all layers and surfaces are scaled by deviceScal
eFactor. | |
2277 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), root->renderSurface()->drawableConte
ntRect()); | |
2278 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), root->drawableContentRect()); | |
2279 EXPECT_RECT_EQ(IntRect(10, 10, 190, 190), renderSurface1->renderSurface()->d
rawableContentRect()); | |
2280 | |
2281 // renderSurface2 lives in the "unclipped universe" of renderSurface1, and | |
2282 // is only implicitly clipped by renderSurface1. | |
2283 EXPECT_RECT_EQ(IntRect(10, 10, 350, 350), renderSurface2->renderSurface()->d
rawableContentRect()); | |
2284 | |
2285 EXPECT_RECT_EQ(IntRect(10, 10, 100, 100), child1->drawableContentRect()); | |
2286 EXPECT_RECT_EQ(IntRect(150, 150, 100, 100), child2->drawableContentRect()); | |
2287 EXPECT_RECT_EQ(IntRect(250, 250, 100, 100), child3->drawableContentRect()); | |
2288 | |
2289 // The root layer does not actually draw content of its own. | |
2290 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root->visibleContentRect()); | |
2291 | |
2292 // All layer visibleContentRects are expressed in content space of each | |
2293 // layer, so they are also scaled by the deviceScaleFactor. | |
2294 EXPECT_RECT_EQ(IntRect(0, 0, 6, 8), renderSurface1->visibleContentRect()); | |
2295 EXPECT_RECT_EQ(IntRect(0, 0, 14, 26), renderSurface2->visibleContentRect()); | |
2296 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child1->visibleContentRect()); | |
2297 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child2->visibleContentRect()); | |
2298 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child3->visibleContentRect()); | |
2299 } | |
2300 | |
2301 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d) | |
2302 { | |
2303 // Verify the behavior of back-face culling when there are no preserve-3d la
yers. Note | |
2304 // that 3d transforms still apply in this case, but they are "flattened" to
each | |
2305 // parent layer according to current W3C spec. | |
2306 | |
2307 const WebTransformationMatrix identityMatrix; | |
2308 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
2309 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChild = make_s
coped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2310 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChild = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2311 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = make
_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2312 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingSurface = make_
scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2313 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFa
cingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2314 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFac
ingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2315 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFac
ingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2316 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFaci
ngSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2317 | |
2318 parent->addChild(frontFacingChild); | |
2319 parent->addChild(backFacingChild); | |
2320 parent->addChild(frontFacingSurface); | |
2321 parent->addChild(backFacingSurface); | |
2322 frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface); | |
2323 frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface); | |
2324 backFacingSurface->addChild(frontFacingChildOfBackFacingSurface); | |
2325 backFacingSurface->addChild(backFacingChildOfBackFacingSurface); | |
2326 | |
2327 // Nothing is double-sided | |
2328 frontFacingChild->setDoubleSided(false); | |
2329 backFacingChild->setDoubleSided(false); | |
2330 frontFacingSurface->setDoubleSided(false); | |
2331 backFacingSurface->setDoubleSided(false); | |
2332 frontFacingChildOfFrontFacingSurface->setDoubleSided(false); | |
2333 backFacingChildOfFrontFacingSurface->setDoubleSided(false); | |
2334 frontFacingChildOfBackFacingSurface->setDoubleSided(false); | |
2335 backFacingChildOfBackFacingSurface->setDoubleSided(false); | |
2336 | |
2337 WebTransformationMatrix backfaceMatrix; | |
2338 backfaceMatrix.translate(50, 50); | |
2339 backfaceMatrix.rotate3d(0, 1, 0, 180); | |
2340 backfaceMatrix.translate(-50, -50); | |
2341 | |
2342 // Having a descendant and opacity will force these to have render surfaces. | |
2343 frontFacingSurface->setOpacity(0.5); | |
2344 backFacingSurface->setOpacity(0.5); | |
2345 | |
2346 // Nothing preserves 3d. According to current W3C CSS Transforms spec, these
layers | |
2347 // should blindly use their own local transforms to determine back-face cull
ing. | |
2348 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2349 setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identit
yMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2350 setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identity
Matrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2351 setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, ident
ityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2352 setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identi
tyMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2353 setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), ide
ntityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 10
0), false); | |
2354 setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), back
faceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100
), false); | |
2355 setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), iden
tityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100
), false); | |
2356 setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backf
aceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100)
, false); | |
2357 | |
2358 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
2359 int dummyMaxTextureSize = 512; | |
2360 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
2361 | |
2362 // Verify which renderSurfaces were created. | |
2363 EXPECT_FALSE(frontFacingChild->renderSurface()); | |
2364 EXPECT_FALSE(backFacingChild->renderSurface()); | |
2365 EXPECT_TRUE(frontFacingSurface->renderSurface()); | |
2366 EXPECT_TRUE(backFacingSurface->renderSurface()); | |
2367 EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface()); | |
2368 EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface()); | |
2369 EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface()); | |
2370 EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface()); | |
2371 | |
2372 // Verify the renderSurfaceLayerList. | |
2373 ASSERT_EQ(3u, renderSurfaceLayerList.size()); | |
2374 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
2375 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id()); | |
2376 // Even though the back facing surface LAYER gets culled, the other descenda
nts should still be added, so the SURFACE should not be culled. | |
2377 EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[2]->id()); | |
2378 | |
2379 // Verify root surface's layerList. | |
2380 ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size()
); | |
2381 EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()
->layerList()[0]->id()); | |
2382 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface
()->layerList()[1]->id()); | |
2383 EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface(
)->layerList()[2]->id()); | |
2384 | |
2385 // Verify frontFacingSurface's layerList. | |
2386 ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size()
); | |
2387 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface
()->layerList()[0]->id()); | |
2388 EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id()); | |
2389 | |
2390 // Verify backFacingSurface's layerList; its own layer should be culled from
the surface list. | |
2391 ASSERT_EQ(1u, renderSurfaceLayerList[2]->renderSurface()->layerList().size()
); | |
2392 EXPECT_EQ(frontFacingChildOfBackFacingSurface->id(), renderSurfaceLayerList[
2]->renderSurface()->layerList()[0]->id()); | |
2393 } | |
2394 | |
2395 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d) | |
2396 { | |
2397 // Verify the behavior of back-face culling when preserves-3d transform styl
e is used. | |
2398 | |
2399 const WebTransformationMatrix identityMatrix; | |
2400 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
2401 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChild = make_s
coped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2402 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChild = make_sc
oped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2403 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = make
_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2404 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingSurface = make_
scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2405 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFa
cingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2406 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFac
ingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2407 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFac
ingSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2408 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFaci
ngSurface = make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2409 scoped_refptr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer1 = make
_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2410 scoped_refptr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer2 = make
_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2411 | |
2412 parent->addChild(frontFacingChild); | |
2413 parent->addChild(backFacingChild); | |
2414 parent->addChild(frontFacingSurface); | |
2415 parent->addChild(backFacingSurface); | |
2416 frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface); | |
2417 frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface); | |
2418 backFacingSurface->addChild(frontFacingChildOfBackFacingSurface); | |
2419 backFacingSurface->addChild(backFacingChildOfBackFacingSurface); | |
2420 | |
2421 // Nothing is double-sided | |
2422 frontFacingChild->setDoubleSided(false); | |
2423 backFacingChild->setDoubleSided(false); | |
2424 frontFacingSurface->setDoubleSided(false); | |
2425 backFacingSurface->setDoubleSided(false); | |
2426 frontFacingChildOfFrontFacingSurface->setDoubleSided(false); | |
2427 backFacingChildOfFrontFacingSurface->setDoubleSided(false); | |
2428 frontFacingChildOfBackFacingSurface->setDoubleSided(false); | |
2429 backFacingChildOfBackFacingSurface->setDoubleSided(false); | |
2430 | |
2431 WebTransformationMatrix backfaceMatrix; | |
2432 backfaceMatrix.translate(50, 50); | |
2433 backfaceMatrix.rotate3d(0, 1, 0, 180); | |
2434 backfaceMatrix.translate(-50, -50); | |
2435 | |
2436 // Opacity will not force creation of renderSurfaces in this case because of
the | |
2437 // preserve-3d transform style. Instead, an example of when a surface would
be | |
2438 // created with preserve-3d is when there is a replica layer. | |
2439 frontFacingSurface->setReplicaLayer(dummyReplicaLayer1.get()); | |
2440 backFacingSurface->setReplicaLayer(dummyReplicaLayer2.get()); | |
2441 | |
2442 // Each surface creates its own new 3d rendering context (as defined by W3C
spec). | |
2443 // According to current W3C CSS Transforms spec, layers in a 3d rendering co
ntext | |
2444 // should use the transform with respect to that context. This 3d rendering
context | |
2445 // occurs when (a) parent's transform style is flat and (b) the layer's tran
sform | |
2446 // style is preserve-3d. | |
2447 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transfor
m style is flat. | |
2448 setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identit
yMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2449 setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identity
Matrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2450 setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, ident
ityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surf
ace transform style is preserve-3d. | |
2451 setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identi
tyMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surfa
ce transform style is preserve-3d. | |
2452 setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), ide
ntityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 10
0), false); | |
2453 setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), back
faceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100
), false); | |
2454 setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), iden
tityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100
), false); | |
2455 setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backf
aceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100)
, false); | |
2456 | |
2457 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
2458 int dummyMaxTextureSize = 512; | |
2459 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
2460 | |
2461 // Verify which renderSurfaces were created. | |
2462 EXPECT_FALSE(frontFacingChild->renderSurface()); | |
2463 EXPECT_FALSE(backFacingChild->renderSurface()); | |
2464 EXPECT_TRUE(frontFacingSurface->renderSurface()); | |
2465 EXPECT_FALSE(backFacingSurface->renderSurface()); | |
2466 EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface()); | |
2467 EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface()); | |
2468 EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface()); | |
2469 EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface()); | |
2470 | |
2471 // Verify the renderSurfaceLayerList. The back-facing surface should be cull
ed. | |
2472 ASSERT_EQ(2u, renderSurfaceLayerList.size()); | |
2473 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
2474 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id()); | |
2475 | |
2476 // Verify root surface's layerList. | |
2477 ASSERT_EQ(2u, renderSurfaceLayerList[0]->renderSurface()->layerList().size()
); | |
2478 EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()
->layerList()[0]->id()); | |
2479 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface
()->layerList()[1]->id()); | |
2480 | |
2481 // Verify frontFacingSurface's layerList. | |
2482 ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size()
); | |
2483 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface
()->layerList()[0]->id()); | |
2484 EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id()); | |
2485 } | |
2486 | |
2487 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms) | |
2488 { | |
2489 // Verify that layers are appropriately culled when their back face is showi
ng and | |
2490 // they are not double sided, while animations are going on. | |
2491 // | |
2492 // Layers that are animating do not get culled on the main thread, as their
transforms should be | |
2493 // treated as "unknown" so we can not be sure that their back face is really
showing. | |
2494 // | |
2495 | |
2496 const WebTransformationMatrix identityMatrix; | |
2497 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
2498 scoped_refptr<LayerChromiumWithForcedDrawsContent> child = make_scoped_refpt
r(new LayerChromiumWithForcedDrawsContent()); | |
2499 scoped_refptr<LayerChromiumWithForcedDrawsContent> animatingSurface = make_s
coped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2500 scoped_refptr<LayerChromiumWithForcedDrawsContent> childOfAnimatingSurface =
make_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2501 scoped_refptr<LayerChromiumWithForcedDrawsContent> animatingChild = make_sco
ped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2502 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2503 | |
2504 parent->addChild(child); | |
2505 parent->addChild(animatingSurface); | |
2506 animatingSurface->addChild(childOfAnimatingSurface); | |
2507 parent->addChild(animatingChild); | |
2508 parent->addChild(child2); | |
2509 | |
2510 // Nothing is double-sided | |
2511 child->setDoubleSided(false); | |
2512 child2->setDoubleSided(false); | |
2513 animatingSurface->setDoubleSided(false); | |
2514 childOfAnimatingSurface->setDoubleSided(false); | |
2515 animatingChild->setDoubleSided(false); | |
2516 | |
2517 WebTransformationMatrix backfaceMatrix; | |
2518 backfaceMatrix.translate(50, 50); | |
2519 backfaceMatrix.rotate3d(0, 1, 0, 180); | |
2520 backfaceMatrix.translate(-50, -50); | |
2521 | |
2522 // Make our render surface. | |
2523 animatingSurface->setForceRenderSurface(true); | |
2524 | |
2525 // Animate the transform on the render surface. | |
2526 addAnimatedTransformToController(*animatingSurface->layerAnimationController
(), 10, 30, 0); | |
2527 // This is just an animating layer, not a surface. | |
2528 addAnimatedTransformToController(*animatingChild->layerAnimationController()
, 10, 30, 0); | |
2529 | |
2530 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2531 setLayerPropertiesForTesting(child.get(), backfaceMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2532 setLayerPropertiesForTesting(animatingSurface.get(), backfaceMatrix, identit
yMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2533 setLayerPropertiesForTesting(childOfAnimatingSurface.get(), backfaceMatrix,
identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2534 setLayerPropertiesForTesting(animatingChild.get(), backfaceMatrix, identityM
atrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2535 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2536 | |
2537 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
2538 int dummyMaxTextureSize = 512; | |
2539 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
2540 | |
2541 EXPECT_FALSE(child->renderSurface()); | |
2542 EXPECT_TRUE(animatingSurface->renderSurface()); | |
2543 EXPECT_FALSE(childOfAnimatingSurface->renderSurface()); | |
2544 EXPECT_FALSE(animatingChild->renderSurface()); | |
2545 EXPECT_FALSE(child2->renderSurface()); | |
2546 | |
2547 // Verify that the animatingChild and childOfAnimatingSurface were not culle
d, but that child was. | |
2548 ASSERT_EQ(2u, renderSurfaceLayerList.size()); | |
2549 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
2550 EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->id()); | |
2551 | |
2552 // The non-animating child be culled from the layer list for the parent rend
er surface. | |
2553 ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size()
); | |
2554 EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[0]->renderSurface()
->layerList()[0]->id()); | |
2555 EXPECT_EQ(animatingChild->id(), renderSurfaceLayerList[0]->renderSurface()->
layerList()[1]->id()); | |
2556 EXPECT_EQ(child2->id(), renderSurfaceLayerList[0]->renderSurface()->layerLis
t()[2]->id()); | |
2557 | |
2558 ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size()
); | |
2559 EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()
->layerList()[0]->id()); | |
2560 EXPECT_EQ(childOfAnimatingSurface->id(), renderSurfaceLayerList[1]->renderSu
rface()->layerList()[1]->id()); | |
2561 | |
2562 EXPECT_FALSE(child2->visibleContentRect().isEmpty()); | |
2563 | |
2564 // The animating layers should have a visibleContentRect that represents the
area of the front face that is within the viewport. | |
2565 EXPECT_EQ(animatingChild->visibleContentRect(), IntRect(IntPoint(), animatin
gChild->contentBounds())); | |
2566 EXPECT_EQ(animatingSurface->visibleContentRect(), IntRect(IntPoint(), animat
ingSurface->contentBounds())); | |
2567 // And layers in the subtree of the animating layer should have valid visibl
eContentRects also. | |
2568 EXPECT_EQ(childOfAnimatingSurface->visibleContentRect(), IntRect(IntPoint(),
childOfAnimatingSurface->contentBounds())); | |
2569 } | |
2570 | |
2571 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlattenin
gSurface) | |
2572 { | |
2573 // Verify the behavior of back-face culling for a renderSurface that is crea
ted | |
2574 // when it flattens its subtree, and its parent has preserves-3d. | |
2575 | |
2576 const WebTransformationMatrix identityMatrix; | |
2577 scoped_refptr<LayerChromium> parent = LayerChromium::create(); | |
2578 scoped_refptr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = make
_scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2579 scoped_refptr<LayerChromiumWithForcedDrawsContent> backFacingSurface = make_
scoped_refptr(new LayerChromiumWithForcedDrawsContent()); | |
2580 scoped_refptr<LayerChromiumWithForcedDrawsContent> child1 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2581 scoped_refptr<LayerChromiumWithForcedDrawsContent> child2 = make_scoped_refp
tr(new LayerChromiumWithForcedDrawsContent()); | |
2582 | |
2583 parent->addChild(frontFacingSurface); | |
2584 parent->addChild(backFacingSurface); | |
2585 frontFacingSurface->addChild(child1); | |
2586 backFacingSurface->addChild(child2); | |
2587 | |
2588 // RenderSurfaces are not double-sided | |
2589 frontFacingSurface->setDoubleSided(false); | |
2590 backFacingSurface->setDoubleSided(false); | |
2591 | |
2592 WebTransformationMatrix backfaceMatrix; | |
2593 backfaceMatrix.translate(50, 50); | |
2594 backfaceMatrix.rotate3d(0, 1, 0, 180); | |
2595 backfaceMatrix.translate(-50, -50); | |
2596 | |
2597 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform
style is preserve3d. | |
2598 setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, ident
ityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // sur
face transform style is flat. | |
2599 setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, ident
ityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // sur
face transform style is flat. | |
2600 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2601 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); | |
2602 | |
2603 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
2604 int dummyMaxTextureSize = 512; | |
2605 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), 1, dummyMaxTextureSize, renderSurfaceLayerList); | |
2606 | |
2607 // Verify which renderSurfaces were created. | |
2608 EXPECT_TRUE(frontFacingSurface->renderSurface()); | |
2609 EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be cu
lled | |
2610 EXPECT_FALSE(child1->renderSurface()); | |
2611 EXPECT_FALSE(child2->renderSurface()); | |
2612 | |
2613 // Verify the renderSurfaceLayerList. The back-facing surface should be cull
ed. | |
2614 ASSERT_EQ(2u, renderSurfaceLayerList.size()); | |
2615 EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id()); | |
2616 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id()); | |
2617 | |
2618 // Verify root surface's layerList. | |
2619 ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size()
); | |
2620 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface
()->layerList()[0]->id()); | |
2621 | |
2622 // Verify frontFacingSurface's layerList. | |
2623 ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size()
); | |
2624 EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface
()->layerList()[0]->id()); | |
2625 EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerLis
t()[1]->id()); | |
2626 } | |
2627 | |
2628 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForEmptyLayerList) | |
2629 { | |
2630 // Hit testing on an empty renderSurfaceLayerList should return a null point
er. | |
2631 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2632 | |
2633 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2634 | |
2635 IntPoint testPoint(0, 0); | |
2636 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2637 EXPECT_FALSE(resultLayer); | |
2638 | |
2639 testPoint = IntPoint(10, 20); | |
2640 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2641 EXPECT_FALSE(resultLayer); | |
2642 } | |
2643 | |
2644 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayer) | |
2645 { | |
2646 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2647 | |
2648 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(12345); | |
2649 | |
2650 WebTransformationMatrix identityMatrix; | |
2651 FloatPoint anchor(0, 0); | |
2652 FloatPoint position(0, 0); | |
2653 IntSize bounds(100, 100); | |
2654 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, position, bounds, false); | |
2655 root->setDrawsContent(true); | |
2656 | |
2657 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2658 int dummyMaxTextureSize = 512; | |
2659 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2660 | |
2661 // Sanity check the scenario we just created. | |
2662 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2663 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2664 | |
2665 // Hit testing for a point outside the layer should return a null pointer. | |
2666 IntPoint testPoint(101, 101); | |
2667 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2668 EXPECT_FALSE(resultLayer); | |
2669 | |
2670 testPoint = IntPoint(-1, -1); | |
2671 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2672 EXPECT_FALSE(resultLayer); | |
2673 | |
2674 // Hit testing for a point inside should return the root layer. | |
2675 testPoint = IntPoint(1, 1); | |
2676 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2677 ASSERT_TRUE(resultLayer); | |
2678 EXPECT_EQ(12345, resultLayer->id()); | |
2679 | |
2680 testPoint = IntPoint(99, 99); | |
2681 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2682 ASSERT_TRUE(resultLayer); | |
2683 EXPECT_EQ(12345, resultLayer->id()); | |
2684 } | |
2685 | |
2686 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForUninvertibleTransform) | |
2687 { | |
2688 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2689 | |
2690 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(12345); | |
2691 | |
2692 WebTransformationMatrix uninvertibleTransform; | |
2693 uninvertibleTransform.setM11(0); | |
2694 uninvertibleTransform.setM22(0); | |
2695 uninvertibleTransform.setM33(0); | |
2696 uninvertibleTransform.setM44(0); | |
2697 ASSERT_FALSE(uninvertibleTransform.isInvertible()); | |
2698 | |
2699 WebTransformationMatrix identityMatrix; | |
2700 FloatPoint anchor(0, 0); | |
2701 FloatPoint position(0, 0); | |
2702 IntSize bounds(100, 100); | |
2703 setLayerPropertiesForTesting(root.get(), uninvertibleTransform, identityMatr
ix, anchor, position, bounds, false); | |
2704 root->setDrawsContent(true); | |
2705 | |
2706 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2707 int dummyMaxTextureSize = 512; | |
2708 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2709 | |
2710 // Sanity check the scenario we just created. | |
2711 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2712 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2713 ASSERT_FALSE(root->screenSpaceTransform().isInvertible()); | |
2714 | |
2715 // Hit testing any point should not hit the layer. If the invertible matrix
is | |
2716 // accidentally ignored and treated like an identity, then the hit testing w
ill | |
2717 // incorrectly hit the layer when it shouldn't. | |
2718 IntPoint testPoint(1, 1); | |
2719 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2720 EXPECT_FALSE(resultLayer); | |
2721 | |
2722 testPoint = IntPoint(10, 10); | |
2723 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2724 EXPECT_FALSE(resultLayer); | |
2725 | |
2726 testPoint = IntPoint(10, 30); | |
2727 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2728 EXPECT_FALSE(resultLayer); | |
2729 | |
2730 testPoint = IntPoint(50, 50); | |
2731 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2732 EXPECT_FALSE(resultLayer); | |
2733 | |
2734 testPoint = IntPoint(67, 48); | |
2735 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2736 EXPECT_FALSE(resultLayer); | |
2737 | |
2738 testPoint = IntPoint(99, 99); | |
2739 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2740 EXPECT_FALSE(resultLayer); | |
2741 | |
2742 testPoint = IntPoint(-1, -1); | |
2743 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2744 EXPECT_FALSE(resultLayer); | |
2745 } | |
2746 | |
2747 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePositionedLayer) | |
2748 { | |
2749 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2750 | |
2751 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(12345); | |
2752 | |
2753 WebTransformationMatrix identityMatrix; | |
2754 FloatPoint anchor(0, 0); | |
2755 FloatPoint position(50, 50); // this layer is positioned, and hit testing sh
ould correctly know where the layer is located. | |
2756 IntSize bounds(100, 100); | |
2757 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, position, bounds, false); | |
2758 root->setDrawsContent(true); | |
2759 | |
2760 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2761 int dummyMaxTextureSize = 512; | |
2762 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2763 | |
2764 // Sanity check the scenario we just created. | |
2765 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2766 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2767 | |
2768 // Hit testing for a point outside the layer should return a null pointer. | |
2769 IntPoint testPoint(49, 49); | |
2770 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2771 EXPECT_FALSE(resultLayer); | |
2772 | |
2773 // Even though the layer exists at (101, 101), it should not be visible ther
e since the root renderSurface would clamp it. | |
2774 testPoint = IntPoint(101, 101); | |
2775 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2776 EXPECT_FALSE(resultLayer); | |
2777 | |
2778 // Hit testing for a point inside should return the root layer. | |
2779 testPoint = IntPoint(51, 51); | |
2780 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2781 ASSERT_TRUE(resultLayer); | |
2782 EXPECT_EQ(12345, resultLayer->id()); | |
2783 | |
2784 testPoint = IntPoint(99, 99); | |
2785 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2786 ASSERT_TRUE(resultLayer); | |
2787 EXPECT_EQ(12345, resultLayer->id()); | |
2788 } | |
2789 | |
2790 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleRotatedLayer) | |
2791 { | |
2792 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2793 | |
2794 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(12345); | |
2795 | |
2796 WebTransformationMatrix identityMatrix; | |
2797 WebTransformationMatrix rotation45DegreesAboutCenter; | |
2798 rotation45DegreesAboutCenter.translate(50, 50); | |
2799 rotation45DegreesAboutCenter.rotate3d(0, 0, 45); | |
2800 rotation45DegreesAboutCenter.translate(-50, -50); | |
2801 FloatPoint anchor(0, 0); | |
2802 FloatPoint position(0, 0); | |
2803 IntSize bounds(100, 100); | |
2804 setLayerPropertiesForTesting(root.get(), rotation45DegreesAboutCenter, ident
ityMatrix, anchor, position, bounds, false); | |
2805 root->setDrawsContent(true); | |
2806 | |
2807 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2808 int dummyMaxTextureSize = 512; | |
2809 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2810 | |
2811 // Sanity check the scenario we just created. | |
2812 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2813 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2814 | |
2815 // Hit testing for points outside the layer. | |
2816 // These corners would have been inside the un-transformed layer, but they s
hould not hit the correctly transformed layer. | |
2817 IntPoint testPoint(99, 99); | |
2818 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2819 EXPECT_FALSE(resultLayer); | |
2820 | |
2821 testPoint = IntPoint(1, 1); | |
2822 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2823 EXPECT_FALSE(resultLayer); | |
2824 | |
2825 // Hit testing for a point inside should return the root layer. | |
2826 testPoint = IntPoint(1, 50); | |
2827 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2828 ASSERT_TRUE(resultLayer); | |
2829 EXPECT_EQ(12345, resultLayer->id()); | |
2830 | |
2831 // Hit testing the corners that would overlap the unclipped layer, but are o
utside the clipped region. | |
2832 testPoint = IntPoint(50, -1); | |
2833 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2834 ASSERT_FALSE(resultLayer); | |
2835 | |
2836 testPoint = IntPoint(-1, 50); | |
2837 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2838 ASSERT_FALSE(resultLayer); | |
2839 } | |
2840 | |
2841 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePerspectiveLayer) | |
2842 { | |
2843 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2844 | |
2845 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(12345); | |
2846 | |
2847 WebTransformationMatrix identityMatrix; | |
2848 | |
2849 // perspectiveProjectionAboutCenter * translationByZ is designed so that the
100 x 100 layer becomes 50 x 50, and remains centered at (50, 50). | |
2850 WebTransformationMatrix perspectiveProjectionAboutCenter; | |
2851 perspectiveProjectionAboutCenter.translate(50, 50); | |
2852 perspectiveProjectionAboutCenter.applyPerspective(1); | |
2853 perspectiveProjectionAboutCenter.translate(-50, -50); | |
2854 WebTransformationMatrix translationByZ; | |
2855 translationByZ.translate3d(0, 0, -1); | |
2856 | |
2857 FloatPoint anchor(0, 0); | |
2858 FloatPoint position(0, 0); | |
2859 IntSize bounds(100, 100); | |
2860 setLayerPropertiesForTesting(root.get(), perspectiveProjectionAboutCenter *
translationByZ, identityMatrix, anchor, position, bounds, false); | |
2861 root->setDrawsContent(true); | |
2862 | |
2863 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2864 int dummyMaxTextureSize = 512; | |
2865 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2866 | |
2867 // Sanity check the scenario we just created. | |
2868 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2869 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2870 | |
2871 // Hit testing for points outside the layer. | |
2872 // These corners would have been inside the un-transformed layer, but they s
hould not hit the correctly transformed layer. | |
2873 IntPoint testPoint(24, 24); | |
2874 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2875 EXPECT_FALSE(resultLayer); | |
2876 | |
2877 testPoint = IntPoint(76, 76); | |
2878 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2879 EXPECT_FALSE(resultLayer); | |
2880 | |
2881 // Hit testing for a point inside should return the root layer. | |
2882 testPoint = IntPoint(26, 26); | |
2883 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2884 ASSERT_TRUE(resultLayer); | |
2885 EXPECT_EQ(12345, resultLayer->id()); | |
2886 | |
2887 testPoint = IntPoint(74, 74); | |
2888 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2889 ASSERT_TRUE(resultLayer); | |
2890 EXPECT_EQ(12345, resultLayer->id()); | |
2891 } | |
2892 | |
2893 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayerWithScaledContents
) | |
2894 { | |
2895 // A layer's visibleContentRect is actually in the layer's content space. Th
e | |
2896 // screenSpaceTransform converts from the layer's origin space to screen spa
ce. This | |
2897 // test makes sure that hit testing works correctly accounts for the content
s scale. | |
2898 // A contentsScale that is not 1 effectively forces a non-identity transform
between | |
2899 // layer's content space and layer's origin space. The hit testing code must
take this into account. | |
2900 // | |
2901 // To test this, the layer is positioned at (25, 25), and is size (50, 50).
If | |
2902 // contentsScale is ignored, then hit testing will mis-interpret the visible
ContentRect | |
2903 // as being larger than the actual bounds of the layer. | |
2904 // | |
2905 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2906 | |
2907 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
2908 | |
2909 WebTransformationMatrix identityMatrix; | |
2910 FloatPoint anchor(0, 0); | |
2911 | |
2912 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, FloatPoint(0, 0), IntSize(100, 100), false); | |
2913 | |
2914 { | |
2915 FloatPoint position(25, 25); | |
2916 IntSize bounds(50, 50); | |
2917 scoped_ptr<CCLayerImpl> testLayer = CCLayerImpl::create(12345); | |
2918 setLayerPropertiesForTesting(testLayer.get(), identityMatrix, identityMa
trix, anchor, position, bounds, false); | |
2919 | |
2920 // override contentBounds | |
2921 testLayer->setContentBounds(IntSize(100, 100)); | |
2922 | |
2923 testLayer->setDrawsContent(true); | |
2924 root->addChild(testLayer.Pass()); | |
2925 } | |
2926 | |
2927 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2928 int dummyMaxTextureSize = 512; | |
2929 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2930 | |
2931 // Sanity check the scenario we just created. | |
2932 // The visibleContentRect for testLayer is actually 100x100, even though its
layout size is 50x50, positioned at 25x25. | |
2933 CCLayerImpl* testLayer = root->children()[0]; | |
2934 EXPECT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(100, 100)), testLayer->visi
bleContentRect()); | |
2935 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2936 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2937 | |
2938 // Hit testing for a point outside the layer should return a null pointer (t
he root layer does not draw content, so it will not be hit tested either). | |
2939 IntPoint testPoint(101, 101); | |
2940 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
2941 EXPECT_FALSE(resultLayer); | |
2942 | |
2943 testPoint = IntPoint(24, 24); | |
2944 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2945 EXPECT_FALSE(resultLayer); | |
2946 | |
2947 testPoint = IntPoint(76, 76); | |
2948 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2949 EXPECT_FALSE(resultLayer); | |
2950 | |
2951 // Hit testing for a point inside should return the test layer. | |
2952 testPoint = IntPoint(26, 26); | |
2953 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2954 ASSERT_TRUE(resultLayer); | |
2955 EXPECT_EQ(12345, resultLayer->id()); | |
2956 | |
2957 testPoint = IntPoint(74, 74); | |
2958 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
2959 ASSERT_TRUE(resultLayer); | |
2960 EXPECT_EQ(12345, resultLayer->id()); | |
2961 } | |
2962 | |
2963 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSimpleClippedLayer) | |
2964 { | |
2965 // Test that hit-testing will only work for the visible portion of a layer,
and not | |
2966 // the entire layer bounds. Here we just test the simple axis-aligned case. | |
2967 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
2968 | |
2969 WebTransformationMatrix identityMatrix; | |
2970 FloatPoint anchor(0, 0); | |
2971 | |
2972 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
2973 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, FloatPoint(0, 0), IntSize(100, 100), false); | |
2974 | |
2975 { | |
2976 scoped_ptr<CCLayerImpl> clippingLayer = CCLayerImpl::create(123); | |
2977 FloatPoint position(25, 25); // this layer is positioned, and hit testin
g should correctly know where the layer is located. | |
2978 IntSize bounds(50, 50); | |
2979 setLayerPropertiesForTesting(clippingLayer.get(), identityMatrix, identi
tyMatrix, anchor, position, bounds, false); | |
2980 clippingLayer->setMasksToBounds(true); | |
2981 | |
2982 scoped_ptr<CCLayerImpl> child = CCLayerImpl::create(456); | |
2983 position = FloatPoint(-50, -50); | |
2984 bounds = IntSize(300, 300); | |
2985 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix
, anchor, position, bounds, false); | |
2986 child->setDrawsContent(true); | |
2987 clippingLayer->addChild(child.Pass()); | |
2988 root->addChild(clippingLayer.Pass()); | |
2989 } | |
2990 | |
2991 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
2992 int dummyMaxTextureSize = 512; | |
2993 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
2994 | |
2995 // Sanity check the scenario we just created. | |
2996 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
2997 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
2998 ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id()); | |
2999 | |
3000 // Hit testing for a point outside the layer should return a null pointer. | |
3001 // Despite the child layer being very large, it should be clipped to the roo
t layer's bounds. | |
3002 IntPoint testPoint(24, 24); | |
3003 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
3004 EXPECT_FALSE(resultLayer); | |
3005 | |
3006 // Even though the layer exists at (101, 101), it should not be visible ther
e since the clippingLayer would clamp it. | |
3007 testPoint = IntPoint(76, 76); | |
3008 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3009 EXPECT_FALSE(resultLayer); | |
3010 | |
3011 // Hit testing for a point inside should return the child layer. | |
3012 testPoint = IntPoint(26, 26); | |
3013 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3014 ASSERT_TRUE(resultLayer); | |
3015 EXPECT_EQ(456, resultLayer->id()); | |
3016 | |
3017 testPoint = IntPoint(74, 74); | |
3018 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3019 ASSERT_TRUE(resultLayer); | |
3020 EXPECT_EQ(456, resultLayer->id()); | |
3021 } | |
3022 | |
3023 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultiClippedRotatedLayer) | |
3024 { | |
3025 // This test checks whether hit testing correctly avoids hit testing with mu
ltiple | |
3026 // ancestors that clip in non axis-aligned ways. To pass this test, the hit
testing | |
3027 // algorithm needs to recognize that multiple parent layers may clip the lay
er, and | |
3028 // should not actually hit those clipped areas. | |
3029 // | |
3030 // The child and grandChild layers are both initialized to clip the rotatedL
eaf. The | |
3031 // child layer is rotated about the top-left corner, so that the root + chil
d clips | |
3032 // combined create a triangle. The rotatedLeaf will only be visible where it
overlaps | |
3033 // this triangle. | |
3034 // | |
3035 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
3036 | |
3037 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(123); | |
3038 | |
3039 WebTransformationMatrix identityMatrix; | |
3040 FloatPoint anchor(0, 0); | |
3041 FloatPoint position(0, 0); | |
3042 IntSize bounds(100, 100); | |
3043 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, position, bounds, false); | |
3044 root->setMasksToBounds(true); | |
3045 | |
3046 { | |
3047 scoped_ptr<CCLayerImpl> child = CCLayerImpl::create(456); | |
3048 scoped_ptr<CCLayerImpl> grandChild = CCLayerImpl::create(789); | |
3049 scoped_ptr<CCLayerImpl> rotatedLeaf = CCLayerImpl::create(2468); | |
3050 | |
3051 position = FloatPoint(10, 10); | |
3052 bounds = IntSize(80, 80); | |
3053 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix
, anchor, position, bounds, false); | |
3054 child->setMasksToBounds(true); | |
3055 | |
3056 WebTransformationMatrix rotation45DegreesAboutCorner; | |
3057 rotation45DegreesAboutCorner.rotate3d(0, 0, 45); | |
3058 | |
3059 position = FloatPoint(0, 0); // remember, positioned with respect to its
parent which is already at 10, 10 | |
3060 bounds = IntSize(200, 200); // to ensure it covers at least sqrt(2) * 10
0. | |
3061 setLayerPropertiesForTesting(grandChild.get(), rotation45DegreesAboutCor
ner, identityMatrix, anchor, position, bounds, false); | |
3062 grandChild->setMasksToBounds(true); | |
3063 | |
3064 // Rotates about the center of the layer | |
3065 WebTransformationMatrix rotatedLeafTransform; | |
3066 rotatedLeafTransform.translate(-10, -10); // cancel out the grandParent'
s position | |
3067 rotatedLeafTransform.rotate3d(0, 0, -45); // cancel out the corner 45-de
gree rotation of the parent. | |
3068 rotatedLeafTransform.translate(50, 50); | |
3069 rotatedLeafTransform.rotate3d(0, 0, 45); | |
3070 rotatedLeafTransform.translate(-50, -50); | |
3071 position = FloatPoint(0, 0); | |
3072 bounds = IntSize(100, 100); | |
3073 setLayerPropertiesForTesting(rotatedLeaf.get(), rotatedLeafTransform, id
entityMatrix, anchor, position, bounds, false); | |
3074 rotatedLeaf->setDrawsContent(true); | |
3075 | |
3076 grandChild->addChild(rotatedLeaf.Pass()); | |
3077 child->addChild(grandChild.Pass()); | |
3078 root->addChild(child.Pass()); | |
3079 } | |
3080 | |
3081 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
3082 int dummyMaxTextureSize = 512; | |
3083 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
3084 | |
3085 // Sanity check the scenario we just created. | |
3086 // The grandChild is expected to create a renderSurface because it masksToBo
unds and is not axis aligned. | |
3087 ASSERT_EQ(2u, renderSurfaceLayerList.size()); | |
3088 ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size()
); | |
3089 ASSERT_EQ(789, renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->i
d()); // grandChild's surface. | |
3090 ASSERT_EQ(1u, renderSurfaceLayerList[1]->renderSurface()->layerList().size()
); | |
3091 ASSERT_EQ(2468, renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->
id()); | |
3092 | |
3093 // (11, 89) is close to the the bottom left corner within the clip, but it i
s not inside the layer. | |
3094 IntPoint testPoint(11, 89); | |
3095 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
3096 EXPECT_FALSE(resultLayer); | |
3097 | |
3098 // Closer inwards from the bottom left will overlap the layer. | |
3099 testPoint = IntPoint(25, 75); | |
3100 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3101 ASSERT_TRUE(resultLayer); | |
3102 EXPECT_EQ(2468, resultLayer->id()); | |
3103 | |
3104 // (4, 50) is inside the unclipped layer, but that corner of the layer shoul
d be | |
3105 // clipped away by the grandParent and should not get hit. If hit testing bl
indly uses | |
3106 // visibleContentRect without considering how parent may clip the layer, the
n hit | |
3107 // testing would accidentally think that the point successfully hits the lay
er. | |
3108 testPoint = IntPoint(4, 50); | |
3109 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3110 EXPECT_FALSE(resultLayer); | |
3111 | |
3112 // (11, 50) is inside the layer and within the clipped area. | |
3113 testPoint = IntPoint(11, 50); | |
3114 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3115 ASSERT_TRUE(resultLayer); | |
3116 EXPECT_EQ(2468, resultLayer->id()); | |
3117 | |
3118 // Around the middle, just to the right and up, would have hit the layer exc
ept that | |
3119 // that area should be clipped away by the parent. | |
3120 testPoint = IntPoint(51, 51); | |
3121 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3122 EXPECT_FALSE(resultLayer); | |
3123 | |
3124 // Around the middle, just to the left and down, should successfully hit the
layer. | |
3125 testPoint = IntPoint(49, 51); | |
3126 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3127 ASSERT_TRUE(resultLayer); | |
3128 EXPECT_EQ(2468, resultLayer->id()); | |
3129 } | |
3130 | |
3131 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForNonClippingIntermediateLayer) | |
3132 { | |
3133 // This test checks that hit testing code does not accidentally clip to laye
r | |
3134 // bounds for a layer that actually does not clip. | |
3135 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
3136 | |
3137 WebTransformationMatrix identityMatrix; | |
3138 FloatPoint anchor(0, 0); | |
3139 | |
3140 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
3141 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, FloatPoint(0, 0), IntSize(100, 100), false); | |
3142 | |
3143 { | |
3144 scoped_ptr<CCLayerImpl> intermediateLayer = CCLayerImpl::create(123); | |
3145 FloatPoint position(10, 10); // this layer is positioned, and hit testin
g should correctly know where the layer is located. | |
3146 IntSize bounds(50, 50); | |
3147 setLayerPropertiesForTesting(intermediateLayer.get(), identityMatrix, id
entityMatrix, anchor, position, bounds, false); | |
3148 // Sanity check the intermediate layer should not clip. | |
3149 ASSERT_FALSE(intermediateLayer->masksToBounds()); | |
3150 ASSERT_FALSE(intermediateLayer->maskLayer()); | |
3151 | |
3152 // The child of the intermediateLayer is translated so that it does not
overlap intermediateLayer at all. | |
3153 // If child is incorrectly clipped, we would not be able to hit it succe
ssfully. | |
3154 scoped_ptr<CCLayerImpl> child = CCLayerImpl::create(456); | |
3155 position = FloatPoint(60, 60); // 70, 70 in screen space | |
3156 bounds = IntSize(20, 20); | |
3157 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix
, anchor, position, bounds, false); | |
3158 child->setDrawsContent(true); | |
3159 intermediateLayer->addChild(child.Pass()); | |
3160 root->addChild(intermediateLayer.Pass()); | |
3161 } | |
3162 | |
3163 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
3164 int dummyMaxTextureSize = 512; | |
3165 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
3166 | |
3167 // Sanity check the scenario we just created. | |
3168 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
3169 ASSERT_EQ(1u, root->renderSurface()->layerList().size()); | |
3170 ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id()); | |
3171 | |
3172 // Hit testing for a point outside the layer should return a null pointer. | |
3173 IntPoint testPoint(69, 69); | |
3174 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
3175 EXPECT_FALSE(resultLayer); | |
3176 | |
3177 testPoint = IntPoint(91, 91); | |
3178 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3179 EXPECT_FALSE(resultLayer); | |
3180 | |
3181 // Hit testing for a point inside should return the child layer. | |
3182 testPoint = IntPoint(71, 71); | |
3183 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3184 ASSERT_TRUE(resultLayer); | |
3185 EXPECT_EQ(456, resultLayer->id()); | |
3186 | |
3187 testPoint = IntPoint(89, 89); | |
3188 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3189 ASSERT_TRUE(resultLayer); | |
3190 EXPECT_EQ(456, resultLayer->id()); | |
3191 } | |
3192 | |
3193 | |
3194 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayers) | |
3195 { | |
3196 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
3197 | |
3198 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
3199 | |
3200 WebTransformationMatrix identityMatrix; | |
3201 FloatPoint anchor(0, 0); | |
3202 FloatPoint position(0, 0); | |
3203 IntSize bounds(100, 100); | |
3204 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, position, bounds, false); | |
3205 root->setDrawsContent(true); | |
3206 | |
3207 { | |
3208 // child 1 and child2 are initialized to overlap between x=50 and x=60. | |
3209 // grandChild is set to overlap both child1 and child2 between y=50 and
y=60. | |
3210 // The expected stacking order is: | |
3211 // (front) child2, (second) grandChild, (third) child1, and (back) the
root layer behind all other layers. | |
3212 | |
3213 scoped_ptr<CCLayerImpl> child1 = CCLayerImpl::create(2); | |
3214 scoped_ptr<CCLayerImpl> child2 = CCLayerImpl::create(3); | |
3215 scoped_ptr<CCLayerImpl> grandChild1 = CCLayerImpl::create(4); | |
3216 | |
3217 position = FloatPoint(10, 10); | |
3218 bounds = IntSize(50, 50); | |
3219 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatri
x, anchor, position, bounds, false); | |
3220 child1->setDrawsContent(true); | |
3221 | |
3222 position = FloatPoint(50, 10); | |
3223 bounds = IntSize(50, 50); | |
3224 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatri
x, anchor, position, bounds, false); | |
3225 child2->setDrawsContent(true); | |
3226 | |
3227 // Remember that grandChild is positioned with respect to its parent (i.
e. child1). | |
3228 // In screen space, the intended position is (10, 50), with size 100 x 5
0. | |
3229 position = FloatPoint(0, 40); | |
3230 bounds = IntSize(100, 50); | |
3231 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identity
Matrix, anchor, position, bounds, false); | |
3232 grandChild1->setDrawsContent(true); | |
3233 | |
3234 child1->addChild(grandChild1.Pass()); | |
3235 root->addChild(child1.Pass()); | |
3236 root->addChild(child2.Pass()); | |
3237 } | |
3238 | |
3239 CCLayerImpl* child1 = root->children()[0]; | |
3240 CCLayerImpl* child2 = root->children()[1]; | |
3241 CCLayerImpl* grandChild1 = child1->children()[0]; | |
3242 | |
3243 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
3244 int dummyMaxTextureSize = 512; | |
3245 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
3246 | |
3247 // Sanity check the scenario we just created. | |
3248 ASSERT_TRUE(child1); | |
3249 ASSERT_TRUE(child2); | |
3250 ASSERT_TRUE(grandChild1); | |
3251 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
3252 ASSERT_EQ(4u, root->renderSurface()->layerList().size()); | |
3253 ASSERT_EQ(1, root->renderSurface()->layerList()[0]->id()); // root layer | |
3254 ASSERT_EQ(2, root->renderSurface()->layerList()[1]->id()); // child1 | |
3255 ASSERT_EQ(4, root->renderSurface()->layerList()[2]->id()); // grandChild1 | |
3256 ASSERT_EQ(3, root->renderSurface()->layerList()[3]->id()); // child2 | |
3257 | |
3258 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should fin
d the root layer. | |
3259 IntPoint testPoint = IntPoint(1, 1); | |
3260 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
3261 ASSERT_TRUE(resultLayer); | |
3262 EXPECT_EQ(1, resultLayer->id()); | |
3263 | |
3264 // At (15, 15), child1 and root are the only layers. child1 is expected to b
e on top. | |
3265 testPoint = IntPoint(15, 15); | |
3266 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3267 ASSERT_TRUE(resultLayer); | |
3268 EXPECT_EQ(2, resultLayer->id()); | |
3269 | |
3270 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. | |
3271 testPoint = IntPoint(51, 20); | |
3272 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3273 ASSERT_TRUE(resultLayer); | |
3274 EXPECT_EQ(3, resultLayer->id()); | |
3275 | |
3276 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on
top. | |
3277 testPoint = IntPoint(80, 51); | |
3278 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3279 ASSERT_TRUE(resultLayer); | |
3280 EXPECT_EQ(3, resultLayer->id()); | |
3281 | |
3282 // At (51, 51), all layers overlap each other. child2 is expected to be on t
op of all other layers. | |
3283 testPoint = IntPoint(51, 51); | |
3284 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3285 ASSERT_TRUE(resultLayer); | |
3286 EXPECT_EQ(3, resultLayer->id()); | |
3287 | |
3288 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to b
e on top. | |
3289 testPoint = IntPoint(20, 51); | |
3290 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3291 ASSERT_TRUE(resultLayer); | |
3292 EXPECT_EQ(4, resultLayer->id()); | |
3293 } | |
3294 | |
3295 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayerLists) | |
3296 { | |
3297 // | |
3298 // The geometry is set up similarly to the previous case, but | |
3299 // all layers are forced to be renderSurfaces now. | |
3300 // | |
3301 DebugScopedSetImplThread thisScopeIsOnImplThread; | |
3302 | |
3303 scoped_ptr<CCLayerImpl> root = CCLayerImpl::create(1); | |
3304 | |
3305 WebTransformationMatrix identityMatrix; | |
3306 FloatPoint anchor(0, 0); | |
3307 FloatPoint position(0, 0); | |
3308 IntSize bounds(100, 100); | |
3309 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc
hor, position, bounds, false); | |
3310 root->setDrawsContent(true); | |
3311 | |
3312 { | |
3313 // child 1 and child2 are initialized to overlap between x=50 and x=60. | |
3314 // grandChild is set to overlap both child1 and child2 between y=50 and
y=60. | |
3315 // The expected stacking order is: | |
3316 // (front) child2, (second) grandChild, (third) child1, and (back) the
root layer behind all other layers. | |
3317 | |
3318 scoped_ptr<CCLayerImpl> child1 = CCLayerImpl::create(2); | |
3319 scoped_ptr<CCLayerImpl> child2 = CCLayerImpl::create(3); | |
3320 scoped_ptr<CCLayerImpl> grandChild1 = CCLayerImpl::create(4); | |
3321 | |
3322 position = FloatPoint(10, 10); | |
3323 bounds = IntSize(50, 50); | |
3324 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatri
x, anchor, position, bounds, false); | |
3325 child1->setDrawsContent(true); | |
3326 child1->setForceRenderSurface(true); | |
3327 | |
3328 position = FloatPoint(50, 10); | |
3329 bounds = IntSize(50, 50); | |
3330 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatri
x, anchor, position, bounds, false); | |
3331 child2->setDrawsContent(true); | |
3332 child2->setForceRenderSurface(true); | |
3333 | |
3334 // Remember that grandChild is positioned with respect to its parent (i.
e. child1). | |
3335 // In screen space, the intended position is (10, 50), with size 100 x 5
0. | |
3336 position = FloatPoint(0, 40); | |
3337 bounds = IntSize(100, 50); | |
3338 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identity
Matrix, anchor, position, bounds, false); | |
3339 grandChild1->setDrawsContent(true); | |
3340 grandChild1->setForceRenderSurface(true); | |
3341 | |
3342 child1->addChild(grandChild1.Pass()); | |
3343 root->addChild(child1.Pass()); | |
3344 root->addChild(child2.Pass()); | |
3345 } | |
3346 | |
3347 CCLayerImpl* child1 = root->children()[0]; | |
3348 CCLayerImpl* child2 = root->children()[1]; | |
3349 CCLayerImpl* grandChild1 = child1->children()[0]; | |
3350 | |
3351 std::vector<CCLayerImpl*> renderSurfaceLayerList; | |
3352 int dummyMaxTextureSize = 512; | |
3353 CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1
, 0, dummyMaxTextureSize, renderSurfaceLayerList); | |
3354 | |
3355 // Sanity check the scenario we just created. | |
3356 ASSERT_TRUE(child1); | |
3357 ASSERT_TRUE(child2); | |
3358 ASSERT_TRUE(grandChild1); | |
3359 ASSERT_TRUE(child1->renderSurface()); | |
3360 ASSERT_TRUE(child2->renderSurface()); | |
3361 ASSERT_TRUE(grandChild1->renderSurface()); | |
3362 ASSERT_EQ(4u, renderSurfaceLayerList.size()); | |
3363 ASSERT_EQ(3u, root->renderSurface()->layerList().size()); // The root surfac
e has the root layer, and child1's and child2's renderSurfaces. | |
3364 ASSERT_EQ(2u, child1->renderSurface()->layerList().size()); // The child1 su
rface has the child1 layer and grandChild1's renderSurface. | |
3365 ASSERT_EQ(1u, child2->renderSurface()->layerList().size()); | |
3366 ASSERT_EQ(1u, grandChild1->renderSurface()->layerList().size()); | |
3367 ASSERT_EQ(1, renderSurfaceLayerList[0]->id()); // root layer | |
3368 ASSERT_EQ(2, renderSurfaceLayerList[1]->id()); // child1 | |
3369 ASSERT_EQ(4, renderSurfaceLayerList[2]->id()); // grandChild1 | |
3370 ASSERT_EQ(3, renderSurfaceLayerList[3]->id()); // child2 | |
3371 | |
3372 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should fin
d the root layer. | |
3373 IntPoint testPoint = IntPoint(1, 1); | |
3374 CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(
testPoint, renderSurfaceLayerList); | |
3375 ASSERT_TRUE(resultLayer); | |
3376 EXPECT_EQ(1, resultLayer->id()); | |
3377 | |
3378 // At (15, 15), child1 and root are the only layers. child1 is expected to b
e on top. | |
3379 testPoint = IntPoint(15, 15); | |
3380 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3381 ASSERT_TRUE(resultLayer); | |
3382 EXPECT_EQ(2, resultLayer->id()); | |
3383 | |
3384 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top. | |
3385 testPoint = IntPoint(51, 20); | |
3386 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3387 ASSERT_TRUE(resultLayer); | |
3388 EXPECT_EQ(3, resultLayer->id()); | |
3389 | |
3390 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on
top. | |
3391 testPoint = IntPoint(80, 51); | |
3392 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3393 ASSERT_TRUE(resultLayer); | |
3394 EXPECT_EQ(3, resultLayer->id()); | |
3395 | |
3396 // At (51, 51), all layers overlap each other. child2 is expected to be on t
op of all other layers. | |
3397 testPoint = IntPoint(51, 51); | |
3398 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3399 ASSERT_TRUE(resultLayer); | |
3400 EXPECT_EQ(3, resultLayer->id()); | |
3401 | |
3402 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to b
e on top. | |
3403 testPoint = IntPoint(20, 51); | |
3404 resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, re
nderSurfaceLayerList); | |
3405 ASSERT_TRUE(resultLayer); | |
3406 EXPECT_EQ(4, resultLayer->id()); | |
3407 } | |
3408 | |
3409 TEST(CCLayerTreeHostCommonTest, verifyLayerTransformsInHighDPI) | |
3410 { | |
3411 // Verify draw and screen space transforms of layers not in a surface. | |
3412 MockContentLayerChromiumClient delegate; | |
3413 WebTransformationMatrix identityMatrix; | |
3414 | |
3415 scoped_refptr<ContentLayerChromium> parent = createDrawableContentLayerChrom
ium(&delegate); | |
3416 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); | |
3417 | |
3418 scoped_refptr<ContentLayerChromium> child = createDrawableContentLayerChromi
um(&delegate); | |
3419 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true); | |
3420 | |
3421 scoped_refptr<ContentLayerChromium> childNoScale = createDrawableContentLaye
rChromium(&delegate); | |
3422 setLayerPropertiesForTesting(childNoScale.get(), identityMatrix, identityMat
rix, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true); | |
3423 | |
3424 parent->addChild(child); | |
3425 parent->addChild(childNoScale); | |
3426 | |
3427 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
3428 int dummyMaxTextureSize = 512; | |
3429 | |
3430 const double deviceScaleFactor = 2.5; | |
3431 parent->setContentsScale(deviceScaleFactor); | |
3432 child->setContentsScale(deviceScaleFactor); | |
3433 EXPECT_EQ(childNoScale->contentsScale(), 1); | |
3434 | |
3435 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), deviceScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList); | |
3436 | |
3437 EXPECT_EQ(1u, renderSurfaceLayerList.size()); | |
3438 | |
3439 // Verify parent transforms | |
3440 WebTransformationMatrix expectedParentTransform; | |
3441 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform, parent->screenSpace
Transform()); | |
3442 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform, parent->drawTransfo
rm()); | |
3443 | |
3444 // Verify results of transformed parent rects | |
3445 FloatRect parentContentBounds(FloatPoint(), FloatSize(parent->contentBounds(
))); | |
3446 | |
3447 FloatRect parentDrawRect = CCMathUtil::mapClippedRect(parent->drawTransform(
), parentContentBounds); | |
3448 FloatRect parentScreenSpaceRect = CCMathUtil::mapClippedRect(parent->screenS
paceTransform(), parentContentBounds); | |
3449 | |
3450 FloatRect expectedParentDrawRect(FloatPoint(), parent->bounds()); | |
3451 expectedParentDrawRect.scale(deviceScaleFactor); | |
3452 EXPECT_FLOAT_RECT_EQ(expectedParentDrawRect, parentDrawRect); | |
3453 EXPECT_FLOAT_RECT_EQ(expectedParentDrawRect, parentScreenSpaceRect); | |
3454 | |
3455 // Verify child transforms | |
3456 WebTransformationMatrix expectedChildTransform; | |
3457 expectedChildTransform.translate(deviceScaleFactor * child->position().x(),
deviceScaleFactor * child->position().y()); | |
3458 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform
()); | |
3459 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->screenSpaceTr
ansform()); | |
3460 | |
3461 // Verify results of transformed child rects | |
3462 FloatRect childContentBounds(FloatPoint(), FloatSize(child->contentBounds())
); | |
3463 | |
3464 FloatRect childDrawRect = CCMathUtil::mapClippedRect(child->drawTransform(),
childContentBounds); | |
3465 FloatRect childScreenSpaceRect = CCMathUtil::mapClippedRect(child->screenSpa
ceTransform(), childContentBounds); | |
3466 | |
3467 FloatRect expectedChildDrawRect(FloatPoint(), child->bounds()); | |
3468 expectedChildDrawRect.move(child->position().x(), child->position().y()); | |
3469 expectedChildDrawRect.scale(deviceScaleFactor); | |
3470 EXPECT_FLOAT_RECT_EQ(expectedChildDrawRect, childDrawRect); | |
3471 EXPECT_FLOAT_RECT_EQ(expectedChildDrawRect, childScreenSpaceRect); | |
3472 | |
3473 // Verify childNoScale transforms | |
3474 WebTransformationMatrix expectedChildNoScaleTransform = child->drawTransform
(); | |
3475 // All transforms operate on content rects. The child's content rect | |
3476 // incorporates device scale, but the childNoScale does not; add it here. | |
3477 expectedChildNoScaleTransform.scale(deviceScaleFactor); | |
3478 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform, childNoScale-
>drawTransform()); | |
3479 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform, childNoScale-
>screenSpaceTransform()); | |
3480 } | |
3481 | |
3482 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceTransformsInHighDPI) | |
3483 { | |
3484 MockContentLayerChromiumClient delegate; | |
3485 WebTransformationMatrix identityMatrix; | |
3486 | |
3487 scoped_refptr<ContentLayerChromium> parent = createDrawableContentLayerChrom
ium(&delegate); | |
3488 setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, F
loatPoint(0, 0), FloatPoint(0, 0), IntSize(30, 30), true); | |
3489 | |
3490 scoped_refptr<ContentLayerChromium> child = createDrawableContentLayerChromi
um(&delegate); | |
3491 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, Fl
oatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true); | |
3492 | |
3493 WebTransformationMatrix replicaTransform; | |
3494 replicaTransform.scaleNonUniform(1, -1); | |
3495 scoped_refptr<ContentLayerChromium> replica = createDrawableContentLayerChro
mium(&delegate); | |
3496 setLayerPropertiesForTesting(replica.get(), replicaTransform, identityMatrix
, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true); | |
3497 | |
3498 // This layer should end up in the same surface as child, with the same draw | |
3499 // and screen space transforms. | |
3500 scoped_refptr<ContentLayerChromium> duplicateChildNonOwner = createDrawableC
ontentLayerChromium(&delegate); | |
3501 setLayerPropertiesForTesting(duplicateChildNonOwner.get(), identityMatrix, i
dentityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true); | |
3502 | |
3503 parent->addChild(child); | |
3504 child->addChild(duplicateChildNonOwner); | |
3505 child->setReplicaLayer(replica.get()); | |
3506 | |
3507 std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList; | |
3508 int dummyMaxTextureSize = 512; | |
3509 | |
3510 const double deviceScaleFactor = 1.5; | |
3511 parent->setContentsScale(deviceScaleFactor); | |
3512 child->setContentsScale(deviceScaleFactor); | |
3513 duplicateChildNonOwner->setContentsScale(deviceScaleFactor); | |
3514 replica->setContentsScale(deviceScaleFactor); | |
3515 | |
3516 CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(
), deviceScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList); | |
3517 | |
3518 // We should have two render surfaces. The root's render surface and child's | |
3519 // render surface (it needs one because it has a replica layer). | |
3520 EXPECT_EQ(2u, renderSurfaceLayerList.size()); | |
3521 | |
3522 WebTransformationMatrix expectedParentTransform; | |
3523 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform, parent->screenSpace
Transform()); | |
3524 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform, parent->drawTransfo
rm()); | |
3525 | |
3526 WebTransformationMatrix expectedDrawTransform; | |
3527 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedDrawTransform, child->drawTransform(
)); | |
3528 | |
3529 WebTransformationMatrix expectedScreenSpaceTransform; | |
3530 expectedScreenSpaceTransform.translate(deviceScaleFactor * child->position()
.x(), deviceScaleFactor * child->position().y()); | |
3531 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedScreenSpaceTransform, child->screenS
paceTransform()); | |
3532 | |
3533 WebTransformationMatrix expectedDuplicateChildDrawTransform = child->drawTra
nsform(); | |
3534 EXPECT_TRANSFORMATION_MATRIX_EQ(child->drawTransform(), duplicateChildNonOwn
er->drawTransform()); | |
3535 EXPECT_TRANSFORMATION_MATRIX_EQ(child->screenSpaceTransform(), duplicateChil
dNonOwner->screenSpaceTransform()); | |
3536 EXPECT_RECT_EQ(child->drawableContentRect(), duplicateChildNonOwner->drawabl
eContentRect()); | |
3537 EXPECT_EQ(child->contentBounds(), duplicateChildNonOwner->contentBounds()); | |
3538 | |
3539 WebTransformationMatrix expectedRenderSurfaceDrawTransform; | |
3540 expectedRenderSurfaceDrawTransform.translate(deviceScaleFactor * child->posi
tion().x(), deviceScaleFactor * child->position().y()); | |
3541 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedRenderSurfaceDrawTransform, child->r
enderSurface()->drawTransform()); | |
3542 | |
3543 WebTransformationMatrix expectedSurfaceDrawTransform; | |
3544 expectedSurfaceDrawTransform.translate(deviceScaleFactor * 2, deviceScaleFac
tor * 2); | |
3545 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, child->renderS
urface()->drawTransform()); | |
3546 | |
3547 WebTransformationMatrix expectedSurfaceScreenSpaceTransform; | |
3548 expectedSurfaceScreenSpaceTransform.translate(deviceScaleFactor * 2, deviceS
caleFactor * 2); | |
3549 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceScreenSpaceTransform, child->
renderSurface()->screenSpaceTransform()); | |
3550 | |
3551 WebTransformationMatrix expectedReplicaDrawTransform; | |
3552 expectedReplicaDrawTransform.setM22(-1); | |
3553 expectedReplicaDrawTransform.setM41(6); | |
3554 expectedReplicaDrawTransform.setM42(6); | |
3555 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedReplicaDrawTransform, child->renderS
urface()->replicaDrawTransform()); | |
3556 | |
3557 WebTransformationMatrix expectedReplicaScreenSpaceTransform; | |
3558 expectedReplicaScreenSpaceTransform.setM22(-1); | |
3559 expectedReplicaScreenSpaceTransform.setM41(6); | |
3560 expectedReplicaScreenSpaceTransform.setM42(6); | |
3561 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedReplicaScreenSpaceTransform, child->
renderSurface()->replicaScreenSpaceTransform()); | |
3562 } | |
3563 | |
3564 TEST(CCLayerTreeHostCommonTest, verifySubtreeSearch) | |
3565 { | |
3566 scoped_refptr<LayerChromium> root = LayerChromium::create(); | |
3567 scoped_refptr<LayerChromium> child = LayerChromium::create(); | |
3568 scoped_refptr<LayerChromium> grandChild = LayerChromium::create(); | |
3569 scoped_refptr<LayerChromium> maskLayer = LayerChromium::create(); | |
3570 scoped_refptr<LayerChromium> replicaLayer = LayerChromium::create(); | |
3571 | |
3572 grandChild->setReplicaLayer(replicaLayer.get()); | |
3573 child->addChild(grandChild.get()); | |
3574 child->setMaskLayer(maskLayer.get()); | |
3575 root->addChild(child.get()); | |
3576 | |
3577 int nonexistentId = -1; | |
3578 EXPECT_EQ(root, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), root->
id())); | |
3579 EXPECT_EQ(child, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), child
->id())); | |
3580 EXPECT_EQ(grandChild, CCLayerTreeHostCommon::findLayerInSubtree(root.get(),
grandChild->id())); | |
3581 EXPECT_EQ(maskLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), m
askLayer->id())); | |
3582 EXPECT_EQ(replicaLayer, CCLayerTreeHostCommon::findLayerInSubtree(root.get()
, replicaLayer->id())); | |
3583 EXPECT_EQ(0, CCLayerTreeHostCommon::findLayerInSubtree(root.get(), nonexiste
ntId)); | |
3584 } | |
3585 | |
3586 } // namespace | |
OLD | NEW |