fce9046c7eb0c5368879b7279efcdac6d78feacf
[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 "cc/CCLayerTreeHostCommon.h"
28
29 #include "CCAnimationTestCommon.h"
30 #include "CCLayerTreeTestCommon.h"
31 #include "LayerChromium.h"
32 #include "TranslateTransformOperation.h"
33 #include "cc/CCLayerAnimationController.h"
34 #include "cc/CCMathUtil.h"
35
36 #include <gmock/gmock.h>
37 #include <gtest/gtest.h>
38 #include <public/WebTransformationMatrix.h>
39
40 using namespace WebCore;
41 using namespace WebKitTests;
42 using WebKit::WebTransformationMatrix;
43
44 namespace {
45
46 void setLayerPropertiesForTesting(LayerChromium* layer, const WebTransformationMatrix& transform, const WebTransformationMatrix& sublayerTransform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D)
47 {
48     layer->setTransform(transform);
49     layer->setSublayerTransform(sublayerTransform);
50     layer->setAnchorPoint(anchor);
51     layer->setPosition(position);
52     layer->setBounds(bounds);
53     layer->setPreserves3D(preserves3D);
54 }
55
56 void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer)
57 {
58     WebTransformationMatrix identityMatrix;
59     Vector<RefPtr<LayerChromium> > dummyRenderSurfaceLayerList;
60     Vector<RefPtr<LayerChromium> > dummyLayerList;
61     int dummyMaxTextureSize = 512;
62     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer, rootLayer, identityMatrix, identityMatrix, dummyRenderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
63 }
64
65 WebTransformationMatrix remove3DComponentOfMatrix(const WebTransformationMatrix& mat)
66 {
67     WebTransformationMatrix ret = mat;
68     ret.setM13(0);
69     ret.setM23(0);
70     ret.setM31(0);
71     ret.setM32(0);
72     ret.setM33(1);
73     ret.setM34(0);
74     ret.setM43(0);
75     return ret;
76 }
77
78 class LayerChromiumWithForcedDrawsContent : public LayerChromium {
79 public:
80     LayerChromiumWithForcedDrawsContent()
81         : LayerChromium()
82     {
83     }
84
85     virtual bool drawsContent() const OVERRIDE { return true; }
86 };
87
88 TEST(CCLayerTreeHostCommonTest, verifyTransformsForNoOpLayer)
89 {
90     // Sanity check: For layers positioned at zero, with zero size,
91     // and with identity transforms, then the drawTransform,
92     // screenSpaceTransform, and the hierarchy passed on to children
93     // layers should also be identity transforms.
94
95     RefPtr<LayerChromium> parent = LayerChromium::create();
96     RefPtr<LayerChromium> child = LayerChromium::create();
97     RefPtr<LayerChromium> grandChild = LayerChromium::create();
98     parent->createRenderSurface();
99     parent->addChild(child);
100     child->addChild(grandChild);
101
102     WebTransformationMatrix identityMatrix;
103     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
104     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
105     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
106
107     executeCalculateDrawTransformsAndVisibility(parent.get());
108
109     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->drawTransform());
110     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->screenSpaceTransform());
111     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
112     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
113     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform());
114     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
115 }
116
117 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleLayer)
118 {
119     // NOTE CAREFULLY:
120     // LayerChromium::position is actually the sum of anchorPoint (in pixel space) and actual position. Because of this, the
121     // value of LayerChromium::position() changes if the anchor changes, even though the layer is not actually located in a
122     // different position. When we initialize layers for testing here, we need to initialize that unintutive position value.
123
124     WebTransformationMatrix identityMatrix;
125     RefPtr<LayerChromium> layer = LayerChromium::create();
126     layer->createRenderSurface();
127
128     // Case 1: setting the sublayer transform should not affect this layer's draw transform or screen-space transform.
129     WebTransformationMatrix arbitraryTranslation;
130     arbitraryTranslation.translate(10.0, 20.0);
131     setLayerPropertiesForTesting(layer.get(), identityMatrix, arbitraryTranslation, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
132     executeCalculateDrawTransformsAndVisibility(layer.get());
133     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform());
134     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
135
136     // Case 2: setting the bounds of the layer should result in a draw transform that translates to half the width and height.
137     //         The screen-space transform should remain as the identity, because it does not deal with transforming to/from the center of the layer.
138     WebTransformationMatrix translationToCenter;
139     translationToCenter.translate(5.0, 6.0);
140     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(10, 12), false);
141     executeCalculateDrawTransformsAndVisibility(layer.get());
142     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, layer->drawTransform());
143     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
144
145     // Case 3: The anchor point by itself (without a layer transform) should have no effect on the transforms.
146     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
147     executeCalculateDrawTransformsAndVisibility(layer.get());
148     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, layer->drawTransform());
149     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
150
151     // Case 4: A change in "actual" position affects both the draw transform and screen space transform.
152     WebTransformationMatrix positionTransform;
153     positionTransform.translate(0.0, 1.2);
154     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
155     executeCalculateDrawTransformsAndVisibility(layer.get());
156     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform * translationToCenter, layer->drawTransform());
157     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->screenSpaceTransform());
158
159     // Case 5: In the correct sequence of transforms, the layer transform should pre-multiply the translationToCenter. This is easily tested by
160     //         using a scale transform, because scale and translation are not commutative.
161     WebTransformationMatrix layerTransform;
162     layerTransform.scale3d(2.0, 2.0, 1.0);
163     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(10, 12), false);
164     executeCalculateDrawTransformsAndVisibility(layer.get());
165     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform * translationToCenter, layer->drawTransform());
166     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->screenSpaceTransform());
167
168     // Case 6: The layer transform should occur with respect to the anchor point.
169     WebTransformationMatrix translationToAnchor;
170     translationToAnchor.translate(5.0, 0.0);
171     WebTransformationMatrix expectedResult = translationToAnchor * layerTransform * translationToAnchor.inverse();
172     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 0.0f), IntSize(10, 12), false);
173     executeCalculateDrawTransformsAndVisibility(layer.get());
174     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
175     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
176
177     // Case 7: Verify that position pre-multiplies the layer transform.
178     //         The current implementation of calculateDrawTransformsAndVisibility does this implicitly, but it is
179     //         still worth testing to detect accidental regressions.
180     expectedResult = positionTransform * translationToAnchor * layerTransform * translationToAnchor.inverse();
181     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 1.2f), IntSize(10, 12), false);
182     executeCalculateDrawTransformsAndVisibility(layer.get());
183     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
184     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
185 }
186
187 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
188 {
189     WebTransformationMatrix identityMatrix;
190     RefPtr<LayerChromium> parent = LayerChromium::create();
191     RefPtr<LayerChromium> child = LayerChromium::create();
192     RefPtr<LayerChromium> grandChild = LayerChromium::create();
193     parent->createRenderSurface();
194     parent->addChild(child);
195     child->addChild(grandChild);
196
197     // Case 1: parent's anchorPoint should not affect child or grandChild.
198     WebTransformationMatrix childTranslationToCenter, grandChildTranslationToCenter;
199     childTranslationToCenter.translate(8.0, 9.0);
200     grandChildTranslationToCenter.translate(38.0, 39.0);
201     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
202     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
203     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
204     executeCalculateDrawTransformsAndVisibility(parent.get());
205     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
206     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
207     EXPECT_TRANSFORMATION_MATRIX_EQ(grandChildTranslationToCenter, grandChild->drawTransform());
208     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
209
210     // Case 2: parent's position affects child and grandChild.
211     WebTransformationMatrix parentPositionTransform;
212     parentPositionTransform.translate(0.0, 1.2);
213     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
214     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
215     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
216     executeCalculateDrawTransformsAndVisibility(parent.get());
217     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * childTranslationToCenter, child->drawTransform());
218     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->screenSpaceTransform());
219     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * grandChildTranslationToCenter, grandChild->drawTransform());
220     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->screenSpaceTransform());
221
222     // Case 3: parent's local transform affects child and grandchild
223     WebTransformationMatrix parentLayerTransform;
224     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
225     WebTransformationMatrix parentTranslationToAnchor;
226     parentTranslationToAnchor.translate(2.5, 3.0);
227     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse();
228     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
229     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
230     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
231     executeCalculateDrawTransformsAndVisibility(parent.get());
232     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
233     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
234     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
235     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
236
237     // Case 4: parent's sublayerMatrix affects child and grandchild
238     //         scaling is used here again so that the correct sequence of transforms is properly tested.
239     //         Note that preserves3D is false, but the sublayer matrix should retain its 3D properties when given to child.
240     //         But then, the child also does not preserve3D. When it gives its hierarchy to the grandChild, it should be flattened to 2D.
241     WebTransformationMatrix parentSublayerMatrix;
242     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
243     WebTransformationMatrix parentTranslationToCenter;
244     parentTranslationToCenter.translate(5.0, 6.0);
245     // Sublayer matrix is applied to the center of the parent layer.
246     parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
247             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
248     WebTransformationMatrix flattenedCompositeTransform = remove3DComponentOfMatrix(parentCompositeTransform);
249     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
250     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
251     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
252     executeCalculateDrawTransformsAndVisibility(parent.get());
253     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
254     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
255     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
256     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->screenSpaceTransform());
257
258     // Case 5: same as Case 4, except that child does preserve 3D, so the grandChild should receive the non-flattened composite transform.
259     //
260     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
261     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), true);
262     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
263     executeCalculateDrawTransformsAndVisibility(parent.get());
264     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
265     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
266     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
267     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
268 }
269
270 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
271 {
272     RefPtr<LayerChromium> parent = LayerChromium::create();
273     RefPtr<LayerChromium> child = LayerChromium::create();
274     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
275     parent->createRenderSurface();
276     parent->addChild(child);
277     child->addChild(grandChild);
278
279     // Child is set up so that a new render surface should be created.
280     child->setOpacity(0.5f);
281
282     WebTransformationMatrix identityMatrix;
283     WebTransformationMatrix parentLayerTransform;
284     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
285     WebTransformationMatrix parentTranslationToAnchor;
286     parentTranslationToAnchor.translate(2.5, 3.0);
287     WebTransformationMatrix parentSublayerMatrix;
288     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
289     WebTransformationMatrix parentTranslationToCenter;
290     parentTranslationToCenter.translate(5.0, 6.0);
291     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
292             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
293     WebTransformationMatrix childTranslationToCenter;
294     childTranslationToCenter.translate(8.0, 9.0);
295
296     // Child's render surface should not exist yet.
297     ASSERT_FALSE(child->renderSurface());
298
299     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
300     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
301     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
302     executeCalculateDrawTransformsAndVisibility(parent.get());
303
304     // Render surface should have been created now.
305     ASSERT_TRUE(child->renderSurface());
306     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
307
308     // The child layer's draw transform should refer to its new render surface; they only differ by a translation to center.
309     // The screen-space transform, however, should still refer to the root.
310     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
311     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
312
313     // Without clipping, the origin transform and draw transform (in this particular case) should be the same.
314     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->originTransform());
315     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->drawTransform());
316
317     // The screen space is the same as the target since the child surface draws into the root.
318     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->screenSpaceTransform());
319 }
320
321 TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica)
322 {
323     RefPtr<LayerChromium> parent = LayerChromium::create();
324     RefPtr<LayerChromium> child = LayerChromium::create();
325     RefPtr<LayerChromium> childReplica = LayerChromium::create();
326     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
327     parent->createRenderSurface();
328     parent->addChild(child);
329     child->addChild(grandChild);
330     child->setReplicaLayer(childReplica.get());
331
332     // Child is set up so that a new render surface should be created.
333     child->setOpacity(0.5f);
334
335     WebTransformationMatrix identityMatrix;
336     WebTransformationMatrix parentLayerTransform;
337     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
338     WebTransformationMatrix parentTranslationToAnchor;
339     parentTranslationToAnchor.translate(2.5, 3.0);
340     WebTransformationMatrix parentSublayerMatrix;
341     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
342     WebTransformationMatrix parentTranslationToCenter;
343     parentTranslationToCenter.translate(5.0, 6.0);
344     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
345             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
346     WebTransformationMatrix childTranslationToCenter;
347     childTranslationToCenter.translate(8.0, 9.0);
348     WebTransformationMatrix replicaLayerTransform;
349     replicaLayerTransform.scale3d(3.0, 3.0, 1.0);
350     WebTransformationMatrix replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform;
351
352     // Child's render surface should not exist yet.
353     ASSERT_FALSE(child->renderSurface());
354
355     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
356     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
357     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
358     setLayerPropertiesForTesting(childReplica.get(), replicaLayerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
359     executeCalculateDrawTransformsAndVisibility(parent.get());
360
361     // Render surface should have been created now.
362     ASSERT_TRUE(child->renderSurface());
363     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
364
365     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaOriginTransform());
366     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaScreenSpaceTransform());
367 }
368
369 TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
370 {
371     // This test creates a more complex tree and verifies it all at once. This covers the following cases:
372     //   - layers that are described w.r.t. a render surface: should have draw transforms described w.r.t. that surface
373     //   - A render surface described w.r.t. an ancestor render surface: should have a draw transform described w.r.t. that ancestor surface
374     //   - Replicas of a render surface are described w.r.t. the replica's transform around its anchor, along with the surface itself.
375     //   - 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.
376     //   - verifying that each layer has a reference to the correct renderSurface and targetRenderSurface values.
377
378     RefPtr<LayerChromium> parent = LayerChromium::create();
379     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
380     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
381     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
382     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
383     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
384     RefPtr<LayerChromium> replicaOfRS1 = LayerChromium::create();
385     RefPtr<LayerChromium> replicaOfRS2 = LayerChromium::create();
386     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
387     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
388     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
389     parent->createRenderSurface();
390     parent->addChild(renderSurface1);
391     parent->addChild(childOfRoot);
392     renderSurface1->addChild(childOfRS1);
393     renderSurface1->addChild(renderSurface2);
394     renderSurface2->addChild(childOfRS2);
395     childOfRoot->addChild(grandChildOfRoot);
396     childOfRS1->addChild(grandChildOfRS1);
397     childOfRS2->addChild(grandChildOfRS2);
398     renderSurface1->setReplicaLayer(replicaOfRS1.get());
399     renderSurface2->setReplicaLayer(replicaOfRS2.get());
400
401     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
402     renderSurface1->setOpacity(0.5f);
403     renderSurface2->setOpacity(0.33f);
404
405     // All layers in the tree are initialized with an anchor at 2.5 and a size of (10,10).
406     // matrix "A" is the composite layer transform used in all layers, centered about the anchor point
407     // matrix "B" is the sublayer transform used in all layers, centered about the center position of the layer.
408     // matrix "R" is the composite replica transform used in all replica layers.
409     //
410     // x component tests that layerTransform and sublayerTransform are done in the right order (translation and scale are noncommutative).
411     // y component has a translation by 1.0 for every ancestor, which indicates the "depth" of the layer in the hierarchy.
412     WebTransformationMatrix translationToAnchor;
413     translationToAnchor.translate(2.5, 0.0);
414     WebTransformationMatrix translationToCenter;
415     translationToCenter.translate(5.0, 5.0);
416     WebTransformationMatrix layerTransform;
417     layerTransform.translate(1.0, 1.0);
418     WebTransformationMatrix sublayerTransform;
419     sublayerTransform.scale3d(10.0, 1.0, 1.0);
420     WebTransformationMatrix replicaLayerTransform;
421     replicaLayerTransform.scale3d(-2.0, 5.0, 1.0);
422
423     WebTransformationMatrix A = translationToAnchor * layerTransform * translationToAnchor.inverse();
424     WebTransformationMatrix B = translationToCenter * sublayerTransform * translationToCenter.inverse();
425     WebTransformationMatrix R = A * translationToAnchor * replicaLayerTransform * translationToAnchor.inverse();
426
427     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
428     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
429     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
430     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
431     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
432     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
433     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
434     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
435     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
436     setLayerPropertiesForTesting(replicaOfRS1.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
437     setLayerPropertiesForTesting(replicaOfRS2.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
438
439     executeCalculateDrawTransformsAndVisibility(parent.get());
440
441     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
442     //
443     ASSERT_TRUE(parent->renderSurface());
444     ASSERT_FALSE(childOfRoot->renderSurface());
445     ASSERT_FALSE(grandChildOfRoot->renderSurface());
446
447     ASSERT_TRUE(renderSurface1->renderSurface());
448     ASSERT_FALSE(childOfRS1->renderSurface());
449     ASSERT_FALSE(grandChildOfRS1->renderSurface());
450
451     ASSERT_TRUE(renderSurface2->renderSurface());
452     ASSERT_FALSE(childOfRS2->renderSurface());
453     ASSERT_FALSE(grandChildOfRS2->renderSurface());
454
455     // Verify all targetRenderSurface accessors
456     //
457     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
458     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
459     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
460
461     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
462     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
463     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
464
465     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
466     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
467     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
468
469     // Verify layer draw transforms
470     //  note that draw transforms are described with respect to the nearest ancestor render surface
471     //  but screen space transforms are described with respect to the root.
472     //
473     EXPECT_TRANSFORMATION_MATRIX_EQ(A * translationToCenter, parent->drawTransform());
474     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * translationToCenter, childOfRoot->drawTransform());
475     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * translationToCenter, grandChildOfRoot->drawTransform());
476
477     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface1->drawTransform());
478     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS1->drawTransform());
479     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS1->drawTransform());
480
481     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface2->drawTransform());
482     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS2->drawTransform());
483     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS2->drawTransform());
484
485     // Verify layer screen-space transforms
486     //
487     EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screenSpaceTransform());
488     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->screenSpaceTransform());
489     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->screenSpaceTransform());
490
491     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->screenSpaceTransform());
492     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, childOfRS1->screenSpaceTransform());
493     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, grandChildOfRS1->screenSpaceTransform());
494
495     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->screenSpaceTransform());
496     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, childOfRS2->screenSpaceTransform());
497     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A, grandChildOfRS2->screenSpaceTransform());
498
499     // Verify render surface transforms.
500     //
501     // Origin transform of render surface 1 is described with respect to root.
502     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->originTransform());
503     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaOriginTransform());
504     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->screenSpaceTransform());
505     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaScreenSpaceTransform());
506     // Origin transform of render surface 2 is described with respect to render surface 2.
507     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, renderSurface2->renderSurface()->originTransform());
508     EXPECT_TRANSFORMATION_MATRIX_EQ(B * R, renderSurface2->renderSurface()->replicaOriginTransform());
509     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->renderSurface()->screenSpaceTransform());
510     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R, renderSurface2->renderSurface()->replicaScreenSpaceTransform());
511
512     // Sanity check. If these fail there is probably a bug in the test itself.
513     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
514     // encodes the "depth" of the layer in the tree.
515     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
516     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
517     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
518
519     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
520     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
521     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
522
523     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
524     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
525     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
526 }
527
528 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForClipLayer)
529 {
530     RefPtr<LayerChromium> parent = LayerChromium::create();
531     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
532     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
533     renderSurface1->setOpacity(0.9f);
534
535     const WebTransformationMatrix identityMatrix;
536     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
537     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false);
538
539     parent->createRenderSurface();
540     parent->setClipRect(IntRect(0, 0, 10, 10));
541     parent->addChild(renderSurface1);
542     renderSurface1->createRenderSurface();
543     renderSurface1->addChild(child);
544
545     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
546     Vector<RefPtr<LayerChromium> > dummyLayerList;
547     int dummyMaxTextureSize = 512;
548     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
549
550     // The child layer's content is entirely outside the parent's clip rect, so the intermediate
551     // render surface should have been removed. Render surfaces without children or visible
552     // content are unexpected at draw time (e.g. we might try to create a content texture of size 0).
553     ASSERT_FALSE(renderSurface1->renderSurface());
554     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
555 }
556
557 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
558 {
559     RefPtr<LayerChromium> parent = LayerChromium::create();
560     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
561     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
562     renderSurface1->setOpacity(0);
563
564     const WebTransformationMatrix identityMatrix;
565     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
566     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
567
568     parent->createRenderSurface();
569     parent->addChild(renderSurface1);
570     renderSurface1->createRenderSurface();
571     renderSurface1->addChild(child);
572
573     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
574     Vector<RefPtr<LayerChromium> > dummyLayerList;
575     int dummyMaxTextureSize = 512;
576     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
577
578     // Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
579     // Also, the drawable content rect should not have been extended by the children.
580     EXPECT_EQ(parent->renderSurface()->layerList().size(), 0U);
581     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
582     EXPECT_EQ(parent->drawableContentRect(), IntRect());
583 }
584
585 TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
586 {
587     RefPtr<LayerChromium> parent = LayerChromium::create();
588     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
589     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
590     renderSurface1->setForceRenderSurface(true);
591
592     const WebTransformationMatrix identityMatrix;
593     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
594     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
595
596     parent->createRenderSurface();
597     parent->setClipRect(IntRect(0, 0, 10, 10));
598     parent->addChild(renderSurface1);
599     renderSurface1->addChild(child);
600
601     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
602     Vector<RefPtr<LayerChromium> > dummyLayerList;
603     int dummyMaxTextureSize = 512;
604     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
605
606     EXPECT_TRUE(renderSurface1->renderSurface());
607     EXPECT_EQ(renderSurfaceLayerList.size(), 1U);
608
609     renderSurfaceLayerList.clear();
610     renderSurface1->setForceRenderSurface(false);
611     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
612     EXPECT_FALSE(renderSurface1->renderSurface());
613     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
614 }
615
616 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
617 {
618     // The entire subtree of layers that are outside the clipRect should be culled away,
619     // and should not affect the renderSurfaceLayerList.
620     //
621     // The test tree is set up as follows:
622     //  - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
623     //  - parent is a large container layer.
624     //  - child has masksToBounds=true to cause clipping.
625     //  - grandChild is positioned outside of the child's bounds
626     //  - greatGrandChild is also kept outside child's bounds.
627     //
628     // In this configuration, grandChild and greatGrandChild are completely outside the
629     // clipRect, and they should never get scheduled on the list of renderSurfaces.
630     //
631
632     const WebTransformationMatrix identityMatrix;
633     RefPtr<LayerChromium> parent = LayerChromium::create();
634     RefPtr<LayerChromium> child = LayerChromium::create();
635     RefPtr<LayerChromium> grandChild = LayerChromium::create();
636     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
637     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
638     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
639     parent->createRenderSurface();
640     parent->addChild(child);
641     child->addChild(grandChild);
642     grandChild->addChild(greatGrandChild);
643
644     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
645     // even though grandChild and greatGrandChild should be clipped.
646     child->addChild(leafNode1);
647     greatGrandChild->addChild(leafNode2);
648
649     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
650     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
651     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
652     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
653     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
654     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
655
656     child->setMasksToBounds(true);
657     child->setOpacity(0.4f);
658     grandChild->setOpacity(0.5f);
659     greatGrandChild->setOpacity(0.4f);
660
661     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
662     Vector<RefPtr<LayerChromium> > dummyLayerList;
663     int dummyMaxTextureSize = 512;
664
665     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
666     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
667     renderSurfaceLayerList.append(parent.get());
668
669     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
670
671     ASSERT_EQ(2U, renderSurfaceLayerList.size());
672     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
673     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
674 }
675
676 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfacesCrashRepro)
677 {
678     // This is a similar situation as verifyClipRectCullsRenderSurfaces, except that
679     // it reproduces a crash bug http://code.google.com/p/chromium/issues/detail?id=106734.
680
681     const WebTransformationMatrix identityMatrix;
682     RefPtr<LayerChromium> parent = LayerChromium::create();
683     RefPtr<LayerChromium> child = LayerChromium::create();
684     RefPtr<LayerChromium> grandChild = LayerChromium::create();
685     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
686     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
687     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
688     parent->createRenderSurface();
689     parent->addChild(child);
690     child->addChild(grandChild);
691     grandChild->addChild(greatGrandChild);
692
693     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
694     // even though grandChild and greatGrandChild should be clipped.
695     child->addChild(leafNode1);
696     greatGrandChild->addChild(leafNode2);
697
698     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
699     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
700     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
701     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
702     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
703     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
704
705     child->setMasksToBounds(true);
706     child->setOpacity(0.4f);
707     grandChild->setOpacity(0.5f);
708     greatGrandChild->setOpacity(0.4f);
709
710     // Contaminate the grandChild and greatGrandChild's clipRect to reproduce the crash
711     // bug found in http://code.google.com/p/chromium/issues/detail?id=106734. In this
712     // bug, the clipRect was not re-computed for layers that create RenderSurfaces, and
713     // therefore leafNode2 thinks it should draw itself. As a result, an extra
714     // renderSurface remains on the renderSurfaceLayerList, which violates the assumption
715     // that an empty renderSurface will always be the last item on the list, which
716     // ultimately caused the crash.
717     child->setClipRect(IntRect(IntPoint::zero(), IntSize(20, 20)));
718     greatGrandChild->setClipRect(IntRect(IntPoint::zero(), IntSize(1234, 1234)));
719
720     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
721     Vector<RefPtr<LayerChromium> > dummyLayerList;
722     int dummyMaxTextureSize = 512;
723
724     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
725     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
726     renderSurfaceLayerList.append(parent.get());
727
728     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
729
730     ASSERT_EQ(2U, renderSurfaceLayerList.size());
731     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
732     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
733 }
734
735 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
736 {
737     // When a renderSurface has a clipRect, it is used to clip the contentRect
738     // of the surface. When the renderSurface is animating its transforms, then
739     // the contentRect's position in the clipRect is not defined on the main
740     // thread, and its contentRect should not be clipped.
741
742     // The test tree is set up as follows:
743     //  - parent is a container layer that masksToBounds=true to cause clipping.
744     //  - child is a renderSurface, which has a clipRect set to the bounds of the parent.
745     //  - grandChild is a renderSurface, and the only visible content in child. It is positioned outside of the clipRect from parent.
746
747     // In this configuration, grandChild should be outside the clipped
748     // contentRect of the child, making grandChild not appear in the
749     // renderSurfaceLayerList. However, when we place an animation on the child,
750     // this clipping should be avoided and we should keep the grandChild
751     // in the renderSurfaceLayerList.
752
753     const WebTransformationMatrix identityMatrix;
754     RefPtr<LayerChromium> parent = LayerChromium::create();
755     RefPtr<LayerChromium> child = LayerChromium::create();
756     RefPtr<LayerChromium> grandChild = LayerChromium::create();
757     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode = adoptRef(new LayerChromiumWithForcedDrawsContent());
758     parent->addChild(child);
759     child->addChild(grandChild);
760     grandChild->addChild(leafNode);
761
762     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
763     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
764     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false);
765     setLayerPropertiesForTesting(leafNode.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
766
767     parent->setMasksToBounds(true);
768     child->setOpacity(0.4f);
769     grandChild->setOpacity(0.4f);
770
771     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
772     Vector<RefPtr<LayerChromium> > dummyLayerList;
773     int dummyMaxTextureSize = 512;
774
775     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
776     parent->createRenderSurface();
777     renderSurfaceLayerList.append(parent.get());
778
779     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
780
781     // Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
782     ASSERT_EQ(1U, renderSurfaceLayerList.size());
783     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
784
785     // Now put an animating transform on child.
786     addAnimatedTransformToController(*child->layerAnimationController(), 10, 30, 0);
787
788     parent->clearRenderSurface();
789     child->clearRenderSurface();
790     grandChild->clearRenderSurface();
791     renderSurfaceLayerList.clear();
792     dummyLayerList.clear();
793
794     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
795     parent->createRenderSurface();
796     renderSurfaceLayerList.append(parent.get());
797
798     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
799
800     // With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
801     ASSERT_EQ(3U, renderSurfaceLayerList.size());
802     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
803     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
804     EXPECT_EQ(grandChild->id(), renderSurfaceLayerList[2]->id());
805 }
806
807 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToLayers)
808 {
809     // Verify that layers get the appropriate clipRects when their parent masksToBounds is true.
810     //
811     //   grandChild1 - completely inside the region; clipRect should be the mask region (larger than this layer's bounds).
812     //   grandChild2 - partially clipped but NOT masksToBounds; the clipRect should be the parent's clipRect regardless of the layer's bounds.
813     //   grandChild3 - partially clipped and masksToBounds; the clipRect will be the intersection of layerBounds and the mask region.
814     //   grandChild4 - outside parent's clipRect, and masksToBounds; the clipRect should be empty.
815     //
816
817     const WebTransformationMatrix identityMatrix;
818     RefPtr<LayerChromium> parent = LayerChromium::create();
819     RefPtr<LayerChromium> child = LayerChromium::create();
820     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
821     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
822     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
823     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
824
825     parent->createRenderSurface();
826     parent->addChild(child);
827     child->addChild(grandChild1);
828     child->addChild(grandChild2);
829     child->addChild(grandChild3);
830     child->addChild(grandChild4);
831
832     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
833     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
834     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
835     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
836     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
837     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
838
839     child->setMasksToBounds(true);
840     grandChild3->setMasksToBounds(true);
841     grandChild4->setMasksToBounds(true);
842
843     // Force everyone to be a render surface.
844     child->setOpacity(0.4f);
845     grandChild1->setOpacity(0.5f);
846     grandChild2->setOpacity(0.5f);
847     grandChild3->setOpacity(0.5f);
848     grandChild4->setOpacity(0.5f);
849
850     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
851     Vector<RefPtr<LayerChromium> > dummyLayerList;
852     int dummyMaxTextureSize = 512;
853
854     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
855     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
856     renderSurfaceLayerList.append(parent.get());
857
858     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
859
860     EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild1->clipRect());
861     EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild2->clipRect());
862     EXPECT_INT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->clipRect());
863     EXPECT_TRUE(grandChild4->clipRect().isEmpty());
864 }
865
866 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
867 {
868     // Verify that renderSurfaces (and their layers) get the appropriate clipRects when their parent masksToBounds is true.
869     //
870     // Layers that own renderSurfaces (at least for now) do not inherit any clipRect;
871     // instead the surface will enforce the clip for the entire subtree. They may still
872     // have a clipRect of their own layer bounds, however, if masksToBounds was true.
873     //
874
875     const WebTransformationMatrix identityMatrix;
876     RefPtr<LayerChromium> parent = LayerChromium::create();
877     RefPtr<LayerChromium> child = LayerChromium::create();
878     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
879     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
880     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
881     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
882     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
883     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
884     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode3 = adoptRef(new LayerChromiumWithForcedDrawsContent());
885     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode4 = adoptRef(new LayerChromiumWithForcedDrawsContent());
886
887     parent->createRenderSurface();
888     parent->addChild(child);
889     child->addChild(grandChild1);
890     child->addChild(grandChild2);
891     child->addChild(grandChild3);
892     child->addChild(grandChild4);
893
894     // the leaf nodes ensure that these grandChildren become renderSurfaces for this test.
895     grandChild1->addChild(leafNode1);
896     grandChild2->addChild(leafNode2);
897     grandChild3->addChild(leafNode3);
898     grandChild4->addChild(leafNode4);
899
900     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
901     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
902     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
903     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
904     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
905     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
906     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
907     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
908     setLayerPropertiesForTesting(leafNode3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
909     setLayerPropertiesForTesting(leafNode4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
910
911     child->setMasksToBounds(true);
912     grandChild3->setMasksToBounds(true);
913     grandChild4->setMasksToBounds(true);
914
915     // Force everyone to be a render surface.
916     child->setOpacity(0.4f);
917     grandChild1->setOpacity(0.5f);
918     grandChild2->setOpacity(0.5f);
919     grandChild3->setOpacity(0.5f);
920     grandChild4->setOpacity(0.5f);
921
922     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
923     Vector<RefPtr<LayerChromium> > dummyLayerList;
924     int dummyMaxTextureSize = 512;
925
926     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
927     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
928     renderSurfaceLayerList.append(parent.get());
929
930     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
931
932     ASSERT_TRUE(grandChild1->renderSurface());
933     ASSERT_TRUE(grandChild2->renderSurface());
934     ASSERT_TRUE(grandChild3->renderSurface());
935     EXPECT_FALSE(grandChild4->renderSurface()); // Because grandChild4 is entirely clipped, it is expected to not have a renderSurface.
936
937     // Surfaces are clipped by their parent, but un-affected by the owning layer's masksToBounds.
938     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1->renderSurface()->clipRect());
939     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2->renderSurface()->clipRect());
940     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3->renderSurface()->clipRect());
941
942     // Layers do not inherit the clipRect from their owned surfaces, but if masksToBounds is true, they do create their own clipRect.
943     EXPECT_FALSE(grandChild1->usesLayerClipping());
944     EXPECT_FALSE(grandChild2->usesLayerClipping());
945     EXPECT_TRUE(grandChild3->usesLayerClipping());
946     EXPECT_TRUE(grandChild4->usesLayerClipping());
947 }
948
949 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
950 {
951     RefPtr<LayerChromium> parent = LayerChromium::create();
952     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
953     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
954     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
955     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
956     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
957     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
958     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
959     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
960     parent->createRenderSurface();
961     parent->addChild(renderSurface1);
962     parent->addChild(childOfRoot);
963     renderSurface1->addChild(childOfRS1);
964     renderSurface1->addChild(renderSurface2);
965     renderSurface2->addChild(childOfRS2);
966     childOfRoot->addChild(grandChildOfRoot);
967     childOfRS1->addChild(grandChildOfRS1);
968     childOfRS2->addChild(grandChildOfRS2);
969
970     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
971     addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false);
972
973     // Also put an animated opacity on a layer without descendants.
974     addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false);
975
976     WebTransformationMatrix layerTransform;
977     layerTransform.translate(1.0, 1.0);
978     WebTransformationMatrix sublayerTransform;
979     sublayerTransform.scale3d(10.0, 1.0, 1.0);
980
981     // In combination with descendantDrawsContent and masksToBounds, an animated transform forces the layer to have a new renderSurface.
982     addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
983     renderSurface2->setMasksToBounds(true);
984
985     // Also put transform animations on grandChildOfRoot, and grandChildOfRS2
986     addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0);
987     addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0);
988
989     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
990     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
991     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
992     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
993     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
994     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
995     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
996     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
997     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
998
999     executeCalculateDrawTransformsAndVisibility(parent.get());
1000
1001     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
1002     //
1003     ASSERT_TRUE(parent->renderSurface());
1004     ASSERT_FALSE(childOfRoot->renderSurface());
1005     ASSERT_FALSE(grandChildOfRoot->renderSurface());
1006
1007     ASSERT_TRUE(renderSurface1->renderSurface());
1008     ASSERT_FALSE(childOfRS1->renderSurface());
1009     ASSERT_FALSE(grandChildOfRS1->renderSurface());
1010
1011     ASSERT_TRUE(renderSurface2->renderSurface());
1012     ASSERT_FALSE(childOfRS2->renderSurface());
1013     ASSERT_FALSE(grandChildOfRS2->renderSurface());
1014
1015     // Verify all targetRenderSurface accessors
1016     //
1017     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
1018     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
1019     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
1020
1021     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
1022     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
1023     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
1024
1025     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
1026     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
1027     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
1028
1029     // Verify drawOpacityIsAnimating values
1030     //
1031     EXPECT_FALSE(parent->drawOpacityIsAnimating());
1032     EXPECT_FALSE(childOfRoot->drawOpacityIsAnimating());
1033     EXPECT_TRUE(grandChildOfRoot->drawOpacityIsAnimating());
1034     EXPECT_FALSE(renderSurface1->drawOpacityIsAnimating());
1035     EXPECT_TRUE(renderSurface1->renderSurface()->drawOpacityIsAnimating());
1036     EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating());
1037     EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating());
1038     EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating());
1039     EXPECT_FALSE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
1040     EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating());
1041     EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating());
1042
1043     // Verify drawTransformsAnimatingInTarget values
1044     //
1045     EXPECT_FALSE(parent->drawTransformIsAnimating());
1046     EXPECT_FALSE(childOfRoot->drawTransformIsAnimating());
1047     EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating());
1048     EXPECT_FALSE(renderSurface1->drawTransformIsAnimating());
1049     EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnimating());
1050     EXPECT_FALSE(childOfRS1->drawTransformIsAnimating());
1051     EXPECT_FALSE(grandChildOfRS1->drawTransformIsAnimating());
1052     EXPECT_FALSE(renderSurface2->drawTransformIsAnimating());
1053     EXPECT_TRUE(renderSurface2->renderSurface()->targetSurfaceTransformsAreAnimating());
1054     EXPECT_FALSE(childOfRS2->drawTransformIsAnimating());
1055     EXPECT_TRUE(grandChildOfRS2->drawTransformIsAnimating());
1056
1057     // Verify drawTransformsAnimatingInScreen values
1058     //
1059     EXPECT_FALSE(parent->screenSpaceTransformIsAnimating());
1060     EXPECT_FALSE(childOfRoot->screenSpaceTransformIsAnimating());
1061     EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating());
1062     EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating());
1063     EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimating());
1064     EXPECT_FALSE(childOfRS1->screenSpaceTransformIsAnimating());
1065     EXPECT_FALSE(grandChildOfRS1->screenSpaceTransformIsAnimating());
1066     EXPECT_TRUE(renderSurface2->screenSpaceTransformIsAnimating());
1067     EXPECT_TRUE(renderSurface2->renderSurface()->screenSpaceTransformsAreAnimating());
1068     EXPECT_TRUE(childOfRS2->screenSpaceTransformIsAnimating());
1069     EXPECT_TRUE(grandChildOfRS2->screenSpaceTransformIsAnimating());
1070
1071
1072     // Sanity check. If these fail there is probably a bug in the test itself.
1073     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
1074     // encodes the "depth" of the layer in the tree.
1075     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
1076     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
1077     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
1078
1079     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
1080     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
1081     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
1082
1083     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
1084     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
1085     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
1086 }
1087
1088 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForIdentityTransform)
1089 {
1090     // Test the calculateVisibleRect() function works correctly for identity transforms.
1091
1092     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1093     WebTransformationMatrix layerToSurfaceTransform;
1094
1095     // Case 1: Layer is contained within the surface.
1096     IntRect layerContentRect = IntRect(IntPoint(10, 10), IntSize(30, 30));
1097     IntRect expected = IntRect(IntPoint(10, 10), IntSize(30, 30));
1098     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1099     EXPECT_INT_RECT_EQ(expected, actual);
1100
1101     // Case 2: Layer is outside the surface rect.
1102     layerContentRect = IntRect(IntPoint(120, 120), IntSize(30, 30));
1103     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1104     EXPECT_TRUE(actual.isEmpty());
1105
1106     // Case 3: Layer is partially overlapping the surface rect.
1107     layerContentRect = IntRect(IntPoint(80, 80), IntSize(30, 30));
1108     expected = IntRect(IntPoint(80, 80), IntSize(20, 20));
1109     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1110     EXPECT_INT_RECT_EQ(expected, actual);
1111 }
1112
1113 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForTranslations)
1114 {
1115     // Test the calculateVisibleRect() function works correctly for scaling transforms.
1116
1117     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1118     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1119     WebTransformationMatrix layerToSurfaceTransform;
1120
1121     // Case 1: Layer is contained within the surface.
1122     layerToSurfaceTransform.makeIdentity();
1123     layerToSurfaceTransform.translate(10, 10);
1124     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1125     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1126     EXPECT_INT_RECT_EQ(expected, actual);
1127
1128     // Case 2: Layer is outside the surface rect.
1129     layerToSurfaceTransform.makeIdentity();
1130     layerToSurfaceTransform.translate(120, 120);
1131     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1132     EXPECT_TRUE(actual.isEmpty());
1133
1134     // Case 3: Layer is partially overlapping the surface rect.
1135     layerToSurfaceTransform.makeIdentity();
1136     layerToSurfaceTransform.translate(80, 80);
1137     expected = IntRect(IntPoint(0, 0), IntSize(20, 20));
1138     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1139     EXPECT_INT_RECT_EQ(expected, actual);
1140 }
1141
1142 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor2DRotations)
1143 {
1144     // Test the calculateVisibleRect() function works correctly for rotations about z-axis (i.e. 2D rotations).
1145     // Remember that calculateVisibleRect() should return the visible rect in the layer's space.
1146
1147     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1148     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1149     WebTransformationMatrix layerToSurfaceTransform;
1150
1151     // Case 1: Layer is contained within the surface.
1152     layerToSurfaceTransform.makeIdentity();
1153     layerToSurfaceTransform.translate(50, 50);
1154     layerToSurfaceTransform.rotate(45);
1155     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1156     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1157     EXPECT_INT_RECT_EQ(expected, actual);
1158
1159     // Case 2: Layer is outside the surface rect.
1160     layerToSurfaceTransform.makeIdentity();
1161     layerToSurfaceTransform.translate(-50, 0);
1162     layerToSurfaceTransform.rotate(45);
1163     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1164     EXPECT_TRUE(actual.isEmpty());
1165
1166     // Case 3: The layer is rotated about its top-left corner. In surface space, the layer
1167     //         is oriented diagonally, with the left half outside of the renderSurface. In
1168     //         this case, the visible rect should still be the entire layer (remember the
1169     //         visible rect is computed in layer space); both the top-left and
1170     //         bottom-right corners of the layer are still visible.
1171     layerToSurfaceTransform.makeIdentity();
1172     layerToSurfaceTransform.rotate(45);
1173     expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1174     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1175     EXPECT_INT_RECT_EQ(expected, actual);
1176
1177     // Case 4: The layer is rotated about its top-left corner, and translated upwards. In
1178     //         surface space, the layer is oriented diagonally, with only the top corner
1179     //         of the surface overlapping the layer. In layer space, the render surface
1180     //         overlaps the right side of the layer. The visible rect should be the
1181     //         layer's right half.
1182     layerToSurfaceTransform.makeIdentity();
1183     layerToSurfaceTransform.translate(0, -sqrt(2.0) * 15);
1184     layerToSurfaceTransform.rotate(45);
1185     expected = IntRect(IntPoint(15, 0), IntSize(15, 30)); // right half of layer bounds.
1186     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1187     EXPECT_INT_RECT_EQ(expected, actual);
1188 }
1189
1190 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicTransform)
1191 {
1192     // Test that the calculateVisibleRect() function works correctly for 3d transforms.
1193
1194     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1195     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1196     WebTransformationMatrix layerToSurfaceTransform;
1197
1198     // Case 1: Orthographic projection of a layer rotated about y-axis by 45 degrees, should be fully contained in the renderSurface.
1199     layerToSurfaceTransform.makeIdentity();
1200     layerToSurfaceTransform.rotate3d(0, 45, 0);
1201     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1202     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1203     EXPECT_INT_RECT_EQ(expected, actual);
1204
1205     // Case 2: Orthographic projection of a layer rotated about y-axis by 45 degrees, but
1206     //         shifted to the side so only the right-half the layer would be visible on
1207     //         the surface.
1208     double halfWidthOfRotatedLayer = (100.0 / sqrt(2.0)) * 0.5; // 100.0 is the un-rotated layer width; divided by sqrt(2.0) is the rotated width.
1209     layerToSurfaceTransform.makeIdentity();
1210     layerToSurfaceTransform.translate(-halfWidthOfRotatedLayer, 0);
1211     layerToSurfaceTransform.rotate3d(0, 45, 0); // rotates about the left edge of the layer
1212     expected = IntRect(IntPoint(50, 0), IntSize(50, 100)); // right half of the layer.
1213     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1214     EXPECT_INT_RECT_EQ(expected, actual);
1215 }
1216
1217 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveTransform)
1218 {
1219     // Test the calculateVisibleRect() function works correctly when the layer has a
1220     // perspective projection onto the target surface.
1221
1222     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1223     IntRect layerContentRect = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1224     WebTransformationMatrix layerToSurfaceTransform;
1225
1226     // Case 1: Even though the layer is twice as large as the surface, due to perspective
1227     //         foreshortening, the layer will fit fully in the surface when its translated
1228     //         more than the perspective amount.
1229     layerToSurfaceTransform.makeIdentity();
1230
1231     // The following sequence of transforms applies the perspective about the center of the surface.
1232     layerToSurfaceTransform.translate(50, 50);
1233     layerToSurfaceTransform.applyPerspective(9);
1234     layerToSurfaceTransform.translate(-50, -50);
1235
1236     // This translate places the layer in front of the surface's projection plane.
1237     layerToSurfaceTransform.translate3d(0, 0, -27);
1238
1239     IntRect expected = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1240     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1241     EXPECT_INT_RECT_EQ(expected, actual);
1242
1243     // Case 2: same projection as before, except that the layer is also translated to the
1244     //         side, so that only the right half of the layer should be visible.
1245     //
1246     // Explanation of expected result:
1247     // The perspective ratio is (z distance between layer and camera origin) / (z distance between projection plane and camera origin) == ((-27 - 9) / 9)
1248     // 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
1249     // visible), then we would need to translate by (-36 / 9) * -50 == -200 in the layer's units.
1250     //
1251     layerToSurfaceTransform.translate3d(-200, 0, 0);
1252     expected = IntRect(IntPoint(50, -50), IntSize(100, 200)); // The right half of the layer's bounding rect.
1253     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1254     EXPECT_INT_RECT_EQ(expected, actual);
1255 }
1256
1257 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicIsNotClippedBehindSurface)
1258 {
1259     // There is currently no explicit concept of an orthographic projection plane in our
1260     // code (nor in the CSS spec to my knowledge). Therefore, layers that are technically
1261     // behind the surface in an orthographic world should not be clipped when they are
1262     // flattened to the surface.
1263
1264     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1265     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1266     WebTransformationMatrix layerToSurfaceTransform;
1267
1268     // This sequence of transforms effectively rotates the layer about the y-axis at the
1269     // center of the layer.
1270     layerToSurfaceTransform.makeIdentity();
1271     layerToSurfaceTransform.translate(50, 0);
1272     layerToSurfaceTransform.rotate3d(0, 45, 0);
1273     layerToSurfaceTransform.translate(-50, 0);
1274
1275     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1276     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1277     EXPECT_INT_RECT_EQ(expected, actual);
1278 }
1279
1280 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveWhenClippedByW)
1281 {
1282     // Test the calculateVisibleRect() function works correctly when projecting a surface
1283     // onto a layer, but the layer is partially behind the camera (not just behind the
1284     // projection plane). In this case, the cartesian coordinates may seem to be valid,
1285     // but actually they are not. The visibleRect needs to be properly clipped by the
1286     // w = 0 plane in homogeneous coordinates before converting to cartesian coordinates.
1287
1288     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1289     IntRect layerContentRect = IntRect(IntPoint(-10, -1), IntSize(20, 2));
1290     WebTransformationMatrix layerToSurfaceTransform;
1291
1292     // The layer is positioned so that the right half of the layer should be in front of
1293     // the camera, while the other half is behind the surface's projection plane. The
1294     // following sequence of transforms applies the perspective and rotation about the
1295     // center of the layer.
1296     layerToSurfaceTransform.makeIdentity();
1297     layerToSurfaceTransform.applyPerspective(1);
1298     layerToSurfaceTransform.translate3d(-2, 0, 1);
1299     layerToSurfaceTransform.rotate3d(0, 45, 0);
1300
1301     // Sanity check that this transform does indeed cause w < 0 when applying the
1302     // transform, otherwise this code is not testing the intended scenario.
1303     bool clipped = false;
1304     CCMathUtil::mapQuad(layerToSurfaceTransform, FloatQuad(FloatRect(layerContentRect)), clipped);
1305     ASSERT_TRUE(clipped);
1306
1307     int expectedXPosition = 0;
1308     int expectedWidth = 10;
1309     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1310     EXPECT_EQ(expectedXPosition, actual.x());
1311     EXPECT_EQ(expectedWidth, actual.width());
1312 }
1313
1314 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection)
1315 {
1316     // To determine visibleRect in layer space, there needs to be an un-projection from
1317     // surface space to layer space. When the original transform was a perspective
1318     // projection that was clipped, it returns a rect that encloses the clipped bounds.
1319     // Un-projecting this new rect may require clipping again.
1320
1321     // This sequence of transforms causes one corner of the layer to protrude across the w = 0 plane, and should be clipped.
1322     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1323     IntRect layerContentRect = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1324     WebTransformationMatrix layerToSurfaceTransform;
1325     layerToSurfaceTransform.makeIdentity();
1326     layerToSurfaceTransform.applyPerspective(1);
1327     layerToSurfaceTransform.translate3d(0, 0, -5);
1328     layerToSurfaceTransform.rotate3d(0, 45, 0);
1329     layerToSurfaceTransform.rotate3d(80, 0, 0);
1330
1331     // Sanity check that un-projection does indeed cause w < 0, otherwise this code is not
1332     // testing the intended scenario.
1333     bool clipped = false;
1334     FloatRect clippedRect = CCMathUtil::mapClippedRect(layerToSurfaceTransform, layerContentRect);
1335     CCMathUtil::projectQuad(layerToSurfaceTransform.inverse(), FloatQuad(clippedRect), clipped);
1336     ASSERT_TRUE(clipped);
1337
1338     // Only the corner of the layer is not visible on the surface because of being
1339     // clipped. But, the net result of rounding visible region to an axis-aligned rect is
1340     // that the entire layer should still be considered visible.
1341     IntRect expected = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1342     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1343     EXPECT_INT_RECT_EQ(expected, actual);
1344 }
1345
1346 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d)
1347 {
1348     // Verify the behavior of back-face culling when there are no preserve-3d layers. Note
1349     // that 3d transforms still apply in this case, but they are "flattened" to each
1350     // parent layer according to current W3C spec.
1351
1352     const WebTransformationMatrix identityMatrix;
1353     RefPtr<LayerChromium> parent = LayerChromium::create();
1354     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1355     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1356     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1357     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1358     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1359     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1360     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1361     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1362
1363     parent->createRenderSurface();
1364     parent->addChild(frontFacingChild);
1365     parent->addChild(backFacingChild);
1366     parent->addChild(frontFacingSurface);
1367     parent->addChild(backFacingSurface);
1368     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
1369     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
1370     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
1371     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
1372
1373     // Nothing is double-sided
1374     frontFacingChild->setDoubleSided(false);
1375     backFacingChild->setDoubleSided(false);
1376     frontFacingSurface->setDoubleSided(false);
1377     backFacingSurface->setDoubleSided(false);
1378     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
1379     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
1380     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
1381     backFacingChildOfBackFacingSurface->setDoubleSided(false);
1382
1383     WebTransformationMatrix backfaceMatrix;
1384     backfaceMatrix.translate(50, 50);
1385     backfaceMatrix.rotate3d(0, 1, 0, 180);
1386     backfaceMatrix.translate(-50, -50);
1387
1388     // Having a descendant and opacity will force these to have render surfaces.
1389     frontFacingSurface->setOpacity(0.5f);
1390     backFacingSurface->setOpacity(0.5f);
1391
1392     // Nothing preserves 3d. According to current W3C CSS Transforms spec, these layers
1393     // should blindly use their own local transforms to determine back-face culling.
1394     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1395     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1396     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1397     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1398     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1399     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1400     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1401     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1402     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1403
1404     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1405     Vector<RefPtr<LayerChromium> > dummyLayerList;
1406     int dummyMaxTextureSize = 512;
1407     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
1408     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1409     renderSurfaceLayerList.append(parent.get());
1410
1411     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1412
1413     // Verify which renderSurfaces were created.
1414     EXPECT_FALSE(frontFacingChild->renderSurface());
1415     EXPECT_FALSE(backFacingChild->renderSurface());
1416     EXPECT_TRUE(frontFacingSurface->renderSurface());
1417     EXPECT_TRUE(backFacingSurface->renderSurface());
1418     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
1419     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
1420     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
1421     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
1422
1423     // Verify the renderSurfaceLayerList.
1424     ASSERT_EQ(3u, renderSurfaceLayerList.size());
1425     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1426     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
1427     // Even though the back facing surface LAYER gets culled, the other descendants should still be added, so the SURFACE should not be culled.
1428     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[2]->id());
1429
1430     // Verify root surface's layerList.
1431     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
1432     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
1433     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
1434     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
1435
1436     // Verify frontFacingSurface's layerList.
1437     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
1438     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
1439     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
1440
1441     // Verify backFacingSurface's layerList; its own layer should be culled from the surface list.
1442     ASSERT_EQ(1u, renderSurfaceLayerList[2]->renderSurface()->layerList().size());
1443     EXPECT_EQ(frontFacingChildOfBackFacingSurface->id(), renderSurfaceLayerList[2]->renderSurface()->layerList()[0]->id());
1444 }
1445
1446 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d)
1447 {
1448     // Verify the behavior of back-face culling when preserves-3d transform style is used.
1449
1450     const WebTransformationMatrix identityMatrix;
1451     RefPtr<LayerChromium> parent = LayerChromium::create();
1452     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1453     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1454     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1455     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1456     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1457     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1458     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1459     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1460     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1461     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1462
1463     parent->createRenderSurface();
1464     parent->addChild(frontFacingChild);
1465     parent->addChild(backFacingChild);
1466     parent->addChild(frontFacingSurface);
1467     parent->addChild(backFacingSurface);
1468     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
1469     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
1470     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
1471     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
1472
1473     // Nothing is double-sided
1474     frontFacingChild->setDoubleSided(false);
1475     backFacingChild->setDoubleSided(false);
1476     frontFacingSurface->setDoubleSided(false);
1477     backFacingSurface->setDoubleSided(false);
1478     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
1479     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
1480     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
1481     backFacingChildOfBackFacingSurface->setDoubleSided(false);
1482
1483     WebTransformationMatrix backfaceMatrix;
1484     backfaceMatrix.translate(50, 50);
1485     backfaceMatrix.rotate3d(0, 1, 0, 180);
1486     backfaceMatrix.translate(-50, -50);
1487
1488     // Opacity will not force creation of renderSurfaces in this case because of the
1489     // preserve-3d transform style. Instead, an example of when a surface would be
1490     // created with preserve-3d is when there is a replica layer.
1491     frontFacingSurface->setReplicaLayer(dummyReplicaLayer1.get());
1492     backFacingSurface->setReplicaLayer(dummyReplicaLayer2.get());
1493
1494     // Each surface creates its own new 3d rendering context (as defined by W3C spec).
1495     // According to current W3C CSS Transforms spec, layers in a 3d rendering context
1496     // should use the transform with respect to that context. This 3d rendering context
1497     // occurs when (a) parent's transform style is flat and (b) the layer's transform
1498     // style is preserve-3d.
1499     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transform style is flat.
1500     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1501     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1502     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
1503     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
1504     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1505     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1506     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1507     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1508
1509     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1510     Vector<RefPtr<LayerChromium> > dummyLayerList;
1511     int dummyMaxTextureSize = 512;
1512     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
1513     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1514     renderSurfaceLayerList.append(parent.get());
1515
1516     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1517
1518     // Verify which renderSurfaces were created.
1519     EXPECT_FALSE(frontFacingChild->renderSurface());
1520     EXPECT_FALSE(backFacingChild->renderSurface());
1521     EXPECT_TRUE(frontFacingSurface->renderSurface());
1522     EXPECT_FALSE(backFacingSurface->renderSurface());
1523     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
1524     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
1525     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
1526     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
1527
1528     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
1529     ASSERT_EQ(2u, renderSurfaceLayerList.size());
1530     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1531     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
1532
1533     // Verify root surface's layerList.
1534     ASSERT_EQ(2u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
1535     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
1536     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
1537
1538     // Verify frontFacingSurface's layerList.
1539     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
1540     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
1541     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
1542 }
1543
1544 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms)
1545 {
1546     // Verify that layers are appropriately culled when their back face is showing and
1547     // they are not double sided, while animations are going on.
1548     //
1549     // Layers that are animating do not get culled on the main thread, as their transforms should be
1550     // treated as "unknown" so we can not be sure that their back face is really showing.
1551     //
1552
1553     const WebTransformationMatrix identityMatrix;
1554     RefPtr<LayerChromium> parent = LayerChromium::create();
1555     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
1556     RefPtr<LayerChromiumWithForcedDrawsContent> animatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1557     RefPtr<LayerChromiumWithForcedDrawsContent> childOfAnimatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1558     RefPtr<LayerChromiumWithForcedDrawsContent> animatingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1559     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1560
1561     parent->createRenderSurface();
1562     parent->addChild(child);
1563     parent->addChild(animatingSurface);
1564     animatingSurface->addChild(childOfAnimatingSurface);
1565     parent->addChild(animatingChild);
1566     parent->addChild(child2);
1567
1568     // Nothing is double-sided
1569     child->setDoubleSided(false);
1570     child2->setDoubleSided(false);
1571     animatingSurface->setDoubleSided(false);
1572     childOfAnimatingSurface->setDoubleSided(false);
1573     animatingChild->setDoubleSided(false);
1574
1575     WebTransformationMatrix backfaceMatrix;
1576     backfaceMatrix.translate(50, 50);
1577     backfaceMatrix.rotate3d(0, 1, 0, 180);
1578     backfaceMatrix.translate(-50, -50);
1579
1580     // Having a descendant that draws, masksToBounds, and animating transforms, will make the animatingSurface own a render surface.
1581     addAnimatedTransformToController(*animatingSurface->layerAnimationController(), 10, 30, 0);
1582     animatingSurface->setMasksToBounds(true);
1583     // This is just an animating layer, not a surface.
1584     addAnimatedTransformToController(*animatingChild->layerAnimationController(), 10, 30, 0);
1585
1586     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1587     setLayerPropertiesForTesting(child.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1588     setLayerPropertiesForTesting(animatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1589     setLayerPropertiesForTesting(childOfAnimatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1590     setLayerPropertiesForTesting(animatingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1591     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1592
1593     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1594     Vector<RefPtr<LayerChromium> > dummyLayerList;
1595     int dummyMaxTextureSize = 512;
1596
1597     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
1598     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1599     renderSurfaceLayerList.append(parent.get());
1600
1601     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1602
1603     EXPECT_FALSE(child->renderSurface());
1604     EXPECT_TRUE(animatingSurface->renderSurface());
1605     EXPECT_FALSE(childOfAnimatingSurface->renderSurface());
1606     EXPECT_FALSE(animatingChild->renderSurface());
1607     EXPECT_FALSE(child2->renderSurface());
1608
1609     // Verify that the animatingChild and childOfAnimatingSurface were not culled, but that child was.
1610     ASSERT_EQ(2u, renderSurfaceLayerList.size());
1611     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1612     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->id());
1613
1614     // The non-animating child be culled from the layer list for the parent render surface.
1615     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
1616     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
1617     EXPECT_EQ(animatingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
1618     EXPECT_EQ(child2->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
1619
1620     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
1621     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
1622     EXPECT_EQ(childOfAnimatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
1623
1624     EXPECT_FALSE(child2->visibleLayerRect().isEmpty());
1625
1626     // The animating layers should have a visibleLayerRect that represents the area of the front face that is within the viewport.
1627     EXPECT_EQ(animatingChild->visibleLayerRect(), IntRect(IntPoint(), animatingChild->contentBounds()));
1628     EXPECT_EQ(animatingSurface->visibleLayerRect(), IntRect(IntPoint(), animatingSurface->contentBounds()));
1629     // And layers in the subtree of the animating layer should have valid visibleLayerRects also.
1630     EXPECT_EQ(childOfAnimatingSurface->visibleLayerRect(), IntRect(IntPoint(), childOfAnimatingSurface->contentBounds()));
1631 }
1632
1633 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlatteningSurface)
1634 {
1635     // Verify the behavior of back-face culling for a renderSurface that is created
1636     // when it flattens its subtree, and its parent has preserves-3d.
1637
1638     const WebTransformationMatrix identityMatrix;
1639     RefPtr<LayerChromium> parent = LayerChromium::create();
1640     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1641     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1642     RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1643     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1644
1645     parent->createRenderSurface();
1646     parent->addChild(frontFacingSurface);
1647     parent->addChild(backFacingSurface);
1648     frontFacingSurface->addChild(child1);
1649     backFacingSurface->addChild(child2);
1650
1651     // RenderSurfaces are not double-sided
1652     frontFacingSurface->setDoubleSided(false);
1653     backFacingSurface->setDoubleSided(false);
1654
1655     WebTransformationMatrix backfaceMatrix;
1656     backfaceMatrix.translate(50, 50);
1657     backfaceMatrix.rotate3d(0, 1, 0, 180);
1658     backfaceMatrix.translate(-50, -50);
1659
1660     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
1661     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
1662     setLayerPropertiesForTesting(backFacingSurface.get(),  backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
1663     setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1664     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1665
1666     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1667     Vector<RefPtr<LayerChromium> > dummyLayerList;
1668     int dummyMaxTextureSize = 512;
1669     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
1670     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1671     renderSurfaceLayerList.append(parent.get());
1672
1673     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1674
1675     // Verify which renderSurfaces were created.
1676     EXPECT_TRUE(frontFacingSurface->renderSurface());
1677     EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be culled
1678     EXPECT_FALSE(child1->renderSurface());
1679     EXPECT_FALSE(child2->renderSurface());
1680
1681     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
1682     ASSERT_EQ(2u, renderSurfaceLayerList.size());
1683     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1684     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
1685
1686     // Verify root surface's layerList.
1687     ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
1688     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
1689
1690     // Verify frontFacingSurface's layerList.
1691     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
1692     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
1693     EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
1694 }
1695
1696 // FIXME:
1697 // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942
1698 //  - add a test to verify clipping that changes the "center point"
1699 //  - add a case that checks if a render surface's drawTransform is computed correctly. For the general case, and for special cases when clipping.
1700 //  - add a case that checks if a render surface's replicaTransform is computed correctly.
1701 //  - test all the conditions under which render surfaces are created
1702 //  - if possible, test all conditions under which render surfaces are not created
1703 //  - verify that the layer lists of render surfaces are correct, verify that "targetRenderSurface" values for each layer are correct.
1704 //  - test the computation of clip rects and content rects
1705 //  - test the special cases for mask layers and replica layers
1706 //  - test the other functions in CCLayerTreeHostCommon
1707 //
1708
1709 } // namespace