Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: cc/CCLayerTreeHostCommonTest.cpp

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

Powered by Google App Engine
This is Rietveld 408576698