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