[chromium] Do not clip root layer's subtree to viewport
[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     parent->setMasksToBounds(true);
676     renderSurface1->addChild(child);
677     renderSurface1->setForceRenderSurface(true);
678
679     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
680     int dummyMaxTextureSize = 512;
681     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
682     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
683
684     // The child layer's content is entirely outside the parent's clip rect, so the intermediate
685     // render surface should not be listed here, even if it was forced to be created. Render surfaces without children or visible
686     // content are unexpected at draw time (e.g. we might try to create a content texture of size 0).
687     ASSERT_TRUE(parent->renderSurface());
688     ASSERT_FALSE(renderSurface1->renderSurface());
689     EXPECT_EQ(1U, renderSurfaceLayerList.size());
690 }
691
692 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
693 {
694     RefPtr<LayerChromium> parent = LayerChromium::create();
695     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
696     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
697
698     const WebTransformationMatrix identityMatrix;
699     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
700     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
701
702     parent->addChild(renderSurface1);
703     renderSurface1->addChild(child);
704     renderSurface1->setForceRenderSurface(true);
705     renderSurface1->setOpacity(0);
706
707     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
708     int dummyMaxTextureSize = 512;
709     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
710     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
711
712     // Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
713     // Also, the drawable content rect should not have been extended by the children.
714     ASSERT_TRUE(parent->renderSurface());
715     EXPECT_EQ(0U, parent->renderSurface()->layerList().size());
716     EXPECT_EQ(1U, renderSurfaceLayerList.size());
717     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
718     EXPECT_EQ(IntRect(), parent->drawableContentRect());
719 }
720
721 TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
722 {
723     RefPtr<LayerChromium> parent = LayerChromium::create();
724     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
725     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
726     renderSurface1->setForceRenderSurface(true);
727
728     const WebTransformationMatrix identityMatrix;
729     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
730     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
731     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
732
733     parent->addChild(renderSurface1);
734     renderSurface1->addChild(child);
735
736     // Sanity check before the actual test
737     EXPECT_FALSE(parent->renderSurface());
738     EXPECT_FALSE(renderSurface1->renderSurface());
739
740     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
741     int dummyMaxTextureSize = 512;
742     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
743
744     // The root layer always creates a renderSurface
745     EXPECT_TRUE(parent->renderSurface());
746     EXPECT_TRUE(renderSurface1->renderSurface());
747     EXPECT_EQ(2U, renderSurfaceLayerList.size());
748
749     renderSurfaceLayerList.clear();
750     renderSurface1->setForceRenderSurface(false);
751     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
752     EXPECT_TRUE(parent->renderSurface());
753     EXPECT_FALSE(renderSurface1->renderSurface());
754     EXPECT_EQ(1U, renderSurfaceLayerList.size());
755 }
756
757 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithDirectContainer)
758 {
759     // This test checks for correct scroll compensation when the fixed-position container
760     // is the direct parent of the fixed-position layer.
761
762     DebugScopedSetImplThread scopedImplThread;
763     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
764     CCLayerImpl* child = root->children()[0].get();
765     CCLayerImpl* grandChild = child->children()[0].get();
766
767     child->setIsContainerForFixedPositionLayers(true);
768     grandChild->setFixedToContainerLayer(true);
769
770     // Case 1: scrollDelta of 0, 0
771     child->setScrollDelta(IntSize(0, 0));
772     executeCalculateDrawTransformsAndVisibility(root.get());
773
774     WebTransformationMatrix expectedChildTransform;
775     WebTransformationMatrix expectedGrandChildTransform = expectedChildTransform;
776
777     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
778     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
779
780     // Case 2: scrollDelta of 10, 10
781     child->setScrollDelta(IntSize(10, 10));
782     executeCalculateDrawTransformsAndVisibility(root.get());
783
784     // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
785     expectedChildTransform.makeIdentity();
786     expectedChildTransform.translate(-10, -10);
787
788     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
789     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
790 }
791
792 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithTransformedDirectContainer)
793 {
794     // This test checks for correct scroll compensation when the fixed-position container
795     // is the direct parent of the fixed-position layer, but that container is transformed.
796     // In this case, the fixed position element inherits the container's transform,
797     // but the scrollDelta that has to be undone should not be affected by that transform.
798     //
799     // Transforms are in general non-commutative; using something like a non-uniform scale
800     // helps to verify that translations and non-uniform scales are applied in the correct
801     // order.
802
803     DebugScopedSetImplThread scopedImplThread;
804     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
805     CCLayerImpl* child = root->children()[0].get();
806     CCLayerImpl* grandChild = child->children()[0].get();
807
808     // This scale will cause child and grandChild to be effectively 200 x 800 with respect to the renderTarget.
809     WebTransformationMatrix nonUniformScale;
810     nonUniformScale.scaleNonUniform(2, 8);
811     child->setTransform(nonUniformScale);
812
813     child->setIsContainerForFixedPositionLayers(true);
814     grandChild->setFixedToContainerLayer(true);
815
816     // Case 1: scrollDelta of 0, 0
817     child->setScrollDelta(IntSize(0, 0));
818     executeCalculateDrawTransformsAndVisibility(root.get());
819
820     WebTransformationMatrix expectedChildTransform;
821     expectedChildTransform.multiply(nonUniformScale);
822
823     WebTransformationMatrix expectedGrandChildTransform = expectedChildTransform;
824
825     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
826     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
827
828     // Case 2: scrollDelta of 10, 20
829     child->setScrollDelta(IntSize(10, 20));
830     executeCalculateDrawTransformsAndVisibility(root.get());
831
832     // The child should be affected by scrollDelta, but the fixed position grandChild should not be affected.
833     expectedChildTransform.makeIdentity();
834     expectedChildTransform.translate(-10, -20); // scrollDelta
835     expectedChildTransform.multiply(nonUniformScale);
836
837     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
838     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
839 }
840
841 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithDistantContainer)
842 {
843     // This test checks for correct scroll compensation when the fixed-position container
844     // is NOT the direct parent of the fixed-position layer.
845     DebugScopedSetImplThread scopedImplThread;
846
847     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
848     CCLayerImpl* child = root->children()[0].get();
849     CCLayerImpl* grandChild = child->children()[0].get();
850     CCLayerImpl* greatGrandChild = grandChild->children()[0].get();
851
852     child->setIsContainerForFixedPositionLayers(true);
853     grandChild->setPosition(FloatPoint(8, 6));
854     greatGrandChild->setFixedToContainerLayer(true);
855
856     // Case 1: scrollDelta of 0, 0
857     child->setScrollDelta(IntSize(0, 0));
858     executeCalculateDrawTransformsAndVisibility(root.get());
859
860     WebTransformationMatrix expectedChildTransform;
861     WebTransformationMatrix expectedGrandChildTransform;
862     expectedGrandChildTransform.translate(8, 6);
863
864     WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChildTransform;
865
866     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
867     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
868     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
869
870     // Case 2: scrollDelta of 10, 10
871     child->setScrollDelta(IntSize(10, 10));
872     executeCalculateDrawTransformsAndVisibility(root.get());
873
874     // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
875     expectedChildTransform.makeIdentity();
876     expectedChildTransform.translate(-10, -10);
877     expectedGrandChildTransform.makeIdentity();
878     expectedGrandChildTransform.translate(-2, -4);
879     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
880     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
881     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
882 }
883
884 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms)
885 {
886     // This test checks for correct scroll compensation when the fixed-position container
887     // is NOT the direct parent of the fixed-position layer, and the hierarchy has various
888     // transforms that have to be processed in the correct order.
889     DebugScopedSetImplThread scopedImplThread;
890
891     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
892     CCLayerImpl* child = root->children()[0].get();
893     CCLayerImpl* grandChild = child->children()[0].get();
894     CCLayerImpl* greatGrandChild = grandChild->children()[0].get();
895
896     WebTransformationMatrix rotationAboutZ;
897     rotationAboutZ.rotate3d(0, 0, 90);
898
899     child->setIsContainerForFixedPositionLayers(true);
900     child->setTransform(rotationAboutZ);
901     grandChild->setPosition(FloatPoint(8, 6));
902     grandChild->setTransform(rotationAboutZ);
903     greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget.
904
905     // Case 1: scrollDelta of 0, 0
906     child->setScrollDelta(IntSize(0, 0));
907     executeCalculateDrawTransformsAndVisibility(root.get());
908
909     WebTransformationMatrix expectedChildTransform;
910     expectedChildTransform.multiply(rotationAboutZ);
911
912     WebTransformationMatrix expectedGrandChildTransform;
913     expectedGrandChildTransform.multiply(rotationAboutZ); // child's local transform is inherited
914     expectedGrandChildTransform.translate(8, 6); // translation because of position occurs before layer's local transform.
915     expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local transform
916
917     WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChildTransform;
918
919     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
920     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
921     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
922
923     // Case 2: scrollDelta of 10, 20
924     child->setScrollDelta(IntSize(10, 20));
925     executeCalculateDrawTransformsAndVisibility(root.get());
926
927     // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
928     expectedChildTransform.makeIdentity();
929     expectedChildTransform.translate(-10, -20); // scrollDelta
930     expectedChildTransform.multiply(rotationAboutZ);
931
932     expectedGrandChildTransform.makeIdentity();
933     expectedGrandChildTransform.translate(-10, -20); // child's scrollDelta is inherited
934     expectedGrandChildTransform.multiply(rotationAboutZ); // child's local transform is inherited
935     expectedGrandChildTransform.translate(8, 6); // translation because of position occurs before layer's local transform.
936     expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local transform
937
938     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
939     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
940     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
941 }
942
943 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas)
944 {
945     // This test checks for correct scroll compensation when the fixed-position container
946     // has multiple ancestors that have nonzero scrollDelta before reaching the space where the layer is fixed.
947     // In this test, each scrollDelta occurs in a different space because of each layer's local transform.
948     // This test checks for correct scroll compensation when the fixed-position container
949     // is NOT the direct parent of the fixed-position layer, and the hierarchy has various
950     // transforms that have to be processed in the correct order.
951     DebugScopedSetImplThread scopedImplThread;
952
953     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
954     CCLayerImpl* child = root->children()[0].get();
955     CCLayerImpl* grandChild = child->children()[0].get();
956     CCLayerImpl* greatGrandChild = grandChild->children()[0].get();
957
958     WebTransformationMatrix rotationAboutZ;
959     rotationAboutZ.rotate3d(0, 0, 90);
960
961     child->setIsContainerForFixedPositionLayers(true);
962     child->setTransform(rotationAboutZ);
963     grandChild->setPosition(FloatPoint(8, 6));
964     grandChild->setTransform(rotationAboutZ);
965     greatGrandChild->setFixedToContainerLayer(true); // greatGrandChild is positioned upside-down with respect to the renderTarget.
966
967     // Case 1: scrollDelta of 0, 0
968     child->setScrollDelta(IntSize(0, 0));
969     executeCalculateDrawTransformsAndVisibility(root.get());
970
971     WebTransformationMatrix expectedChildTransform;
972     expectedChildTransform.multiply(rotationAboutZ);
973
974     WebTransformationMatrix expectedGrandChildTransform;
975     expectedGrandChildTransform.multiply(rotationAboutZ); // child's local transform is inherited
976     expectedGrandChildTransform.translate(8, 6); // translation because of position occurs before layer's local transform.
977     expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local transform
978
979     WebTransformationMatrix expectedGreatGrandChildTransform = expectedGrandChildTransform;
980
981     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
982     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
983     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
984
985     // Case 2: scrollDelta of 10, 20
986     child->setScrollDelta(IntSize(10, 0));
987     grandChild->setScrollDelta(IntSize(5, 0));
988     executeCalculateDrawTransformsAndVisibility(root.get());
989
990     // Here the child and grandChild are affected by scrollDelta, but the fixed position greatGrandChild should not be affected.
991     expectedChildTransform.makeIdentity();
992     expectedChildTransform.translate(-10, 0); // scrollDelta
993     expectedChildTransform.multiply(rotationAboutZ);
994
995     expectedGrandChildTransform.makeIdentity();
996     expectedGrandChildTransform.translate(-10, 0); // child's scrollDelta is inherited
997     expectedGrandChildTransform.multiply(rotationAboutZ); // child's local transform is inherited
998     expectedGrandChildTransform.translate(-5, 0); // grandChild's scrollDelta
999     expectedGrandChildTransform.translate(8, 6); // translation because of position occurs before layer's local transform.
1000     expectedGrandChildTransform.multiply(rotationAboutZ); // grandChild's local transform
1001
1002     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1003     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1004     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
1005 }
1006
1007 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithIntermediateSurfaceAndTransforms)
1008 {
1009     // This test checks for correct scroll compensation when the fixed-position container
1010     // contributes to a different renderSurface than the fixed-position layer. In this
1011     // case, the surface drawTransforms also have to be accounted for when checking the
1012     // scrollDelta.
1013     DebugScopedSetImplThread scopedImplThread;
1014
1015     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
1016     CCLayerImpl* child = root->children()[0].get();
1017     CCLayerImpl* grandChild = child->children()[0].get();
1018     CCLayerImpl* greatGrandChild = grandChild->children()[0].get();
1019
1020     child->setIsContainerForFixedPositionLayers(true);
1021     grandChild->setPosition(FloatPoint(8, 6));
1022     grandChild->setForceRenderSurface(true);
1023     greatGrandChild->setFixedToContainerLayer(true);
1024     greatGrandChild->setDrawsContent(true);
1025
1026     WebTransformationMatrix rotationAboutZ;
1027     rotationAboutZ.rotate3d(0, 0, 90);
1028     grandChild->setTransform(rotationAboutZ);
1029
1030     // Case 1: scrollDelta of 0, 0
1031     child->setScrollDelta(IntSize(0, 0));
1032     executeCalculateDrawTransformsAndVisibility(root.get());
1033
1034     WebTransformationMatrix expectedChildTransform;
1035     WebTransformationMatrix expectedSurfaceDrawTransform;
1036     expectedSurfaceDrawTransform.translate(8, 6);
1037     expectedSurfaceDrawTransform.multiply(rotationAboutZ);
1038     WebTransformationMatrix expectedGrandChildTransform;
1039     WebTransformationMatrix expectedGreatGrandChildTransform;
1040     ASSERT_TRUE(grandChild->renderSurface());
1041     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1042     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, grandChild->renderSurface()->drawTransform());
1043     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1044     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
1045
1046     // Case 2: scrollDelta of 10, 30
1047     child->setScrollDelta(IntSize(10, 30));
1048     executeCalculateDrawTransformsAndVisibility(root.get());
1049
1050     // Here the grandChild remains unchanged, because it scrolls along with the
1051     // renderSurface, and the translation is actually in the renderSurface. But, the fixed
1052     // position greatGrandChild is more awkward: its actually being drawn with respect to
1053     // the renderSurface, but it needs to remain fixed with resepct to a container beyond
1054     // that surface. So, the net result is that, unlike previous tests where the fixed
1055     // position layer's transform remains unchanged, here the fixed position layer's
1056     // transform explicitly contains the translation that cancels out the scroll.
1057     expectedChildTransform.makeIdentity();
1058     expectedChildTransform.translate(-10, -30); // scrollDelta
1059
1060     expectedSurfaceDrawTransform.makeIdentity();
1061     expectedSurfaceDrawTransform.translate(-10, -30); // scrollDelta
1062     expectedSurfaceDrawTransform.translate(8, 6);
1063     expectedSurfaceDrawTransform.multiply(rotationAboutZ);
1064
1065     // The rotation and its inverse are needed to place the scrollDelta compensation in
1066     // the correct space. This test will fail if the rotation/inverse are backwards, too,
1067     // so it requires perfect order of operations.
1068     expectedGreatGrandChildTransform.makeIdentity();
1069     expectedGreatGrandChildTransform.multiply(rotationAboutZ.inverse());
1070     expectedGreatGrandChildTransform.translate(10, 30); // explicit canceling out the scrollDelta that gets embedded in the fixed position layer's surface.
1071     expectedGreatGrandChildTransform.multiply(rotationAboutZ);
1072
1073     ASSERT_TRUE(grandChild->renderSurface());
1074     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1075     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, grandChild->renderSurface()->drawTransform());
1076     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1077     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
1078 }
1079
1080 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces)
1081 {
1082     // This test checks for correct scroll compensation when the fixed-position container
1083     // contributes to a different renderSurface than the fixed-position layer, with
1084     // additional renderSurfaces in-between. This checks that the conversion to ancestor
1085     // surfaces is accumulated properly in the final matrix transform.
1086     DebugScopedSetImplThread scopedImplThread;
1087
1088     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
1089     CCLayerImpl* child = root->children()[0].get();
1090     CCLayerImpl* grandChild = child->children()[0].get();
1091     CCLayerImpl* greatGrandChild = grandChild->children()[0].get();
1092
1093     // Add one more layer to the test tree for this scenario.
1094     {
1095         WebTransformationMatrix identity;
1096         OwnPtr<CCLayerImpl> fixedPositionChild = CCLayerImpl::create(5);
1097         setLayerPropertiesForTesting(fixedPositionChild.get(), identity, identity, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1098         greatGrandChild->addChild(fixedPositionChild.release());
1099     }
1100     CCLayerImpl* fixedPositionChild = greatGrandChild->children()[0].get();
1101
1102     // Actually set up the scenario here.
1103     child->setIsContainerForFixedPositionLayers(true);
1104     grandChild->setPosition(FloatPoint(8, 6));
1105     grandChild->setForceRenderSurface(true);
1106     greatGrandChild->setPosition(FloatPoint(40, 60));
1107     greatGrandChild->setForceRenderSurface(true);
1108     fixedPositionChild->setFixedToContainerLayer(true);
1109     fixedPositionChild->setDrawsContent(true);
1110
1111     // The additional rotations, which are non-commutative with translations, help to
1112     // verify that we have correct order-of-operations in the final scroll compensation.
1113     // Note that rotating about the center of the layer ensures we do not accidentally
1114     // clip away layers that we want to test.
1115     WebTransformationMatrix rotationAboutZ;
1116     rotationAboutZ.translate(50, 50);
1117     rotationAboutZ.rotate3d(0, 0, 90);
1118     rotationAboutZ.translate(-50, -50);
1119     grandChild->setTransform(rotationAboutZ);
1120     greatGrandChild->setTransform(rotationAboutZ);
1121
1122     // Case 1: scrollDelta of 0, 0
1123     child->setScrollDelta(IntSize(0, 0));
1124     executeCalculateDrawTransformsAndVisibility(root.get());
1125
1126     WebTransformationMatrix expectedChildTransform;
1127
1128     WebTransformationMatrix expectedGrandChildSurfaceDrawTransform;
1129     expectedGrandChildSurfaceDrawTransform.translate(8, 6);
1130     expectedGrandChildSurfaceDrawTransform.multiply(rotationAboutZ);
1131
1132     WebTransformationMatrix expectedGrandChildTransform;
1133
1134     WebTransformationMatrix expectedGreatGrandChildSurfaceDrawTransform;
1135     expectedGreatGrandChildSurfaceDrawTransform.translate(40, 60);
1136     expectedGreatGrandChildSurfaceDrawTransform.multiply(rotationAboutZ);
1137
1138     WebTransformationMatrix expectedGreatGrandChildTransform;
1139
1140     WebTransformationMatrix expectedFixedPositionChildTransform;
1141
1142     ASSERT_TRUE(grandChild->renderSurface());
1143     ASSERT_TRUE(greatGrandChild->renderSurface());
1144     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1145     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform, grandChild->renderSurface()->drawTransform());
1146     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1147     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform, greatGrandChild->renderSurface()->drawTransform());
1148     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
1149     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform, fixedPositionChild->drawTransform());
1150
1151     // Case 2: scrollDelta of 10, 30
1152     child->setScrollDelta(IntSize(10, 30));
1153     executeCalculateDrawTransformsAndVisibility(root.get());
1154
1155     expectedChildTransform.makeIdentity();
1156     expectedChildTransform.translate(-10, -30); // scrollDelta
1157
1158     expectedGrandChildSurfaceDrawTransform.makeIdentity();
1159     expectedGrandChildSurfaceDrawTransform.translate(-10, -30); // scrollDelta
1160     expectedGrandChildSurfaceDrawTransform.translate(8, 6);
1161     expectedGrandChildSurfaceDrawTransform.multiply(rotationAboutZ);
1162
1163     // grandChild, greatGrandChild, and greatGrandChild's surface are not expected to
1164     // change, since they are all not fixed, and they are all drawn with respect to
1165     // grandChild's surface that already has the scrollDelta accounted for.
1166
1167     // But the great-great grandchild, "fixedPositionChild", should have a transform that explicitly cancels out the scrollDelta.
1168     // The expected transform is:
1169     //   compoundDrawTransform.inverse() * translate(positive scrollDelta) * compoundOriginTransform
1170     WebTransformationMatrix compoundDrawTransform; // transform from greatGrandChildSurface's origin to the root surface.
1171     compoundDrawTransform.translate(8, 6); // origin translation of grandChild
1172     compoundDrawTransform.multiply(rotationAboutZ); // rotation of grandChild
1173     compoundDrawTransform.translate(40, 60); // origin translation of greatGrandChild
1174     compoundDrawTransform.multiply(rotationAboutZ); // rotation of greatGrandChild
1175
1176     expectedFixedPositionChildTransform.makeIdentity();
1177     expectedFixedPositionChildTransform.multiply(compoundDrawTransform.inverse());
1178     expectedFixedPositionChildTransform.translate(10, 30); // explicit canceling out the scrollDelta that gets embedded in the fixed position layer's surface.
1179     expectedFixedPositionChildTransform.multiply(compoundDrawTransform);
1180
1181     ASSERT_TRUE(grandChild->renderSurface());
1182     ASSERT_TRUE(greatGrandChild->renderSurface());
1183     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1184     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildSurfaceDrawTransform, grandChild->renderSurface()->drawTransform());
1185     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1186     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildSurfaceDrawTransform, greatGrandChild->renderSurface()->drawTransform());
1187     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGreatGrandChildTransform, greatGrandChild->drawTransform());
1188     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedFixedPositionChildTransform, fixedPositionChild->drawTransform());
1189 }
1190
1191 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface)
1192 {
1193     // This test checks for correct scroll compensation when the fixed-position container
1194     // itself has a renderSurface. In this case, the container layer should be treated
1195     // like a layer that contributes to a renderTarget, and that renderTarget
1196     // is completely irrelevant; it should not affect the scroll compensation.
1197     DebugScopedSetImplThread scopedImplThread;
1198
1199     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
1200     CCLayerImpl* child = root->children()[0].get();
1201     CCLayerImpl* grandChild = child->children()[0].get();
1202
1203     child->setIsContainerForFixedPositionLayers(true);
1204     child->setForceRenderSurface(true);
1205     grandChild->setFixedToContainerLayer(true);
1206     grandChild->setDrawsContent(true);
1207
1208     // Case 1: scrollDelta of 0, 0
1209     child->setScrollDelta(IntSize(0, 0));
1210     executeCalculateDrawTransformsAndVisibility(root.get());
1211
1212     WebTransformationMatrix expectedSurfaceDrawTransform;
1213     expectedSurfaceDrawTransform.translate(0, 0);
1214     WebTransformationMatrix expectedChildTransform;
1215     WebTransformationMatrix expectedGrandChildTransform;
1216     ASSERT_TRUE(child->renderSurface());
1217     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, child->renderSurface()->drawTransform());
1218     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1219     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1220
1221     // Case 2: scrollDelta of 10, 10
1222     child->setScrollDelta(IntSize(10, 10));
1223     executeCalculateDrawTransformsAndVisibility(root.get());
1224
1225     // The surface is translated by scrollDelta, the child transform doesn't change
1226     // because it scrolls along with the surface, but the fixed position grandChild
1227     // needs to compensate for the scroll translation.
1228     expectedSurfaceDrawTransform.makeIdentity();
1229     expectedSurfaceDrawTransform.translate(-10, -10);
1230     expectedGrandChildTransform.makeIdentity();
1231     expectedGrandChildTransform.translate(10, 10);
1232
1233     ASSERT_TRUE(child->renderSurface());
1234     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedSurfaceDrawTransform, child->renderSurface()->drawTransform());
1235     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1236     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1237 }
1238
1239 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer)
1240 {
1241     // This test checks the scenario where a fixed-position layer also happens to be a
1242     // container itself for a descendant fixed position layer. In particular, the layer
1243     // should not accidentally be fixed to itself.
1244     DebugScopedSetImplThread scopedImplThread;
1245
1246     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
1247     CCLayerImpl* child = root->children()[0].get();
1248     CCLayerImpl* grandChild = child->children()[0].get();
1249
1250     child->setIsContainerForFixedPositionLayers(true);
1251     grandChild->setFixedToContainerLayer(true);
1252
1253     // This should not confuse the grandChild. If correct, the grandChild would still be considered fixed to its container (i.e. "child").
1254     grandChild->setIsContainerForFixedPositionLayers(true);
1255
1256     // Case 1: scrollDelta of 0, 0
1257     child->setScrollDelta(IntSize(0, 0));
1258     executeCalculateDrawTransformsAndVisibility(root.get());
1259
1260     WebTransformationMatrix expectedChildTransform;
1261     WebTransformationMatrix expectedGrandChildTransform;
1262     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1263     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1264
1265     // Case 2: scrollDelta of 10, 10
1266     child->setScrollDelta(IntSize(10, 10));
1267     executeCalculateDrawTransformsAndVisibility(root.get());
1268
1269     // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
1270     expectedChildTransform.makeIdentity();
1271     expectedChildTransform.translate(-10, -10);
1272     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1273     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1274 }
1275
1276 TEST(CCLayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerThatHasNoContainer)
1277 {
1278     // This test checks scroll compensation when a fixed-position layer does not find any
1279     // ancestor that is a "containerForFixedPositionLayers". In this situation, the layer should
1280     // be fixed to the viewport -- not the rootLayer, which may have transforms of its own.
1281     DebugScopedSetImplThread scopedImplThread;
1282
1283     OwnPtr<CCLayerImpl> root = createTreeForFixedPositionTests();
1284     CCLayerImpl* child = root->children()[0].get();
1285     CCLayerImpl* grandChild = child->children()[0].get();
1286
1287     WebTransformationMatrix rotationByZ;
1288     rotationByZ.rotate3d(0, 0, 90);
1289
1290     root->setTransform(rotationByZ);
1291     grandChild->setFixedToContainerLayer(true);
1292
1293     // Case 1: root scrollDelta of 0, 0
1294     root->setScrollDelta(IntSize(0, 0));
1295     executeCalculateDrawTransformsAndVisibility(root.get());
1296
1297     WebTransformationMatrix expectedChildTransform;
1298     expectedChildTransform.multiply(rotationByZ);
1299
1300     WebTransformationMatrix expectedGrandChildTransform;
1301     expectedGrandChildTransform.multiply(rotationByZ);
1302
1303     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1304     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1305
1306     // Case 2: root scrollDelta of 10, 10
1307     root->setScrollDelta(IntSize(10, 10));
1308     executeCalculateDrawTransformsAndVisibility(root.get());
1309
1310     // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
1311     expectedChildTransform.makeIdentity();
1312     expectedChildTransform.translate(-10, -10); // the scrollDelta
1313     expectedChildTransform.multiply(rotationByZ);
1314
1315     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
1316     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
1317 }
1318
1319 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
1320 {
1321     // The entire subtree of layers that are outside the clipRect should be culled away,
1322     // and should not affect the renderSurfaceLayerList.
1323     //
1324     // The test tree is set up as follows:
1325     //  - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
1326     //  - parent is a large container layer.
1327     //  - child has masksToBounds=true to cause clipping.
1328     //  - grandChild is positioned outside of the child's bounds
1329     //  - greatGrandChild is also kept outside child's bounds.
1330     //
1331     // In this configuration, grandChild and greatGrandChild are completely outside the
1332     // clipRect, and they should never get scheduled on the list of renderSurfaces.
1333     //
1334
1335     const WebTransformationMatrix identityMatrix;
1336     RefPtr<LayerChromium> parent = LayerChromium::create();
1337     RefPtr<LayerChromium> child = LayerChromium::create();
1338     RefPtr<LayerChromium> grandChild = LayerChromium::create();
1339     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
1340     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1341     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1342     parent->addChild(child);
1343     child->addChild(grandChild);
1344     grandChild->addChild(greatGrandChild);
1345
1346     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
1347     // even though grandChild and greatGrandChild should be clipped.
1348     child->addChild(leafNode1);
1349     greatGrandChild->addChild(leafNode2);
1350
1351     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1352     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1353     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1354     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1355     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1356     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1357
1358     child->setMasksToBounds(true);
1359     child->setOpacity(0.4f);
1360     grandChild->setOpacity(0.5);
1361     greatGrandChild->setOpacity(0.4f);
1362
1363     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1364     int dummyMaxTextureSize = 512;
1365     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
1366     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
1367
1368
1369     ASSERT_EQ(2U, renderSurfaceLayerList.size());
1370     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1371     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
1372 }
1373
1374 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
1375 {
1376     // When a renderSurface has a clipRect, it is used to clip the contentRect
1377     // of the surface. When the renderSurface is animating its transforms, then
1378     // the contentRect's position in the clipRect is not defined on the main
1379     // thread, and its contentRect should not be clipped.
1380
1381     // The test tree is set up as follows:
1382     //  - parent is a container layer that masksToBounds=true to cause clipping.
1383     //  - child is a renderSurface, which has a clipRect set to the bounds of the parent.
1384     //  - grandChild is a renderSurface, and the only visible content in child. It is positioned outside of the clipRect from parent.
1385
1386     // In this configuration, grandChild should be outside the clipped
1387     // contentRect of the child, making grandChild not appear in the
1388     // renderSurfaceLayerList. However, when we place an animation on the child,
1389     // this clipping should be avoided and we should keep the grandChild
1390     // in the renderSurfaceLayerList.
1391
1392     const WebTransformationMatrix identityMatrix;
1393     RefPtr<LayerChromium> parent = LayerChromium::create();
1394     RefPtr<LayerChromium> child = LayerChromium::create();
1395     RefPtr<LayerChromium> grandChild = LayerChromium::create();
1396     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode = adoptRef(new LayerChromiumWithForcedDrawsContent());
1397     parent->addChild(child);
1398     child->addChild(grandChild);
1399     grandChild->addChild(leafNode);
1400
1401     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1402     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1403     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false);
1404     setLayerPropertiesForTesting(leafNode.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1405
1406     parent->setMasksToBounds(true);
1407     child->setOpacity(0.4f);
1408     grandChild->setOpacity(0.4f);
1409
1410     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1411     int dummyMaxTextureSize = 512;
1412     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
1413
1414     // Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
1415     ASSERT_EQ(1U, renderSurfaceLayerList.size());
1416     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1417
1418     // Now put an animating transform on child.
1419     addAnimatedTransformToController(*child->layerAnimationController(), 10, 30, 0);
1420
1421     parent->clearRenderSurface();
1422     child->clearRenderSurface();
1423     grandChild->clearRenderSurface();
1424     renderSurfaceLayerList.clear();
1425
1426     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
1427
1428     // With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
1429     ASSERT_EQ(3U, renderSurfaceLayerList.size());
1430     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1431     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
1432     EXPECT_EQ(grandChild->id(), renderSurfaceLayerList[2]->id());
1433 }
1434
1435 TEST(CCLayerTreeHostCommonTest, verifyDrawableContentRectForLayers)
1436 {
1437     // Verify that layers get the appropriate drawableContentRect when their parent masksToBounds is true.
1438     //
1439     //   grandChild1 - completely inside the region; drawableContentRect should be the layer rect expressed in target space.
1440     //   grandChild2 - partially clipped but NOT masksToBounds; the clipRect will be the intersection of layerBounds and the mask region.
1441     //   grandChild3 - partially clipped and masksToBounds; the drawableContentRect will still be the intersection of layerBounds and the mask region.
1442     //   grandChild4 - outside parent's clipRect; the drawableContentRect should be empty.
1443     //
1444
1445     const WebTransformationMatrix identityMatrix;
1446     RefPtr<LayerChromium> parent = LayerChromium::create();
1447     RefPtr<LayerChromium> child = LayerChromium::create();
1448     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
1449     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
1450     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
1451     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
1452
1453     parent->addChild(child);
1454     child->addChild(grandChild1);
1455     child->addChild(grandChild2);
1456     child->addChild(grandChild3);
1457     child->addChild(grandChild4);
1458
1459     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1460     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1461     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1462     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1463     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1464     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1465
1466     child->setMasksToBounds(true);
1467     grandChild3->setMasksToBounds(true);
1468
1469     // Force everyone to be a render surface.
1470     child->setOpacity(0.4f);
1471     grandChild1->setOpacity(0.5);
1472     grandChild2->setOpacity(0.5);
1473     grandChild3->setOpacity(0.5);
1474     grandChild4->setOpacity(0.5);
1475
1476     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1477     int dummyMaxTextureSize = 512;
1478     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
1479     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
1480
1481     EXPECT_INT_RECT_EQ(IntRect(IntPoint(5, 5), IntSize(10, 10)), grandChild1->drawableContentRect());
1482     EXPECT_INT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->drawableContentRect());
1483     EXPECT_INT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->drawableContentRect());
1484     EXPECT_TRUE(grandChild4->drawableContentRect().isEmpty());
1485 }
1486
1487 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
1488 {
1489     // Verify that renderSurfaces (and their layers) get the appropriate clipRects when their parent masksToBounds is true.
1490     //
1491     // Layers that own renderSurfaces (at least for now) do not inherit any clipping;
1492     // instead the surface will enforce the clip for the entire subtree. They may still
1493     // have a clipRect of their own layer bounds, however, if masksToBounds was true.
1494     //
1495
1496     const WebTransformationMatrix identityMatrix;
1497     RefPtr<LayerChromium> parent = LayerChromium::create();
1498     RefPtr<LayerChromium> child = LayerChromium::create();
1499     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
1500     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
1501     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
1502     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
1503     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1504     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1505     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode3 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1506     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode4 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1507
1508     parent->addChild(child);
1509     child->addChild(grandChild1);
1510     child->addChild(grandChild2);
1511     child->addChild(grandChild3);
1512     child->addChild(grandChild4);
1513
1514     // the leaf nodes ensure that these grandChildren become renderSurfaces for this test.
1515     grandChild1->addChild(leafNode1);
1516     grandChild2->addChild(leafNode2);
1517     grandChild3->addChild(leafNode3);
1518     grandChild4->addChild(leafNode4);
1519
1520     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1521     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1522     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1523     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1524     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1525     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1526     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1527     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1528     setLayerPropertiesForTesting(leafNode3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1529     setLayerPropertiesForTesting(leafNode4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1530
1531     child->setMasksToBounds(true);
1532     grandChild3->setMasksToBounds(true);
1533     grandChild4->setMasksToBounds(true);
1534
1535     // Force everyone to be a render surface.
1536     child->setOpacity(0.4f);
1537     grandChild1->setOpacity(0.5);
1538     grandChild2->setOpacity(0.5);
1539     grandChild3->setOpacity(0.5);
1540     grandChild4->setOpacity(0.5);
1541
1542     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1543     int dummyMaxTextureSize = 512;
1544     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
1545     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
1546
1547     ASSERT_TRUE(grandChild1->renderSurface());
1548     ASSERT_TRUE(grandChild2->renderSurface());
1549     ASSERT_TRUE(grandChild3->renderSurface());
1550     EXPECT_FALSE(grandChild4->renderSurface()); // Because grandChild4 is entirely clipped, it is expected to not have a renderSurface.
1551
1552     // Surfaces are clipped by their parent, but un-affected by the owning layer's masksToBounds.
1553     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1->renderSurface()->clipRect());
1554     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2->renderSurface()->clipRect());
1555     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3->renderSurface()->clipRect());
1556 }
1557
1558 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
1559 {
1560     RefPtr<LayerChromium> parent = LayerChromium::create();
1561     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
1562     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
1563     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
1564     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
1565     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
1566     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
1567     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1568     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1569     parent->addChild(renderSurface1);
1570     parent->addChild(childOfRoot);
1571     renderSurface1->addChild(childOfRS1);
1572     renderSurface1->addChild(renderSurface2);
1573     renderSurface2->addChild(childOfRS2);
1574     childOfRoot->addChild(grandChildOfRoot);
1575     childOfRS1->addChild(grandChildOfRS1);
1576     childOfRS2->addChild(grandChildOfRS2);
1577
1578     // Make our render surfaces.
1579     renderSurface1->setForceRenderSurface(true);
1580     renderSurface2->setForceRenderSurface(true);
1581
1582     // Put an animated opacity on the render surface.
1583     addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false);
1584
1585     // Also put an animated opacity on a layer without descendants.
1586     addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false);
1587
1588     WebTransformationMatrix layerTransform;
1589     layerTransform.translate(1, 1);
1590     WebTransformationMatrix sublayerTransform;
1591     sublayerTransform.scale3d(10, 1, 1);
1592
1593     // Put a transform animation on the render surface.
1594     addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
1595
1596     // Also put transform animations on grandChildOfRoot, and grandChildOfRS2
1597     addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0);
1598     addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0);
1599
1600     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1601     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1602     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1603     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1604     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1605     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1606     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1607     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1608     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(2.5, 0), IntSize(10, 10), false);
1609
1610     executeCalculateDrawTransformsAndVisibility(parent.get());
1611
1612     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
1613     //
1614     ASSERT_TRUE(parent->renderSurface());
1615     ASSERT_FALSE(childOfRoot->renderSurface());
1616     ASSERT_FALSE(grandChildOfRoot->renderSurface());
1617
1618     ASSERT_TRUE(renderSurface1->renderSurface());
1619     ASSERT_FALSE(childOfRS1->renderSurface());
1620     ASSERT_FALSE(grandChildOfRS1->renderSurface());
1621
1622     ASSERT_TRUE(renderSurface2->renderSurface());
1623     ASSERT_FALSE(childOfRS2->renderSurface());
1624     ASSERT_FALSE(grandChildOfRS2->renderSurface());
1625
1626     // Verify all renderTarget accessors
1627     //
1628     EXPECT_EQ(parent, parent->renderTarget());
1629     EXPECT_EQ(parent, childOfRoot->renderTarget());
1630     EXPECT_EQ(parent, grandChildOfRoot->renderTarget());
1631
1632     EXPECT_EQ(renderSurface1, renderSurface1->renderTarget());
1633     EXPECT_EQ(renderSurface1, childOfRS1->renderTarget());
1634     EXPECT_EQ(renderSurface1, grandChildOfRS1->renderTarget());
1635
1636     EXPECT_EQ(renderSurface2, renderSurface2->renderTarget());
1637     EXPECT_EQ(renderSurface2, childOfRS2->renderTarget());
1638     EXPECT_EQ(renderSurface2, grandChildOfRS2->renderTarget());
1639
1640     // Verify drawOpacityIsAnimating values
1641     //
1642     EXPECT_FALSE(parent->drawOpacityIsAnimating());
1643     EXPECT_FALSE(childOfRoot->drawOpacityIsAnimating());
1644     EXPECT_TRUE(grandChildOfRoot->drawOpacityIsAnimating());
1645     EXPECT_FALSE(renderSurface1->drawOpacityIsAnimating());
1646     EXPECT_TRUE(renderSurface1->renderSurface()->drawOpacityIsAnimating());
1647     EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating());
1648     EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating());
1649     EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating());
1650     EXPECT_FALSE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
1651     EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating());
1652     EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating());
1653
1654     // Verify drawTransformsAnimatingInTarget values
1655     //
1656     EXPECT_FALSE(parent->drawTransformIsAnimating());
1657     EXPECT_FALSE(childOfRoot->drawTransformIsAnimating());
1658     EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating());
1659     EXPECT_FALSE(renderSurface1->drawTransformIsAnimating());
1660     EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnimating());
1661     EXPECT_FALSE(childOfRS1->drawTransformIsAnimating());
1662     EXPECT_FALSE(grandChildOfRS1->drawTransformIsAnimating());
1663     EXPECT_FALSE(renderSurface2->drawTransformIsAnimating());
1664     EXPECT_TRUE(renderSurface2->renderSurface()->targetSurfaceTransformsAreAnimating());
1665     EXPECT_FALSE(childOfRS2->drawTransformIsAnimating());
1666     EXPECT_TRUE(grandChildOfRS2->drawTransformIsAnimating());
1667
1668     // Verify drawTransformsAnimatingInScreen values
1669     //
1670     EXPECT_FALSE(parent->screenSpaceTransformIsAnimating());
1671     EXPECT_FALSE(childOfRoot->screenSpaceTransformIsAnimating());
1672     EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating());
1673     EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating());
1674     EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimating());
1675     EXPECT_FALSE(childOfRS1->screenSpaceTransformIsAnimating());
1676     EXPECT_FALSE(grandChildOfRS1->screenSpaceTransformIsAnimating());
1677     EXPECT_TRUE(renderSurface2->screenSpaceTransformIsAnimating());
1678     EXPECT_TRUE(renderSurface2->renderSurface()->screenSpaceTransformsAreAnimating());
1679     EXPECT_TRUE(childOfRS2->screenSpaceTransformIsAnimating());
1680     EXPECT_TRUE(grandChildOfRS2->screenSpaceTransformIsAnimating());
1681
1682
1683     // Sanity check. If these fail there is probably a bug in the test itself.
1684     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
1685     // encodes the "depth" of the layer in the tree.
1686     EXPECT_FLOAT_EQ(1, parent->screenSpaceTransform().m42());
1687     EXPECT_FLOAT_EQ(2, childOfRoot->screenSpaceTransform().m42());
1688     EXPECT_FLOAT_EQ(3, grandChildOfRoot->screenSpaceTransform().m42());
1689
1690     EXPECT_FLOAT_EQ(2, renderSurface1->screenSpaceTransform().m42());
1691     EXPECT_FLOAT_EQ(3, childOfRS1->screenSpaceTransform().m42());
1692     EXPECT_FLOAT_EQ(4, grandChildOfRS1->screenSpaceTransform().m42());
1693
1694     EXPECT_FLOAT_EQ(3, renderSurface2->screenSpaceTransform().m42());
1695     EXPECT_FLOAT_EQ(4, childOfRS2->screenSpaceTransform().m42());
1696     EXPECT_FLOAT_EQ(5, grandChildOfRS2->screenSpaceTransform().m42());
1697 }
1698
1699 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForIdentityTransform)
1700 {
1701     // Test the calculateVisibleRect() function works correctly for identity transforms.
1702
1703     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1704     WebTransformationMatrix layerToSurfaceTransform;
1705
1706     // Case 1: Layer is contained within the surface.
1707     IntRect layerContentRect = IntRect(IntPoint(10, 10), IntSize(30, 30));
1708     IntRect expected = IntRect(IntPoint(10, 10), IntSize(30, 30));
1709     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1710     EXPECT_INT_RECT_EQ(expected, actual);
1711
1712     // Case 2: Layer is outside the surface rect.
1713     layerContentRect = IntRect(IntPoint(120, 120), IntSize(30, 30));
1714     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1715     EXPECT_TRUE(actual.isEmpty());
1716
1717     // Case 3: Layer is partially overlapping the surface rect.
1718     layerContentRect = IntRect(IntPoint(80, 80), IntSize(30, 30));
1719     expected = IntRect(IntPoint(80, 80), IntSize(20, 20));
1720     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1721     EXPECT_INT_RECT_EQ(expected, actual);
1722 }
1723
1724 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForTranslations)
1725 {
1726     // Test the calculateVisibleRect() function works correctly for scaling transforms.
1727
1728     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1729     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1730     WebTransformationMatrix layerToSurfaceTransform;
1731
1732     // Case 1: Layer is contained within the surface.
1733     layerToSurfaceTransform.makeIdentity();
1734     layerToSurfaceTransform.translate(10, 10);
1735     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1736     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1737     EXPECT_INT_RECT_EQ(expected, actual);
1738
1739     // Case 2: Layer is outside the surface rect.
1740     layerToSurfaceTransform.makeIdentity();
1741     layerToSurfaceTransform.translate(120, 120);
1742     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1743     EXPECT_TRUE(actual.isEmpty());
1744
1745     // Case 3: Layer is partially overlapping the surface rect.
1746     layerToSurfaceTransform.makeIdentity();
1747     layerToSurfaceTransform.translate(80, 80);
1748     expected = IntRect(IntPoint(0, 0), IntSize(20, 20));
1749     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1750     EXPECT_INT_RECT_EQ(expected, actual);
1751 }
1752
1753 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor2DRotations)
1754 {
1755     // Test the calculateVisibleRect() function works correctly for rotations about z-axis (i.e. 2D rotations).
1756     // Remember that calculateVisibleRect() should return the visible rect in the layer's space.
1757
1758     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1759     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1760     WebTransformationMatrix layerToSurfaceTransform;
1761
1762     // Case 1: Layer is contained within the surface.
1763     layerToSurfaceTransform.makeIdentity();
1764     layerToSurfaceTransform.translate(50, 50);
1765     layerToSurfaceTransform.rotate(45);
1766     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1767     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1768     EXPECT_INT_RECT_EQ(expected, actual);
1769
1770     // Case 2: Layer is outside the surface rect.
1771     layerToSurfaceTransform.makeIdentity();
1772     layerToSurfaceTransform.translate(-50, 0);
1773     layerToSurfaceTransform.rotate(45);
1774     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1775     EXPECT_TRUE(actual.isEmpty());
1776
1777     // Case 3: The layer is rotated about its top-left corner. In surface space, the layer
1778     //         is oriented diagonally, with the left half outside of the renderSurface. In
1779     //         this case, the visible rect should still be the entire layer (remember the
1780     //         visible rect is computed in layer space); both the top-left and
1781     //         bottom-right corners of the layer are still visible.
1782     layerToSurfaceTransform.makeIdentity();
1783     layerToSurfaceTransform.rotate(45);
1784     expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1785     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1786     EXPECT_INT_RECT_EQ(expected, actual);
1787
1788     // Case 4: The layer is rotated about its top-left corner, and translated upwards. In
1789     //         surface space, the layer is oriented diagonally, with only the top corner
1790     //         of the surface overlapping the layer. In layer space, the render surface
1791     //         overlaps the right side of the layer. The visible rect should be the
1792     //         layer's right half.
1793     layerToSurfaceTransform.makeIdentity();
1794     layerToSurfaceTransform.translate(0, -sqrt(2.0) * 15);
1795     layerToSurfaceTransform.rotate(45);
1796     expected = IntRect(IntPoint(15, 0), IntSize(15, 30)); // right half of layer bounds.
1797     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1798     EXPECT_INT_RECT_EQ(expected, actual);
1799 }
1800
1801 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicTransform)
1802 {
1803     // Test that the calculateVisibleRect() function works correctly for 3d transforms.
1804
1805     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1806     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1807     WebTransformationMatrix layerToSurfaceTransform;
1808
1809     // Case 1: Orthographic projection of a layer rotated about y-axis by 45 degrees, should be fully contained in the renderSurface.
1810     layerToSurfaceTransform.makeIdentity();
1811     layerToSurfaceTransform.rotate3d(0, 45, 0);
1812     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1813     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1814     EXPECT_INT_RECT_EQ(expected, actual);
1815
1816     // Case 2: Orthographic projection of a layer rotated about y-axis by 45 degrees, but
1817     //         shifted to the side so only the right-half the layer would be visible on
1818     //         the surface.
1819     double halfWidthOfRotatedLayer = (100 / sqrt(2.0)) * 0.5; // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
1820     layerToSurfaceTransform.makeIdentity();
1821     layerToSurfaceTransform.translate(-halfWidthOfRotatedLayer, 0);
1822     layerToSurfaceTransform.rotate3d(0, 45, 0); // rotates about the left edge of the layer
1823     expected = IntRect(IntPoint(50, 0), IntSize(50, 100)); // right half of the layer.
1824     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1825     EXPECT_INT_RECT_EQ(expected, actual);
1826 }
1827
1828 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveTransform)
1829 {
1830     // Test the calculateVisibleRect() function works correctly when the layer has a
1831     // perspective projection onto the target surface.
1832
1833     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1834     IntRect layerContentRect = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1835     WebTransformationMatrix layerToSurfaceTransform;
1836
1837     // Case 1: Even though the layer is twice as large as the surface, due to perspective
1838     //         foreshortening, the layer will fit fully in the surface when its translated
1839     //         more than the perspective amount.
1840     layerToSurfaceTransform.makeIdentity();
1841
1842     // The following sequence of transforms applies the perspective about the center of the surface.
1843     layerToSurfaceTransform.translate(50, 50);
1844     layerToSurfaceTransform.applyPerspective(9);
1845     layerToSurfaceTransform.translate(-50, -50);
1846
1847     // This translate places the layer in front of the surface's projection plane.
1848     layerToSurfaceTransform.translate3d(0, 0, -27);
1849
1850     IntRect expected = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1851     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1852     EXPECT_INT_RECT_EQ(expected, actual);
1853
1854     // Case 2: same projection as before, except that the layer is also translated to the
1855     //         side, so that only the right half of the layer should be visible.
1856     //
1857     // Explanation of expected result:
1858     // The perspective ratio is (z distance between layer and camera origin) / (z distance between projection plane and camera origin) == ((-27 - 9) / 9)
1859     // 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
1860     // visible), then we would need to translate by (-36 / 9) * -50 == -200 in the layer's units.
1861     //
1862     layerToSurfaceTransform.translate3d(-200, 0, 0);
1863     expected = IntRect(IntPoint(50, -50), IntSize(100, 200)); // The right half of the layer's bounding rect.
1864     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1865     EXPECT_INT_RECT_EQ(expected, actual);
1866 }
1867
1868 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicIsNotClippedBehindSurface)
1869 {
1870     // There is currently no explicit concept of an orthographic projection plane in our
1871     // code (nor in the CSS spec to my knowledge). Therefore, layers that are technically
1872     // behind the surface in an orthographic world should not be clipped when they are
1873     // flattened to the surface.
1874
1875     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1876     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1877     WebTransformationMatrix layerToSurfaceTransform;
1878
1879     // This sequence of transforms effectively rotates the layer about the y-axis at the
1880     // center of the layer.
1881     layerToSurfaceTransform.makeIdentity();
1882     layerToSurfaceTransform.translate(50, 0);
1883     layerToSurfaceTransform.rotate3d(0, 45, 0);
1884     layerToSurfaceTransform.translate(-50, 0);
1885
1886     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1887     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1888     EXPECT_INT_RECT_EQ(expected, actual);
1889 }
1890
1891 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveWhenClippedByW)
1892 {
1893     // Test the calculateVisibleRect() function works correctly when projecting a surface
1894     // onto a layer, but the layer is partially behind the camera (not just behind the
1895     // projection plane). In this case, the cartesian coordinates may seem to be valid,
1896     // but actually they are not. The visibleRect needs to be properly clipped by the
1897     // w = 0 plane in homogeneous coordinates before converting to cartesian coordinates.
1898
1899     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1900     IntRect layerContentRect = IntRect(IntPoint(-10, -1), IntSize(20, 2));
1901     WebTransformationMatrix layerToSurfaceTransform;
1902
1903     // The layer is positioned so that the right half of the layer should be in front of
1904     // the camera, while the other half is behind the surface's projection plane. The
1905     // following sequence of transforms applies the perspective and rotation about the
1906     // center of the layer.
1907     layerToSurfaceTransform.makeIdentity();
1908     layerToSurfaceTransform.applyPerspective(1);
1909     layerToSurfaceTransform.translate3d(-2, 0, 1);
1910     layerToSurfaceTransform.rotate3d(0, 45, 0);
1911
1912     // Sanity check that this transform does indeed cause w < 0 when applying the
1913     // transform, otherwise this code is not testing the intended scenario.
1914     bool clipped = false;
1915     CCMathUtil::mapQuad(layerToSurfaceTransform, FloatQuad(FloatRect(layerContentRect)), clipped);
1916     ASSERT_TRUE(clipped);
1917
1918     int expectedXPosition = 0;
1919     int expectedWidth = 10;
1920     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1921     EXPECT_EQ(expectedXPosition, actual.x());
1922     EXPECT_EQ(expectedWidth, actual.width());
1923 }
1924
1925 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection)
1926 {
1927     // To determine visibleRect in layer space, there needs to be an un-projection from
1928     // surface space to layer space. When the original transform was a perspective
1929     // projection that was clipped, it returns a rect that encloses the clipped bounds.
1930     // Un-projecting this new rect may require clipping again.
1931
1932     // This sequence of transforms causes one corner of the layer to protrude across the w = 0 plane, and should be clipped.
1933     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1934     IntRect layerContentRect = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1935     WebTransformationMatrix layerToSurfaceTransform;
1936     layerToSurfaceTransform.makeIdentity();
1937     layerToSurfaceTransform.applyPerspective(1);
1938     layerToSurfaceTransform.translate3d(0, 0, -5);
1939     layerToSurfaceTransform.rotate3d(0, 45, 0);
1940     layerToSurfaceTransform.rotate3d(80, 0, 0);
1941
1942     // Sanity check that un-projection does indeed cause w < 0, otherwise this code is not
1943     // testing the intended scenario.
1944     bool clipped = false;
1945     FloatRect clippedRect = CCMathUtil::mapClippedRect(layerToSurfaceTransform, layerContentRect);
1946     CCMathUtil::projectQuad(layerToSurfaceTransform.inverse(), FloatQuad(clippedRect), clipped);
1947     ASSERT_TRUE(clipped);
1948
1949     // Only the corner of the layer is not visible on the surface because of being
1950     // clipped. But, the net result of rounding visible region to an axis-aligned rect is
1951     // that the entire layer should still be considered visible.
1952     IntRect expected = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1953     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1954     EXPECT_INT_RECT_EQ(expected, actual);
1955 }
1956
1957 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d)
1958 {
1959     // Verify the behavior of back-face culling when there are no preserve-3d layers. Note
1960     // that 3d transforms still apply in this case, but they are "flattened" to each
1961     // parent layer according to current W3C spec.
1962
1963     const WebTransformationMatrix identityMatrix;
1964     RefPtr<LayerChromium> parent = LayerChromium::create();
1965     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1966     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1967     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1968     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1969     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1970     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1971     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1972     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1973
1974     parent->addChild(frontFacingChild);
1975     parent->addChild(backFacingChild);
1976     parent->addChild(frontFacingSurface);
1977     parent->addChild(backFacingSurface);
1978     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
1979     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
1980     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
1981     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
1982
1983     // Nothing is double-sided
1984     frontFacingChild->setDoubleSided(false);
1985     backFacingChild->setDoubleSided(false);
1986     frontFacingSurface->setDoubleSided(false);
1987     backFacingSurface->setDoubleSided(false);
1988     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
1989     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
1990     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
1991     backFacingChildOfBackFacingSurface->setDoubleSided(false);
1992
1993     WebTransformationMatrix backfaceMatrix;
1994     backfaceMatrix.translate(50, 50);
1995     backfaceMatrix.rotate3d(0, 1, 0, 180);
1996     backfaceMatrix.translate(-50, -50);
1997
1998     // Having a descendant and opacity will force these to have render surfaces.
1999     frontFacingSurface->setOpacity(0.5);
2000     backFacingSurface->setOpacity(0.5);
2001
2002     // Nothing preserves 3d. According to current W3C CSS Transforms spec, these layers
2003     // should blindly use their own local transforms to determine back-face culling.
2004     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2005     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2006     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2007     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2008     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2009     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2010     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2011     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2012     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2013
2014     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2015     int dummyMaxTextureSize = 512;
2016     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
2017
2018     // Verify which renderSurfaces were created.
2019     EXPECT_FALSE(frontFacingChild->renderSurface());
2020     EXPECT_FALSE(backFacingChild->renderSurface());
2021     EXPECT_TRUE(frontFacingSurface->renderSurface());
2022     EXPECT_TRUE(backFacingSurface->renderSurface());
2023     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
2024     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
2025     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
2026     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
2027
2028     // Verify the renderSurfaceLayerList.
2029     ASSERT_EQ(3u, renderSurfaceLayerList.size());
2030     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2031     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2032     // Even though the back facing surface LAYER gets culled, the other descendants should still be added, so the SURFACE should not be culled.
2033     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[2]->id());
2034
2035     // Verify root surface's layerList.
2036     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2037     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2038     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2039     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
2040
2041     // Verify frontFacingSurface's layerList.
2042     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2043     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2044     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2045
2046     // Verify backFacingSurface's layerList; its own layer should be culled from the surface list.
2047     ASSERT_EQ(1u, renderSurfaceLayerList[2]->renderSurface()->layerList().size());
2048     EXPECT_EQ(frontFacingChildOfBackFacingSurface->id(), renderSurfaceLayerList[2]->renderSurface()->layerList()[0]->id());
2049 }
2050
2051 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d)
2052 {
2053     // Verify the behavior of back-face culling when preserves-3d transform style is used.
2054
2055     const WebTransformationMatrix identityMatrix;
2056     RefPtr<LayerChromium> parent = LayerChromium::create();
2057     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2058     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2059     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2060     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2061     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2062     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2063     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2064     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2065     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2066     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2067
2068     parent->addChild(frontFacingChild);
2069     parent->addChild(backFacingChild);
2070     parent->addChild(frontFacingSurface);
2071     parent->addChild(backFacingSurface);
2072     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
2073     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
2074     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
2075     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
2076
2077     // Nothing is double-sided
2078     frontFacingChild->setDoubleSided(false);
2079     backFacingChild->setDoubleSided(false);
2080     frontFacingSurface->setDoubleSided(false);
2081     backFacingSurface->setDoubleSided(false);
2082     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
2083     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
2084     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
2085     backFacingChildOfBackFacingSurface->setDoubleSided(false);
2086
2087     WebTransformationMatrix backfaceMatrix;
2088     backfaceMatrix.translate(50, 50);
2089     backfaceMatrix.rotate3d(0, 1, 0, 180);
2090     backfaceMatrix.translate(-50, -50);
2091
2092     // Opacity will not force creation of renderSurfaces in this case because of the
2093     // preserve-3d transform style. Instead, an example of when a surface would be
2094     // created with preserve-3d is when there is a replica layer.
2095     frontFacingSurface->setReplicaLayer(dummyReplicaLayer1.get());
2096     backFacingSurface->setReplicaLayer(dummyReplicaLayer2.get());
2097
2098     // Each surface creates its own new 3d rendering context (as defined by W3C spec).
2099     // According to current W3C CSS Transforms spec, layers in a 3d rendering context
2100     // should use the transform with respect to that context. This 3d rendering context
2101     // occurs when (a) parent's transform style is flat and (b) the layer's transform
2102     // style is preserve-3d.
2103     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transform style is flat.
2104     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2105     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2106     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2107     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2108     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2109     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2110     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2111     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2112
2113     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2114     int dummyMaxTextureSize = 512;
2115     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
2116
2117     // Verify which renderSurfaces were created.
2118     EXPECT_FALSE(frontFacingChild->renderSurface());
2119     EXPECT_FALSE(backFacingChild->renderSurface());
2120     EXPECT_TRUE(frontFacingSurface->renderSurface());
2121     EXPECT_FALSE(backFacingSurface->renderSurface());
2122     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
2123     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
2124     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
2125     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
2126
2127     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2128     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2129     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2130     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2131
2132     // Verify root surface's layerList.
2133     ASSERT_EQ(2u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2134     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2135     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2136
2137     // Verify frontFacingSurface's layerList.
2138     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2139     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2140     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2141 }
2142
2143 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms)
2144 {
2145     // Verify that layers are appropriately culled when their back face is showing and
2146     // they are not double sided, while animations are going on.
2147     //
2148     // Layers that are animating do not get culled on the main thread, as their transforms should be
2149     // treated as "unknown" so we can not be sure that their back face is really showing.
2150     //
2151
2152     const WebTransformationMatrix identityMatrix;
2153     RefPtr<LayerChromium> parent = LayerChromium::create();
2154     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
2155     RefPtr<LayerChromiumWithForcedDrawsContent> animatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2156     RefPtr<LayerChromiumWithForcedDrawsContent> childOfAnimatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2157     RefPtr<LayerChromiumWithForcedDrawsContent> animatingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2158     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2159
2160     parent->addChild(child);
2161     parent->addChild(animatingSurface);
2162     animatingSurface->addChild(childOfAnimatingSurface);
2163     parent->addChild(animatingChild);
2164     parent->addChild(child2);
2165
2166     // Nothing is double-sided
2167     child->setDoubleSided(false);
2168     child2->setDoubleSided(false);
2169     animatingSurface->setDoubleSided(false);
2170     childOfAnimatingSurface->setDoubleSided(false);
2171     animatingChild->setDoubleSided(false);
2172
2173     WebTransformationMatrix backfaceMatrix;
2174     backfaceMatrix.translate(50, 50);
2175     backfaceMatrix.rotate3d(0, 1, 0, 180);
2176     backfaceMatrix.translate(-50, -50);
2177
2178     // Make our render surface.
2179     animatingSurface->setForceRenderSurface(true);
2180
2181     // Animate the transform on the render surface.
2182     addAnimatedTransformToController(*animatingSurface->layerAnimationController(), 10, 30, 0);
2183     // This is just an animating layer, not a surface.
2184     addAnimatedTransformToController(*animatingChild->layerAnimationController(), 10, 30, 0);
2185
2186     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2187     setLayerPropertiesForTesting(child.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2188     setLayerPropertiesForTesting(animatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2189     setLayerPropertiesForTesting(childOfAnimatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2190     setLayerPropertiesForTesting(animatingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2191     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2192
2193     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2194     int dummyMaxTextureSize = 512;
2195     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
2196     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2197
2198     EXPECT_FALSE(child->renderSurface());
2199     EXPECT_TRUE(animatingSurface->renderSurface());
2200     EXPECT_FALSE(childOfAnimatingSurface->renderSurface());
2201     EXPECT_FALSE(animatingChild->renderSurface());
2202     EXPECT_FALSE(child2->renderSurface());
2203
2204     // Verify that the animatingChild and childOfAnimatingSurface were not culled, but that child was.
2205     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2206     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2207     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->id());
2208
2209     // The non-animating child be culled from the layer list for the parent render surface.
2210     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2211     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2212     EXPECT_EQ(animatingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2213     EXPECT_EQ(child2->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
2214
2215     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2216     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2217     EXPECT_EQ(childOfAnimatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2218
2219     EXPECT_FALSE(child2->visibleContentRect().isEmpty());
2220
2221     // The animating layers should have a visibleContentRect that represents the area of the front face that is within the viewport.
2222     EXPECT_EQ(animatingChild->visibleContentRect(), IntRect(IntPoint(), animatingChild->contentBounds()));
2223     EXPECT_EQ(animatingSurface->visibleContentRect(), IntRect(IntPoint(), animatingSurface->contentBounds()));
2224     // And layers in the subtree of the animating layer should have valid visibleContentRects also.
2225     EXPECT_EQ(childOfAnimatingSurface->visibleContentRect(), IntRect(IntPoint(), childOfAnimatingSurface->contentBounds()));
2226 }
2227
2228 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlatteningSurface)
2229 {
2230     // Verify the behavior of back-face culling for a renderSurface that is created
2231     // when it flattens its subtree, and its parent has preserves-3d.
2232
2233     const WebTransformationMatrix identityMatrix;
2234     RefPtr<LayerChromium> parent = LayerChromium::create();
2235     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2236     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2237     RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2238     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2239
2240     parent->addChild(frontFacingSurface);
2241     parent->addChild(backFacingSurface);
2242     frontFacingSurface->addChild(child1);
2243     backFacingSurface->addChild(child2);
2244
2245     // RenderSurfaces are not double-sided
2246     frontFacingSurface->setDoubleSided(false);
2247     backFacingSurface->setDoubleSided(false);
2248
2249     WebTransformationMatrix backfaceMatrix;
2250     backfaceMatrix.translate(50, 50);
2251     backfaceMatrix.rotate3d(0, 1, 0, 180);
2252     backfaceMatrix.translate(-50, -50);
2253
2254     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
2255     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2256     setLayerPropertiesForTesting(backFacingSurface.get(),  backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2257     setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2258     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2259
2260     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2261     int dummyMaxTextureSize = 512;
2262     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
2263
2264     // Verify which renderSurfaces were created.
2265     EXPECT_TRUE(frontFacingSurface->renderSurface());
2266     EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be culled
2267     EXPECT_FALSE(child1->renderSurface());
2268     EXPECT_FALSE(child2->renderSurface());
2269
2270     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2271     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2272     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2273     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2274
2275     // Verify root surface's layerList.
2276     ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2277     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2278
2279     // Verify frontFacingSurface's layerList.
2280     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2281     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2282     EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2283 }
2284
2285 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForEmptyLayerList)
2286 {
2287     // Hit testing on an empty renderSurfaceLayerList should return a null pointer.
2288     DebugScopedSetImplThread thisScopeIsOnImplThread;
2289
2290     Vector<CCLayerImpl*> renderSurfaceLayerList;
2291
2292     IntPoint testPoint(0, 0);
2293     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2294     EXPECT_FALSE(resultLayer);
2295
2296     testPoint = IntPoint(10, 20);
2297     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2298     EXPECT_FALSE(resultLayer);
2299 }
2300
2301 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayer)
2302 {
2303     DebugScopedSetImplThread thisScopeIsOnImplThread;
2304
2305     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(12345);
2306
2307     WebTransformationMatrix identityMatrix;
2308     FloatPoint anchor(0, 0);
2309     FloatPoint position(0, 0);
2310     IntSize bounds(100, 100);
2311     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2312     root->setDrawsContent(true);
2313
2314     Vector<CCLayerImpl*> renderSurfaceLayerList;
2315     int dummyMaxTextureSize = 512;
2316     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2317     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2318
2319     // Sanity check the scenario we just created.
2320     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2321     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2322
2323     // Hit testing for a point outside the layer should return a null pointer.
2324     IntPoint testPoint(101, 101);
2325     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2326     EXPECT_FALSE(resultLayer);
2327
2328     testPoint = IntPoint(-1, -1);
2329     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2330     EXPECT_FALSE(resultLayer);
2331
2332     // Hit testing for a point inside should return the root layer.
2333     testPoint = IntPoint(1, 1);
2334     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2335     ASSERT_TRUE(resultLayer);
2336     EXPECT_EQ(12345, resultLayer->id());
2337
2338     testPoint = IntPoint(99, 99);
2339     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2340     ASSERT_TRUE(resultLayer);
2341     EXPECT_EQ(12345, resultLayer->id());
2342 }
2343
2344 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForUninvertibleTransform)
2345 {
2346     DebugScopedSetImplThread thisScopeIsOnImplThread;
2347
2348     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(12345);
2349
2350     WebTransformationMatrix uninvertibleTransform;
2351     uninvertibleTransform.setM11(0);
2352     uninvertibleTransform.setM22(0);
2353     uninvertibleTransform.setM33(0);
2354     uninvertibleTransform.setM44(0);
2355     ASSERT_FALSE(uninvertibleTransform.isInvertible());
2356
2357     WebTransformationMatrix identityMatrix;
2358     FloatPoint anchor(0, 0);
2359     FloatPoint position(0, 0);
2360     IntSize bounds(100, 100);
2361     setLayerPropertiesForTesting(root.get(), uninvertibleTransform, identityMatrix, anchor, position, bounds, false);
2362     root->setDrawsContent(true);
2363
2364     Vector<CCLayerImpl*> renderSurfaceLayerList;
2365     int dummyMaxTextureSize = 512;
2366     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2367     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2368
2369     // Sanity check the scenario we just created.
2370     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2371     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2372     ASSERT_FALSE(root->screenSpaceTransform().isInvertible());
2373
2374     // Hit testing any point should not hit the layer. If the invertible matrix is
2375     // accidentally ignored and treated like an identity, then the hit testing will
2376     // incorrectly hit the layer when it shouldn't.
2377     IntPoint testPoint(1, 1);
2378     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2379     EXPECT_FALSE(resultLayer);
2380
2381     testPoint = IntPoint(10, 10);
2382     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2383     EXPECT_FALSE(resultLayer);
2384
2385     testPoint = IntPoint(10, 30);
2386     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2387     EXPECT_FALSE(resultLayer);
2388
2389     testPoint = IntPoint(50, 50);
2390     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2391     EXPECT_FALSE(resultLayer);
2392
2393     testPoint = IntPoint(67, 48);
2394     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2395     EXPECT_FALSE(resultLayer);
2396
2397     testPoint = IntPoint(99, 99);
2398     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2399     EXPECT_FALSE(resultLayer);
2400
2401     testPoint = IntPoint(-1, -1);
2402     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2403     EXPECT_FALSE(resultLayer);
2404 }
2405
2406 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePositionedLayer)
2407 {
2408     DebugScopedSetImplThread thisScopeIsOnImplThread;
2409
2410     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(12345);
2411
2412     WebTransformationMatrix identityMatrix;
2413     FloatPoint anchor(0, 0);
2414     FloatPoint position(50, 50); // this layer is positioned, and hit testing should correctly know where the layer is located.
2415     IntSize bounds(100, 100);
2416     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2417     root->setDrawsContent(true);
2418
2419     Vector<CCLayerImpl*> renderSurfaceLayerList;
2420     int dummyMaxTextureSize = 512;
2421     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2422     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2423
2424     // Sanity check the scenario we just created.
2425     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2426     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2427
2428     // Hit testing for a point outside the layer should return a null pointer.
2429     IntPoint testPoint(49, 49);
2430     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2431     EXPECT_FALSE(resultLayer);
2432
2433     // Even though the layer exists at (101, 101), it should not be visible there since the root renderSurface would clamp it.
2434     testPoint = IntPoint(101, 101);
2435     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2436     EXPECT_FALSE(resultLayer);
2437
2438     // Hit testing for a point inside should return the root layer.
2439     testPoint = IntPoint(51, 51);
2440     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2441     ASSERT_TRUE(resultLayer);
2442     EXPECT_EQ(12345, resultLayer->id());
2443
2444     testPoint = IntPoint(99, 99);
2445     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2446     ASSERT_TRUE(resultLayer);
2447     EXPECT_EQ(12345, resultLayer->id());
2448 }
2449
2450 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleRotatedLayer)
2451 {
2452     DebugScopedSetImplThread thisScopeIsOnImplThread;
2453
2454     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(12345);
2455
2456     WebTransformationMatrix identityMatrix;
2457     WebTransformationMatrix rotation45DegreesAboutCenter;
2458     rotation45DegreesAboutCenter.translate(50, 50);
2459     rotation45DegreesAboutCenter.rotate3d(0, 0, 45);
2460     rotation45DegreesAboutCenter.translate(-50, -50);
2461     FloatPoint anchor(0, 0);
2462     FloatPoint position(0, 0);
2463     IntSize bounds(100, 100);
2464     setLayerPropertiesForTesting(root.get(), rotation45DegreesAboutCenter, identityMatrix, anchor, position, bounds, false);
2465     root->setDrawsContent(true);
2466
2467     Vector<CCLayerImpl*> renderSurfaceLayerList;
2468     int dummyMaxTextureSize = 512;
2469     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2470     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2471
2472     // Sanity check the scenario we just created.
2473     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2474     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2475
2476     // Hit testing for points outside the layer.
2477     // These corners would have been inside the un-transformed layer, but they should not hit the correctly transformed layer.
2478     IntPoint testPoint(99, 99);
2479     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2480     EXPECT_FALSE(resultLayer);
2481
2482     testPoint = IntPoint(1, 1);
2483     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2484     EXPECT_FALSE(resultLayer);
2485
2486     // Hit testing for a point inside should return the root layer.
2487     testPoint = IntPoint(1, 50);
2488     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2489     ASSERT_TRUE(resultLayer);
2490     EXPECT_EQ(12345, resultLayer->id());
2491
2492     // Hit testing the corners that would overlap the unclipped layer, but are outside the clipped region.
2493     testPoint = IntPoint(50, -1);
2494     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2495     ASSERT_FALSE(resultLayer);
2496
2497     testPoint = IntPoint(-1, 50);
2498     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2499     ASSERT_FALSE(resultLayer);
2500 }
2501
2502 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePerspectiveLayer)
2503 {
2504     DebugScopedSetImplThread thisScopeIsOnImplThread;
2505
2506     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(12345);
2507
2508     WebTransformationMatrix identityMatrix;
2509
2510     // perspectiveProjectionAboutCenter * translationByZ is designed so that the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
2511     WebTransformationMatrix perspectiveProjectionAboutCenter;
2512     perspectiveProjectionAboutCenter.translate(50, 50);
2513     perspectiveProjectionAboutCenter.applyPerspective(1);
2514     perspectiveProjectionAboutCenter.translate(-50, -50);
2515     WebTransformationMatrix translationByZ;
2516     translationByZ.translate3d(0, 0, -1);
2517
2518     FloatPoint anchor(0, 0);
2519     FloatPoint position(0, 0);
2520     IntSize bounds(100, 100);
2521     setLayerPropertiesForTesting(root.get(), perspectiveProjectionAboutCenter * translationByZ, identityMatrix, anchor, position, bounds, false);
2522     root->setDrawsContent(true);
2523
2524     Vector<CCLayerImpl*> renderSurfaceLayerList;
2525     int dummyMaxTextureSize = 512;
2526     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2527     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2528
2529     // Sanity check the scenario we just created.
2530     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2531     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2532
2533     // Hit testing for points outside the layer.
2534     // These corners would have been inside the un-transformed layer, but they should not hit the correctly transformed layer.
2535     IntPoint testPoint(24, 24);
2536     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2537     EXPECT_FALSE(resultLayer);
2538
2539     testPoint = IntPoint(76, 76);
2540     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2541     EXPECT_FALSE(resultLayer);
2542
2543     // Hit testing for a point inside should return the root layer.
2544     testPoint = IntPoint(26, 26);
2545     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2546     ASSERT_TRUE(resultLayer);
2547     EXPECT_EQ(12345, resultLayer->id());
2548
2549     testPoint = IntPoint(74, 74);
2550     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2551     ASSERT_TRUE(resultLayer);
2552     EXPECT_EQ(12345, resultLayer->id());
2553 }
2554
2555 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayerWithScaledContents)
2556 {
2557     // A layer's visibleContentRect is actually in the layer's content space. The
2558     // screenSpaceTransform converts from the layer's origin space to screen space. This
2559     // test makes sure that hit testing works correctly accounts for the contents scale.
2560     // A contentsScale that is not 1 effectively forces a non-identity transform between
2561     // layer's content space and layer's origin space. The hit testing code must take this into account.
2562     //
2563     // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
2564     // contentsScale is ignored, then hit testing will mis-interpret the visibleContentRect
2565     // as being larger than the actual bounds of the layer.
2566     //
2567     DebugScopedSetImplThread thisScopeIsOnImplThread;
2568
2569     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
2570
2571     WebTransformationMatrix identityMatrix;
2572     FloatPoint anchor(0, 0);
2573
2574     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, FloatPoint(0, 0), IntSize(100, 100), false);
2575
2576     {
2577         FloatPoint position(25, 25);
2578         IntSize bounds(50, 50);
2579         OwnPtr<CCLayerImpl> testLayer = CCLayerImpl::create(12345);
2580         setLayerPropertiesForTesting(testLayer.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2581
2582         // override contentBounds
2583         testLayer->setContentBounds(IntSize(100, 100));
2584
2585         testLayer->setDrawsContent(true);
2586         root->addChild(testLayer.release());
2587     }
2588
2589     Vector<CCLayerImpl*> renderSurfaceLayerList;
2590     int dummyMaxTextureSize = 512;
2591     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2592     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2593
2594     // Sanity check the scenario we just created.
2595     // The visibleContentRect for testLayer is actually 100x100, even though its layout size is 50x50, positioned at 25x25.
2596     CCLayerImpl* testLayer = root->children()[0].get();
2597     EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(100, 100)), testLayer->visibleContentRect());
2598     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2599     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2600
2601     // 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).
2602     IntPoint testPoint(101, 101);
2603     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2604     EXPECT_FALSE(resultLayer);
2605
2606     testPoint = IntPoint(24, 24);
2607     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2608     EXPECT_FALSE(resultLayer);
2609
2610     testPoint = IntPoint(76, 76);
2611     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2612     EXPECT_FALSE(resultLayer);
2613
2614     // Hit testing for a point inside should return the test layer.
2615     testPoint = IntPoint(26, 26);
2616     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2617     ASSERT_TRUE(resultLayer);
2618     EXPECT_EQ(12345, resultLayer->id());
2619
2620     testPoint = IntPoint(74, 74);
2621     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2622     ASSERT_TRUE(resultLayer);
2623     EXPECT_EQ(12345, resultLayer->id());
2624 }
2625
2626 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSimpleClippedLayer)
2627 {
2628     // Test that hit-testing will only work for the visible portion of a layer, and not
2629     // the entire layer bounds. Here we just test the simple axis-aligned case.
2630     DebugScopedSetImplThread thisScopeIsOnImplThread;
2631
2632     WebTransformationMatrix identityMatrix;
2633     FloatPoint anchor(0, 0);
2634
2635     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
2636     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, FloatPoint(0, 0), IntSize(100, 100), false);
2637
2638     {
2639         OwnPtr<CCLayerImpl> clippingLayer = CCLayerImpl::create(123);
2640         FloatPoint position(25, 25); // this layer is positioned, and hit testing should correctly know where the layer is located.
2641         IntSize bounds(50, 50);
2642         setLayerPropertiesForTesting(clippingLayer.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2643         clippingLayer->setMasksToBounds(true);
2644
2645         OwnPtr<CCLayerImpl> child = CCLayerImpl::create(456);
2646         position = FloatPoint(-50, -50);
2647         bounds = IntSize(300, 300);
2648         setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2649         child->setDrawsContent(true);
2650         clippingLayer->addChild(child.release());
2651         root->addChild(clippingLayer.release());
2652     }
2653
2654     Vector<CCLayerImpl*> renderSurfaceLayerList;
2655     int dummyMaxTextureSize = 512;
2656     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2657     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2658
2659     // Sanity check the scenario we just created.
2660     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2661     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2662     ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id());
2663
2664     // Hit testing for a point outside the layer should return a null pointer.
2665     // Despite the child layer being very large, it should be clipped to the root layer's bounds.
2666     IntPoint testPoint(24, 24);
2667     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2668     EXPECT_FALSE(resultLayer);
2669
2670     // Even though the layer exists at (101, 101), it should not be visible there since the clippingLayer would clamp it.
2671     testPoint = IntPoint(76, 76);
2672     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2673     EXPECT_FALSE(resultLayer);
2674
2675     // Hit testing for a point inside should return the child layer.
2676     testPoint = IntPoint(26, 26);
2677     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2678     ASSERT_TRUE(resultLayer);
2679     EXPECT_EQ(456, resultLayer->id());
2680
2681     testPoint = IntPoint(74, 74);
2682     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2683     ASSERT_TRUE(resultLayer);
2684     EXPECT_EQ(456, resultLayer->id());
2685 }
2686
2687 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultiClippedRotatedLayer)
2688 {
2689     // This test checks whether hit testing correctly avoids hit testing with multiple
2690     // ancestors that clip in non axis-aligned ways. To pass this test, the hit testing
2691     // algorithm needs to recognize that multiple parent layers may clip the layer, and
2692     // should not actually hit those clipped areas.
2693     //
2694     // The child and grandChild layers are both initialized to clip the rotatedLeaf. The
2695     // child layer is rotated about the top-left corner, so that the root + child clips
2696     // combined create a triangle. The rotatedLeaf will only be visible where it overlaps
2697     // this triangle.
2698     //
2699     DebugScopedSetImplThread thisScopeIsOnImplThread;
2700
2701     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(123);
2702
2703     WebTransformationMatrix identityMatrix;
2704     FloatPoint anchor(0, 0);
2705     FloatPoint position(0, 0);
2706     IntSize bounds(100, 100);
2707     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2708     root->setMasksToBounds(true);
2709
2710     {
2711         OwnPtr<CCLayerImpl> child = CCLayerImpl::create(456);
2712         OwnPtr<CCLayerImpl> grandChild = CCLayerImpl::create(789);
2713         OwnPtr<CCLayerImpl> rotatedLeaf = CCLayerImpl::create(2468);
2714
2715         position = FloatPoint(10, 10);
2716         bounds = IntSize(80, 80);
2717         setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2718         child->setMasksToBounds(true);
2719         
2720         WebTransformationMatrix rotation45DegreesAboutCorner;
2721         rotation45DegreesAboutCorner.rotate3d(0, 0, 45);
2722
2723         position = FloatPoint(0, 0); // remember, positioned with respect to its parent which is already at 10, 10
2724         bounds = IntSize(200, 200); // to ensure it covers at least sqrt(2) * 100.
2725         setLayerPropertiesForTesting(grandChild.get(), rotation45DegreesAboutCorner, identityMatrix, anchor, position, bounds, false);
2726         grandChild->setMasksToBounds(true);
2727
2728         // Rotates about the center of the layer
2729         WebTransformationMatrix rotatedLeafTransform;
2730         rotatedLeafTransform.translate(-10, -10); // cancel out the grandParent's position
2731         rotatedLeafTransform.rotate3d(0, 0, -45); // cancel out the corner 45-degree rotation of the parent.
2732         rotatedLeafTransform.translate(50, 50);
2733         rotatedLeafTransform.rotate3d(0, 0, 45);
2734         rotatedLeafTransform.translate(-50, -50);
2735         position = FloatPoint(0, 0);
2736         bounds = IntSize(100, 100);
2737         setLayerPropertiesForTesting(rotatedLeaf.get(), rotatedLeafTransform, identityMatrix, anchor, position, bounds, false);
2738         rotatedLeaf->setDrawsContent(true);
2739
2740         grandChild->addChild(rotatedLeaf.release());
2741         child->addChild(grandChild.release());
2742         root->addChild(child.release());
2743     }
2744
2745     Vector<CCLayerImpl*> renderSurfaceLayerList;
2746     int dummyMaxTextureSize = 512;
2747     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2748     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2749
2750     // Sanity check the scenario we just created.
2751     // The grandChild is expected to create a renderSurface because it masksToBounds and is not axis aligned.
2752     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2753     ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2754     ASSERT_EQ(789, renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id()); // grandChild's surface.
2755     ASSERT_EQ(1u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2756     ASSERT_EQ(2468, renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2757
2758     // (11, 89) is close to the the bottom left corner within the clip, but it is not inside the layer.
2759     IntPoint testPoint(11, 89);
2760     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2761     EXPECT_FALSE(resultLayer);
2762
2763     // Closer inwards from the bottom left will overlap the layer.
2764     testPoint = IntPoint(25, 75);
2765     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2766     ASSERT_TRUE(resultLayer);
2767     EXPECT_EQ(2468, resultLayer->id());
2768
2769     // (4, 50) is inside the unclipped layer, but that corner of the layer should be
2770     // clipped away by the grandParent and should not get hit. If hit testing blindly uses
2771     // visibleContentRect without considering how parent may clip the layer, then hit
2772     // testing would accidentally think that the point successfully hits the layer.
2773     testPoint = IntPoint(4, 50);
2774     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2775     EXPECT_FALSE(resultLayer);
2776
2777     // (11, 50) is inside the layer and within the clipped area.
2778     testPoint = IntPoint(11, 50);
2779     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2780     ASSERT_TRUE(resultLayer);
2781     EXPECT_EQ(2468, resultLayer->id());
2782
2783     // Around the middle, just to the right and up, would have hit the layer except that
2784     // that area should be clipped away by the parent.
2785     testPoint = IntPoint(51, 51);
2786     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2787     EXPECT_FALSE(resultLayer);
2788
2789     // Around the middle, just to the left and down, should successfully hit the layer.
2790     testPoint = IntPoint(49, 51);
2791     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2792     ASSERT_TRUE(resultLayer);
2793     EXPECT_EQ(2468, resultLayer->id());
2794 }
2795
2796 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForNonClippingIntermediateLayer)
2797 {
2798     // This test checks that hit testing code does not accidentally clip to layer
2799     // bounds for a layer that actually does not clip.
2800     DebugScopedSetImplThread thisScopeIsOnImplThread;
2801
2802     WebTransformationMatrix identityMatrix;
2803     FloatPoint anchor(0, 0);
2804
2805     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
2806     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, FloatPoint(0, 0), IntSize(100, 100), false);
2807
2808     {
2809         OwnPtr<CCLayerImpl> intermediateLayer = CCLayerImpl::create(123);
2810         FloatPoint position(10, 10); // this layer is positioned, and hit testing should correctly know where the layer is located.
2811         IntSize bounds(50, 50);
2812         setLayerPropertiesForTesting(intermediateLayer.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2813         // Sanity check the intermediate layer should not clip.
2814         ASSERT_FALSE(intermediateLayer->masksToBounds());
2815         ASSERT_FALSE(intermediateLayer->maskLayer());
2816
2817         // The child of the intermediateLayer is translated so that it does not overlap intermediateLayer at all.
2818         // If child is incorrectly clipped, we would not be able to hit it successfully.
2819         OwnPtr<CCLayerImpl> child = CCLayerImpl::create(456);
2820         position = FloatPoint(60, 60); // 70, 70 in screen space
2821         bounds = IntSize(20, 20);
2822         setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2823         child->setDrawsContent(true);
2824         intermediateLayer->addChild(child.release());
2825         root->addChild(intermediateLayer.release());
2826     }
2827
2828     Vector<CCLayerImpl*> renderSurfaceLayerList;
2829     int dummyMaxTextureSize = 512;
2830     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2831     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2832
2833     // Sanity check the scenario we just created.
2834     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2835     ASSERT_EQ(1u, root->renderSurface()->layerList().size());
2836     ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id());
2837
2838     // Hit testing for a point outside the layer should return a null pointer.
2839     IntPoint testPoint(69, 69);
2840     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2841     EXPECT_FALSE(resultLayer);
2842
2843     testPoint = IntPoint(91, 91);
2844     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2845     EXPECT_FALSE(resultLayer);
2846
2847     // Hit testing for a point inside should return the child layer.
2848     testPoint = IntPoint(71, 71);
2849     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2850     ASSERT_TRUE(resultLayer);
2851     EXPECT_EQ(456, resultLayer->id());
2852
2853     testPoint = IntPoint(89, 89);
2854     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2855     ASSERT_TRUE(resultLayer);
2856     EXPECT_EQ(456, resultLayer->id());
2857 }
2858
2859
2860 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayers)
2861 {
2862     DebugScopedSetImplThread thisScopeIsOnImplThread;
2863
2864     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
2865
2866     WebTransformationMatrix identityMatrix;
2867     FloatPoint anchor(0, 0);
2868     FloatPoint position(0, 0);
2869     IntSize bounds(100, 100);
2870     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2871     root->setDrawsContent(true);
2872
2873     {
2874         // child 1 and child2 are initialized to overlap between x=50 and x=60.
2875         // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
2876         // The expected stacking order is:
2877         //   (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
2878
2879         OwnPtr<CCLayerImpl> child1 = CCLayerImpl::create(2);
2880         OwnPtr<CCLayerImpl> child2 = CCLayerImpl::create(3);
2881         OwnPtr<CCLayerImpl> grandChild1 = CCLayerImpl::create(4);
2882
2883         position = FloatPoint(10, 10);
2884         bounds = IntSize(50, 50);
2885         setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2886         child1->setDrawsContent(true);
2887
2888         position = FloatPoint(50, 10);
2889         bounds = IntSize(50, 50);
2890         setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2891         child2->setDrawsContent(true);
2892
2893         // Remember that grandChild is positioned with respect to its parent (i.e. child1).
2894         // In screen space, the intended position is (10, 50), with size 100 x 50.
2895         position = FloatPoint(0, 40);
2896         bounds = IntSize(100, 50);
2897         setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2898         grandChild1->setDrawsContent(true);
2899
2900         child1->addChild(grandChild1.release());
2901         root->addChild(child1.release());
2902         root->addChild(child2.release());
2903     }
2904
2905     CCLayerImpl* child1 = root->children()[0].get();
2906     CCLayerImpl* child2 = root->children()[1].get();
2907     CCLayerImpl* grandChild1 = child1->children()[0].get();
2908
2909     Vector<CCLayerImpl*> renderSurfaceLayerList;
2910     int dummyMaxTextureSize = 512;
2911     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
2912     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
2913
2914     // Sanity check the scenario we just created.
2915     ASSERT_TRUE(child1);
2916     ASSERT_TRUE(child2);
2917     ASSERT_TRUE(grandChild1);
2918     ASSERT_EQ(1u, renderSurfaceLayerList.size());
2919     ASSERT_EQ(4u, root->renderSurface()->layerList().size());
2920     ASSERT_EQ(1, root->renderSurface()->layerList()[0]->id()); // root layer
2921     ASSERT_EQ(2, root->renderSurface()->layerList()[1]->id()); // child1
2922     ASSERT_EQ(4, root->renderSurface()->layerList()[2]->id()); // grandChild1
2923     ASSERT_EQ(3, root->renderSurface()->layerList()[3]->id()); // child2
2924
2925     // Nothing overlaps the rootLayer at (1, 1), so hit testing there should find the root layer.
2926     IntPoint testPoint = IntPoint(1, 1);
2927     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2928     ASSERT_TRUE(resultLayer);
2929     EXPECT_EQ(1, resultLayer->id());
2930
2931     // At (15, 15), child1 and root are the only layers. child1 is expected to be on top.
2932     testPoint = IntPoint(15, 15);
2933     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2934     ASSERT_TRUE(resultLayer);
2935     EXPECT_EQ(2, resultLayer->id());
2936
2937     // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
2938     testPoint = IntPoint(51, 20);
2939     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2940     ASSERT_TRUE(resultLayer);
2941     EXPECT_EQ(3, resultLayer->id());
2942
2943     // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
2944     testPoint = IntPoint(80, 51);
2945     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2946     ASSERT_TRUE(resultLayer);
2947     EXPECT_EQ(3, resultLayer->id());
2948
2949     // At (51, 51), all layers overlap each other. child2 is expected to be on top of all other layers.
2950     testPoint = IntPoint(51, 51);
2951     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2952     ASSERT_TRUE(resultLayer);
2953     EXPECT_EQ(3, resultLayer->id());
2954
2955     // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to be on top.
2956     testPoint = IntPoint(20, 51);
2957     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
2958     ASSERT_TRUE(resultLayer);
2959     EXPECT_EQ(4, resultLayer->id());
2960 }
2961
2962 TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayerLists)
2963 {
2964     //
2965     // The geometry is set up similarly to the previous case, but
2966     // all layers are forced to be renderSurfaces now.
2967     //
2968     DebugScopedSetImplThread thisScopeIsOnImplThread;
2969
2970     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
2971
2972     WebTransformationMatrix identityMatrix;
2973     FloatPoint anchor(0, 0);
2974     FloatPoint position(0, 0);
2975     IntSize bounds(100, 100);
2976     setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2977     root->setDrawsContent(true);
2978
2979     {
2980         // child 1 and child2 are initialized to overlap between x=50 and x=60.
2981         // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
2982         // The expected stacking order is:
2983         //   (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
2984
2985         OwnPtr<CCLayerImpl> child1 = CCLayerImpl::create(2);
2986         OwnPtr<CCLayerImpl> child2 = CCLayerImpl::create(3);
2987         OwnPtr<CCLayerImpl> grandChild1 = CCLayerImpl::create(4);
2988
2989         position = FloatPoint(10, 10);
2990         bounds = IntSize(50, 50);
2991         setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2992         child1->setDrawsContent(true);
2993         child1->setForceRenderSurface(true);
2994
2995         position = FloatPoint(50, 10);
2996         bounds = IntSize(50, 50);
2997         setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
2998         child2->setDrawsContent(true);
2999         child2->setForceRenderSurface(true);
3000
3001         // Remember that grandChild is positioned with respect to its parent (i.e. child1).
3002         // In screen space, the intended position is (10, 50), with size 100 x 50.
3003         position = FloatPoint(0, 40);
3004         bounds = IntSize(100, 50);
3005         setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, anchor, position, bounds, false);
3006         grandChild1->setDrawsContent(true);
3007         grandChild1->setForceRenderSurface(true);
3008
3009         child1->addChild(grandChild1.release());
3010         root->addChild(child1.release());
3011         root->addChild(child2.release());
3012     }
3013
3014     CCLayerImpl* child1 = root->children()[0].get();
3015     CCLayerImpl* child2 = root->children()[1].get();
3016     CCLayerImpl* grandChild1 = child1->children()[0].get();
3017
3018     Vector<CCLayerImpl*> renderSurfaceLayerList;
3019     int dummyMaxTextureSize = 512;
3020     CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
3021     CCLayerTreeHostCommon::calculateVisibleRects(renderSurfaceLayerList);
3022
3023     // Sanity check the scenario we just created.
3024     ASSERT_TRUE(child1);
3025     ASSERT_TRUE(child2);
3026     ASSERT_TRUE(grandChild1);
3027     ASSERT_TRUE(child1->renderSurface());
3028     ASSERT_TRUE(child2->renderSurface());
3029     ASSERT_TRUE(grandChild1->renderSurface());
3030     ASSERT_EQ(4u, renderSurfaceLayerList.size());
3031     ASSERT_EQ(3u, root->renderSurface()->layerList().size()); // The root surface has the root layer, and child1's and child2's renderSurfaces.
3032     ASSERT_EQ(2u, child1->renderSurface()->layerList().size()); // The child1 surface has the child1 layer and grandChild1's renderSurface.
3033     ASSERT_EQ(1u, child2->renderSurface()->layerList().size());
3034     ASSERT_EQ(1u, grandChild1->renderSurface()->layerList().size());
3035     ASSERT_EQ(1, renderSurfaceLayerList[0]->id()); // root layer
3036     ASSERT_EQ(2, renderSurfaceLayerList[1]->id()); // child1
3037     ASSERT_EQ(4, renderSurfaceLayerList[2]->id()); // grandChild1
3038     ASSERT_EQ(3, renderSurfaceLayerList[3]->id()); // child2
3039
3040     // Nothing overlaps the rootLayer at (1, 1), so hit testing there should find the root layer.
3041     IntPoint testPoint = IntPoint(1, 1);
3042     CCLayerImpl* resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3043     ASSERT_TRUE(resultLayer);
3044     EXPECT_EQ(1, resultLayer->id());
3045
3046     // At (15, 15), child1 and root are the only layers. child1 is expected to be on top.
3047     testPoint = IntPoint(15, 15);
3048     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3049     ASSERT_TRUE(resultLayer);
3050     EXPECT_EQ(2, resultLayer->id());
3051
3052     // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
3053     testPoint = IntPoint(51, 20);
3054     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3055     ASSERT_TRUE(resultLayer);
3056     EXPECT_EQ(3, resultLayer->id());
3057
3058     // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
3059     testPoint = IntPoint(80, 51);
3060     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3061     ASSERT_TRUE(resultLayer);
3062     EXPECT_EQ(3, resultLayer->id());
3063
3064     // At (51, 51), all layers overlap each other. child2 is expected to be on top of all other layers.
3065     testPoint = IntPoint(51, 51);
3066     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3067     ASSERT_TRUE(resultLayer);
3068     EXPECT_EQ(3, resultLayer->id());
3069
3070     // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to be on top.
3071     testPoint = IntPoint(20, 51);
3072     resultLayer = CCLayerTreeHostCommon::findLayerThatIsHitByPoint(testPoint, renderSurfaceLayerList);
3073     ASSERT_TRUE(resultLayer);
3074     EXPECT_EQ(4, resultLayer->id());
3075 }
3076
3077 class MockContentLayerDelegate : public ContentLayerDelegate {
3078 public:
3079     MockContentLayerDelegate() { }
3080     virtual ~MockContentLayerDelegate() { }
3081     virtual void paintContents(SkCanvas*, const IntRect& clip, FloatRect& opaque) OVERRIDE { }
3082 };
3083
3084 PassRefPtr<ContentLayerChromium> createDrawableContentLayerChromium(ContentLayerDelegate* delegate)
3085 {
3086     RefPtr<ContentLayerChromium> toReturn = ContentLayerChromium::create(delegate);
3087     toReturn->setIsD