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.
7 #include "CCLayerTreeHostCommon.h"
9 #include "CCLayerAnimationController.h"
10 #include "CCLayerImpl.h"
11 #include "CCLayerSorter.h"
12 #include "CCMathUtil.h"
14 #include "CCSingleThreadProxy.h"
16 #include "ContentLayerChromium.h"
17 #include "ContentLayerChromiumClient.h"
18 #include "LayerChromium.h"
19 #include "cc/test/animation_test_common.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include <public/WebTransformationMatrix.h>
26 using namespace WebKitTests
;
27 using WebKit::WebTransformationMatrix
;
31 template<typename LayerType
>
32 void setLayerPropertiesForTesting(LayerType
* layer
, const WebTransformationMatrix
& transform
, const WebTransformationMatrix
& sublayerTransform
, const FloatPoint
& anchor
, const FloatPoint
& position
, const IntSize
& bounds
, bool preserves3D
)
34 layer
->setTransform(transform
);
35 layer
->setSublayerTransform(sublayerTransform
);
36 layer
->setAnchorPoint(anchor
);
37 layer
->setPosition(position
);
38 layer
->setBounds(bounds
);
39 layer
->setPreserves3D(preserves3D
);
42 void setLayerPropertiesForTesting(LayerChromium
* layer
, const WebTransformationMatrix
& transform
, const WebTransformationMatrix
& sublayerTransform
, const FloatPoint
& anchor
, const FloatPoint
& position
, const IntSize
& bounds
, bool preserves3D
)
44 setLayerPropertiesForTesting
<LayerChromium
>(layer
, transform
, sublayerTransform
, anchor
, position
, bounds
, preserves3D
);
47 void setLayerPropertiesForTesting(CCLayerImpl
* layer
, const WebTransformationMatrix
& transform
, const WebTransformationMatrix
& sublayerTransform
, const FloatPoint
& anchor
, const FloatPoint
& position
, const IntSize
& bounds
, bool preserves3D
)
49 setLayerPropertiesForTesting
<CCLayerImpl
>(layer
, transform
, sublayerTransform
, anchor
, position
, bounds
, preserves3D
);
50 layer
->setContentBounds(bounds
);
53 void executeCalculateDrawTransformsAndVisibility(LayerChromium
* rootLayer
, float deviceScaleFactor
= 1)
55 WebTransformationMatrix identityMatrix
;
56 std::vector
<scoped_refptr
<LayerChromium
> > dummyRenderSurfaceLayerList
;
57 int dummyMaxTextureSize
= 512;
58 IntSize deviceViewportSize
= IntSize(rootLayer
->bounds().width() * deviceScaleFactor
, rootLayer
->bounds().height() * deviceScaleFactor
);
60 // We are probably not testing what is intended if the rootLayer bounds are empty.
61 ASSERT(!rootLayer
->bounds().isEmpty());
62 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer
, deviceViewportSize
, deviceScaleFactor
, dummyMaxTextureSize
, dummyRenderSurfaceLayerList
);
65 void executeCalculateDrawTransformsAndVisibility(CCLayerImpl
* rootLayer
, float deviceScaleFactor
= 1)
67 // Note: this version skips layer sorting.
69 WebTransformationMatrix identityMatrix
;
70 std::vector
<CCLayerImpl
*> dummyRenderSurfaceLayerList
;
71 int dummyMaxTextureSize
= 512;
72 IntSize deviceViewportSize
= IntSize(rootLayer
->bounds().width() * deviceScaleFactor
, rootLayer
->bounds().height() * deviceScaleFactor
);
74 // We are probably not testing what is intended if the rootLayer bounds are empty.
75 ASSERT(!rootLayer
->bounds().isEmpty());
76 CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer
, deviceViewportSize
, deviceScaleFactor
, 0, dummyMaxTextureSize
, dummyRenderSurfaceLayerList
);
79 WebTransformationMatrix
remove3DComponentOfMatrix(const WebTransformationMatrix
& mat
)
81 WebTransformationMatrix ret
= mat
;
92 scoped_ptr
<CCLayerImpl
> createTreeForFixedPositionTests()
94 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
95 scoped_ptr
<CCLayerImpl
> child
= CCLayerImpl::create(2);
96 scoped_ptr
<CCLayerImpl
> grandChild
= CCLayerImpl::create(3);
97 scoped_ptr
<CCLayerImpl
> greatGrandChild
= CCLayerImpl::create(4);
99 WebTransformationMatrix IdentityMatrix
;
100 FloatPoint
anchor(0, 0);
101 FloatPoint
position(0, 0);
102 IntSize
bounds(100, 100);
103 setLayerPropertiesForTesting(root
.get(), IdentityMatrix
, IdentityMatrix
, anchor
, position
, bounds
, false);
104 setLayerPropertiesForTesting(child
.get(), IdentityMatrix
, IdentityMatrix
, anchor
, position
, bounds
, false);
105 setLayerPropertiesForTesting(grandChild
.get(), IdentityMatrix
, IdentityMatrix
, anchor
, position
, bounds
, false);
106 setLayerPropertiesForTesting(greatGrandChild
.get(), IdentityMatrix
, IdentityMatrix
, anchor
, position
, bounds
, false);
108 grandChild
->addChild(greatGrandChild
.Pass());
109 child
->addChild(grandChild
.Pass());
110 root
->addChild(child
.Pass());
115 class LayerChromiumWithForcedDrawsContent
: public LayerChromium
{
117 LayerChromiumWithForcedDrawsContent()
122 virtual bool drawsContent() const OVERRIDE
{ return true; }
125 virtual ~LayerChromiumWithForcedDrawsContent()
130 class MockContentLayerChromiumClient
: public ContentLayerChromiumClient
{
132 MockContentLayerChromiumClient() { }
133 virtual ~MockContentLayerChromiumClient() { }
134 virtual void paintContents(SkCanvas
*, const IntRect
& clip
, FloatRect
& opaque
) OVERRIDE
{ }
137 scoped_refptr
<ContentLayerChromium
> createDrawableContentLayerChromium(ContentLayerChromiumClient
* delegate
)
139 scoped_refptr
<ContentLayerChromium
> toReturn
= ContentLayerChromium::create(delegate
);
140 toReturn
->setIsDrawable(true);
144 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForNoOpLayer
)
146 // Sanity check: For layers positioned at zero, with zero size,
147 // and with identity transforms, then the drawTransform,
148 // screenSpaceTransform, and the hierarchy passed on to children
149 // layers should also be identity transforms.
151 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
152 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
153 scoped_refptr
<LayerChromium
> grandChild
= LayerChromium::create();
154 parent
->addChild(child
);
155 child
->addChild(grandChild
);
157 WebTransformationMatrix identityMatrix
;
158 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
159 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false);
160 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false);
162 executeCalculateDrawTransformsAndVisibility(parent
.get());
164 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->drawTransform());
165 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->screenSpaceTransform());
166 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, grandChild
->drawTransform());
167 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, grandChild
->screenSpaceTransform());
170 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForSingleLayer
)
172 WebTransformationMatrix identityMatrix
;
173 scoped_refptr
<LayerChromium
> layer
= LayerChromium::create();
175 // Case 1: setting the sublayer transform should not affect this layer's draw transform or screen-space transform.
176 WebTransformationMatrix arbitraryTranslation
;
177 arbitraryTranslation
.translate(10, 20);
178 setLayerPropertiesForTesting(layer
.get(), identityMatrix
, arbitraryTranslation
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
179 executeCalculateDrawTransformsAndVisibility(layer
.get());
180 WebTransformationMatrix expectedDrawTransform
= identityMatrix
;
181 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedDrawTransform
, layer
->drawTransform());
182 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, layer
->screenSpaceTransform());
184 // Case 2: Setting the bounds of the layer should not affect either the draw transform or the screenspace transform.
185 WebTransformationMatrix translationToCenter
;
186 translationToCenter
.translate(5, 6);
187 setLayerPropertiesForTesting(layer
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false);
188 executeCalculateDrawTransformsAndVisibility(layer
.get());
189 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, layer
->drawTransform());
190 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, layer
->screenSpaceTransform());
192 // Case 3: The anchor point by itself (without a layer transform) should have no effect on the transforms.
193 setLayerPropertiesForTesting(layer
.get(), identityMatrix
, identityMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
194 executeCalculateDrawTransformsAndVisibility(layer
.get());
195 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, layer
->drawTransform());
196 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, layer
->screenSpaceTransform());
198 // Case 4: A change in actual position affects both the draw transform and screen space transform.
199 WebTransformationMatrix positionTransform
;
200 positionTransform
.translate(0, 1.2);
201 setLayerPropertiesForTesting(layer
.get(), identityMatrix
, identityMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 1.2f
), IntSize(10, 12), false);
202 executeCalculateDrawTransformsAndVisibility(layer
.get());
203 EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform
, layer
->drawTransform());
204 EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform
, layer
->screenSpaceTransform());
206 // Case 5: In the correct sequence of transforms, the layer transform should pre-multiply the translationToCenter. This is easily tested by
207 // using a scale transform, because scale and translation are not commutative.
208 WebTransformationMatrix layerTransform
;
209 layerTransform
.scale3d(2, 2, 1);
210 setLayerPropertiesForTesting(layer
.get(), layerTransform
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false);
211 executeCalculateDrawTransformsAndVisibility(layer
.get());
212 EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform
, layer
->drawTransform());
213 EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform
, layer
->screenSpaceTransform());
215 // Case 6: The layer transform should occur with respect to the anchor point.
216 WebTransformationMatrix translationToAnchor
;
217 translationToAnchor
.translate(5, 0);
218 WebTransformationMatrix expectedResult
= translationToAnchor
* layerTransform
* translationToAnchor
.inverse();
219 setLayerPropertiesForTesting(layer
.get(), layerTransform
, identityMatrix
, FloatPoint(0.5, 0), FloatPoint(0, 0), IntSize(10, 12), false);
220 executeCalculateDrawTransformsAndVisibility(layer
.get());
221 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult
, layer
->drawTransform());
222 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult
, layer
->screenSpaceTransform());
224 // Case 7: Verify that position pre-multiplies the layer transform.
225 // The current implementation of calculateDrawTransforms does this implicitly, but it is
226 // still worth testing to detect accidental regressions.
227 expectedResult
= positionTransform
* translationToAnchor
* layerTransform
* translationToAnchor
.inverse();
228 setLayerPropertiesForTesting(layer
.get(), layerTransform
, identityMatrix
, FloatPoint(0.5, 0), FloatPoint(0, 1.2f
), IntSize(10, 12), false);
229 executeCalculateDrawTransformsAndVisibility(layer
.get());
230 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult
, layer
->drawTransform());
231 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult
, layer
->screenSpaceTransform());
234 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForSimpleHierarchy
)
236 WebTransformationMatrix identityMatrix
;
237 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
238 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
239 scoped_refptr
<LayerChromium
> grandChild
= LayerChromium::create();
240 parent
->addChild(child
);
241 child
->addChild(grandChild
);
243 // Case 1: parent's anchorPoint should not affect child or grandChild.
244 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
245 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
246 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
247 executeCalculateDrawTransformsAndVisibility(parent
.get());
248 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->drawTransform());
249 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->screenSpaceTransform());
250 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, grandChild
->drawTransform());
251 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, grandChild
->screenSpaceTransform());
253 // Case 2: parent's position affects child and grandChild.
254 WebTransformationMatrix parentPositionTransform
;
255 parentPositionTransform
.translate(0, 1.2);
256 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 1.2f
), IntSize(10, 12), false);
257 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
258 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
259 executeCalculateDrawTransformsAndVisibility(parent
.get());
260 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform
, child
->drawTransform());
261 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform
, child
->screenSpaceTransform());
262 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform
, grandChild
->drawTransform());
263 EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform
, grandChild
->screenSpaceTransform());
265 // Case 3: parent's local transform affects child and grandchild
266 WebTransformationMatrix parentLayerTransform
;
267 parentLayerTransform
.scale3d(2, 2, 1);
268 WebTransformationMatrix parentTranslationToAnchor
;
269 parentTranslationToAnchor
.translate(2.5, 3);
270 WebTransformationMatrix parentCompositeTransform
= parentTranslationToAnchor
* parentLayerTransform
* parentTranslationToAnchor
.inverse();
271 setLayerPropertiesForTesting(parent
.get(), parentLayerTransform
, identityMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
272 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
273 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
274 executeCalculateDrawTransformsAndVisibility(parent
.get());
275 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->drawTransform());
276 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->screenSpaceTransform());
277 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, grandChild
->drawTransform());
278 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, grandChild
->screenSpaceTransform());
280 // Case 4: parent's sublayerMatrix affects child and grandchild
281 // scaling is used here again so that the correct sequence of transforms is properly tested.
282 // Note that preserves3D is false, but the sublayer matrix should retain its 3D properties when given to child.
283 // But then, the child also does not preserve3D. When it gives its hierarchy to the grandChild, it should be flattened to 2D.
284 WebTransformationMatrix parentSublayerMatrix
;
285 parentSublayerMatrix
.scale3d(10, 10, 3.3);
286 WebTransformationMatrix parentTranslationToCenter
;
287 parentTranslationToCenter
.translate(5, 6);
288 // Sublayer matrix is applied to the center of the parent layer.
289 parentCompositeTransform
= parentTranslationToAnchor
* parentLayerTransform
* parentTranslationToAnchor
.inverse()
290 * parentTranslationToCenter
* parentSublayerMatrix
* parentTranslationToCenter
.inverse();
291 WebTransformationMatrix flattenedCompositeTransform
= remove3DComponentOfMatrix(parentCompositeTransform
);
292 setLayerPropertiesForTesting(parent
.get(), parentLayerTransform
, parentSublayerMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
293 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
294 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
295 executeCalculateDrawTransformsAndVisibility(parent
.get());
296 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->drawTransform());
297 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->screenSpaceTransform());
298 EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform
, grandChild
->drawTransform());
299 EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform
, grandChild
->screenSpaceTransform());
301 // Case 5: same as Case 4, except that child does preserve 3D, so the grandChild should receive the non-flattened composite transform.
303 setLayerPropertiesForTesting(parent
.get(), parentLayerTransform
, parentSublayerMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
304 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), true);
305 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
306 executeCalculateDrawTransformsAndVisibility(parent
.get());
307 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->drawTransform());
308 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->screenSpaceTransform());
309 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, grandChild
->drawTransform());
310 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, grandChild
->screenSpaceTransform());
313 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForSingleRenderSurface
)
315 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
316 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
317 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
318 parent
->addChild(child
);
319 child
->addChild(grandChild
);
321 // Child is set up so that a new render surface should be created.
322 child
->setOpacity(0.5);
324 WebTransformationMatrix identityMatrix
;
325 WebTransformationMatrix parentLayerTransform
;
326 parentLayerTransform
.scale3d(1, 0.9, 1);
327 WebTransformationMatrix parentTranslationToAnchor
;
328 parentTranslationToAnchor
.translate(25, 30);
329 WebTransformationMatrix parentSublayerMatrix
;
330 parentSublayerMatrix
.scale3d(0.9, 1, 3.3);
331 WebTransformationMatrix parentTranslationToCenter
;
332 parentTranslationToCenter
.translate(50, 60);
333 WebTransformationMatrix parentCompositeTransform
= parentTranslationToAnchor
* parentLayerTransform
* parentTranslationToAnchor
.inverse()
334 * parentTranslationToCenter
* parentSublayerMatrix
* parentTranslationToCenter
.inverse();
336 // Child's render surface should not exist yet.
337 ASSERT_FALSE(child
->renderSurface());
339 setLayerPropertiesForTesting(parent
.get(), parentLayerTransform
, parentSublayerMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(100, 120), false);
340 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
341 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(8, 10), false);
342 executeCalculateDrawTransformsAndVisibility(parent
.get());
344 // Render surface should have been created now.
345 ASSERT_TRUE(child
->renderSurface());
346 ASSERT_EQ(child
, child
->renderTarget());
348 // The child layer's draw transform should refer to its new render surface.
349 // The screen-space transform, however, should still refer to the root.
350 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->drawTransform());
351 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->screenSpaceTransform());
353 // Because the grandChild is the only drawable content, the child's renderSurface will tighten its bounds to the grandChild.
354 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->renderTarget()->renderSurface()->drawTransform());
356 // The screen space is the same as the target since the child surface draws into the root.
357 EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform
, child
->renderTarget()->renderSurface()->screenSpaceTransform());
360 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForReplica
)
362 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
363 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
364 scoped_refptr
<LayerChromium
> childReplica
= LayerChromium::create();
365 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
366 parent
->addChild(child
);
367 child
->addChild(grandChild
);
368 child
->setReplicaLayer(childReplica
.get());
370 // Child is set up so that a new render surface should be created.
371 child
->setOpacity(0.5);
373 WebTransformationMatrix identityMatrix
;
374 WebTransformationMatrix parentLayerTransform
;
375 parentLayerTransform
.scale3d(2, 2, 1);
376 WebTransformationMatrix parentTranslationToAnchor
;
377 parentTranslationToAnchor
.translate(2.5, 3);
378 WebTransformationMatrix parentSublayerMatrix
;
379 parentSublayerMatrix
.scale3d(10, 10, 3.3);
380 WebTransformationMatrix parentTranslationToCenter
;
381 parentTranslationToCenter
.translate(5, 6);
382 WebTransformationMatrix parentCompositeTransform
= parentTranslationToAnchor
* parentLayerTransform
* parentTranslationToAnchor
.inverse()
383 * parentTranslationToCenter
* parentSublayerMatrix
* parentTranslationToCenter
.inverse();
384 WebTransformationMatrix childTranslationToCenter
;
385 childTranslationToCenter
.translate(8, 9);
386 WebTransformationMatrix replicaLayerTransform
;
387 replicaLayerTransform
.scale3d(3, 3, 1);
388 WebTransformationMatrix replicaCompositeTransform
= parentCompositeTransform
* replicaLayerTransform
;
390 // Child's render surface should not exist yet.
391 ASSERT_FALSE(child
->renderSurface());
393 setLayerPropertiesForTesting(parent
.get(), parentLayerTransform
, parentSublayerMatrix
, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
394 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
395 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(-0.5, -0.5), IntSize(1, 1), false);
396 setLayerPropertiesForTesting(childReplica
.get(), replicaLayerTransform
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false);
397 executeCalculateDrawTransformsAndVisibility(parent
.get());
399 // Render surface should have been created now.
400 ASSERT_TRUE(child
->renderSurface());
401 ASSERT_EQ(child
, child
->renderTarget());
403 EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform
, child
->renderTarget()->renderSurface()->replicaDrawTransform());
404 EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform
, child
->renderTarget()->renderSurface()->replicaScreenSpaceTransform());
407 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForRenderSurfaceHierarchy
)
409 // This test creates a more complex tree and verifies it all at once. This covers the following cases:
410 // - layers that are described w.r.t. a render surface: should have draw transforms described w.r.t. that surface
411 // - A render surface described w.r.t. an ancestor render surface: should have a draw transform described w.r.t. that ancestor surface
412 // - Replicas of a render surface are described w.r.t. the replica's transform around its anchor, along with the surface itself.
413 // - 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.
414 // - verifying that each layer has a reference to the correct renderSurface and renderTarget values.
416 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
417 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
418 scoped_refptr
<LayerChromium
> renderSurface2
= LayerChromium::create();
419 scoped_refptr
<LayerChromium
> childOfRoot
= LayerChromium::create();
420 scoped_refptr
<LayerChromium
> childOfRS1
= LayerChromium::create();
421 scoped_refptr
<LayerChromium
> childOfRS2
= LayerChromium::create();
422 scoped_refptr
<LayerChromium
> replicaOfRS1
= LayerChromium::create();
423 scoped_refptr
<LayerChromium
> replicaOfRS2
= LayerChromium::create();
424 scoped_refptr
<LayerChromium
> grandChildOfRoot
= LayerChromium::create();
425 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChildOfRS1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
426 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChildOfRS2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
427 parent
->addChild(renderSurface1
);
428 parent
->addChild(childOfRoot
);
429 renderSurface1
->addChild(childOfRS1
);
430 renderSurface1
->addChild(renderSurface2
);
431 renderSurface2
->addChild(childOfRS2
);
432 childOfRoot
->addChild(grandChildOfRoot
);
433 childOfRS1
->addChild(grandChildOfRS1
);
434 childOfRS2
->addChild(grandChildOfRS2
);
435 renderSurface1
->setReplicaLayer(replicaOfRS1
.get());
436 renderSurface2
->setReplicaLayer(replicaOfRS2
.get());
438 // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
439 renderSurface1
->setOpacity(0.5);
440 renderSurface2
->setOpacity(0.33f
);
442 // All layers in the tree are initialized with an anchor at .25 and a size of (10,10).
443 // matrix "A" is the composite layer transform used in all layers, centered about the anchor point
444 // matrix "B" is the sublayer transform used in all layers, centered about the center position of the layer.
445 // matrix "R" is the composite replica transform used in all replica layers.
447 // x component tests that layerTransform and sublayerTransform are done in the right order (translation and scale are noncommutative).
448 // y component has a translation by 1 for every ancestor, which indicates the "depth" of the layer in the hierarchy.
449 WebTransformationMatrix translationToAnchor
;
450 translationToAnchor
.translate(2.5, 0);
451 WebTransformationMatrix translationToCenter
;
452 translationToCenter
.translate(5, 5);
453 WebTransformationMatrix layerTransform
;
454 layerTransform
.translate(1, 1);
455 WebTransformationMatrix sublayerTransform
;
456 sublayerTransform
.scale3d(10, 1, 1);
457 WebTransformationMatrix replicaLayerTransform
;
458 replicaLayerTransform
.scale3d(-2, 5, 1);
460 WebTransformationMatrix A
= translationToAnchor
* layerTransform
* translationToAnchor
.inverse();
461 WebTransformationMatrix B
= translationToCenter
* sublayerTransform
* translationToCenter
.inverse();
462 WebTransformationMatrix R
= A
* translationToAnchor
* replicaLayerTransform
* translationToAnchor
.inverse();
463 WebTransformationMatrix identityMatrix
;
465 setLayerPropertiesForTesting(parent
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
466 setLayerPropertiesForTesting(renderSurface1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
467 setLayerPropertiesForTesting(renderSurface2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
468 setLayerPropertiesForTesting(childOfRoot
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
469 setLayerPropertiesForTesting(childOfRS1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
470 setLayerPropertiesForTesting(childOfRS2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
471 setLayerPropertiesForTesting(grandChildOfRoot
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
472 setLayerPropertiesForTesting(grandChildOfRS1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
473 setLayerPropertiesForTesting(grandChildOfRS2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
474 setLayerPropertiesForTesting(replicaOfRS1
.get(), replicaLayerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false);
475 setLayerPropertiesForTesting(replicaOfRS2
.get(), replicaLayerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false);
477 executeCalculateDrawTransformsAndVisibility(parent
.get());
479 // Only layers that are associated with render surfaces should have an actual renderSurface() value.
481 ASSERT_TRUE(parent
->renderSurface());
482 ASSERT_FALSE(childOfRoot
->renderSurface());
483 ASSERT_FALSE(grandChildOfRoot
->renderSurface());
485 ASSERT_TRUE(renderSurface1
->renderSurface());
486 ASSERT_FALSE(childOfRS1
->renderSurface());
487 ASSERT_FALSE(grandChildOfRS1
->renderSurface());
489 ASSERT_TRUE(renderSurface2
->renderSurface());
490 ASSERT_FALSE(childOfRS2
->renderSurface());
491 ASSERT_FALSE(grandChildOfRS2
->renderSurface());
493 // Verify all renderTarget accessors
495 EXPECT_EQ(parent
, parent
->renderTarget());
496 EXPECT_EQ(parent
, childOfRoot
->renderTarget());
497 EXPECT_EQ(parent
, grandChildOfRoot
->renderTarget());
499 EXPECT_EQ(renderSurface1
, renderSurface1
->renderTarget());
500 EXPECT_EQ(renderSurface1
, childOfRS1
->renderTarget());
501 EXPECT_EQ(renderSurface1
, grandChildOfRS1
->renderTarget());
503 EXPECT_EQ(renderSurface2
, renderSurface2
->renderTarget());
504 EXPECT_EQ(renderSurface2
, childOfRS2
->renderTarget());
505 EXPECT_EQ(renderSurface2
, grandChildOfRS2
->renderTarget());
507 // Verify layer draw transforms
508 // note that draw transforms are described with respect to the nearest ancestor render surface
509 // but screen space transforms are described with respect to the root.
511 EXPECT_TRANSFORMATION_MATRIX_EQ(A
, parent
->drawTransform());
512 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
, childOfRoot
->drawTransform());
513 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
, grandChildOfRoot
->drawTransform());
515 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, renderSurface1
->drawTransform());
516 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* A
, childOfRS1
->drawTransform());
517 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* A
* B
* A
, grandChildOfRS1
->drawTransform());
519 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, renderSurface2
->drawTransform());
520 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* A
, childOfRS2
->drawTransform());
521 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* A
* B
* A
, grandChildOfRS2
->drawTransform());
523 // Verify layer screen-space transforms
525 EXPECT_TRANSFORMATION_MATRIX_EQ(A
, parent
->screenSpaceTransform());
526 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
, childOfRoot
->screenSpaceTransform());
527 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
, grandChildOfRoot
->screenSpaceTransform());
529 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
, renderSurface1
->screenSpaceTransform());
530 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
, childOfRS1
->screenSpaceTransform());
531 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
* B
* A
, grandChildOfRS1
->screenSpaceTransform());
533 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
, renderSurface2
->screenSpaceTransform());
534 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
* B
* A
, childOfRS2
->screenSpaceTransform());
535 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
* B
* A
* B
* A
, grandChildOfRS2
->screenSpaceTransform());
537 // Verify render surface transforms.
539 // Draw transform of render surface 1 is described with respect to root.
540 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
, renderSurface1
->renderSurface()->drawTransform());
541 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* R
, renderSurface1
->renderSurface()->replicaDrawTransform());
542 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
, renderSurface1
->renderSurface()->screenSpaceTransform());
543 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* R
, renderSurface1
->renderSurface()->replicaScreenSpaceTransform());
544 // Draw transform of render surface 2 is described with respect to render surface 2.
545 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* A
, renderSurface2
->renderSurface()->drawTransform());
546 EXPECT_TRANSFORMATION_MATRIX_EQ(B
* R
, renderSurface2
->renderSurface()->replicaDrawTransform());
547 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* A
, renderSurface2
->renderSurface()->screenSpaceTransform());
548 EXPECT_TRANSFORMATION_MATRIX_EQ(A
* B
* A
* B
* R
, renderSurface2
->renderSurface()->replicaScreenSpaceTransform());
550 // Sanity check. If these fail there is probably a bug in the test itself.
551 // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
552 // encodes the "depth" of the layer in the tree.
553 EXPECT_FLOAT_EQ(1, parent
->screenSpaceTransform().m42());
554 EXPECT_FLOAT_EQ(2, childOfRoot
->screenSpaceTransform().m42());
555 EXPECT_FLOAT_EQ(3, grandChildOfRoot
->screenSpaceTransform().m42());
557 EXPECT_FLOAT_EQ(2, renderSurface1
->screenSpaceTransform().m42());
558 EXPECT_FLOAT_EQ(3, childOfRS1
->screenSpaceTransform().m42());
559 EXPECT_FLOAT_EQ(4, grandChildOfRS1
->screenSpaceTransform().m42());
561 EXPECT_FLOAT_EQ(3, renderSurface2
->screenSpaceTransform().m42());
562 EXPECT_FLOAT_EQ(4, childOfRS2
->screenSpaceTransform().m42());
563 EXPECT_FLOAT_EQ(5, grandChildOfRS2
->screenSpaceTransform().m42());
566 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForFlatteningLayer
)
568 // For layers that flatten their subtree, there should be an orthographic projection
569 // (for x and y values) in the middle of the transform sequence. Note that the way the
570 // code is currently implemented, it is not expected to use a canonical orthographic
573 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
574 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
575 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
577 WebTransformationMatrix rotationAboutYAxis
;
578 rotationAboutYAxis
.rotate3d(0, 30, 0);
580 const WebTransformationMatrix identityMatrix
;
581 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(100, 100), false);
582 setLayerPropertiesForTesting(child
.get(), rotationAboutYAxis
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
583 setLayerPropertiesForTesting(grandChild
.get(), rotationAboutYAxis
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
585 root
->addChild(child
);
586 child
->addChild(grandChild
);
587 child
->setForceRenderSurface(true);
589 // No layers in this test should preserve 3d.
590 ASSERT_FALSE(root
->preserves3D());
591 ASSERT_FALSE(child
->preserves3D());
592 ASSERT_FALSE(grandChild
->preserves3D());
594 WebTransformationMatrix expectedChildDrawTransform
= rotationAboutYAxis
;
595 WebTransformationMatrix expectedChildScreenSpaceTransform
= rotationAboutYAxis
;
596 WebTransformationMatrix expectedGrandChildDrawTransform
= rotationAboutYAxis
; // draws onto child's renderSurface
597 WebTransformationMatrix expectedGrandChildScreenSpaceTransform
= rotationAboutYAxis
.to2dTransform() * rotationAboutYAxis
;
599 executeCalculateDrawTransformsAndVisibility(root
.get());
601 // The child's drawTransform should have been taken by its surface.
602 ASSERT_TRUE(child
->renderSurface());
603 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildDrawTransform
, child
->renderSurface()->drawTransform());
604 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform
, child
->renderSurface()->screenSpaceTransform());
605 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->drawTransform());
606 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform
, child
->screenSpaceTransform());
607 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildDrawTransform
, grandChild
->drawTransform());
608 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildScreenSpaceTransform
, grandChild
->screenSpaceTransform());
611 TEST(CCLayerTreeHostCommonTest
, verifyTransformsForDegenerateIntermediateLayer
)
613 // A layer that is empty in one axis, but not the other, was accidentally skipping a necessary translation.
614 // Without that translation, the coordinate space of the layer's drawTransform is incorrect.
616 // Normally this isn't a problem, because the layer wouldn't be drawn anyway, but if that layer becomes a renderSurface, then
617 // its drawTransform is implicitly inherited by the rest of the subtree, which then is positioned incorrectly as a result.
619 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
620 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
621 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
623 // The child height is zero, but has non-zero width that should be accounted for while computing drawTransforms.
624 const WebTransformationMatrix identityMatrix
;
625 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(100, 100), false);
626 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 0), false);
627 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
629 root
->addChild(child
);
630 child
->addChild(grandChild
);
631 child
->setForceRenderSurface(true);
633 executeCalculateDrawTransformsAndVisibility(root
.get());
635 ASSERT_TRUE(child
->renderSurface());
636 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->renderSurface()->drawTransform()); // This is the real test, the rest are sanity checks.
637 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, child
->drawTransform());
638 EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix
, grandChild
->drawTransform());
641 TEST(CCLayerTreeHostCommonTest
, verifyRenderSurfaceListForRenderSurfaceWithClippedLayer
)
643 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
644 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
645 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
647 const WebTransformationMatrix identityMatrix
;
648 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
649 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
650 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false);
652 parent
->addChild(renderSurface1
);
653 parent
->setMasksToBounds(true);
654 renderSurface1
->addChild(child
);
655 renderSurface1
->setForceRenderSurface(true);
657 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
658 int dummyMaxTextureSize
= 512;
659 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
661 // The child layer's content is entirely outside the parent's clip rect, so the intermediate
662 // render surface should not be listed here, even if it was forced to be created. Render surfaces without children or visible
663 // content are unexpected at draw time (e.g. we might try to create a content texture of size 0).
664 ASSERT_TRUE(parent
->renderSurface());
665 ASSERT_FALSE(renderSurface1
->renderSurface());
666 EXPECT_EQ(1U, renderSurfaceLayerList
.size());
669 TEST(CCLayerTreeHostCommonTest
, verifyRenderSurfaceListForTransparentChild
)
671 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
672 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
673 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
675 const WebTransformationMatrix identityMatrix
;
676 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
677 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
679 parent
->addChild(renderSurface1
);
680 renderSurface1
->addChild(child
);
681 renderSurface1
->setForceRenderSurface(true);
682 renderSurface1
->setOpacity(0);
684 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
685 int dummyMaxTextureSize
= 512;
686 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
688 // Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
689 // Also, the drawable content rect should not have been extended by the children.
690 ASSERT_TRUE(parent
->renderSurface());
691 EXPECT_EQ(0U, parent
->renderSurface()->layerList().size());
692 EXPECT_EQ(1U, renderSurfaceLayerList
.size());
693 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
694 EXPECT_EQ(IntRect(), parent
->drawableContentRect());
697 TEST(CCLayerTreeHostCommonTest
, verifyForceRenderSurface
)
699 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
700 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
701 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
702 renderSurface1
->setForceRenderSurface(true);
704 const WebTransformationMatrix identityMatrix
;
705 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
706 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
707 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
709 parent
->addChild(renderSurface1
);
710 renderSurface1
->addChild(child
);
712 // Sanity check before the actual test
713 EXPECT_FALSE(parent
->renderSurface());
714 EXPECT_FALSE(renderSurface1
->renderSurface());
716 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
717 int dummyMaxTextureSize
= 512;
718 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
720 // The root layer always creates a renderSurface
721 EXPECT_TRUE(parent
->renderSurface());
722 EXPECT_TRUE(renderSurface1
->renderSurface());
723 EXPECT_EQ(2U, renderSurfaceLayerList
.size());
725 renderSurfaceLayerList
.clear();
726 renderSurface1
->setForceRenderSurface(false);
727 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
728 EXPECT_TRUE(parent
->renderSurface());
729 EXPECT_FALSE(renderSurface1
->renderSurface());
730 EXPECT_EQ(1U, renderSurfaceLayerList
.size());
733 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithDirectContainer
)
735 // This test checks for correct scroll compensation when the fixed-position container
736 // is the direct parent of the fixed-position layer.
738 DebugScopedSetImplThread scopedImplThread
;
739 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
740 CCLayerImpl
* child
= root
->children()[0];
741 CCLayerImpl
* grandChild
= child
->children()[0];
743 child
->setIsContainerForFixedPositionLayers(true);
744 grandChild
->setFixedToContainerLayer(true);
746 // Case 1: scrollDelta of 0, 0
747 child
->setScrollDelta(IntSize(0, 0));
748 executeCalculateDrawTransformsAndVisibility(root
.get());
750 WebTransformationMatrix expectedChildTransform
;
751 WebTransformationMatrix expectedGrandChildTransform
= expectedChildTransform
;
753 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
754 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
756 // Case 2: scrollDelta of 10, 10
757 child
->setScrollDelta(IntSize(10, 10));
758 executeCalculateDrawTransformsAndVisibility(root
.get());
760 // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
761 expectedChildTransform
.makeIdentity();
762 expectedChildTransform
.translate(-10, -10);
764 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
765 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
768 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithTransformedDirectContainer
)
770 // This test checks for correct scroll compensation when the fixed-position container
771 // is the direct parent of the fixed-position layer, but that container is transformed.
772 // In this case, the fixed position element inherits the container's transform,
773 // but the scrollDelta that has to be undone should not be affected by that transform.
775 // Transforms are in general non-commutative; using something like a non-uniform scale
776 // helps to verify that translations and non-uniform scales are applied in the correct
779 DebugScopedSetImplThread scopedImplThread
;
780 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
781 CCLayerImpl
* child
= root
->children()[0];
782 CCLayerImpl
* grandChild
= child
->children()[0];
784 // This scale will cause child and grandChild to be effectively 200 x 800 with respect to the renderTarget.
785 WebTransformationMatrix nonUniformScale
;
786 nonUniformScale
.scaleNonUniform(2, 8);
787 child
->setTransform(nonUniformScale
);
789 child
->setIsContainerForFixedPositionLayers(true);
790 grandChild
->setFixedToContainerLayer(true);
792 // Case 1: scrollDelta of 0, 0
793 child
->setScrollDelta(IntSize(0, 0));
794 executeCalculateDrawTransformsAndVisibility(root
.get());
796 WebTransformationMatrix expectedChildTransform
;
797 expectedChildTransform
.multiply(nonUniformScale
);
799 WebTransformationMatrix expectedGrandChildTransform
= expectedChildTransform
;
801 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
802 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
804 // Case 2: scrollDelta of 10, 20
805 child
->setScrollDelta(IntSize(10, 20));
806 executeCalculateDrawTransformsAndVisibility(root
.get());
808 // The child should be affected by scrollDelta, but the fixed position grandChild should not be affected.
809 expectedChildTransform
.makeIdentity();
810 expectedChildTransform
.translate(-10, -20); // scrollDelta
811 expectedChildTransform
.multiply(nonUniformScale
);
813 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
814 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
817 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithDistantContainer
)
819 // This test checks for correct scroll compensation when the fixed-position container
820 // is NOT the direct parent of the fixed-position layer.
821 DebugScopedSetImplThread scopedImplThread
;
823 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
824 CCLayerImpl
* child
= root
->children()[0];
825 CCLayerImpl
* grandChild
= child
->children()[0];
826 CCLayerImpl
* greatGrandChild
= grandChild
->children()[0];
828 child
->setIsContainerForFixedPositionLayers(true);
829 grandChild
->setPosition(FloatPoint(8, 6));
830 greatGrandChild
->setFixedToContainerLayer(true);
832 // Case 1: scrollDelta of 0, 0
833 child
->setScrollDelta(IntSize(0, 0));
834 executeCalculateDrawTransformsAndVisibility(root
.get());
836 WebTransformationMatrix expectedChildTransform
;
837 WebTransformationMatrix expectedGrandChildTransform
;
838 expectedGrandChildTransform
.translate(8, 6);
840 WebTransformationMatrix expectedGreatGrandChildTransform
= expectedGrandChildTransform
;
842 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
843 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
844 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
846 // Case 2: scrollDelta of 10, 10
847 child
->setScrollDelta(IntSize(10, 10));
848 executeCalculateDrawTransformsAndVisibility(root
.get());
850 // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
851 expectedChildTransform
.makeIdentity();
852 expectedChildTransform
.translate(-10, -10);
853 expectedGrandChildTransform
.makeIdentity();
854 expectedGrandChildTransform
.translate(-2, -4);
855 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
856 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
857 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
860 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms
)
862 // This test checks for correct scroll compensation when the fixed-position container
863 // is NOT the direct parent of the fixed-position layer, and the hierarchy has various
864 // transforms that have to be processed in the correct order.
865 DebugScopedSetImplThread scopedImplThread
;
867 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
868 CCLayerImpl
* child
= root
->children()[0];
869 CCLayerImpl
* grandChild
= child
->children()[0];
870 CCLayerImpl
* greatGrandChild
= grandChild
->children()[0];
872 WebTransformationMatrix rotationAboutZ
;
873 rotationAboutZ
.rotate3d(0, 0, 90);
875 child
->setIsContainerForFixedPositionLayers(true);
876 child
->setTransform(rotationAboutZ
);
877 grandChild
->setPosition(FloatPoint(8, 6));
878 grandChild
->setTransform(rotationAboutZ
);
879 greatGrandChild
->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget.
881 // Case 1: scrollDelta of 0, 0
882 child
->setScrollDelta(IntSize(0, 0));
883 executeCalculateDrawTransformsAndVisibility(root
.get());
885 WebTransformationMatrix expectedChildTransform
;
886 expectedChildTransform
.multiply(rotationAboutZ
);
888 WebTransformationMatrix expectedGrandChildTransform
;
889 expectedGrandChildTransform
.multiply(rotationAboutZ
); // child's local transform is inherited
890 expectedGrandChildTransform
.translate(8, 6); // translation because of position occurs before layer's local transform.
891 expectedGrandChildTransform
.multiply(rotationAboutZ
); // grandChild's local transform
893 WebTransformationMatrix expectedGreatGrandChildTransform
= expectedGrandChildTransform
;
895 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
896 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
897 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
899 // Case 2: scrollDelta of 10, 20
900 child
->setScrollDelta(IntSize(10, 20));
901 executeCalculateDrawTransformsAndVisibility(root
.get());
903 // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
904 expectedChildTransform
.makeIdentity();
905 expectedChildTransform
.translate(-10, -20); // scrollDelta
906 expectedChildTransform
.multiply(rotationAboutZ
);
908 expectedGrandChildTransform
.makeIdentity();
909 expectedGrandChildTransform
.translate(-10, -20); // child's scrollDelta is inherited
910 expectedGrandChildTransform
.multiply(rotationAboutZ
); // child's local transform is inherited
911 expectedGrandChildTransform
.translate(8, 6); // translation because of position occurs before layer's local transform.
912 expectedGrandChildTransform
.multiply(rotationAboutZ
); // grandChild's local transform
914 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
915 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
916 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
919 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
)
921 // This test checks for correct scroll compensation when the fixed-position container
922 // has multiple ancestors that have nonzero scrollDelta before reaching the space where the layer is fixed.
923 // In this test, each scrollDelta occurs in a different space because of each layer's local transform.
924 // This test checks for correct scroll compensation when the fixed-position container
925 // is NOT the direct parent of the fixed-position layer, and the hierarchy has various
926 // transforms that have to be processed in the correct order.
927 DebugScopedSetImplThread scopedImplThread
;
929 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
930 CCLayerImpl
* child
= root
->children()[0];
931 CCLayerImpl
* grandChild
= child
->children()[0];
932 CCLayerImpl
* greatGrandChild
= grandChild
->children()[0];
934 WebTransformationMatrix rotationAboutZ
;
935 rotationAboutZ
.rotate3d(0, 0, 90);
937 child
->setIsContainerForFixedPositionLayers(true);
938 child
->setTransform(rotationAboutZ
);
939 grandChild
->setPosition(FloatPoint(8, 6));
940 grandChild
->setTransform(rotationAboutZ
);
941 greatGrandChild
->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget.
943 // Case 1: scrollDelta of 0, 0
944 child
->setScrollDelta(IntSize(0, 0));
945 executeCalculateDrawTransformsAndVisibility(root
.get());
947 WebTransformationMatrix expectedChildTransform
;
948 expectedChildTransform
.multiply(rotationAboutZ
);
950 WebTransformationMatrix expectedGrandChildTransform
;
951 expectedGrandChildTransform
.multiply(rotationAboutZ
); // child's local transform is inherited
952 expectedGrandChildTransform
.translate(8, 6); // translation because of position occurs before layer's local transform.
953 expectedGrandChildTransform
.multiply(rotationAboutZ
); // grandChild's local transform
955 WebTransformationMatrix expectedGreatGrandChildTransform
= expectedGrandChildTransform
;
957 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
958 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
959 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
961 // Case 2: scrollDelta of 10, 20
962 child
->setScrollDelta(IntSize(10, 0));
963 grandChild
->setScrollDelta(IntSize(5, 0));
964 executeCalculateDrawTransformsAndVisibility(root
.get());
966 // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
967 expectedChildTransform
.makeIdentity();
968 expectedChildTransform
.translate(-10, 0); // scrollDelta
969 expectedChildTransform
.multiply(rotationAboutZ
);
971 expectedGrandChildTransform
.makeIdentity();
972 expectedGrandChildTransform
.translate(-10, 0); // child's scrollDelta is inherited
973 expectedGrandChildTransform
.multiply(rotationAboutZ
); // child's local transform is inherited
974 expectedGrandChildTransform
.translate(-5, 0); // grandChild's scrollDelta
975 expectedGrandChildTransform
.translate(8, 6); // translation because of position occurs before layer's local transform.
976 expectedGrandChildTransform
.multiply(rotationAboutZ
); // grandChild's local transform
978 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
979 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
980 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
983 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithIntermediateSurfaceAndTransforms
)
985 // This test checks for correct scroll compensation when the fixed-position container
986 // contributes to a different renderSurface than the fixed-position layer. In this
987 // case, the surface drawTransforms also have to be accounted for when checking the
989 DebugScopedSetImplThread scopedImplThread
;
991 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
992 CCLayerImpl
* child
= root
->children()[0];
993 CCLayerImpl
* grandChild
= child
->children()[0];
994 CCLayerImpl
* greatGrandChild
= grandChild
->children()[0];
996 child
->setIsContainerForFixedPositionLayers(true);
997 grandChild
->setPosition(FloatPoint(8, 6));
998 grandChild
->setForceRenderSurface(true);
999 greatGrandChild
->setFixedToContainerLayer(true);
1000 greatGrandChild
->setDrawsContent(true);
1002 WebTransformationMatrix rotationAboutZ
;
1003 rotationAboutZ
.rotate3d(0, 0, 90);
1004 grandChild
->setTransform(rotationAboutZ
);
1006 // Case 1: scrollDelta of 0, 0
1007 child
->setScrollDelta(IntSize(0, 0));
1008 executeCalculateDrawTransformsAndVisibility(root
.get());
1010 WebTransformationMatrix expectedChildTransform
;
1011 WebTransformationMatrix expectedSurfaceDrawTransform
;
1012 expectedSurfaceDrawTransform
.translate(8, 6);
1013 expectedSurfaceDrawTransform
.multiply(rotationAboutZ
);
1014 WebTransformationMatrix expectedGrandChildTransform
;
1015 WebTransformationMatrix expectedGreatGrandChildTransform
;
1016 ASSERT_TRUE(grandChild
->renderSurface());
1017 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1018 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform
, grandChild
->renderSurface()->drawTransform());
1019 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1020 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
1022 // Case 2: scrollDelta of 10, 30
1023 child
->setScrollDelta(IntSize(10, 30));
1024 executeCalculateDrawTransformsAndVisibility(root
.get());
1026 // Here the grandChild remains unchanged, because it scrolls along with the
1027 // renderSurface, and the translation is actually in the renderSurface. But, the fixed
1028 // position greatGrandChild is more awkward: its actually being drawn with respect to
1029 // the renderSurface, but it needs to remain fixed with resepct to a container beyond
1030 // that surface. So, the net result is that, unlike previous tests where the fixed
1031 // position layer's transform remains unchanged, here the fixed position layer's
1032 // transform explicitly contains the translation that cancels out the scroll.
1033 expectedChildTransform
.makeIdentity();
1034 expectedChildTransform
.translate(-10, -30); // scrollDelta
1036 expectedSurfaceDrawTransform
.makeIdentity();
1037 expectedSurfaceDrawTransform
.translate(-10, -30); // scrollDelta
1038 expectedSurfaceDrawTransform
.translate(8, 6);
1039 expectedSurfaceDrawTransform
.multiply(rotationAboutZ
);
1041 // The rotation and its inverse are needed to place the scrollDelta compensation in
1042 // the correct space. This test will fail if the rotation/inverse are backwards, too,
1043 // so it requires perfect order of operations.
1044 expectedGreatGrandChildTransform
.makeIdentity();
1045 expectedGreatGrandChildTransform
.multiply(rotationAboutZ
.inverse());
1046 expectedGreatGrandChildTransform
.translate(10, 30); // explicit canceling out the scrollDelta that gets embedded in the fixed position layer's surface.
1047 expectedGreatGrandChildTransform
.multiply(rotationAboutZ
);
1049 ASSERT_TRUE(grandChild
->renderSurface());
1050 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1051 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform
, grandChild
->renderSurface()->drawTransform());
1052 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1053 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
1056 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
)
1058 // This test checks for correct scroll compensation when the fixed-position container
1059 // contributes to a different renderSurface than the fixed-position layer, with
1060 // additional renderSurfaces in-between. This checks that the conversion to ancestor
1061 // surfaces is accumulated properly in the final matrix transform.
1062 DebugScopedSetImplThread scopedImplThread
;
1064 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
1065 CCLayerImpl
* child
= root
->children()[0];
1066 CCLayerImpl
* grandChild
= child
->children()[0];
1067 CCLayerImpl
* greatGrandChild
= grandChild
->children()[0];
1069 // Add one more layer to the test tree for this scenario.
1071 WebTransformationMatrix identity
;
1072 scoped_ptr
<CCLayerImpl
> fixedPositionChild
= CCLayerImpl::create(5);
1073 setLayerPropertiesForTesting(fixedPositionChild
.get(), identity
, identity
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1074 greatGrandChild
->addChild(fixedPositionChild
.Pass());
1076 CCLayerImpl
* fixedPositionChild
= greatGrandChild
->children()[0];
1078 // Actually set up the scenario here.
1079 child
->setIsContainerForFixedPositionLayers(true);
1080 grandChild
->setPosition(FloatPoint(8, 6));
1081 grandChild
->setForceRenderSurface(true);
1082 greatGrandChild
->setPosition(FloatPoint(40, 60));
1083 greatGrandChild
->setForceRenderSurface(true);
1084 fixedPositionChild
->setFixedToContainerLayer(true);
1085 fixedPositionChild
->setDrawsContent(true);
1087 // The additional rotations, which are non-commutative with translations, help to
1088 // verify that we have correct order-of-operations in the final scroll compensation.
1089 // Note that rotating about the center of the layer ensures we do not accidentally
1090 // clip away layers that we want to test.
1091 WebTransformationMatrix rotationAboutZ
;
1092 rotationAboutZ
.translate(50, 50);
1093 rotationAboutZ
.rotate3d(0, 0, 90);
1094 rotationAboutZ
.translate(-50, -50);
1095 grandChild
->setTransform(rotationAboutZ
);
1096 greatGrandChild
->setTransform(rotationAboutZ
);
1098 // Case 1: scrollDelta of 0, 0
1099 child
->setScrollDelta(IntSize(0, 0));
1100 executeCalculateDrawTransformsAndVisibility(root
.get());
1102 WebTransformationMatrix expectedChildTransform
;
1104 WebTransformationMatrix expectedGrandChildSurfaceDrawTransform
;
1105 expectedGrandChildSurfaceDrawTransform
.translate(8, 6);
1106 expectedGrandChildSurfaceDrawTransform
.multiply(rotationAboutZ
);
1108 WebTransformationMatrix expectedGrandChildTransform
;
1110 WebTransformationMatrix expectedGreatGrandChildSurfaceDrawTransform
;
1111 expectedGreatGrandChildSurfaceDrawTransform
.translate(40, 60);
1112 expectedGreatGrandChildSurfaceDrawTransform
.multiply(rotationAboutZ
);
1114 WebTransformationMatrix expectedGreatGrandChildTransform
;
1116 WebTransformationMatrix expectedFixedPositionChildTransform
;
1118 ASSERT_TRUE(grandChild
->renderSurface());
1119 ASSERT_TRUE(greatGrandChild
->renderSurface());
1120 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1121 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform
, grandChild
->renderSurface()->drawTransform());
1122 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1123 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform
, greatGrandChild
->renderSurface()->drawTransform());
1124 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
1125 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform
, fixedPositionChild
->drawTransform());
1127 // Case 2: scrollDelta of 10, 30
1128 child
->setScrollDelta(IntSize(10, 30));
1129 executeCalculateDrawTransformsAndVisibility(root
.get());
1131 expectedChildTransform
.makeIdentity();
1132 expectedChildTransform
.translate(-10, -30); // scrollDelta
1134 expectedGrandChildSurfaceDrawTransform
.makeIdentity();
1135 expectedGrandChildSurfaceDrawTransform
.translate(-10, -30); // scrollDelta
1136 expectedGrandChildSurfaceDrawTransform
.translate(8, 6);
1137 expectedGrandChildSurfaceDrawTransform
.multiply(rotationAboutZ
);
1139 // grandChild, greatGrandChild, and greatGrandChild's surface are not expected to
1140 // change, since they are all not fixed, and they are all drawn with respect to
1141 // grandChild's surface that already has the scrollDelta accounted for.
1143 // But the great-great grandchild, "fixedPositionChild", should have a transform that explicitly cancels out the scrollDelta.
1144 // The expected transform is:
1145 // compoundDrawTransform.inverse() * translate(positive scrollDelta) * compoundOriginTransform
1146 WebTransformationMatrix compoundDrawTransform
; // transform from greatGrandChildSurface's origin to the root surface.
1147 compoundDrawTransform
.translate(8, 6); // origin translation of grandChild
1148 compoundDrawTransform
.multiply(rotationAboutZ
); // rotation of grandChild
1149 compoundDrawTransform
.translate(40, 60); // origin translation of greatGrandChild
1150 compoundDrawTransform
.multiply(rotationAboutZ
); // rotation of greatGrandChild
1152 expectedFixedPositionChildTransform
.makeIdentity();
1153 expectedFixedPositionChildTransform
.multiply(compoundDrawTransform
.inverse());
1154 expectedFixedPositionChildTransform
.translate(10, 30); // explicit canceling out the scrollDelta that gets embedded in the fixed position layer's surface.
1155 expectedFixedPositionChildTransform
.multiply(compoundDrawTransform
);
1157 ASSERT_TRUE(grandChild
->renderSurface());
1158 ASSERT_TRUE(greatGrandChild
->renderSurface());
1159 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1160 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform
, grandChild
->renderSurface()->drawTransform());
1161 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1162 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform
, greatGrandChild
->renderSurface()->drawTransform());
1163 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform
, greatGrandChild
->drawTransform());
1164 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform
, fixedPositionChild
->drawTransform());
1167 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
)
1169 // This test checks for correct scroll compensation when the fixed-position container
1170 // itself has a renderSurface. In this case, the container layer should be treated
1171 // like a layer that contributes to a renderTarget, and that renderTarget
1172 // is completely irrelevant; it should not affect the scroll compensation.
1173 DebugScopedSetImplThread scopedImplThread
;
1175 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
1176 CCLayerImpl
* child
= root
->children()[0];
1177 CCLayerImpl
* grandChild
= child
->children()[0];
1179 child
->setIsContainerForFixedPositionLayers(true);
1180 child
->setForceRenderSurface(true);
1181 grandChild
->setFixedToContainerLayer(true);
1182 grandChild
->setDrawsContent(true);
1184 // Case 1: scrollDelta of 0, 0
1185 child
->setScrollDelta(IntSize(0, 0));
1186 executeCalculateDrawTransformsAndVisibility(root
.get());
1188 WebTransformationMatrix expectedSurfaceDrawTransform
;
1189 expectedSurfaceDrawTransform
.translate(0, 0);
1190 WebTransformationMatrix expectedChildTransform
;
1191 WebTransformationMatrix expectedGrandChildTransform
;
1192 ASSERT_TRUE(child
->renderSurface());
1193 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform
, child
->renderSurface()->drawTransform());
1194 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1195 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1197 // Case 2: scrollDelta of 10, 10
1198 child
->setScrollDelta(IntSize(10, 10));
1199 executeCalculateDrawTransformsAndVisibility(root
.get());
1201 // The surface is translated by scrollDelta, the child transform doesn't change
1202 // because it scrolls along with the surface, but the fixed position grandChild
1203 // needs to compensate for the scroll translation.
1204 expectedSurfaceDrawTransform
.makeIdentity();
1205 expectedSurfaceDrawTransform
.translate(-10, -10);
1206 expectedGrandChildTransform
.makeIdentity();
1207 expectedGrandChildTransform
.translate(10, 10);
1209 ASSERT_TRUE(child
->renderSurface());
1210 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform
, child
->renderSurface()->drawTransform());
1211 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1212 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1215 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
)
1217 // This test checks the scenario where a fixed-position layer also happens to be a
1218 // container itself for a descendant fixed position layer. In particular, the layer
1219 // should not accidentally be fixed to itself.
1220 DebugScopedSetImplThread scopedImplThread
;
1222 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
1223 CCLayerImpl
* child
= root
->children()[0];
1224 CCLayerImpl
* grandChild
= child
->children()[0];
1226 child
->setIsContainerForFixedPositionLayers(true);
1227 grandChild
->setFixedToContainerLayer(true);
1229 // This should not confuse the grandChild. If correct, the grandChild would still be considered fixed to its container (i.e. "child").
1230 grandChild
->setIsContainerForFixedPositionLayers(true);
1232 // Case 1: scrollDelta of 0, 0
1233 child
->setScrollDelta(IntSize(0, 0));
1234 executeCalculateDrawTransformsAndVisibility(root
.get());
1236 WebTransformationMatrix expectedChildTransform
;
1237 WebTransformationMatrix expectedGrandChildTransform
;
1238 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1239 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1241 // Case 2: scrollDelta of 10, 10
1242 child
->setScrollDelta(IntSize(10, 10));
1243 executeCalculateDrawTransformsAndVisibility(root
.get());
1245 // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
1246 expectedChildTransform
.makeIdentity();
1247 expectedChildTransform
.translate(-10, -10);
1248 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1249 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1252 TEST(CCLayerTreeHostCommonTest
, verifyScrollCompensationForFixedPositionLayerThatHasNoContainer
)
1254 // This test checks scroll compensation when a fixed-position layer does not find any
1255 // ancestor that is a "containerForFixedPositionLayers". In this situation, the layer should
1256 // be fixed to the viewport -- not the rootLayer, which may have transforms of its own.
1257 DebugScopedSetImplThread scopedImplThread
;
1259 scoped_ptr
<CCLayerImpl
> root
= createTreeForFixedPositionTests();
1260 CCLayerImpl
* child
= root
->children()[0];
1261 CCLayerImpl
* grandChild
= child
->children()[0];
1263 WebTransformationMatrix rotationByZ
;
1264 rotationByZ
.rotate3d(0, 0, 90);
1266 root
->setTransform(rotationByZ
);
1267 grandChild
->setFixedToContainerLayer(true);
1269 // Case 1: root scrollDelta of 0, 0
1270 root
->setScrollDelta(IntSize(0, 0));
1271 executeCalculateDrawTransformsAndVisibility(root
.get());
1273 WebTransformationMatrix expectedChildTransform
;
1274 expectedChildTransform
.multiply(rotationByZ
);
1276 WebTransformationMatrix expectedGrandChildTransform
;
1277 expectedGrandChildTransform
.multiply(rotationByZ
);
1279 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1280 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1282 // Case 2: root scrollDelta of 10, 10
1283 root
->setScrollDelta(IntSize(10, 10));
1284 executeCalculateDrawTransformsAndVisibility(root
.get());
1286 // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
1287 expectedChildTransform
.makeIdentity();
1288 expectedChildTransform
.translate(-10, -10); // the scrollDelta
1289 expectedChildTransform
.multiply(rotationByZ
);
1291 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
1292 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform
, grandChild
->drawTransform());
1295 TEST(CCLayerTreeHostCommonTest
, verifyClipRectCullsRenderSurfaces
)
1297 // The entire subtree of layers that are outside the clipRect should be culled away,
1298 // and should not affect the renderSurfaceLayerList.
1300 // The test tree is set up as follows:
1301 // - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
1302 // - parent is a large container layer.
1303 // - child has masksToBounds=true to cause clipping.
1304 // - grandChild is positioned outside of the child's bounds
1305 // - greatGrandChild is also kept outside child's bounds.
1307 // In this configuration, grandChild and greatGrandChild are completely outside the
1308 // clipRect, and they should never get scheduled on the list of renderSurfaces.
1311 const WebTransformationMatrix identityMatrix
;
1312 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
1313 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
1314 scoped_refptr
<LayerChromium
> grandChild
= LayerChromium::create();
1315 scoped_refptr
<LayerChromium
> greatGrandChild
= LayerChromium::create();
1316 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1317 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1318 parent
->addChild(child
);
1319 child
->addChild(grandChild
);
1320 grandChild
->addChild(greatGrandChild
);
1322 // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
1323 // even though grandChild and greatGrandChild should be clipped.
1324 child
->addChild(leafNode1
);
1325 greatGrandChild
->addChild(leafNode2
);
1327 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1328 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1329 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1330 setLayerPropertiesForTesting(greatGrandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1331 setLayerPropertiesForTesting(leafNode1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1332 setLayerPropertiesForTesting(leafNode2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1334 child
->setMasksToBounds(true);
1335 child
->setOpacity(0.4f
);
1336 grandChild
->setOpacity(0.5);
1337 greatGrandChild
->setOpacity(0.4f
);
1339 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
1340 int dummyMaxTextureSize
= 512;
1341 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
1343 ASSERT_EQ(2U, renderSurfaceLayerList
.size());
1344 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
1345 EXPECT_EQ(child
->id(), renderSurfaceLayerList
[1]->id());
1348 TEST(CCLayerTreeHostCommonTest
, verifyClipRectCullsSurfaceWithoutVisibleContent
)
1350 // When a renderSurface has a clipRect, it is used to clip the contentRect
1351 // of the surface. When the renderSurface is animating its transforms, then
1352 // the contentRect's position in the clipRect is not defined on the main
1353 // thread, and its contentRect should not be clipped.
1355 // The test tree is set up as follows:
1356 // - parent is a container layer that masksToBounds=true to cause clipping.
1357 // - child is a renderSurface, which has a clipRect set to the bounds of the parent.
1358 // - grandChild is a renderSurface, and the only visible content in child. It is positioned outside of the clipRect from parent.
1360 // In this configuration, grandChild should be outside the clipped
1361 // contentRect of the child, making grandChild not appear in the
1362 // renderSurfaceLayerList. However, when we place an animation on the child,
1363 // this clipping should be avoided and we should keep the grandChild
1364 // in the renderSurfaceLayerList.
1366 const WebTransformationMatrix identityMatrix
;
1367 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
1368 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
1369 scoped_refptr
<LayerChromium
> grandChild
= LayerChromium::create();
1370 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1371 parent
->addChild(child
);
1372 child
->addChild(grandChild
);
1373 grandChild
->addChild(leafNode
);
1375 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1376 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1377 setLayerPropertiesForTesting(grandChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false);
1378 setLayerPropertiesForTesting(leafNode
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1380 parent
->setMasksToBounds(true);
1381 child
->setOpacity(0.4f
);
1382 grandChild
->setOpacity(0.4f
);
1384 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
1385 int dummyMaxTextureSize
= 512;
1386 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
1388 // Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
1389 ASSERT_EQ(1U, renderSurfaceLayerList
.size());
1390 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
1392 // Now put an animating transform on child.
1393 addAnimatedTransformToController(*child
->layerAnimationController(), 10, 30, 0);
1395 parent
->clearRenderSurface();
1396 child
->clearRenderSurface();
1397 grandChild
->clearRenderSurface();
1398 renderSurfaceLayerList
.clear();
1400 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
1402 // With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
1403 ASSERT_EQ(3U, renderSurfaceLayerList
.size());
1404 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
1405 EXPECT_EQ(child
->id(), renderSurfaceLayerList
[1]->id());
1406 EXPECT_EQ(grandChild
->id(), renderSurfaceLayerList
[2]->id());
1409 TEST(CCLayerTreeHostCommonTest
, verifyDrawableContentRectForLayers
)
1411 // Verify that layers get the appropriate drawableContentRect when their parent masksToBounds is true.
1413 // grandChild1 - completely inside the region; drawableContentRect should be the layer rect expressed in target space.
1414 // grandChild2 - partially clipped but NOT masksToBounds; the clipRect will be the intersection of layerBounds and the mask region.
1415 // grandChild3 - partially clipped and masksToBounds; the drawableContentRect will still be the intersection of layerBounds and the mask region.
1416 // grandChild4 - outside parent's clipRect; the drawableContentRect should be empty.
1419 const WebTransformationMatrix identityMatrix
;
1420 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
1421 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
1422 scoped_refptr
<LayerChromium
> grandChild1
= LayerChromium::create();
1423 scoped_refptr
<LayerChromium
> grandChild2
= LayerChromium::create();
1424 scoped_refptr
<LayerChromium
> grandChild3
= LayerChromium::create();
1425 scoped_refptr
<LayerChromium
> grandChild4
= LayerChromium::create();
1427 parent
->addChild(child
);
1428 child
->addChild(grandChild1
);
1429 child
->addChild(grandChild2
);
1430 child
->addChild(grandChild3
);
1431 child
->addChild(grandChild4
);
1433 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1434 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1435 setLayerPropertiesForTesting(grandChild1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1436 setLayerPropertiesForTesting(grandChild2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1437 setLayerPropertiesForTesting(grandChild3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1438 setLayerPropertiesForTesting(grandChild4
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1440 child
->setMasksToBounds(true);
1441 grandChild3
->setMasksToBounds(true);
1443 // Force everyone to be a render surface.
1444 child
->setOpacity(0.4f
);
1445 grandChild1
->setOpacity(0.5);
1446 grandChild2
->setOpacity(0.5);
1447 grandChild3
->setOpacity(0.5);
1448 grandChild4
->setOpacity(0.5);
1450 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
1451 int dummyMaxTextureSize
= 512;
1452 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
1454 EXPECT_RECT_EQ(IntRect(IntPoint(5, 5), IntSize(10, 10)), grandChild1
->drawableContentRect());
1455 EXPECT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3
->drawableContentRect());
1456 EXPECT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3
->drawableContentRect());
1457 EXPECT_TRUE(grandChild4
->drawableContentRect().isEmpty());
1460 TEST(CCLayerTreeHostCommonTest
, verifyClipRectIsPropagatedCorrectlyToSurfaces
)
1462 // Verify that renderSurfaces (and their layers) get the appropriate clipRects when their parent masksToBounds is true.
1464 // Layers that own renderSurfaces (at least for now) do not inherit any clipping;
1465 // instead the surface will enforce the clip for the entire subtree. They may still
1466 // have a clipRect of their own layer bounds, however, if masksToBounds was true.
1469 const WebTransformationMatrix identityMatrix
;
1470 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
1471 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
1472 scoped_refptr
<LayerChromium
> grandChild1
= LayerChromium::create();
1473 scoped_refptr
<LayerChromium
> grandChild2
= LayerChromium::create();
1474 scoped_refptr
<LayerChromium
> grandChild3
= LayerChromium::create();
1475 scoped_refptr
<LayerChromium
> grandChild4
= LayerChromium::create();
1476 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1477 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1478 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1479 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> leafNode4
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1481 parent
->addChild(child
);
1482 child
->addChild(grandChild1
);
1483 child
->addChild(grandChild2
);
1484 child
->addChild(grandChild3
);
1485 child
->addChild(grandChild4
);
1487 // the leaf nodes ensure that these grandChildren become renderSurfaces for this test.
1488 grandChild1
->addChild(leafNode1
);
1489 grandChild2
->addChild(leafNode2
);
1490 grandChild3
->addChild(leafNode3
);
1491 grandChild4
->addChild(leafNode4
);
1493 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1494 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1495 setLayerPropertiesForTesting(grandChild1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1496 setLayerPropertiesForTesting(grandChild2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1497 setLayerPropertiesForTesting(grandChild3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1498 setLayerPropertiesForTesting(grandChild4
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1499 setLayerPropertiesForTesting(leafNode1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1500 setLayerPropertiesForTesting(leafNode2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1501 setLayerPropertiesForTesting(leafNode3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1502 setLayerPropertiesForTesting(leafNode4
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1504 child
->setMasksToBounds(true);
1505 grandChild3
->setMasksToBounds(true);
1506 grandChild4
->setMasksToBounds(true);
1508 // Force everyone to be a render surface.
1509 child
->setOpacity(0.4f
);
1510 grandChild1
->setOpacity(0.5);
1511 grandChild2
->setOpacity(0.5);
1512 grandChild3
->setOpacity(0.5);
1513 grandChild4
->setOpacity(0.5);
1515 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
1516 int dummyMaxTextureSize
= 512;
1517 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
1519 ASSERT_TRUE(grandChild1
->renderSurface());
1520 ASSERT_TRUE(grandChild2
->renderSurface());
1521 ASSERT_TRUE(grandChild3
->renderSurface());
1522 EXPECT_FALSE(grandChild4
->renderSurface()); // Because grandChild4 is entirely clipped, it is expected to not have a renderSurface.
1524 // Surfaces are clipped by their parent, but un-affected by the owning layer's masksToBounds.
1525 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1
->renderSurface()->clipRect());
1526 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2
->renderSurface()->clipRect());
1527 EXPECT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3
->renderSurface()->clipRect());
1530 TEST(CCLayerTreeHostCommonTest
, verifyAnimationsForRenderSurfaceHierarchy
)
1532 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
1533 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
1534 scoped_refptr
<LayerChromium
> renderSurface2
= LayerChromium::create();
1535 scoped_refptr
<LayerChromium
> childOfRoot
= LayerChromium::create();
1536 scoped_refptr
<LayerChromium
> childOfRS1
= LayerChromium::create();
1537 scoped_refptr
<LayerChromium
> childOfRS2
= LayerChromium::create();
1538 scoped_refptr
<LayerChromium
> grandChildOfRoot
= LayerChromium::create();
1539 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChildOfRS1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1540 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChildOfRS2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1541 parent
->addChild(renderSurface1
);
1542 parent
->addChild(childOfRoot
);
1543 renderSurface1
->addChild(childOfRS1
);
1544 renderSurface1
->addChild(renderSurface2
);
1545 renderSurface2
->addChild(childOfRS2
);
1546 childOfRoot
->addChild(grandChildOfRoot
);
1547 childOfRS1
->addChild(grandChildOfRS1
);
1548 childOfRS2
->addChild(grandChildOfRS2
);
1550 // Make our render surfaces.
1551 renderSurface1
->setForceRenderSurface(true);
1552 renderSurface2
->setForceRenderSurface(true);
1554 // Put an animated opacity on the render surface.
1555 addOpacityTransitionToController(*renderSurface1
->layerAnimationController(), 10, 1, 0, false);
1557 // Also put an animated opacity on a layer without descendants.
1558 addOpacityTransitionToController(*grandChildOfRoot
->layerAnimationController(), 10, 1, 0, false);
1560 WebTransformationMatrix layerTransform
;
1561 layerTransform
.translate(1, 1);
1562 WebTransformationMatrix sublayerTransform
;
1563 sublayerTransform
.scale3d(10, 1, 1);
1565 // Put a transform animation on the render surface.
1566 addAnimatedTransformToController(*renderSurface2
->layerAnimationController(), 10, 30, 0);
1568 // Also put transform animations on grandChildOfRoot, and grandChildOfRS2
1569 addAnimatedTransformToController(*grandChildOfRoot
->layerAnimationController(), 10, 30, 0);
1570 addAnimatedTransformToController(*grandChildOfRS2
->layerAnimationController(), 10, 30, 0);
1572 setLayerPropertiesForTesting(parent
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1573 setLayerPropertiesForTesting(renderSurface1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1574 setLayerPropertiesForTesting(renderSurface2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1575 setLayerPropertiesForTesting(childOfRoot
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1576 setLayerPropertiesForTesting(childOfRS1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1577 setLayerPropertiesForTesting(childOfRS2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1578 setLayerPropertiesForTesting(grandChildOfRoot
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1579 setLayerPropertiesForTesting(grandChildOfRS1
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1580 setLayerPropertiesForTesting(grandChildOfRS2
.get(), layerTransform
, sublayerTransform
, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1582 executeCalculateDrawTransformsAndVisibility(parent
.get());
1584 // Only layers that are associated with render surfaces should have an actual renderSurface() value.
1586 ASSERT_TRUE(parent
->renderSurface());
1587 ASSERT_FALSE(childOfRoot
->renderSurface());
1588 ASSERT_FALSE(grandChildOfRoot
->renderSurface());
1590 ASSERT_TRUE(renderSurface1
->renderSurface());
1591 ASSERT_FALSE(childOfRS1
->renderSurface());
1592 ASSERT_FALSE(grandChildOfRS1
->renderSurface());
1594 ASSERT_TRUE(renderSurface2
->renderSurface());
1595 ASSERT_FALSE(childOfRS2
->renderSurface());
1596 ASSERT_FALSE(grandChildOfRS2
->renderSurface());
1598 // Verify all renderTarget accessors
1600 EXPECT_EQ(parent
, parent
->renderTarget());
1601 EXPECT_EQ(parent
, childOfRoot
->renderTarget());
1602 EXPECT_EQ(parent
, grandChildOfRoot
->renderTarget());
1604 EXPECT_EQ(renderSurface1
, renderSurface1
->renderTarget());
1605 EXPECT_EQ(renderSurface1
, childOfRS1
->renderTarget());
1606 EXPECT_EQ(renderSurface1
, grandChildOfRS1
->renderTarget());
1608 EXPECT_EQ(renderSurface2
, renderSurface2
->renderTarget());
1609 EXPECT_EQ(renderSurface2
, childOfRS2
->renderTarget());
1610 EXPECT_EQ(renderSurface2
, grandChildOfRS2
->renderTarget());
1612 // Verify drawOpacityIsAnimating values
1614 EXPECT_FALSE(parent
->drawOpacityIsAnimating());
1615 EXPECT_FALSE(childOfRoot
->drawOpacityIsAnimating());
1616 EXPECT_TRUE(grandChildOfRoot
->drawOpacityIsAnimating());
1617 EXPECT_FALSE(renderSurface1
->drawOpacityIsAnimating());
1618 EXPECT_TRUE(renderSurface1
->renderSurface()->drawOpacityIsAnimating());
1619 EXPECT_FALSE(childOfRS1
->drawOpacityIsAnimating());
1620 EXPECT_FALSE(grandChildOfRS1
->drawOpacityIsAnimating());
1621 EXPECT_FALSE(renderSurface2
->drawOpacityIsAnimating());
1622 EXPECT_FALSE(renderSurface2
->renderSurface()->drawOpacityIsAnimating());
1623 EXPECT_FALSE(childOfRS2
->drawOpacityIsAnimating());
1624 EXPECT_FALSE(grandChildOfRS2
->drawOpacityIsAnimating());
1626 // Verify drawTransformsAnimatingInTarget values
1628 EXPECT_FALSE(parent
->drawTransformIsAnimating());
1629 EXPECT_FALSE(childOfRoot
->drawTransformIsAnimating());
1630 EXPECT_TRUE(grandChildOfRoot
->drawTransformIsAnimating());
1631 EXPECT_FALSE(renderSurface1
->drawTransformIsAnimating());
1632 EXPECT_FALSE(renderSurface1
->renderSurface()->targetSurfaceTransformsAreAnimating());
1633 EXPECT_FALSE(childOfRS1
->drawTransformIsAnimating());
1634 EXPECT_FALSE(grandChildOfRS1
->drawTransformIsAnimating());
1635 EXPECT_FALSE(renderSurface2
->drawTransformIsAnimating());
1636 EXPECT_TRUE(renderSurface2
->renderSurface()->targetSurfaceTransformsAreAnimating());
1637 EXPECT_FALSE(childOfRS2
->drawTransformIsAnimating());
1638 EXPECT_TRUE(grandChildOfRS2
->drawTransformIsAnimating());
1640 // Verify drawTransformsAnimatingInScreen values
1642 EXPECT_FALSE(parent
->screenSpaceTransformIsAnimating());
1643 EXPECT_FALSE(childOfRoot
->screenSpaceTransformIsAnimating());
1644 EXPECT_TRUE(grandChildOfRoot
->screenSpaceTransformIsAnimating());
1645 EXPECT_FALSE(renderSurface1
->screenSpaceTransformIsAnimating());
1646 EXPECT_FALSE(renderSurface1
->renderSurface()->screenSpaceTransformsAreAnimating());
1647 EXPECT_FALSE(childOfRS1
->screenSpaceTransformIsAnimating());
1648 EXPECT_FALSE(grandChildOfRS1
->screenSpaceTransformIsAnimating());
1649 EXPECT_TRUE(renderSurface2
->screenSpaceTransformIsAnimating());
1650 EXPECT_TRUE(renderSurface2
->renderSurface()->screenSpaceTransformsAreAnimating());
1651 EXPECT_TRUE(childOfRS2
->screenSpaceTransformIsAnimating());
1652 EXPECT_TRUE(grandChildOfRS2
->screenSpaceTransformIsAnimating());
1655 // Sanity check. If these fail there is probably a bug in the test itself.
1656 // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
1657 // encodes the "depth" of the layer in the tree.
1658 EXPECT_FLOAT_EQ(1, parent
->screenSpaceTransform().m42());
1659 EXPECT_FLOAT_EQ(2, childOfRoot
->screenSpaceTransform().m42());
1660 EXPECT_FLOAT_EQ(3, grandChildOfRoot
->screenSpaceTransform().m42());
1662 EXPECT_FLOAT_EQ(2, renderSurface1
->screenSpaceTransform().m42());
1663 EXPECT_FLOAT_EQ(3, childOfRS1
->screenSpaceTransform().m42());
1664 EXPECT_FLOAT_EQ(4, grandChildOfRS1
->screenSpaceTransform().m42());
1666 EXPECT_FLOAT_EQ(3, renderSurface2
->screenSpaceTransform().m42());
1667 EXPECT_FLOAT_EQ(4, childOfRS2
->screenSpaceTransform().m42());
1668 EXPECT_FLOAT_EQ(5, grandChildOfRS2
->screenSpaceTransform().m42());
1671 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectForIdentityTransform
)
1673 // Test the calculateVisibleRect() function works correctly for identity transforms.
1675 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1676 WebTransformationMatrix layerToSurfaceTransform
;
1678 // Case 1: Layer is contained within the surface.
1679 IntRect layerContentRect
= IntRect(IntPoint(10, 10), IntSize(30, 30));
1680 IntRect expected
= IntRect(IntPoint(10, 10), IntSize(30, 30));
1681 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1682 EXPECT_RECT_EQ(expected
, actual
);
1684 // Case 2: Layer is outside the surface rect.
1685 layerContentRect
= IntRect(IntPoint(120, 120), IntSize(30, 30));
1686 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1687 EXPECT_TRUE(actual
.isEmpty());
1689 // Case 3: Layer is partially overlapping the surface rect.
1690 layerContentRect
= IntRect(IntPoint(80, 80), IntSize(30, 30));
1691 expected
= IntRect(IntPoint(80, 80), IntSize(20, 20));
1692 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1693 EXPECT_RECT_EQ(expected
, actual
);
1696 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectForTranslations
)
1698 // Test the calculateVisibleRect() function works correctly for scaling transforms.
1700 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1701 IntRect layerContentRect
= IntRect(IntPoint(0, 0), IntSize(30, 30));
1702 WebTransformationMatrix layerToSurfaceTransform
;
1704 // Case 1: Layer is contained within the surface.
1705 layerToSurfaceTransform
.makeIdentity();
1706 layerToSurfaceTransform
.translate(10, 10);
1707 IntRect expected
= IntRect(IntPoint(0, 0), IntSize(30, 30));
1708 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1709 EXPECT_RECT_EQ(expected
, actual
);
1711 // Case 2: Layer is outside the surface rect.
1712 layerToSurfaceTransform
.makeIdentity();
1713 layerToSurfaceTransform
.translate(120, 120);
1714 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1715 EXPECT_TRUE(actual
.isEmpty());
1717 // Case 3: Layer is partially overlapping the surface rect.
1718 layerToSurfaceTransform
.makeIdentity();
1719 layerToSurfaceTransform
.translate(80, 80);
1720 expected
= IntRect(IntPoint(0, 0), IntSize(20, 20));
1721 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1722 EXPECT_RECT_EQ(expected
, actual
);
1725 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectFor2DRotations
)
1727 // Test the calculateVisibleRect() function works correctly for rotations about z-axis (i.e. 2D rotations).
1728 // Remember that calculateVisibleRect() should return the visible rect in the layer's space.
1730 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1731 IntRect layerContentRect
= IntRect(IntPoint(0, 0), IntSize(30, 30));
1732 WebTransformationMatrix layerToSurfaceTransform
;
1734 // Case 1: Layer is contained within the surface.
1735 layerToSurfaceTransform
.makeIdentity();
1736 layerToSurfaceTransform
.translate(50, 50);
1737 layerToSurfaceTransform
.rotate(45);
1738 IntRect expected
= IntRect(IntPoint(0, 0), IntSize(30, 30));
1739 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1740 EXPECT_RECT_EQ(expected
, actual
);
1742 // Case 2: Layer is outside the surface rect.
1743 layerToSurfaceTransform
.makeIdentity();
1744 layerToSurfaceTransform
.translate(-50, 0);
1745 layerToSurfaceTransform
.rotate(45);
1746 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1747 EXPECT_TRUE(actual
.isEmpty());
1749 // Case 3: The layer is rotated about its top-left corner. In surface space, the layer
1750 // is oriented diagonally, with the left half outside of the renderSurface. In
1751 // this case, the visible rect should still be the entire layer (remember the
1752 // visible rect is computed in layer space); both the top-left and
1753 // bottom-right corners of the layer are still visible.
1754 layerToSurfaceTransform
.makeIdentity();
1755 layerToSurfaceTransform
.rotate(45);
1756 expected
= IntRect(IntPoint(0, 0), IntSize(30, 30));
1757 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1758 EXPECT_RECT_EQ(expected
, actual
);
1760 // Case 4: The layer is rotated about its top-left corner, and translated upwards. In
1761 // surface space, the layer is oriented diagonally, with only the top corner
1762 // of the surface overlapping the layer. In layer space, the render surface
1763 // overlaps the right side of the layer. The visible rect should be the
1764 // layer's right half.
1765 layerToSurfaceTransform
.makeIdentity();
1766 layerToSurfaceTransform
.translate(0, -sqrt(2.0) * 15);
1767 layerToSurfaceTransform
.rotate(45);
1768 expected
= IntRect(IntPoint(15, 0), IntSize(15, 30)); // right half of layer bounds.
1769 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1770 EXPECT_RECT_EQ(expected
, actual
);
1773 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectFor3dOrthographicTransform
)
1775 // Test that the calculateVisibleRect() function works correctly for 3d transforms.
1777 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1778 IntRect layerContentRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1779 WebTransformationMatrix layerToSurfaceTransform
;
1781 // Case 1: Orthographic projection of a layer rotated about y-axis by 45 degrees, should be fully contained in the renderSurface.
1782 layerToSurfaceTransform
.makeIdentity();
1783 layerToSurfaceTransform
.rotate3d(0, 45, 0);
1784 IntRect expected
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1785 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1786 EXPECT_RECT_EQ(expected
, actual
);
1788 // Case 2: Orthographic projection of a layer rotated about y-axis by 45 degrees, but
1789 // shifted to the side so only the right-half the layer would be visible on
1791 double halfWidthOfRotatedLayer
= (100 / sqrt(2.0)) * 0.5; // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
1792 layerToSurfaceTransform
.makeIdentity();
1793 layerToSurfaceTransform
.translate(-halfWidthOfRotatedLayer
, 0);
1794 layerToSurfaceTransform
.rotate3d(0, 45, 0); // rotates about the left edge of the layer
1795 expected
= IntRect(IntPoint(50, 0), IntSize(50, 100)); // right half of the layer.
1796 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1797 EXPECT_RECT_EQ(expected
, actual
);
1800 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectFor3dPerspectiveTransform
)
1802 // Test the calculateVisibleRect() function works correctly when the layer has a
1803 // perspective projection onto the target surface.
1805 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1806 IntRect layerContentRect
= IntRect(IntPoint(-50, -50), IntSize(200, 200));
1807 WebTransformationMatrix layerToSurfaceTransform
;
1809 // Case 1: Even though the layer is twice as large as the surface, due to perspective
1810 // foreshortening, the layer will fit fully in the surface when its translated
1811 // more than the perspective amount.
1812 layerToSurfaceTransform
.makeIdentity();
1814 // The following sequence of transforms applies the perspective about the center of the surface.
1815 layerToSurfaceTransform
.translate(50, 50);
1816 layerToSurfaceTransform
.applyPerspective(9);
1817 layerToSurfaceTransform
.translate(-50, -50);
1819 // This translate places the layer in front of the surface's projection plane.
1820 layerToSurfaceTransform
.translate3d(0, 0, -27);
1822 IntRect expected
= IntRect(IntPoint(-50, -50), IntSize(200, 200));
1823 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1824 EXPECT_RECT_EQ(expected
, actual
);
1826 // Case 2: same projection as before, except that the layer is also translated to the
1827 // side, so that only the right half of the layer should be visible.
1829 // Explanation of expected result:
1830 // The perspective ratio is (z distance between layer and camera origin) / (z distance between projection plane and camera origin) == ((-27 - 9) / 9)
1831 // 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
1832 // visible), then we would need to translate by (-36 / 9) * -50 == -200 in the layer's units.
1834 layerToSurfaceTransform
.translate3d(-200, 0, 0);
1835 expected
= IntRect(IntPoint(50, -50), IntSize(100, 200)); // The right half of the layer's bounding rect.
1836 actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1837 EXPECT_RECT_EQ(expected
, actual
);
1840 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectFor3dOrthographicIsNotClippedBehindSurface
)
1842 // There is currently no explicit concept of an orthographic projection plane in our
1843 // code (nor in the CSS spec to my knowledge). Therefore, layers that are technically
1844 // behind the surface in an orthographic world should not be clipped when they are
1845 // flattened to the surface.
1847 IntRect targetSurfaceRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1848 IntRect layerContentRect
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1849 WebTransformationMatrix layerToSurfaceTransform
;
1851 // This sequence of transforms effectively rotates the layer about the y-axis at the
1852 // center of the layer.
1853 layerToSurfaceTransform
.makeIdentity();
1854 layerToSurfaceTransform
.translate(50, 0);
1855 layerToSurfaceTransform
.rotate3d(0, 45, 0);
1856 layerToSurfaceTransform
.translate(-50, 0);
1858 IntRect expected
= IntRect(IntPoint(0, 0), IntSize(100, 100));
1859 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1860 EXPECT_RECT_EQ(expected
, actual
);
1863 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectFor3dPerspectiveWhenClippedByW
)
1865 // Test the calculateVisibleRect() function works correctly when projecting a surface
1866 // onto a layer, but the layer is partially behind the camera (not just behind the
1867 // projection plane). In this case, the cartesian coordinates may seem to be valid,
1868 // but actually they are not. The visibleRect needs to be properly clipped by the
1869 // w = 0 plane in homogeneous coordinates before converting to cartesian coordinates.
1871 IntRect targetSurfaceRect
= IntRect(IntPoint(-50, -50), IntSize(100, 100));
1872 IntRect layerContentRect
= IntRect(IntPoint(-10, -1), IntSize(20, 2));
1873 WebTransformationMatrix layerToSurfaceTransform
;
1875 // The layer is positioned so that the right half of the layer should be in front of
1876 // the camera, while the other half is behind the surface's projection plane. The
1877 // following sequence of transforms applies the perspective and rotation about the
1878 // center of the layer.
1879 layerToSurfaceTransform
.makeIdentity();
1880 layerToSurfaceTransform
.applyPerspective(1);
1881 layerToSurfaceTransform
.translate3d(-2, 0, 1);
1882 layerToSurfaceTransform
.rotate3d(0, 45, 0);
1884 // Sanity check that this transform does indeed cause w < 0 when applying the
1885 // transform, otherwise this code is not testing the intended scenario.
1886 bool clipped
= false;
1887 CCMathUtil::mapQuad(layerToSurfaceTransform
, FloatQuad(FloatRect(layerContentRect
)), clipped
);
1888 ASSERT_TRUE(clipped
);
1890 int expectedXPosition
= 0;
1891 int expectedWidth
= 10;
1892 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1893 EXPECT_EQ(expectedXPosition
, actual
.x());
1894 EXPECT_EQ(expectedWidth
, actual
.width());
1897 TEST(CCLayerTreeHostCommonTest
, verifyVisibleRectForPerspectiveUnprojection
)
1899 // To determine visibleRect in layer space, there needs to be an un-projection from
1900 // surface space to layer space. When the original transform was a perspective
1901 // projection that was clipped, it returns a rect that encloses the clipped bounds.
1902 // Un-projecting this new rect may require clipping again.
1904 // This sequence of transforms causes one corner of the layer to protrude across the w = 0 plane, and should be clipped.
1905 IntRect targetSurfaceRect
= IntRect(IntPoint(-50, -50), IntSize(100, 100));
1906 IntRect layerContentRect
= IntRect(IntPoint(-10, -10), IntSize(20, 20));
1907 WebTransformationMatrix layerToSurfaceTransform
;
1908 layerToSurfaceTransform
.makeIdentity();
1909 layerToSurfaceTransform
.applyPerspective(1);
1910 layerToSurfaceTransform
.translate3d(0, 0, -5);
1911 layerToSurfaceTransform
.rotate3d(0, 45, 0);
1912 layerToSurfaceTransform
.rotate3d(80, 0, 0);
1914 // Sanity check that un-projection does indeed cause w < 0, otherwise this code is not
1915 // testing the intended scenario.
1916 bool clipped
= false;
1917 FloatRect clippedRect
= CCMathUtil::mapClippedRect(layerToSurfaceTransform
, layerContentRect
);
1918 CCMathUtil::projectQuad(layerToSurfaceTransform
.inverse(), FloatQuad(clippedRect
), clipped
);
1919 ASSERT_TRUE(clipped
);
1921 // Only the corner of the layer is not visible on the surface because of being
1922 // clipped. But, the net result of rounding visible region to an axis-aligned rect is
1923 // that the entire layer should still be considered visible.
1924 IntRect expected
= IntRect(IntPoint(-10, -10), IntSize(20, 20));
1925 IntRect actual
= CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect
, layerContentRect
, layerToSurfaceTransform
);
1926 EXPECT_RECT_EQ(expected
, actual
);
1929 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsForSimpleLayers
)
1931 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
1932 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1933 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1934 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1935 root
->addChild(child1
);
1936 root
->addChild(child2
);
1937 root
->addChild(child3
);
1939 WebTransformationMatrix identityMatrix
;
1940 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1941 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false);
1942 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
1943 setLayerPropertiesForTesting(child3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
1945 executeCalculateDrawTransformsAndVisibility(root
.get());
1947 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
1948 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
1950 // Layers that do not draw content should have empty visibleContentRects.
1951 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
1953 // layer visibleContentRects are clipped by their targetSurface
1954 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->visibleContentRect());
1955 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), child2
->visibleContentRect());
1956 EXPECT_TRUE(child3
->visibleContentRect().isEmpty());
1958 // layer drawableContentRects are not clipped.
1959 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->drawableContentRect());
1960 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2
->drawableContentRect());
1961 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3
->drawableContentRect());
1964 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsForLayersClippedByLayer
)
1966 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
1967 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
1968 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1969 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1970 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> grandChild3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
1971 root
->addChild(child
);
1972 child
->addChild(grandChild1
);
1973 child
->addChild(grandChild2
);
1974 child
->addChild(grandChild3
);
1976 WebTransformationMatrix identityMatrix
;
1977 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1978 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1979 setLayerPropertiesForTesting(grandChild1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false);
1980 setLayerPropertiesForTesting(grandChild2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
1981 setLayerPropertiesForTesting(grandChild3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
1983 child
->setMasksToBounds(true);
1984 executeCalculateDrawTransformsAndVisibility(root
.get());
1986 ASSERT_FALSE(child
->renderSurface());
1988 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
1989 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
1991 // Layers that do not draw content should have empty visibleContentRects.
1992 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
1993 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), child
->visibleContentRect());
1995 // All grandchild visibleContentRects should be clipped by child.
1996 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), grandChild1
->visibleContentRect());
1997 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), grandChild2
->visibleContentRect());
1998 EXPECT_TRUE(grandChild3
->visibleContentRect().isEmpty());
2000 // All grandchild drawableContentRects should also be clipped by child.
2001 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), grandChild1
->drawableContentRect());
2002 EXPECT_RECT_EQ(IntRect(75, 75, 25, 25), grandChild2
->drawableContentRect());
2003 EXPECT_TRUE(grandChild3
->drawableContentRect().isEmpty());
2006 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface
)
2008 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2009 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
2010 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2011 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2012 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2013 root
->addChild(renderSurface1
);
2014 renderSurface1
->addChild(child1
);
2015 renderSurface1
->addChild(child2
);
2016 renderSurface1
->addChild(child3
);
2018 WebTransformationMatrix identityMatrix
;
2019 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2020 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false);
2021 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false);
2022 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
2023 setLayerPropertiesForTesting(child3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
2025 renderSurface1
->setForceRenderSurface(true);
2026 executeCalculateDrawTransformsAndVisibility(root
.get());
2028 ASSERT_TRUE(renderSurface1
->renderSurface());
2030 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
2031 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
2033 // Layers that do not draw content should have empty visibleContentRects.
2034 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
2035 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1
->visibleContentRect());
2037 // An unclipped surface grows its drawableContentRect to include all drawable regions of the subtree.
2038 EXPECT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface1
->renderSurface()->drawableContentRect());
2040 // All layers that draw content into the unclipped surface are also unclipped.
2041 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->visibleContentRect());
2042 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child2
->visibleContentRect());
2043 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child3
->visibleContentRect());
2045 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1
->drawableContentRect());
2046 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2
->drawableContentRect());
2047 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3
->drawableContentRect());
2050 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsForLayersInClippedRenderSurface
)
2052 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2053 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
2054 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2055 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2056 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2057 root
->addChild(renderSurface1
);
2058 renderSurface1
->addChild(child1
);
2059 renderSurface1
->addChild(child2
);
2060 renderSurface1
->addChild(child3
);
2062 WebTransformationMatrix identityMatrix
;
2063 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2064 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false);
2065 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false);
2066 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
2067 setLayerPropertiesForTesting(child3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
2069 root
->setMasksToBounds(true);
2070 renderSurface1
->setForceRenderSurface(true);
2071 executeCalculateDrawTransformsAndVisibility(root
.get());
2073 ASSERT_TRUE(renderSurface1
->renderSurface());
2075 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
2076 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
2078 // Layers that do not draw content should have empty visibleContentRects.
2079 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
2080 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1
->visibleContentRect());
2082 // A clipped surface grows its drawableContentRect to include all drawable regions of the subtree,
2083 // but also gets clamped by the ancestor's clip.
2084 EXPECT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1
->renderSurface()->drawableContentRect());
2086 // All layers that draw content into the surface have their visibleContentRect clipped by the surface clipRect.
2087 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->visibleContentRect());
2088 EXPECT_RECT_EQ(IntRect(0, 0, 25, 25), child2
->visibleContentRect());
2089 EXPECT_TRUE(child3
->visibleContentRect().isEmpty());
2091 // But the drawableContentRects are unclipped.
2092 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1
->drawableContentRect());
2093 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2
->drawableContentRect());
2094 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3
->drawableContentRect());
2097 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsForSurfaceHierarchy
)
2099 // Check that clipping does not propagate down surfaces.
2100 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2101 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
2102 scoped_refptr
<LayerChromium
> renderSurface2
= LayerChromium::create();
2103 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2104 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2105 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child3
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2106 root
->addChild(renderSurface1
);
2107 renderSurface1
->addChild(renderSurface2
);
2108 renderSurface2
->addChild(child1
);
2109 renderSurface2
->addChild(child2
);
2110 renderSurface2
->addChild(child3
);
2112 WebTransformationMatrix identityMatrix
;
2113 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2114 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false);
2115 setLayerPropertiesForTesting(renderSurface2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(7, 13), false);
2116 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false);
2117 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
2118 setLayerPropertiesForTesting(child3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
2120 root
->setMasksToBounds(true);
2121 renderSurface1
->setForceRenderSurface(true);
2122 renderSurface2
->setForceRenderSurface(true);
2123 executeCalculateDrawTransformsAndVisibility(root
.get());
2125 ASSERT_TRUE(renderSurface1
->renderSurface());
2126 ASSERT_TRUE(renderSurface2
->renderSurface());
2128 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
2129 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
2131 // Layers that do not draw content should have empty visibleContentRects.
2132 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
2133 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1
->visibleContentRect());
2134 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface2
->visibleContentRect());
2136 // A clipped surface grows its drawableContentRect to include all drawable regions of the subtree,
2137 // but also gets clamped by the ancestor's clip.
2138 EXPECT_RECT_EQ(IntRect(5, 5, 95, 95), renderSurface1
->renderSurface()->drawableContentRect());
2140 // renderSurface1 lives in the "unclipped universe" of renderSurface1, and is only
2141 // implicitly clipped by renderSurface1's contentRect. So, renderSurface2 grows to
2142 // enclose all drawable content of its subtree.
2143 EXPECT_RECT_EQ(IntRect(5, 5, 170, 170), renderSurface2
->renderSurface()->drawableContentRect());
2145 // All layers that draw content into renderSurface2 think they are unclipped.
2146 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->visibleContentRect());
2147 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child2
->visibleContentRect());
2148 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child3
->visibleContentRect());
2150 // drawableContentRects are also unclipped.
2151 EXPECT_RECT_EQ(IntRect(5, 5, 50, 50), child1
->drawableContentRect());
2152 EXPECT_RECT_EQ(IntRect(75, 75, 50, 50), child2
->drawableContentRect());
2153 EXPECT_RECT_EQ(IntRect(125, 125, 50, 50), child3
->drawableContentRect());
2156 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsWithTransformOnUnclippedSurface
)
2158 // Layers that have non-axis aligned bounds (due to transforms) have an expanded,
2159 // axis-aligned drawableContentRect and visibleContentRect.
2161 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2162 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
2163 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2164 root
->addChild(renderSurface1
);
2165 renderSurface1
->addChild(child1
);
2167 WebTransformationMatrix identityMatrix
;
2168 WebTransformationMatrix childRotation
;
2169 childRotation
.rotate(45);
2170 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2171 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false);
2172 setLayerPropertiesForTesting(child1
.get(), childRotation
, identityMatrix
, FloatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false);
2174 renderSurface1
->setForceRenderSurface(true);
2175 executeCalculateDrawTransformsAndVisibility(root
.get());
2177 ASSERT_TRUE(renderSurface1
->renderSurface());
2179 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->renderSurface()->drawableContentRect());
2180 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), root
->drawableContentRect());
2182 // Layers that do not draw content should have empty visibleContentRects.
2183 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
2184 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), renderSurface1
->visibleContentRect());
2186 // The unclipped surface grows its drawableContentRect to include all drawable regions of the subtree.
2187 int diagonalRadius
= ceil(sqrt(2.0) * 25);
2188 IntRect expectedSurfaceDrawableContent
= IntRect(50 - diagonalRadius
, 50 - diagonalRadius
, diagonalRadius
* 2, diagonalRadius
* 2);
2189 EXPECT_RECT_EQ(expectedSurfaceDrawableContent
, renderSurface1
->renderSurface()->drawableContentRect());
2191 // All layers that draw content into the unclipped surface are also unclipped.
2192 EXPECT_RECT_EQ(IntRect(0, 0, 50, 50), child1
->visibleContentRect());
2193 EXPECT_RECT_EQ(expectedSurfaceDrawableContent
, child1
->drawableContentRect());
2196 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsWithTransformOnClippedSurface
)
2198 // Layers that have non-axis aligned bounds (due to transforms) have an expanded,
2199 // axis-aligned drawableContentRect and visibleContentRect.
2201 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2202 scoped_refptr
<LayerChromium
> renderSurface1
= LayerChromium::create();
2203 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2204 root
->addChild(renderSurface1
);
2205 renderSurface1
->addChild(child1
);
2207 WebTransformationMatrix identityMatrix
;
2208 WebTransformationMatrix childRotation
;
2209 childRotation
.rotate(45);
2210 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(50, 50), false);
2211 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(3, 4), false);
2212 setLayerPropertiesForTesting(child1
.get(), childRotation
, identityMatrix
, FloatPoint(0.5, 0.5), FloatPoint(25, 25), IntSize(50, 50), false);
2214 root
->setMasksToBounds(true);
2215 renderSurface1
->setForceRenderSurface(true);
2216 executeCalculateDrawTransformsAndVisibility(root
.get());
2218 ASSERT_TRUE(renderSurface1
->renderSurface());
2220 // The clipped surface clamps the drawableContentRect that encloses the rotated layer.
2221 int diagonalRadius
= ceil(sqrt(2.0) * 25);
2222 IntRect unclippedSurfaceContent
= IntRect(50 - diagonalRadius
, 50 - diagonalRadius
, diagonalRadius
* 2, diagonalRadius
* 2);
2223 IntRect expectedSurfaceDrawableContent
= intersection(unclippedSurfaceContent
, IntRect(0, 0, 50, 50));
2224 EXPECT_RECT_EQ(expectedSurfaceDrawableContent
, renderSurface1
->renderSurface()->drawableContentRect());
2226 // On the clipped surface, only a quarter of the child1 is visible, but when rotating
2227 // it back to child1's content space, the actual enclosing rect ends up covering the
2228 // full left half of child1.
2229 EXPECT_RECT_EQ(IntRect(0, 0, 26, 50), child1
->visibleContentRect());
2231 // The child's drawableContentRect is unclipped.
2232 EXPECT_RECT_EQ(unclippedSurfaceContent
, child1
->drawableContentRect());
2235 TEST(CCLayerTreeHostCommonTest
, verifyDrawableAndVisibleContentRectsInHighDPI
)
2237 MockContentLayerChromiumClient client
;
2239 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
2240 scoped_refptr
<ContentLayerChromium
> renderSurface1
= createDrawableContentLayerChromium(&client
);
2241 scoped_refptr
<ContentLayerChromium
> renderSurface2
= createDrawableContentLayerChromium(&client
);
2242 scoped_refptr
<ContentLayerChromium
> child1
= createDrawableContentLayerChromium(&client
);
2243 scoped_refptr
<ContentLayerChromium
> child2
= createDrawableContentLayerChromium(&client
);
2244 scoped_refptr
<ContentLayerChromium
> child3
= createDrawableContentLayerChromium(&client
);
2245 root
->addChild(renderSurface1
);
2246 renderSurface1
->addChild(renderSurface2
);
2247 renderSurface2
->addChild(child1
);
2248 renderSurface2
->addChild(child2
);
2249 renderSurface2
->addChild(child3
);
2251 WebTransformationMatrix identityMatrix
;
2252 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2253 setLayerPropertiesForTesting(renderSurface1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(3, 4), false);
2254 setLayerPropertiesForTesting(renderSurface2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(7, 13), false);
2255 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(50, 50), false);
2256 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(75, 75), IntSize(50, 50), false);
2257 setLayerPropertiesForTesting(child3
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(125, 125), IntSize(50, 50), false);
2259 const double deviceScaleFactor
= 2;
2260 root
->setContentsScale(deviceScaleFactor
);
2261 renderSurface1
->setContentsScale(deviceScaleFactor
);
2262 renderSurface2
->setContentsScale(deviceScaleFactor
);
2263 child1
->setContentsScale(deviceScaleFactor
);
2264 child2
->setContentsScale(deviceScaleFactor
);
2265 child3
->setContentsScale(deviceScaleFactor
);
2267 root
->setMasksToBounds(true);
2268 renderSurface1
->setForceRenderSurface(true);
2269 renderSurface2
->setForceRenderSurface(true);
2270 executeCalculateDrawTransformsAndVisibility(root
.get(), deviceScaleFactor
);
2272 ASSERT_TRUE(renderSurface1
->renderSurface());
2273 ASSERT_TRUE(renderSurface2
->renderSurface());
2275 // DrawableContentRects for all layers and surfaces are scaled by deviceScaleFactor.
2276 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), root
->renderSurface()->drawableContentRect());
2277 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), root
->drawableContentRect());
2278 EXPECT_RECT_EQ(IntRect(10, 10, 190, 190), renderSurface1
->renderSurface()->drawableContentRect());
2280 // renderSurface2 lives in the "unclipped universe" of renderSurface1, and
2281 // is only implicitly clipped by renderSurface1.
2282 EXPECT_RECT_EQ(IntRect(10, 10, 350, 350), renderSurface2
->renderSurface()->drawableContentRect());
2284 EXPECT_RECT_EQ(IntRect(10, 10, 100, 100), child1
->drawableContentRect());
2285 EXPECT_RECT_EQ(IntRect(150, 150, 100, 100), child2
->drawableContentRect());
2286 EXPECT_RECT_EQ(IntRect(250, 250, 100, 100), child3
->drawableContentRect());
2288 // The root layer does not actually draw content of its own.
2289 EXPECT_RECT_EQ(IntRect(0, 0, 0, 0), root
->visibleContentRect());
2291 // All layer visibleContentRects are expressed in content space of each
2292 // layer, so they are also scaled by the deviceScaleFactor.
2293 EXPECT_RECT_EQ(IntRect(0, 0, 6, 8), renderSurface1
->visibleContentRect());
2294 EXPECT_RECT_EQ(IntRect(0, 0, 14, 26), renderSurface2
->visibleContentRect());
2295 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child1
->visibleContentRect());
2296 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child2
->visibleContentRect());
2297 EXPECT_RECT_EQ(IntRect(0, 0, 100, 100), child3
->visibleContentRect());
2300 TEST(CCLayerTreeHostCommonTest
, verifyBackFaceCullingWithoutPreserves3d
)
2302 // Verify the behavior of back-face culling when there are no preserve-3d layers. Note
2303 // that 3d transforms still apply in this case, but they are "flattened" to each
2304 // parent layer according to current W3C spec.
2306 const WebTransformationMatrix identityMatrix
;
2307 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
2308 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2309 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2310 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2311 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2312 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChildOfFrontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2313 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChildOfFrontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2314 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChildOfBackFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2315 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChildOfBackFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2317 parent
->addChild(frontFacingChild
);
2318 parent
->addChild(backFacingChild
);
2319 parent
->addChild(frontFacingSurface
);
2320 parent
->addChild(backFacingSurface
);
2321 frontFacingSurface
->addChild(frontFacingChildOfFrontFacingSurface
);
2322 frontFacingSurface
->addChild(backFacingChildOfFrontFacingSurface
);
2323 backFacingSurface
->addChild(frontFacingChildOfBackFacingSurface
);
2324 backFacingSurface
->addChild(backFacingChildOfBackFacingSurface
);
2326 // Nothing is double-sided
2327 frontFacingChild
->setDoubleSided(false);
2328 backFacingChild
->setDoubleSided(false);
2329 frontFacingSurface
->setDoubleSided(false);
2330 backFacingSurface
->setDoubleSided(false);
2331 frontFacingChildOfFrontFacingSurface
->setDoubleSided(false);
2332 backFacingChildOfFrontFacingSurface
->setDoubleSided(false);
2333 frontFacingChildOfBackFacingSurface
->setDoubleSided(false);
2334 backFacingChildOfBackFacingSurface
->setDoubleSided(false);
2336 WebTransformationMatrix backfaceMatrix
;
2337 backfaceMatrix
.translate(50, 50);
2338 backfaceMatrix
.rotate3d(0, 1, 0, 180);
2339 backfaceMatrix
.translate(-50, -50);
2341 // Having a descendant and opacity will force these to have render surfaces.
2342 frontFacingSurface
->setOpacity(0.5);
2343 backFacingSurface
->setOpacity(0.5);
2345 // Nothing preserves 3d. According to current W3C CSS Transforms spec, these layers
2346 // should blindly use their own local transforms to determine back-face culling.
2347 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2348 setLayerPropertiesForTesting(frontFacingChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2349 setLayerPropertiesForTesting(backFacingChild
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2350 setLayerPropertiesForTesting(frontFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2351 setLayerPropertiesForTesting(backFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2352 setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2353 setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2354 setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2355 setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2357 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
2358 int dummyMaxTextureSize
= 512;
2359 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
2361 // Verify which renderSurfaces were created.
2362 EXPECT_FALSE(frontFacingChild
->renderSurface());
2363 EXPECT_FALSE(backFacingChild
->renderSurface());
2364 EXPECT_TRUE(frontFacingSurface
->renderSurface());
2365 EXPECT_TRUE(backFacingSurface
->renderSurface());
2366 EXPECT_FALSE(frontFacingChildOfFrontFacingSurface
->renderSurface());
2367 EXPECT_FALSE(backFacingChildOfFrontFacingSurface
->renderSurface());
2368 EXPECT_FALSE(frontFacingChildOfBackFacingSurface
->renderSurface());
2369 EXPECT_FALSE(backFacingChildOfBackFacingSurface
->renderSurface());
2371 // Verify the renderSurfaceLayerList.
2372 ASSERT_EQ(3u, renderSurfaceLayerList
.size());
2373 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
2374 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->id());
2375 // Even though the back facing surface LAYER gets culled, the other descendants should still be added, so the SURFACE should not be culled.
2376 EXPECT_EQ(backFacingSurface
->id(), renderSurfaceLayerList
[2]->id());
2378 // Verify root surface's layerList.
2379 ASSERT_EQ(3u, renderSurfaceLayerList
[0]->renderSurface()->layerList().size());
2380 EXPECT_EQ(frontFacingChild
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[0]->id());
2381 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[1]->id());
2382 EXPECT_EQ(backFacingSurface
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[2]->id());
2384 // Verify frontFacingSurface's layerList.
2385 ASSERT_EQ(2u, renderSurfaceLayerList
[1]->renderSurface()->layerList().size());
2386 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[0]->id());
2387 EXPECT_EQ(frontFacingChildOfFrontFacingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id());
2389 // Verify backFacingSurface's layerList; its own layer should be culled from the surface list.
2390 ASSERT_EQ(1u, renderSurfaceLayerList
[2]->renderSurface()->layerList().size());
2391 EXPECT_EQ(frontFacingChildOfBackFacingSurface
->id(), renderSurfaceLayerList
[2]->renderSurface()->layerList()[0]->id());
2394 TEST(CCLayerTreeHostCommonTest
, verifyBackFaceCullingWithPreserves3d
)
2396 // Verify the behavior of back-face culling when preserves-3d transform style is used.
2398 const WebTransformationMatrix identityMatrix
;
2399 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
2400 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2401 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2402 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2403 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2404 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChildOfFrontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2405 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChildOfFrontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2406 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingChildOfBackFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2407 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingChildOfBackFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2408 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> dummyReplicaLayer1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2409 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> dummyReplicaLayer2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2411 parent
->addChild(frontFacingChild
);
2412 parent
->addChild(backFacingChild
);
2413 parent
->addChild(frontFacingSurface
);
2414 parent
->addChild(backFacingSurface
);
2415 frontFacingSurface
->addChild(frontFacingChildOfFrontFacingSurface
);
2416 frontFacingSurface
->addChild(backFacingChildOfFrontFacingSurface
);
2417 backFacingSurface
->addChild(frontFacingChildOfBackFacingSurface
);
2418 backFacingSurface
->addChild(backFacingChildOfBackFacingSurface
);
2420 // Nothing is double-sided
2421 frontFacingChild
->setDoubleSided(false);
2422 backFacingChild
->setDoubleSided(false);
2423 frontFacingSurface
->setDoubleSided(false);
2424 backFacingSurface
->setDoubleSided(false);
2425 frontFacingChildOfFrontFacingSurface
->setDoubleSided(false);
2426 backFacingChildOfFrontFacingSurface
->setDoubleSided(false);
2427 frontFacingChildOfBackFacingSurface
->setDoubleSided(false);
2428 backFacingChildOfBackFacingSurface
->setDoubleSided(false);
2430 WebTransformationMatrix backfaceMatrix
;
2431 backfaceMatrix
.translate(50, 50);
2432 backfaceMatrix
.rotate3d(0, 1, 0, 180);
2433 backfaceMatrix
.translate(-50, -50);
2435 // Opacity will not force creation of renderSurfaces in this case because of the
2436 // preserve-3d transform style. Instead, an example of when a surface would be
2437 // created with preserve-3d is when there is a replica layer.
2438 frontFacingSurface
->setReplicaLayer(dummyReplicaLayer1
.get());
2439 backFacingSurface
->setReplicaLayer(dummyReplicaLayer2
.get());
2441 // Each surface creates its own new 3d rendering context (as defined by W3C spec).
2442 // According to current W3C CSS Transforms spec, layers in a 3d rendering context
2443 // should use the transform with respect to that context. This 3d rendering context
2444 // occurs when (a) parent's transform style is flat and (b) the layer's transform
2445 // style is preserve-3d.
2446 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transform style is flat.
2447 setLayerPropertiesForTesting(frontFacingChild
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2448 setLayerPropertiesForTesting(backFacingChild
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2449 setLayerPropertiesForTesting(frontFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2450 setLayerPropertiesForTesting(backFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2451 setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2452 setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2453 setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2454 setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2456 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
2457 int dummyMaxTextureSize
= 512;
2458 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
2460 // Verify which renderSurfaces were created.
2461 EXPECT_FALSE(frontFacingChild
->renderSurface());
2462 EXPECT_FALSE(backFacingChild
->renderSurface());
2463 EXPECT_TRUE(frontFacingSurface
->renderSurface());
2464 EXPECT_FALSE(backFacingSurface
->renderSurface());
2465 EXPECT_FALSE(frontFacingChildOfFrontFacingSurface
->renderSurface());
2466 EXPECT_FALSE(backFacingChildOfFrontFacingSurface
->renderSurface());
2467 EXPECT_FALSE(frontFacingChildOfBackFacingSurface
->renderSurface());
2468 EXPECT_FALSE(backFacingChildOfBackFacingSurface
->renderSurface());
2470 // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2471 ASSERT_EQ(2u, renderSurfaceLayerList
.size());
2472 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
2473 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->id());
2475 // Verify root surface's layerList.
2476 ASSERT_EQ(2u, renderSurfaceLayerList
[0]->renderSurface()->layerList().size());
2477 EXPECT_EQ(frontFacingChild
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[0]->id());
2478 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[1]->id());
2480 // Verify frontFacingSurface's layerList.
2481 ASSERT_EQ(2u, renderSurfaceLayerList
[1]->renderSurface()->layerList().size());
2482 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[0]->id());
2483 EXPECT_EQ(frontFacingChildOfFrontFacingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id());
2486 TEST(CCLayerTreeHostCommonTest
, verifyBackFaceCullingWithAnimatingTransforms
)
2488 // Verify that layers are appropriately culled when their back face is showing and
2489 // they are not double sided, while animations are going on.
2491 // Layers that are animating do not get culled on the main thread, as their transforms should be
2492 // treated as "unknown" so we can not be sure that their back face is really showing.
2495 const WebTransformationMatrix identityMatrix
;
2496 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
2497 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2498 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> animatingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2499 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> childOfAnimatingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2500 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> animatingChild
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2501 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2503 parent
->addChild(child
);
2504 parent
->addChild(animatingSurface
);
2505 animatingSurface
->addChild(childOfAnimatingSurface
);
2506 parent
->addChild(animatingChild
);
2507 parent
->addChild(child2
);
2509 // Nothing is double-sided
2510 child
->setDoubleSided(false);
2511 child2
->setDoubleSided(false);
2512 animatingSurface
->setDoubleSided(false);
2513 childOfAnimatingSurface
->setDoubleSided(false);
2514 animatingChild
->setDoubleSided(false);
2516 WebTransformationMatrix backfaceMatrix
;
2517 backfaceMatrix
.translate(50, 50);
2518 backfaceMatrix
.rotate3d(0, 1, 0, 180);
2519 backfaceMatrix
.translate(-50, -50);
2521 // Make our render surface.
2522 animatingSurface
->setForceRenderSurface(true);
2524 // Animate the transform on the render surface.
2525 addAnimatedTransformToController(*animatingSurface
->layerAnimationController(), 10, 30, 0);
2526 // This is just an animating layer, not a surface.
2527 addAnimatedTransformToController(*animatingChild
->layerAnimationController(), 10, 30, 0);
2529 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2530 setLayerPropertiesForTesting(child
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2531 setLayerPropertiesForTesting(animatingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2532 setLayerPropertiesForTesting(childOfAnimatingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2533 setLayerPropertiesForTesting(animatingChild
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2534 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2536 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
2537 int dummyMaxTextureSize
= 512;
2538 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
2540 EXPECT_FALSE(child
->renderSurface());
2541 EXPECT_TRUE(animatingSurface
->renderSurface());
2542 EXPECT_FALSE(childOfAnimatingSurface
->renderSurface());
2543 EXPECT_FALSE(animatingChild
->renderSurface());
2544 EXPECT_FALSE(child2
->renderSurface());
2546 // Verify that the animatingChild and childOfAnimatingSurface were not culled, but that child was.
2547 ASSERT_EQ(2u, renderSurfaceLayerList
.size());
2548 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
2549 EXPECT_EQ(animatingSurface
->id(), renderSurfaceLayerList
[1]->id());
2551 // The non-animating child be culled from the layer list for the parent render surface.
2552 ASSERT_EQ(3u, renderSurfaceLayerList
[0]->renderSurface()->layerList().size());
2553 EXPECT_EQ(animatingSurface
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[0]->id());
2554 EXPECT_EQ(animatingChild
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[1]->id());
2555 EXPECT_EQ(child2
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[2]->id());
2557 ASSERT_EQ(2u, renderSurfaceLayerList
[1]->renderSurface()->layerList().size());
2558 EXPECT_EQ(animatingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[0]->id());
2559 EXPECT_EQ(childOfAnimatingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id());
2561 EXPECT_FALSE(child2
->visibleContentRect().isEmpty());
2563 // The animating layers should have a visibleContentRect that represents the area of the front face that is within the viewport.
2564 EXPECT_EQ(animatingChild
->visibleContentRect(), IntRect(IntPoint(), animatingChild
->contentBounds()));
2565 EXPECT_EQ(animatingSurface
->visibleContentRect(), IntRect(IntPoint(), animatingSurface
->contentBounds()));
2566 // And layers in the subtree of the animating layer should have valid visibleContentRects also.
2567 EXPECT_EQ(childOfAnimatingSurface
->visibleContentRect(), IntRect(IntPoint(), childOfAnimatingSurface
->contentBounds()));
2570 TEST(CCLayerTreeHostCommonTest
, verifyBackFaceCullingWithPreserves3dForFlatteningSurface
)
2572 // Verify the behavior of back-face culling for a renderSurface that is created
2573 // when it flattens its subtree, and its parent has preserves-3d.
2575 const WebTransformationMatrix identityMatrix
;
2576 scoped_refptr
<LayerChromium
> parent
= LayerChromium::create();
2577 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> frontFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2578 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> backFacingSurface
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2579 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child1
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2580 scoped_refptr
<LayerChromiumWithForcedDrawsContent
> child2
= make_scoped_refptr(new LayerChromiumWithForcedDrawsContent());
2582 parent
->addChild(frontFacingSurface
);
2583 parent
->addChild(backFacingSurface
);
2584 frontFacingSurface
->addChild(child1
);
2585 backFacingSurface
->addChild(child2
);
2587 // RenderSurfaces are not double-sided
2588 frontFacingSurface
->setDoubleSided(false);
2589 backFacingSurface
->setDoubleSided(false);
2591 WebTransformationMatrix backfaceMatrix
;
2592 backfaceMatrix
.translate(50, 50);
2593 backfaceMatrix
.rotate3d(0, 1, 0, 180);
2594 backfaceMatrix
.translate(-50, -50);
2596 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
2597 setLayerPropertiesForTesting(frontFacingSurface
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2598 setLayerPropertiesForTesting(backFacingSurface
.get(), backfaceMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2599 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2600 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2602 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
2603 int dummyMaxTextureSize
= 512;
2604 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), 1, dummyMaxTextureSize
, renderSurfaceLayerList
);
2606 // Verify which renderSurfaces were created.
2607 EXPECT_TRUE(frontFacingSurface
->renderSurface());
2608 EXPECT_FALSE(backFacingSurface
->renderSurface()); // because it should be culled
2609 EXPECT_FALSE(child1
->renderSurface());
2610 EXPECT_FALSE(child2
->renderSurface());
2612 // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2613 ASSERT_EQ(2u, renderSurfaceLayerList
.size());
2614 EXPECT_EQ(parent
->id(), renderSurfaceLayerList
[0]->id());
2615 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->id());
2617 // Verify root surface's layerList.
2618 ASSERT_EQ(1u, renderSurfaceLayerList
[0]->renderSurface()->layerList().size());
2619 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[0]->renderSurface()->layerList()[0]->id());
2621 // Verify frontFacingSurface's layerList.
2622 ASSERT_EQ(2u, renderSurfaceLayerList
[1]->renderSurface()->layerList().size());
2623 EXPECT_EQ(frontFacingSurface
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[0]->id());
2624 EXPECT_EQ(child1
->id(), renderSurfaceLayerList
[1]->renderSurface()->layerList()[1]->id());
2627 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForEmptyLayerList
)
2629 // Hit testing on an empty renderSurfaceLayerList should return a null pointer.
2630 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2632 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2634 IntPoint
testPoint(0, 0);
2635 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2636 EXPECT_FALSE(resultLayer
);
2638 testPoint
= IntPoint(10, 20);
2639 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2640 EXPECT_FALSE(resultLayer
);
2643 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSingleLayer
)
2645 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2647 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(12345);
2649 WebTransformationMatrix identityMatrix
;
2650 FloatPoint
anchor(0, 0);
2651 FloatPoint
position(0, 0);
2652 IntSize
bounds(100, 100);
2653 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
2654 root
->setDrawsContent(true);
2656 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2657 int dummyMaxTextureSize
= 512;
2658 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2660 // Sanity check the scenario we just created.
2661 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2662 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2664 // Hit testing for a point outside the layer should return a null pointer.
2665 IntPoint
testPoint(101, 101);
2666 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2667 EXPECT_FALSE(resultLayer
);
2669 testPoint
= IntPoint(-1, -1);
2670 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2671 EXPECT_FALSE(resultLayer
);
2673 // Hit testing for a point inside should return the root layer.
2674 testPoint
= IntPoint(1, 1);
2675 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2676 ASSERT_TRUE(resultLayer
);
2677 EXPECT_EQ(12345, resultLayer
->id());
2679 testPoint
= IntPoint(99, 99);
2680 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2681 ASSERT_TRUE(resultLayer
);
2682 EXPECT_EQ(12345, resultLayer
->id());
2685 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForUninvertibleTransform
)
2687 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2689 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(12345);
2691 WebTransformationMatrix uninvertibleTransform
;
2692 uninvertibleTransform
.setM11(0);
2693 uninvertibleTransform
.setM22(0);
2694 uninvertibleTransform
.setM33(0);
2695 uninvertibleTransform
.setM44(0);
2696 ASSERT_FALSE(uninvertibleTransform
.isInvertible());
2698 WebTransformationMatrix identityMatrix
;
2699 FloatPoint
anchor(0, 0);
2700 FloatPoint
position(0, 0);
2701 IntSize
bounds(100, 100);
2702 setLayerPropertiesForTesting(root
.get(), uninvertibleTransform
, identityMatrix
, anchor
, position
, bounds
, false);
2703 root
->setDrawsContent(true);
2705 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2706 int dummyMaxTextureSize
= 512;
2707 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2709 // Sanity check the scenario we just created.
2710 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2711 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2712 ASSERT_FALSE(root
->screenSpaceTransform().isInvertible());
2714 // Hit testing any point should not hit the layer. If the invertible matrix is
2715 // accidentally ignored and treated like an identity, then the hit testing will
2716 // incorrectly hit the layer when it shouldn't.
2717 IntPoint
testPoint(1, 1);
2718 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2719 EXPECT_FALSE(resultLayer
);
2721 testPoint
= IntPoint(10, 10);
2722 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2723 EXPECT_FALSE(resultLayer
);
2725 testPoint
= IntPoint(10, 30);
2726 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2727 EXPECT_FALSE(resultLayer
);
2729 testPoint
= IntPoint(50, 50);
2730 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2731 EXPECT_FALSE(resultLayer
);
2733 testPoint
= IntPoint(67, 48);
2734 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2735 EXPECT_FALSE(resultLayer
);
2737 testPoint
= IntPoint(99, 99);
2738 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2739 EXPECT_FALSE(resultLayer
);
2741 testPoint
= IntPoint(-1, -1);
2742 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2743 EXPECT_FALSE(resultLayer
);
2746 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSinglePositionedLayer
)
2748 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2750 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(12345);
2752 WebTransformationMatrix identityMatrix
;
2753 FloatPoint
anchor(0, 0);
2754 FloatPoint
position(50, 50); // this layer is positioned, and hit testing should correctly know where the layer is located.
2755 IntSize
bounds(100, 100);
2756 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
2757 root
->setDrawsContent(true);
2759 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2760 int dummyMaxTextureSize
= 512;
2761 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2763 // Sanity check the scenario we just created.
2764 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2765 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2767 // Hit testing for a point outside the layer should return a null pointer.
2768 IntPoint
testPoint(49, 49);
2769 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2770 EXPECT_FALSE(resultLayer
);
2772 // Even though the layer exists at (101, 101), it should not be visible there since the root renderSurface would clamp it.
2773 testPoint
= IntPoint(101, 101);
2774 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2775 EXPECT_FALSE(resultLayer
);
2777 // Hit testing for a point inside should return the root layer.
2778 testPoint
= IntPoint(51, 51);
2779 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2780 ASSERT_TRUE(resultLayer
);
2781 EXPECT_EQ(12345, resultLayer
->id());
2783 testPoint
= IntPoint(99, 99);
2784 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2785 ASSERT_TRUE(resultLayer
);
2786 EXPECT_EQ(12345, resultLayer
->id());
2789 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSingleRotatedLayer
)
2791 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2793 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(12345);
2795 WebTransformationMatrix identityMatrix
;
2796 WebTransformationMatrix rotation45DegreesAboutCenter
;
2797 rotation45DegreesAboutCenter
.translate(50, 50);
2798 rotation45DegreesAboutCenter
.rotate3d(0, 0, 45);
2799 rotation45DegreesAboutCenter
.translate(-50, -50);
2800 FloatPoint
anchor(0, 0);
2801 FloatPoint
position(0, 0);
2802 IntSize
bounds(100, 100);
2803 setLayerPropertiesForTesting(root
.get(), rotation45DegreesAboutCenter
, identityMatrix
, anchor
, position
, bounds
, false);
2804 root
->setDrawsContent(true);
2806 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2807 int dummyMaxTextureSize
= 512;
2808 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2810 // Sanity check the scenario we just created.
2811 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2812 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2814 // Hit testing for points outside the layer.
2815 // These corners would have been inside the un-transformed layer, but they should not hit the correctly transformed layer.
2816 IntPoint
testPoint(99, 99);
2817 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2818 EXPECT_FALSE(resultLayer
);
2820 testPoint
= IntPoint(1, 1);
2821 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2822 EXPECT_FALSE(resultLayer
);
2824 // Hit testing for a point inside should return the root layer.
2825 testPoint
= IntPoint(1, 50);
2826 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2827 ASSERT_TRUE(resultLayer
);
2828 EXPECT_EQ(12345, resultLayer
->id());
2830 // Hit testing the corners that would overlap the unclipped layer, but are outside the clipped region.
2831 testPoint
= IntPoint(50, -1);
2832 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2833 ASSERT_FALSE(resultLayer
);
2835 testPoint
= IntPoint(-1, 50);
2836 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2837 ASSERT_FALSE(resultLayer
);
2840 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSinglePerspectiveLayer
)
2842 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2844 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(12345);
2846 WebTransformationMatrix identityMatrix
;
2848 // perspectiveProjectionAboutCenter * translationByZ is designed so that the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
2849 WebTransformationMatrix perspectiveProjectionAboutCenter
;
2850 perspectiveProjectionAboutCenter
.translate(50, 50);
2851 perspectiveProjectionAboutCenter
.applyPerspective(1);
2852 perspectiveProjectionAboutCenter
.translate(-50, -50);
2853 WebTransformationMatrix translationByZ
;
2854 translationByZ
.translate3d(0, 0, -1);
2856 FloatPoint
anchor(0, 0);
2857 FloatPoint
position(0, 0);
2858 IntSize
bounds(100, 100);
2859 setLayerPropertiesForTesting(root
.get(), perspectiveProjectionAboutCenter
* translationByZ
, identityMatrix
, anchor
, position
, bounds
, false);
2860 root
->setDrawsContent(true);
2862 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2863 int dummyMaxTextureSize
= 512;
2864 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2866 // Sanity check the scenario we just created.
2867 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2868 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2870 // Hit testing for points outside the layer.
2871 // These corners would have been inside the un-transformed layer, but they should not hit the correctly transformed layer.
2872 IntPoint
testPoint(24, 24);
2873 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2874 EXPECT_FALSE(resultLayer
);
2876 testPoint
= IntPoint(76, 76);
2877 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2878 EXPECT_FALSE(resultLayer
);
2880 // Hit testing for a point inside should return the root layer.
2881 testPoint
= IntPoint(26, 26);
2882 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2883 ASSERT_TRUE(resultLayer
);
2884 EXPECT_EQ(12345, resultLayer
->id());
2886 testPoint
= IntPoint(74, 74);
2887 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2888 ASSERT_TRUE(resultLayer
);
2889 EXPECT_EQ(12345, resultLayer
->id());
2892 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSingleLayerWithScaledContents
)
2894 // A layer's visibleContentRect is actually in the layer's content space. The
2895 // screenSpaceTransform converts from the layer's origin space to screen space. This
2896 // test makes sure that hit testing works correctly accounts for the contents scale.
2897 // A contentsScale that is not 1 effectively forces a non-identity transform between
2898 // layer's content space and layer's origin space. The hit testing code must take this into account.
2900 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
2901 // contentsScale is ignored, then hit testing will mis-interpret the visibleContentRect
2902 // as being larger than the actual bounds of the layer.
2904 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2906 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
2908 WebTransformationMatrix identityMatrix
;
2909 FloatPoint
anchor(0, 0);
2911 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, FloatPoint(0, 0), IntSize(100, 100), false);
2914 FloatPoint
position(25, 25);
2915 IntSize
bounds(50, 50);
2916 scoped_ptr
<CCLayerImpl
> testLayer
= CCLayerImpl::create(12345);
2917 setLayerPropertiesForTesting(testLayer
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
2919 // override contentBounds
2920 testLayer
->setContentBounds(IntSize(100, 100));
2922 testLayer
->setDrawsContent(true);
2923 root
->addChild(testLayer
.Pass());
2926 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2927 int dummyMaxTextureSize
= 512;
2928 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2930 // Sanity check the scenario we just created.
2931 // The visibleContentRect for testLayer is actually 100x100, even though its layout size is 50x50, positioned at 25x25.
2932 CCLayerImpl
* testLayer
= root
->children()[0];
2933 EXPECT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(100, 100)), testLayer
->visibleContentRect());
2934 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2935 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2937 // Hit testing for a point outside the layer should return a null pointer (the root layer does not draw content, so it will not be hit tested either).
2938 IntPoint
testPoint(101, 101);
2939 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2940 EXPECT_FALSE(resultLayer
);
2942 testPoint
= IntPoint(24, 24);
2943 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2944 EXPECT_FALSE(resultLayer
);
2946 testPoint
= IntPoint(76, 76);
2947 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2948 EXPECT_FALSE(resultLayer
);
2950 // Hit testing for a point inside should return the test layer.
2951 testPoint
= IntPoint(26, 26);
2952 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2953 ASSERT_TRUE(resultLayer
);
2954 EXPECT_EQ(12345, resultLayer
->id());
2956 testPoint
= IntPoint(74, 74);
2957 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
2958 ASSERT_TRUE(resultLayer
);
2959 EXPECT_EQ(12345, resultLayer
->id());
2962 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForSimpleClippedLayer
)
2964 // Test that hit-testing will only work for the visible portion of a layer, and not
2965 // the entire layer bounds. Here we just test the simple axis-aligned case.
2966 DebugScopedSetImplThread thisScopeIsOnImplThread
;
2968 WebTransformationMatrix identityMatrix
;
2969 FloatPoint
anchor(0, 0);
2971 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
2972 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, FloatPoint(0, 0), IntSize(100, 100), false);
2975 scoped_ptr
<CCLayerImpl
> clippingLayer
= CCLayerImpl::create(123);
2976 FloatPoint
position(25, 25); // this layer is positioned, and hit testing should correctly know where the layer is located.
2977 IntSize
bounds(50, 50);
2978 setLayerPropertiesForTesting(clippingLayer
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
2979 clippingLayer
->setMasksToBounds(true);
2981 scoped_ptr
<CCLayerImpl
> child
= CCLayerImpl::create(456);
2982 position
= FloatPoint(-50, -50);
2983 bounds
= IntSize(300, 300);
2984 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
2985 child
->setDrawsContent(true);
2986 clippingLayer
->addChild(child
.Pass());
2987 root
->addChild(clippingLayer
.Pass());
2990 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
2991 int dummyMaxTextureSize
= 512;
2992 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
2994 // Sanity check the scenario we just created.
2995 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
2996 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
2997 ASSERT_EQ(456, root
->renderSurface()->layerList()[0]->id());
2999 // Hit testing for a point outside the layer should return a null pointer.
3000 // Despite the child layer being very large, it should be clipped to the root layer's bounds.
3001 IntPoint
testPoint(24, 24);
3002 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3003 EXPECT_FALSE(resultLayer
);
3005 // Even though the layer exists at (101, 101), it should not be visible there since the clippingLayer would clamp it.
3006 testPoint
= IntPoint(76, 76);
3007 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3008 EXPECT_FALSE(resultLayer
);
3010 // Hit testing for a point inside should return the child layer.
3011 testPoint
= IntPoint(26, 26);
3012 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3013 ASSERT_TRUE(resultLayer
);
3014 EXPECT_EQ(456, resultLayer
->id());
3016 testPoint
= IntPoint(74, 74);
3017 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3018 ASSERT_TRUE(resultLayer
);
3019 EXPECT_EQ(456, resultLayer
->id());
3022 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForMultiClippedRotatedLayer
)
3024 // This test checks whether hit testing correctly avoids hit testing with multiple
3025 // ancestors that clip in non axis-aligned ways. To pass this test, the hit testing
3026 // algorithm needs to recognize that multiple parent layers may clip the layer, and
3027 // should not actually hit those clipped areas.
3029 // The child and grandChild layers are both initialized to clip the rotatedLeaf. The
3030 // child layer is rotated about the top-left corner, so that the root + child clips
3031 // combined create a triangle. The rotatedLeaf will only be visible where it overlaps
3034 DebugScopedSetImplThread thisScopeIsOnImplThread
;
3036 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(123);
3038 WebTransformationMatrix identityMatrix
;
3039 FloatPoint
anchor(0, 0);
3040 FloatPoint
position(0, 0);
3041 IntSize
bounds(100, 100);
3042 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3043 root
->setMasksToBounds(true);
3046 scoped_ptr
<CCLayerImpl
> child
= CCLayerImpl::create(456);
3047 scoped_ptr
<CCLayerImpl
> grandChild
= CCLayerImpl::create(789);
3048 scoped_ptr
<CCLayerImpl
> rotatedLeaf
= CCLayerImpl::create(2468);
3050 position
= FloatPoint(10, 10);
3051 bounds
= IntSize(80, 80);
3052 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3053 child
->setMasksToBounds(true);
3055 WebTransformationMatrix rotation45DegreesAboutCorner
;
3056 rotation45DegreesAboutCorner
.rotate3d(0, 0, 45);
3058 position
= FloatPoint(0, 0); // remember, positioned with respect to its parent which is already at 10, 10
3059 bounds
= IntSize(200, 200); // to ensure it covers at least sqrt(2) * 100.
3060 setLayerPropertiesForTesting(grandChild
.get(), rotation45DegreesAboutCorner
, identityMatrix
, anchor
, position
, bounds
, false);
3061 grandChild
->setMasksToBounds(true);
3063 // Rotates about the center of the layer
3064 WebTransformationMatrix rotatedLeafTransform
;
3065 rotatedLeafTransform
.translate(-10, -10); // cancel out the grandParent's position
3066 rotatedLeafTransform
.rotate3d(0, 0, -45); // cancel out the corner 45-degree rotation of the parent.
3067 rotatedLeafTransform
.translate(50, 50);
3068 rotatedLeafTransform
.rotate3d(0, 0, 45);
3069 rotatedLeafTransform
.translate(-50, -50);
3070 position
= FloatPoint(0, 0);
3071 bounds
= IntSize(100, 100);
3072 setLayerPropertiesForTesting(rotatedLeaf
.get(), rotatedLeafTransform
, identityMatrix
, anchor
, position
, bounds
, false);
3073 rotatedLeaf
->setDrawsContent(true);
3075 grandChild
->addChild(rotatedLeaf
.Pass());
3076 child
->addChild(grandChild
.Pass());
3077 root
->addChild(child
.Pass());
3080 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
3081 int dummyMaxTextureSize
= 512;
3082 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
3084 // Sanity check the scenario we just created.
3085 // The grandChild is expected to create a renderSurface because it masksToBounds and is not axis aligned.
3086 ASSERT_EQ(2u, renderSurfaceLayerList
.size());
3087 ASSERT_EQ(1u, renderSurfaceLayerList
[0]->renderSurface()->layerList().size());
3088 ASSERT_EQ(789, renderSurfaceLayerList
[0]->renderSurface()->layerList()[0]->id()); // grandChild's surface.
3089 ASSERT_EQ(1u, renderSurfaceLayerList
[1]->renderSurface()->layerList().size());
3090 ASSERT_EQ(2468, renderSurfaceLayerList
[1]->renderSurface()->layerList()[0]->id());
3092 // (11, 89) is close to the the bottom left corner within the clip, but it is not inside the layer.
3093 IntPoint
testPoint(11, 89);
3094 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3095 EXPECT_FALSE(resultLayer
);
3097 // Closer inwards from the bottom left will overlap the layer.
3098 testPoint
= IntPoint(25, 75);
3099 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3100 ASSERT_TRUE(resultLayer
);
3101 EXPECT_EQ(2468, resultLayer
->id());
3103 // (4, 50) is inside the unclipped layer, but that corner of the layer should be
3104 // clipped away by the grandParent and should not get hit. If hit testing blindly uses
3105 // visibleContentRect without considering how parent may clip the layer, then hit
3106 // testing would accidentally think that the point successfully hits the layer.
3107 testPoint
= IntPoint(4, 50);
3108 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3109 EXPECT_FALSE(resultLayer
);
3111 // (11, 50) is inside the layer and within the clipped area.
3112 testPoint
= IntPoint(11, 50);
3113 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3114 ASSERT_TRUE(resultLayer
);
3115 EXPECT_EQ(2468, resultLayer
->id());
3117 // Around the middle, just to the right and up, would have hit the layer except that
3118 // that area should be clipped away by the parent.
3119 testPoint
= IntPoint(51, 51);
3120 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3121 EXPECT_FALSE(resultLayer
);
3123 // Around the middle, just to the left and down, should successfully hit the layer.
3124 testPoint
= IntPoint(49, 51);
3125 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3126 ASSERT_TRUE(resultLayer
);
3127 EXPECT_EQ(2468, resultLayer
->id());
3130 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForNonClippingIntermediateLayer
)
3132 // This test checks that hit testing code does not accidentally clip to layer
3133 // bounds for a layer that actually does not clip.
3134 DebugScopedSetImplThread thisScopeIsOnImplThread
;
3136 WebTransformationMatrix identityMatrix
;
3137 FloatPoint
anchor(0, 0);
3139 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
3140 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, FloatPoint(0, 0), IntSize(100, 100), false);
3143 scoped_ptr
<CCLayerImpl
> intermediateLayer
= CCLayerImpl::create(123);
3144 FloatPoint
position(10, 10); // this layer is positioned, and hit testing should correctly know where the layer is located.
3145 IntSize
bounds(50, 50);
3146 setLayerPropertiesForTesting(intermediateLayer
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3147 // Sanity check the intermediate layer should not clip.
3148 ASSERT_FALSE(intermediateLayer
->masksToBounds());
3149 ASSERT_FALSE(intermediateLayer
->maskLayer());
3151 // The child of the intermediateLayer is translated so that it does not overlap intermediateLayer at all.
3152 // If child is incorrectly clipped, we would not be able to hit it successfully.
3153 scoped_ptr
<CCLayerImpl
> child
= CCLayerImpl::create(456);
3154 position
= FloatPoint(60, 60); // 70, 70 in screen space
3155 bounds
= IntSize(20, 20);
3156 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3157 child
->setDrawsContent(true);
3158 intermediateLayer
->addChild(child
.Pass());
3159 root
->addChild(intermediateLayer
.Pass());
3162 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
3163 int dummyMaxTextureSize
= 512;
3164 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
3166 // Sanity check the scenario we just created.
3167 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
3168 ASSERT_EQ(1u, root
->renderSurface()->layerList().size());
3169 ASSERT_EQ(456, root
->renderSurface()->layerList()[0]->id());
3171 // Hit testing for a point outside the layer should return a null pointer.
3172 IntPoint
testPoint(69, 69);
3173 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3174 EXPECT_FALSE(resultLayer
);
3176 testPoint
= IntPoint(91, 91);
3177 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3178 EXPECT_FALSE(resultLayer
);
3180 // Hit testing for a point inside should return the child layer.
3181 testPoint
= IntPoint(71, 71);
3182 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3183 ASSERT_TRUE(resultLayer
);
3184 EXPECT_EQ(456, resultLayer
->id());
3186 testPoint
= IntPoint(89, 89);
3187 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3188 ASSERT_TRUE(resultLayer
);
3189 EXPECT_EQ(456, resultLayer
->id());
3193 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForMultipleLayers
)
3195 DebugScopedSetImplThread thisScopeIsOnImplThread
;
3197 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
3199 WebTransformationMatrix identityMatrix
;
3200 FloatPoint
anchor(0, 0);
3201 FloatPoint
position(0, 0);
3202 IntSize
bounds(100, 100);
3203 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3204 root
->setDrawsContent(true);
3207 // child 1 and child2 are initialized to overlap between x=50 and x=60.
3208 // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
3209 // The expected stacking order is:
3210 // (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
3212 scoped_ptr
<CCLayerImpl
> child1
= CCLayerImpl::create(2);
3213 scoped_ptr
<CCLayerImpl
> child2
= CCLayerImpl::create(3);
3214 scoped_ptr
<CCLayerImpl
> grandChild1
= CCLayerImpl::create(4);
3216 position
= FloatPoint(10, 10);
3217 bounds
= IntSize(50, 50);
3218 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3219 child1
->setDrawsContent(true);
3221 position
= FloatPoint(50, 10);
3222 bounds
= IntSize(50, 50);
3223 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3224 child2
->setDrawsContent(true);
3226 // Remember that grandChild is positioned with respect to its parent (i.e. child1).
3227 // In screen space, the intended position is (10, 50), with size 100 x 50.
3228 position
= FloatPoint(0, 40);
3229 bounds
= IntSize(100, 50);
3230 setLayerPropertiesForTesting(grandChild1
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3231 grandChild1
->setDrawsContent(true);
3233 child1
->addChild(grandChild1
.Pass());
3234 root
->addChild(child1
.Pass());
3235 root
->addChild(child2
.Pass());
3238 CCLayerImpl
* child1
= root
->children()[0];
3239 CCLayerImpl
* child2
= root
->children()[1];
3240 CCLayerImpl
* grandChild1
= child1
->children()[0];
3242 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
3243 int dummyMaxTextureSize
= 512;
3244 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
3246 // Sanity check the scenario we just created.
3247 ASSERT_TRUE(child1
);
3248 ASSERT_TRUE(child2
);
3249 ASSERT_TRUE(grandChild1
);
3250 ASSERT_EQ(1u, renderSurfaceLayerList
.size());
3251 ASSERT_EQ(4u, root
->renderSurface()->layerList().size());
3252 ASSERT_EQ(1, root
->renderSurface()->layerList()[0]->id()); // root layer
3253 ASSERT_EQ(2, root
->renderSurface()->layerList()[1]->id()); // child1
3254 ASSERT_EQ(4, root
->renderSurface()->layerList()[2]->id()); // grandChild1
3255 ASSERT_EQ(3, root
->renderSurface()->layerList()[3]->id()); // child2
3257 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should find the root layer.
3258 IntPoint testPoint
= IntPoint(1, 1);
3259 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3260 ASSERT_TRUE(resultLayer
);
3261 EXPECT_EQ(1, resultLayer
->id());
3263 // At (15, 15), child1 and root are the only layers. child1 is expected to be on top.
3264 testPoint
= IntPoint(15, 15);
3265 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3266 ASSERT_TRUE(resultLayer
);
3267 EXPECT_EQ(2, resultLayer
->id());
3269 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
3270 testPoint
= IntPoint(51, 20);
3271 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3272 ASSERT_TRUE(resultLayer
);
3273 EXPECT_EQ(3, resultLayer
->id());
3275 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
3276 testPoint
= IntPoint(80, 51);
3277 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3278 ASSERT_TRUE(resultLayer
);
3279 EXPECT_EQ(3, resultLayer
->id());
3281 // At (51, 51), all layers overlap each other. child2 is expected to be on top of all other layers.
3282 testPoint
= IntPoint(51, 51);
3283 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3284 ASSERT_TRUE(resultLayer
);
3285 EXPECT_EQ(3, resultLayer
->id());
3287 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to be on top.
3288 testPoint
= IntPoint(20, 51);
3289 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3290 ASSERT_TRUE(resultLayer
);
3291 EXPECT_EQ(4, resultLayer
->id());
3294 TEST(CCLayerTreeHostCommonTest
, verifyHitTestingForMultipleLayerLists
)
3297 // The geometry is set up similarly to the previous case, but
3298 // all layers are forced to be renderSurfaces now.
3300 DebugScopedSetImplThread thisScopeIsOnImplThread
;
3302 scoped_ptr
<CCLayerImpl
> root
= CCLayerImpl::create(1);
3304 WebTransformationMatrix identityMatrix
;
3305 FloatPoint
anchor(0, 0);
3306 FloatPoint
position(0, 0);
3307 IntSize
bounds(100, 100);
3308 setLayerPropertiesForTesting(root
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3309 root
->setDrawsContent(true);
3312 // child 1 and child2 are initialized to overlap between x=50 and x=60.
3313 // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
3314 // The expected stacking order is:
3315 // (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
3317 scoped_ptr
<CCLayerImpl
> child1
= CCLayerImpl::create(2);
3318 scoped_ptr
<CCLayerImpl
> child2
= CCLayerImpl::create(3);
3319 scoped_ptr
<CCLayerImpl
> grandChild1
= CCLayerImpl::create(4);
3321 position
= FloatPoint(10, 10);
3322 bounds
= IntSize(50, 50);
3323 setLayerPropertiesForTesting(child1
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3324 child1
->setDrawsContent(true);
3325 child1
->setForceRenderSurface(true);
3327 position
= FloatPoint(50, 10);
3328 bounds
= IntSize(50, 50);
3329 setLayerPropertiesForTesting(child2
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3330 child2
->setDrawsContent(true);
3331 child2
->setForceRenderSurface(true);
3333 // Remember that grandChild is positioned with respect to its parent (i.e. child1).
3334 // In screen space, the intended position is (10, 50), with size 100 x 50.
3335 position
= FloatPoint(0, 40);
3336 bounds
= IntSize(100, 50);
3337 setLayerPropertiesForTesting(grandChild1
.get(), identityMatrix
, identityMatrix
, anchor
, position
, bounds
, false);
3338 grandChild1
->setDrawsContent(true);
3339 grandChild1
->setForceRenderSurface(true);
3341 child1
->addChild(grandChild1
.Pass());
3342 root
->addChild(child1
.Pass());
3343 root
->addChild(child2
.Pass());
3346 CCLayerImpl
* child1
= root
->children()[0];
3347 CCLayerImpl
* child2
= root
->children()[1];
3348 CCLayerImpl
* grandChild1
= child1
->children()[0];
3350 std::vector
<CCLayerImpl
*> renderSurfaceLayerList
;
3351 int dummyMaxTextureSize
= 512;
3352 CCLayerTreeHostCommon::calculateDrawTransforms(root
.get(), root
->bounds(), 1, 0, dummyMaxTextureSize
, renderSurfaceLayerList
);
3354 // Sanity check the scenario we just created.
3355 ASSERT_TRUE(child1
);
3356 ASSERT_TRUE(child2
);
3357 ASSERT_TRUE(grandChild1
);
3358 ASSERT_TRUE(child1
->renderSurface());
3359 ASSERT_TRUE(child2
->renderSurface());
3360 ASSERT_TRUE(grandChild1
->renderSurface());
3361 ASSERT_EQ(4u, renderSurfaceLayerList
.size());
3362 ASSERT_EQ(3u, root
->renderSurface()->layerList().size()); // The root surface has the root layer, and child1's and child2's renderSurfaces.
3363 ASSERT_EQ(2u, child1
->renderSurface()->layerList().size()); // The child1 surface has the child1 layer and grandChild1's renderSurface.
3364 ASSERT_EQ(1u, child2
->renderSurface()->layerList().size());
3365 ASSERT_EQ(1u, grandChild1
->renderSurface()->layerList().size());
3366 ASSERT_EQ(1, renderSurfaceLayerList
[0]->id()); // root layer
3367 ASSERT_EQ(2, renderSurfaceLayerList
[1]->id()); // child1
3368 ASSERT_EQ(4, renderSurfaceLayerList
[2]->id()); // grandChild1
3369 ASSERT_EQ(3, renderSurfaceLayerList
[3]->id()); // child2
3371 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should find the root layer.
3372 IntPoint testPoint
= IntPoint(1, 1);
3373 CCLayerImpl
* resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3374 ASSERT_TRUE(resultLayer
);
3375 EXPECT_EQ(1, resultLayer
->id());
3377 // At (15, 15), child1 and root are the only layers. child1 is expected to be on top.
3378 testPoint
= IntPoint(15, 15);
3379 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3380 ASSERT_TRUE(resultLayer
);
3381 EXPECT_EQ(2, resultLayer
->id());
3383 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
3384 testPoint
= IntPoint(51, 20);
3385 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3386 ASSERT_TRUE(resultLayer
);
3387 EXPECT_EQ(3, resultLayer
->id());
3389 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
3390 testPoint
= IntPoint(80, 51);
3391 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3392 ASSERT_TRUE(resultLayer
);
3393 EXPECT_EQ(3, resultLayer
->id());
3395 // At (51, 51), all layers overlap each other. child2 is expected to be on top of all other layers.
3396 testPoint
= IntPoint(51, 51);
3397 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3398 ASSERT_TRUE(resultLayer
);
3399 EXPECT_EQ(3, resultLayer
->id());
3401 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to be on top.
3402 testPoint
= IntPoint(20, 51);
3403 resultLayer
= CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint
, renderSurfaceLayerList
);
3404 ASSERT_TRUE(resultLayer
);
3405 EXPECT_EQ(4, resultLayer
->id());
3408 TEST(CCLayerTreeHostCommonTest
, verifyLayerTransformsInHighDPI
)
3410 // Verify draw and screen space transforms of layers not in a surface.
3411 MockContentLayerChromiumClient delegate
;
3412 WebTransformationMatrix identityMatrix
;
3414 scoped_refptr
<ContentLayerChromium
> parent
= createDrawableContentLayerChromium(&delegate
);
3415 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true);
3417 scoped_refptr
<ContentLayerChromium
> child
= createDrawableContentLayerChromium(&delegate
);
3418 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
3420 scoped_refptr
<ContentLayerChromium
> childNoScale
= createDrawableContentLayerChromium(&delegate
);
3421 setLayerPropertiesForTesting(childNoScale
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
3423 parent
->addChild(child
);
3424 parent
->addChild(childNoScale
);
3426 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
3427 int dummyMaxTextureSize
= 512;
3429 const double deviceScaleFactor
= 2.5;
3430 parent
->setContentsScale(deviceScaleFactor
);
3431 child
->setContentsScale(deviceScaleFactor
);
3432 EXPECT_EQ(childNoScale
->contentsScale(), 1);
3434 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), deviceScaleFactor
, dummyMaxTextureSize
, renderSurfaceLayerList
);
3436 EXPECT_EQ(1u, renderSurfaceLayerList
.size());
3438 // Verify parent transforms
3439 WebTransformationMatrix expectedParentTransform
;
3440 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform
, parent
->screenSpaceTransform());
3441 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform
, parent
->drawTransform());
3443 // Verify results of transformed parent rects
3444 FloatRect
parentContentBounds(FloatPoint(), FloatSize(parent
->contentBounds()));
3446 FloatRect parentDrawRect
= CCMathUtil::mapClippedRect(parent
->drawTransform(), parentContentBounds
);
3447 FloatRect parentScreenSpaceRect
= CCMathUtil::mapClippedRect(parent
->screenSpaceTransform(), parentContentBounds
);
3449 FloatRect
expectedParentDrawRect(FloatPoint(), parent
->bounds());
3450 expectedParentDrawRect
.scale(deviceScaleFactor
);
3451 EXPECT_FLOAT_RECT_EQ(expectedParentDrawRect
, parentDrawRect
);
3452 EXPECT_FLOAT_RECT_EQ(expectedParentDrawRect
, parentScreenSpaceRect
);
3454 // Verify child transforms
3455 WebTransformationMatrix expectedChildTransform
;
3456 expectedChildTransform
.translate(deviceScaleFactor
* child
->position().x(), deviceScaleFactor
* child
->position().y());
3457 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->drawTransform());
3458 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform
, child
->screenSpaceTransform());
3460 // Verify results of transformed child rects
3461 FloatRect
childContentBounds(FloatPoint(), FloatSize(child
->contentBounds()));
3463 FloatRect childDrawRect
= CCMathUtil::mapClippedRect(child
->drawTransform(), childContentBounds
);
3464 FloatRect childScreenSpaceRect
= CCMathUtil::mapClippedRect(child
->screenSpaceTransform(), childContentBounds
);
3466 FloatRect
expectedChildDrawRect(FloatPoint(), child
->bounds());
3467 expectedChildDrawRect
.move(child
->position().x(), child
->position().y());
3468 expectedChildDrawRect
.scale(deviceScaleFactor
);
3469 EXPECT_FLOAT_RECT_EQ(expectedChildDrawRect
, childDrawRect
);
3470 EXPECT_FLOAT_RECT_EQ(expectedChildDrawRect
, childScreenSpaceRect
);
3472 // Verify childNoScale transforms
3473 WebTransformationMatrix expectedChildNoScaleTransform
= child
->drawTransform();
3474 // All transforms operate on content rects. The child's content rect
3475 // incorporates device scale, but the childNoScale does not; add it here.
3476 expectedChildNoScaleTransform
.scale(deviceScaleFactor
);
3477 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform
, childNoScale
->drawTransform());
3478 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform
, childNoScale
->screenSpaceTransform());
3481 TEST(CCLayerTreeHostCommonTest
, verifyRenderSurfaceTransformsInHighDPI
)
3483 MockContentLayerChromiumClient delegate
;
3484 WebTransformationMatrix identityMatrix
;
3486 scoped_refptr
<ContentLayerChromium
> parent
= createDrawableContentLayerChromium(&delegate
);
3487 setLayerPropertiesForTesting(parent
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(30, 30), true);
3489 scoped_refptr
<ContentLayerChromium
> child
= createDrawableContentLayerChromium(&delegate
);
3490 setLayerPropertiesForTesting(child
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
3492 WebTransformationMatrix replicaTransform
;
3493 replicaTransform
.scaleNonUniform(1, -1);
3494 scoped_refptr
<ContentLayerChromium
> replica
= createDrawableContentLayerChromium(&delegate
);
3495 setLayerPropertiesForTesting(replica
.get(), replicaTransform
, identityMatrix
, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
3497 // This layer should end up in the same surface as child, with the same draw
3498 // and screen space transforms.
3499 scoped_refptr
<ContentLayerChromium
> duplicateChildNonOwner
= createDrawableContentLayerChromium(&delegate
);
3500 setLayerPropertiesForTesting(duplicateChildNonOwner
.get(), identityMatrix
, identityMatrix
, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true);
3502 parent
->addChild(child
);
3503 child
->addChild(duplicateChildNonOwner
);
3504 child
->setReplicaLayer(replica
.get());
3506 std::vector
<scoped_refptr
<LayerChromium
> > renderSurfaceLayerList
;
3507 int dummyMaxTextureSize
= 512;
3509 const double deviceScaleFactor
= 1.5;
3510 parent
->setContentsScale(deviceScaleFactor
);
3511 child
->setContentsScale(deviceScaleFactor
);
3512 duplicateChildNonOwner
->setContentsScale(deviceScaleFactor
);
3513 replica
->setContentsScale(deviceScaleFactor
);
3515 CCLayerTreeHostCommon::calculateDrawTransforms(parent
.get(), parent
->bounds(), deviceScaleFactor
, dummyMaxTextureSize
, renderSurfaceLayerList
);
3517 // We should have two render surfaces. The root's render surface and child's
3518 // render surface (it needs one because it has a replica layer).
3519 EXPECT_EQ(2u, renderSurfaceLayerList
.size());
3521 WebTransformationMatrix expectedParentTransform
;
3522 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform
, parent
->screenSpaceTransform());
3523 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentTransform
, parent
->drawTransform());
3525 WebTransformationMatrix expectedDrawTransform
;
3526 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedDrawTransform
, child
->drawTransform());
3528 WebTransformationMatrix expectedScreenSpaceTransform
;
3529 expectedScreenSpaceTransform
.translate(deviceScaleFactor
* child
->position().x(), deviceScaleFactor
* child
->position().y());
3530 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedScreenSpaceTransform
, child
->screenSpaceTransform());
3532 WebTransformationMatrix expectedDuplicateChildDrawTransform
= child
->drawTransform();
3533 EXPECT_TRANSFORMATION_MATRIX_EQ(child
->drawTransform(), duplicateChildNonOwner
->drawTransform());
3534 EXPECT_TRANSFORMATION_MATRIX_EQ(child
->screenSpaceTransform(), duplicateChildNonOwner
->screenSpaceTransform());
3535 EXPECT_RECT_EQ(child
->drawableContentRect(), duplicateChildNonOwner
->drawableContentRect());
3536 EXPECT_EQ(child
->contentBounds(), duplicateChildNonOwner
->contentBounds());
3538 WebTransformationMatrix expectedRenderSurfaceDrawTransform
;
3539 expectedRenderSurfaceDrawTransform
.translate(deviceScaleFactor
* child
->position().x(), deviceScaleFactor
* child
->position().y());
3540 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedRenderSurfaceDrawTransform
, child
->renderSurface()->drawTransform());
3542 WebTransformationMatrix expectedSurfaceDrawTransform
;
3543 expectedSurfaceDrawTransform
.translate(deviceScaleFactor
* 2, deviceScaleFactor
* 2);
3544 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform
, child
->renderSurface()->drawTransform());
3546 WebTransformationMatrix expectedSurfaceScreenSpaceTransform
;
3547 expectedSurfaceScreenSpaceTransform
.translate(deviceScaleFactor
* 2, deviceScaleFactor
* 2);
3548 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceScreenSpaceTransform
, child
->renderSurface()->screenSpaceTransform());
3550 WebTransformationMatrix expectedReplicaDrawTransform
;
3551 expectedReplicaDrawTransform
.setM22(-1);
3552 expectedReplicaDrawTransform
.setM41(6);
3553 expectedReplicaDrawTransform
.setM42(6);
3554 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedReplicaDrawTransform
, child
->renderSurface()->replicaDrawTransform());
3556 WebTransformationMatrix expectedReplicaScreenSpaceTransform
;
3557 expectedReplicaScreenSpaceTransform
.setM22(-1);
3558 expectedReplicaScreenSpaceTransform
.setM41(6);
3559 expectedReplicaScreenSpaceTransform
.setM42(6);
3560 EXPECT_TRANSFORMATION_MATRIX_EQ(expectedReplicaScreenSpaceTransform
, child
->renderSurface()->replicaScreenSpaceTransform());
3563 TEST(CCLayerTreeHostCommonTest
, verifySubtreeSearch
)
3565 scoped_refptr
<LayerChromium
> root
= LayerChromium::create();
3566 scoped_refptr
<LayerChromium
> child
= LayerChromium::create();
3567 scoped_refptr
<LayerChromium
> grandChild
= LayerChromium::create();
3568 scoped_refptr
<LayerChromium
> maskLayer
= LayerChromium::create();
3569 scoped_refptr
<LayerChromium
> replicaLayer
= LayerChromium::create();
3571 grandChild
->setReplicaLayer(replicaLayer
.get());
3572 child
->addChild(grandChild
.get());
3573 child
->setMaskLayer(maskLayer
.get());
3574 root
->addChild(child
.get());
3576 int nonexistentId
= -1;
3577 EXPECT_EQ(root
, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), root
->id()));
3578 EXPECT_EQ(child
, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), child
->id()));
3579 EXPECT_EQ(grandChild
, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), grandChild
->id()));
3580 EXPECT_EQ(maskLayer
, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), maskLayer
->id()));
3581 EXPECT_EQ(replicaLayer
, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), replicaLayer
->id()));
3582 EXPECT_EQ(0, CCLayerTreeHostCommon::findLayerInSubtree(root
.get(), nonexistentId
));