9efddf9fb1a78252a08080e37d45f7aabf8e3e37
[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 "CCLayerTreeTestCommon.h"
30 #include "LayerChromium.h"
31 #include "TransformationMatrix.h"
32 #include "TranslateTransformOperation.h"
33 #include "cc/CCLayerAnimationController.h"
34
35 #include <gmock/gmock.h>
36 #include <gtest/gtest.h>
37
38 using namespace WebCore;
39
40 namespace {
41
42 void setLayerPropertiesForTesting(LayerChromium* layer, const TransformationMatrix& transform, const TransformationMatrix& sublayerTransform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D)
43 {
44     layer->setTransform(transform);
45     layer->setSublayerTransform(sublayerTransform);
46     layer->setAnchorPoint(anchor);
47     layer->setPosition(position);
48     layer->setBounds(bounds);
49     layer->setPreserves3D(preserves3D);
50 }
51
52 void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer)
53 {
54     TransformationMatrix identityMatrix;
55     Vector<RefPtr<LayerChromium> > dummyRenderSurfaceLayerList;
56     Vector<RefPtr<LayerChromium> > dummyLayerList;
57     int dummyMaxTextureSize = 512;
58     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootLayer, rootLayer, identityMatrix, identityMatrix, dummyRenderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
59 }
60
61 TransformationMatrix remove3DComponentOfMatrix(const TransformationMatrix& mat)
62 {
63     TransformationMatrix ret = mat;
64     ret.setM13(0);
65     ret.setM23(0);
66     ret.setM31(0);
67     ret.setM32(0);
68     ret.setM33(1);
69     ret.setM34(0);
70     ret.setM43(0);
71     return ret;
72 }
73
74 class LayerChromiumWithForcedDrawsContent : public LayerChromium {
75 public:
76     LayerChromiumWithForcedDrawsContent()
77         : LayerChromium()
78     {
79     }
80
81     virtual bool drawsContent() const { return true; }
82 };
83
84 TEST(CCLayerTreeHostCommonTest, verifyTransformsForNoOpLayer)
85 {
86     // Sanity check: For layers positioned at zero, with zero size,
87     // and with identity transforms, then the drawTransform,
88     // screenSpaceTransform, and the hierarchy passed on to children
89     // layers should also be identity transforms.
90
91     RefPtr<LayerChromium> parent = LayerChromium::create();
92     RefPtr<LayerChromium> child = LayerChromium::create();
93     RefPtr<LayerChromium> grandChild = LayerChromium::create();
94     parent->createRenderSurface();
95     parent->addChild(child);
96     child->addChild(grandChild);
97
98     TransformationMatrix identityMatrix;
99     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
100     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
101     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
102
103     executeCalculateDrawTransformsAndVisibility(parent.get());
104
105     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->drawTransform());
106     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->screenSpaceTransform());
107     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
108     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
109     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform());
110     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
111 }
112
113 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleLayer)
114 {
115     // NOTE CAREFULLY:
116     // LayerChromium::position is actually the sum of anchorPoint (in pixel space) and actual position. Because of this, the
117     // value of LayerChromium::position() changes if the anchor changes, even though the layer is not actually located in a
118     // different position. When we initialize layers for testing here, we need to initialize that unintutive position value.
119
120     TransformationMatrix identityMatrix;
121     RefPtr<LayerChromium> layer = LayerChromium::create();
122     layer->createRenderSurface();
123
124     // Case 1: setting the sublayer transform should not affect this layer's draw transform or screen-space transform.
125     TransformationMatrix arbitraryTranslation;
126     arbitraryTranslation.translate(10.0, 20.0);
127     setLayerPropertiesForTesting(layer.get(), identityMatrix, arbitraryTranslation, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
128     executeCalculateDrawTransformsAndVisibility(layer.get());
129     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform());
130     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
131
132     // Case 2: setting the bounds of the layer should result in a draw transform that translates to half the width and height.
133     //         The screen-space transform should remain as the identity, because it does not deal with transforming to/from the center of the layer.
134     TransformationMatrix translationToCenter;
135     translationToCenter.translate(5.0, 6.0);
136     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(10, 12), false);
137     executeCalculateDrawTransformsAndVisibility(layer.get());
138     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, layer->drawTransform());
139     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
140
141     // Case 3: The anchor point by itself (without a layer transform) should have no effect on the transforms.
142     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
143     executeCalculateDrawTransformsAndVisibility(layer.get());
144     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, layer->drawTransform());
145     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
146
147     // Case 4: A change in "actual" position affects both the draw transform and screen space transform.
148     TransformationMatrix positionTransform;
149     positionTransform.translate(0.0, 1.2);
150     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
151     executeCalculateDrawTransformsAndVisibility(layer.get());
152     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform * translationToCenter, layer->drawTransform());
153     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->screenSpaceTransform());
154
155     // Case 5: In the correct sequence of transforms, the layer transform should pre-multiply the translationToCenter. This is easily tested by
156     //         using a scale transform, because scale and translation are not commutative.
157     TransformationMatrix layerTransform;
158     layerTransform.scale3d(2.0, 2.0, 1.0);
159     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(10, 12), false);
160     executeCalculateDrawTransformsAndVisibility(layer.get());
161     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform * translationToCenter, layer->drawTransform());
162     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->screenSpaceTransform());
163
164     // Case 6: The layer transform should occur with respect to the anchor point.
165     TransformationMatrix translationToAnchor;
166     translationToAnchor.translate(5.0, 0.0);
167     TransformationMatrix expectedResult = translationToAnchor * layerTransform * translationToAnchor.inverse();
168     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 0.0f), IntSize(10, 12), false);
169     executeCalculateDrawTransformsAndVisibility(layer.get());
170     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
171     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
172
173     // Case 7: Verify that position pre-multiplies the layer transform.
174     //         The current implementation of calculateDrawTransformsAndVisibility does this implicitly, but it is
175     //         still worth testing to detect accidental regressions.
176     expectedResult = positionTransform * translationToAnchor * layerTransform * translationToAnchor.inverse();
177     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 1.2f), IntSize(10, 12), false);
178     executeCalculateDrawTransformsAndVisibility(layer.get());
179     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
180     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
181 }
182
183 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
184 {
185     TransformationMatrix identityMatrix;
186     RefPtr<LayerChromium> parent = LayerChromium::create();
187     RefPtr<LayerChromium> child = LayerChromium::create();
188     RefPtr<LayerChromium> grandChild = LayerChromium::create();
189     parent->createRenderSurface();
190     parent->addChild(child);
191     child->addChild(grandChild);
192
193     // Case 1: parent's anchorPoint should not affect child or grandChild.
194     TransformationMatrix childTranslationToCenter, grandChildTranslationToCenter;
195     childTranslationToCenter.translate(8.0, 9.0);
196     grandChildTranslationToCenter.translate(38.0, 39.0);
197     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
198     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
199     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
200     executeCalculateDrawTransformsAndVisibility(parent.get());
201     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
202     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
203     EXPECT_TRANSFORMATION_MATRIX_EQ(grandChildTranslationToCenter, grandChild->drawTransform());
204     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
205
206     // Case 2: parent's position affects child and grandChild.
207     TransformationMatrix parentPositionTransform;
208     parentPositionTransform.translate(0.0, 1.2);
209     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
210     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
211     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
212     executeCalculateDrawTransformsAndVisibility(parent.get());
213     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * childTranslationToCenter, child->drawTransform());
214     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->screenSpaceTransform());
215     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * grandChildTranslationToCenter, grandChild->drawTransform());
216     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->screenSpaceTransform());
217
218     // Case 3: parent's local transform affects child and grandchild
219     TransformationMatrix parentLayerTransform;
220     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
221     TransformationMatrix parentTranslationToAnchor;
222     parentTranslationToAnchor.translate(2.5, 3.0);
223     TransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse();
224     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
225     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
226     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
227     executeCalculateDrawTransformsAndVisibility(parent.get());
228     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
229     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
230     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
231     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
232
233     // Case 4: parent's sublayerMatrix affects child and grandchild
234     //         scaling is used here again so that the correct sequence of transforms is properly tested.
235     //         Note that preserves3D is false, but the sublayer matrix should retain its 3D properties when given to child.
236     //         But then, the child also does not preserve3D. When it gives its hierarchy to the grandChild, it should be flattened to 2D.
237     TransformationMatrix parentSublayerMatrix;
238     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
239     TransformationMatrix parentTranslationToCenter;
240     parentTranslationToCenter.translate(5.0, 6.0);
241     // Sublayer matrix is applied to the center of the parent layer.
242     parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
243             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
244     TransformationMatrix flattenedCompositeTransform = remove3DComponentOfMatrix(parentCompositeTransform);
245     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
246     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
247     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
248     executeCalculateDrawTransformsAndVisibility(parent.get());
249     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
250     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
251     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
252     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->screenSpaceTransform());
253
254     // Case 5: same as Case 4, except that child does preserve 3D, so the grandChild should receive the non-flattened composite transform.
255     //
256     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
257     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), true);
258     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
259     executeCalculateDrawTransformsAndVisibility(parent.get());
260     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
261     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
262     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
263     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
264 }
265
266 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
267 {
268     RefPtr<LayerChromium> parent = LayerChromium::create();
269     RefPtr<LayerChromium> child = LayerChromium::create();
270     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
271     parent->createRenderSurface();
272     parent->addChild(child);
273     child->addChild(grandChild);
274
275     // Child is set up so that a new render surface should be created.
276     child->setOpacity(0.5f);
277
278     TransformationMatrix identityMatrix;
279     TransformationMatrix parentLayerTransform;
280     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
281     TransformationMatrix parentTranslationToAnchor;
282     parentTranslationToAnchor.translate(2.5, 3.0);
283     TransformationMatrix parentSublayerMatrix;
284     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
285     TransformationMatrix parentTranslationToCenter;
286     parentTranslationToCenter.translate(5.0, 6.0);
287     TransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
288             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
289     TransformationMatrix childTranslationToCenter;
290     childTranslationToCenter.translate(8.0, 9.0);
291
292     // Child's render surface should not exist yet.
293     ASSERT_FALSE(child->renderSurface());
294
295     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
296     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
297     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
298     executeCalculateDrawTransformsAndVisibility(parent.get());
299
300     // Render surface should have been created now.
301     ASSERT_TRUE(child->renderSurface());
302     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
303
304     // The child layer's draw transform should refer to its new render surface; they only differ by a translation to center.
305     // The screen-space transform, however, should still refer to the root.
306     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
307     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
308
309     // Without clipping, the origin transform and draw transform (in this particular case) should be the same.
310     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->originTransform());
311     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->drawTransform());
312
313     // The screen space is the same as the target since the child surface draws into the root.
314     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->screenSpaceTransform());
315 }
316
317 TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica)
318 {
319     RefPtr<LayerChromium> parent = LayerChromium::create();
320     RefPtr<LayerChromium> child = LayerChromium::create();
321     RefPtr<LayerChromium> childReplica = LayerChromium::create();
322     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
323     parent->createRenderSurface();
324     parent->addChild(child);
325     child->addChild(grandChild);
326     child->setReplicaLayer(childReplica.get());
327
328     // Child is set up so that a new render surface should be created.
329     child->setOpacity(0.5f);
330
331     TransformationMatrix identityMatrix;
332     TransformationMatrix parentLayerTransform;
333     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
334     TransformationMatrix parentTranslationToAnchor;
335     parentTranslationToAnchor.translate(2.5, 3.0);
336     TransformationMatrix parentSublayerMatrix;
337     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
338     TransformationMatrix parentTranslationToCenter;
339     parentTranslationToCenter.translate(5.0, 6.0);
340     TransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
341             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
342     TransformationMatrix childTranslationToCenter;
343     childTranslationToCenter.translate(8.0, 9.0);
344     TransformationMatrix replicaLayerTransform;
345     replicaLayerTransform.scale3d(3.0, 3.0, 1.0);
346     TransformationMatrix replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform;
347
348     // Child's render surface should not exist yet.
349     ASSERT_FALSE(child->renderSurface());
350
351     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
352     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
353     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
354     setLayerPropertiesForTesting(childReplica.get(), replicaLayerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
355     executeCalculateDrawTransformsAndVisibility(parent.get());
356
357     // Render surface should have been created now.
358     ASSERT_TRUE(child->renderSurface());
359     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
360
361     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaOriginTransform());
362     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaScreenSpaceTransform());
363 }
364
365 TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
366 {
367     // This test creates a more complex tree and verifies it all at once. This covers the following cases:
368     //   - layers that are described w.r.t. a render surface: should have draw transforms described w.r.t. that surface
369     //   - A render surface described w.r.t. an ancestor render surface: should have a draw transform described w.r.t. that ancestor surface
370     //   - Replicas of a render surface are described w.r.t. the replica's transform around its anchor, along with the surface itself.
371     //   - 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.
372     //   - verifying that each layer has a reference to the correct renderSurface and targetRenderSurface values.
373
374     RefPtr<LayerChromium> parent = LayerChromium::create();
375     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
376     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
377     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
378     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
379     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
380     RefPtr<LayerChromium> replicaOfRS1 = LayerChromium::create();
381     RefPtr<LayerChromium> replicaOfRS2 = LayerChromium::create();
382     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
383     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
384     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
385     parent->createRenderSurface();
386     parent->addChild(renderSurface1);
387     parent->addChild(childOfRoot);
388     renderSurface1->addChild(childOfRS1);
389     renderSurface1->addChild(renderSurface2);
390     renderSurface2->addChild(childOfRS2);
391     childOfRoot->addChild(grandChildOfRoot);
392     childOfRS1->addChild(grandChildOfRS1);
393     childOfRS2->addChild(grandChildOfRS2);
394     renderSurface1->setReplicaLayer(replicaOfRS1.get());
395     renderSurface2->setReplicaLayer(replicaOfRS2.get());
396
397     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
398     renderSurface1->setOpacity(0.5f);
399     renderSurface2->setOpacity(0.33f);
400
401     // All layers in the tree are initialized with an anchor at 2.5 and a size of (10,10).
402     // matrix "A" is the composite layer transform used in all layers, centered about the anchor point
403     // matrix "B" is the sublayer transform used in all layers, centered about the center position of the layer.
404     // matrix "R" is the composite replica transform used in all replica layers.
405     //
406     // x component tests that layerTransform and sublayerTransform are done in the right order (translation and scale are noncommutative).
407     // y component has a translation by 1.0 for every ancestor, which indicates the "depth" of the layer in the hierarchy.
408     TransformationMatrix translationToAnchor;
409     translationToAnchor.translate(2.5, 0.0);
410     TransformationMatrix translationToCenter;
411     translationToCenter.translate(5.0, 5.0);
412     TransformationMatrix layerTransform;
413     layerTransform.translate(1.0, 1.0);
414     TransformationMatrix sublayerTransform;
415     sublayerTransform.scale3d(10.0, 1.0, 1.0);
416     TransformationMatrix replicaLayerTransform;
417     replicaLayerTransform.scale3d(-2.0, 5.0, 1.0);
418
419     TransformationMatrix A = translationToAnchor * layerTransform * translationToAnchor.inverse();
420     TransformationMatrix B = translationToCenter * sublayerTransform * translationToCenter.inverse();
421     TransformationMatrix R = A * translationToAnchor * replicaLayerTransform * translationToAnchor.inverse();
422
423     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
424     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
425     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
426     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
427     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
428     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
429     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
430     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
431     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
432     setLayerPropertiesForTesting(replicaOfRS1.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
433     setLayerPropertiesForTesting(replicaOfRS2.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
434
435     executeCalculateDrawTransformsAndVisibility(parent.get());
436
437     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
438     //
439     ASSERT_TRUE(parent->renderSurface());
440     ASSERT_FALSE(childOfRoot->renderSurface());
441     ASSERT_FALSE(grandChildOfRoot->renderSurface());
442
443     ASSERT_TRUE(renderSurface1->renderSurface());
444     ASSERT_FALSE(childOfRS1->renderSurface());
445     ASSERT_FALSE(grandChildOfRS1->renderSurface());
446
447     ASSERT_TRUE(renderSurface2->renderSurface());
448     ASSERT_FALSE(childOfRS2->renderSurface());
449     ASSERT_FALSE(grandChildOfRS2->renderSurface());
450
451     // Verify all targetRenderSurface accessors
452     //
453     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
454     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
455     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
456
457     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
458     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
459     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
460
461     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
462     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
463     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
464
465     // Verify layer draw transforms
466     //  note that draw transforms are described with respect to the nearest ancestor render surface
467     //  but screen space transforms are described with respect to the root.
468     //
469     EXPECT_TRANSFORMATION_MATRIX_EQ(A * translationToCenter, parent->drawTransform());
470     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * translationToCenter, childOfRoot->drawTransform());
471     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * translationToCenter, grandChildOfRoot->drawTransform());
472
473     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface1->drawTransform());
474     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS1->drawTransform());
475     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS1->drawTransform());
476
477     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface2->drawTransform());
478     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS2->drawTransform());
479     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS2->drawTransform());
480
481     // Verify layer screen-space transforms
482     //
483     EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screenSpaceTransform());
484     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->screenSpaceTransform());
485     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->screenSpaceTransform());
486
487     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->screenSpaceTransform());
488     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, childOfRS1->screenSpaceTransform());
489     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, grandChildOfRS1->screenSpaceTransform());
490
491     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->screenSpaceTransform());
492     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, childOfRS2->screenSpaceTransform());
493     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A, grandChildOfRS2->screenSpaceTransform());
494
495     // Verify render surface transforms.
496     //
497     // Origin transform of render surface 1 is described with respect to root.
498     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->originTransform());
499     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaOriginTransform());
500     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->screenSpaceTransform());
501     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaScreenSpaceTransform());
502     // Origin transform of render surface 2 is described with respect to render surface 2.
503     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, renderSurface2->renderSurface()->originTransform());
504     EXPECT_TRANSFORMATION_MATRIX_EQ(B * R, renderSurface2->renderSurface()->replicaOriginTransform());
505     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->renderSurface()->screenSpaceTransform());
506     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R, renderSurface2->renderSurface()->replicaScreenSpaceTransform());
507
508     // Sanity check. If these fail there is probably a bug in the test itself.
509     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
510     // encodes the "depth" of the layer in the tree.
511     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
512     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
513     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
514
515     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
516     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
517     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
518
519     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
520     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
521     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
522 }
523
524 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForClipLayer)
525 {
526     RefPtr<LayerChromium> parent = LayerChromium::create();
527     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
528     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
529     renderSurface1->setOpacity(0.9);
530
531     const TransformationMatrix identityMatrix;
532     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
533     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false);
534
535     parent->createRenderSurface();
536     parent->setClipRect(IntRect(0, 0, 10, 10));
537     parent->addChild(renderSurface1);
538     renderSurface1->createRenderSurface();
539     renderSurface1->addChild(child);
540
541     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
542     Vector<RefPtr<LayerChromium> > dummyLayerList;
543     int dummyMaxTextureSize = 512;
544     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
545
546     // The child layer's content is entirely outside the parent's clip rect, so the intermediate
547     // render surface should have been removed. Render surfaces without children or visible
548     // content are unexpected at draw time (e.g. we might try to create a content texture of size 0).
549     ASSERT_FALSE(renderSurface1->renderSurface());
550     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
551 }
552
553 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
554 {
555     RefPtr<LayerChromium> parent = LayerChromium::create();
556     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
557     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
558     renderSurface1->setOpacity(0);
559
560     const TransformationMatrix identityMatrix;
561     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
562     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
563
564     parent->createRenderSurface();
565     parent->addChild(renderSurface1);
566     renderSurface1->createRenderSurface();
567     renderSurface1->addChild(child);
568
569     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
570     Vector<RefPtr<LayerChromium> > dummyLayerList;
571     int dummyMaxTextureSize = 512;
572     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
573
574     // Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
575     // Also, the drawable content rect should not have been extended by the children.
576     EXPECT_EQ(parent->renderSurface()->layerList().size(), 0U);
577     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
578     EXPECT_EQ(parent->drawableContentRect(), IntRect());
579 }
580
581 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
582 {
583     // The entire subtree of layers that are outside the clipRect should be culled away,
584     // and should not affect the renderSurfaceLayerList.
585     //
586     // The test tree is set up as follows:
587     //  - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
588     //  - parent is a large container layer.
589     //  - child has masksToBounds=true to cause clipping.
590     //  - grandChild is positioned outside of the child's bounds
591     //  - greatGrandChild is also kept outside child's bounds.
592     //
593     // In this configuration, grandChild and greatGrandChild are completely outside the
594     // clipRect, and they should never get scheduled on the list of renderSurfaces.
595     //
596
597     const TransformationMatrix identityMatrix;
598     RefPtr<LayerChromium> parent = LayerChromium::create();
599     RefPtr<LayerChromium> child = LayerChromium::create();
600     RefPtr<LayerChromium> grandChild = LayerChromium::create();
601     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
602     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
603     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
604     parent->createRenderSurface();
605     parent->addChild(child);
606     child->addChild(grandChild);
607     grandChild->addChild(greatGrandChild);
608
609     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
610     // even though grandChild and greatGrandChild should be clipped.
611     child->addChild(leafNode1);
612     greatGrandChild->addChild(leafNode2);
613
614     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
615     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
616     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
617     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
618     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
619     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
620
621     child->setMasksToBounds(true);
622     child->setOpacity(0.4);
623     grandChild->setOpacity(0.5);
624     greatGrandChild->setOpacity(0.4);
625
626     // Contaminate the grandChild and greatGrandChild's clipRect to reproduce the crash
627     // bug found in http://code.google.com/p/chromium/issues/detail?id=106734. In this
628     // bug, the clipRect was not re-computed for layers that create RenderSurfaces, and
629     // therefore leafNode2 thinks it should draw itself. As a result, an extra
630     // renderSurface remains on the renderSurfaceLayerList, which violates the assumption
631     // that an empty renderSurface will always be the last item on the list, which
632     // ultimately caused the crash.
633     //
634     // FIXME: it is also useful to test with this commented out. Eventually we should
635     // create several test cases that test clipRect/drawableContentRect computation.
636     child->setClipRect(IntRect(IntPoint::zero(), IntSize(20, 20)));
637     greatGrandChild->setClipRect(IntRect(IntPoint::zero(), IntSize(1234, 1234)));
638
639     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
640     Vector<RefPtr<LayerChromium> > dummyLayerList;
641     int dummyMaxTextureSize = 512;
642
643     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
644     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
645     renderSurfaceLayerList.append(parent.get());
646
647     CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
648
649     ASSERT_EQ(2U, renderSurfaceLayerList.size());
650     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
651     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
652 }
653
654 static int addOpacityAnimationToLayer(LayerChromium* layer, float startValue, float endValue, double duration)
655 {
656     static int id = 0;
657     WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
658     values.insert(new FloatAnimationValue(0, startValue));
659     values.insert(new FloatAnimationValue(duration, endValue));
660
661     RefPtr<Animation> animation = Animation::create();
662     animation->setDuration(duration);
663
664     IntSize boxSize;
665     layer->layerAnimationController()->addAnimation(values, boxSize, animation.get(), id, 0, 0);
666     return id++;
667 }
668
669 static int addTransformAnimationToLayer(LayerChromium* layer, double duration)
670 {
671     static int id = 0;
672     WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
673
674     TransformOperations operations1;
675     operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TRANSLATE_X));
676     values.insert(new TransformAnimationValue(0, &operations1));
677
678     RefPtr<Animation> animation = Animation::create();
679     animation->setDuration(duration);
680
681     IntSize boxSize;
682     layer->layerAnimationController()->addAnimation(values, boxSize, animation.get(), id, 0, 0);
683     return id++;
684 }
685
686 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
687 {
688     RefPtr<LayerChromium> parent = LayerChromium::create();
689     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
690     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
691     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
692     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
693     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
694     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
695     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
696     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
697     parent->createRenderSurface();
698     parent->addChild(renderSurface1);
699     parent->addChild(childOfRoot);
700     renderSurface1->addChild(childOfRS1);
701     renderSurface1->addChild(renderSurface2);
702     renderSurface2->addChild(childOfRS2);
703     childOfRoot->addChild(grandChildOfRoot);
704     childOfRS1->addChild(grandChildOfRS1);
705     childOfRS2->addChild(grandChildOfRS2);
706
707     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
708     addOpacityAnimationToLayer(renderSurface1.get(), 1, 0, 10);
709     addOpacityAnimationToLayer(renderSurface2.get(), 1, 0, 10);
710
711     // Also put an animation on a layer without descendants.
712     addOpacityAnimationToLayer(grandChildOfRoot.get(), 1, 0, 10);
713
714     TransformationMatrix layerTransform;
715     layerTransform.translate(1.0, 1.0);
716     TransformationMatrix sublayerTransform;
717     sublayerTransform.scale3d(10.0, 1.0, 1.0);
718
719     // Put transform animations on child, renderSurface2, grandChildOfRoot, and grandChildOfRS2
720     addTransformAnimationToLayer(childOfRoot.get(), 10);
721     addTransformAnimationToLayer(grandChildOfRoot.get(), 10);
722     addTransformAnimationToLayer(renderSurface2.get(), 10);
723     addTransformAnimationToLayer(grandChildOfRS2.get(), 10);
724
725     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
726     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
727     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
728     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
729     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
730     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
731     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
732     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
733     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
734
735     executeCalculateDrawTransformsAndVisibility(parent.get());
736
737     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
738     //
739     ASSERT_TRUE(parent->renderSurface());
740     ASSERT_FALSE(childOfRoot->renderSurface());
741     ASSERT_FALSE(grandChildOfRoot->renderSurface());
742
743     ASSERT_TRUE(renderSurface1->renderSurface());
744     ASSERT_FALSE(childOfRS1->renderSurface());
745     ASSERT_FALSE(grandChildOfRS1->renderSurface());
746
747     ASSERT_TRUE(renderSurface2->renderSurface());
748     ASSERT_FALSE(childOfRS2->renderSurface());
749     ASSERT_FALSE(grandChildOfRS2->renderSurface());
750
751     // Verify all targetRenderSurface accessors
752     //
753     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
754     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
755     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
756
757     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
758     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
759     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
760
761     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
762     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
763     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
764
765     // Verify drawOpacityIsAnimating values
766     //
767     EXPECT_FALSE(parent->drawOpacityIsAnimating());
768     EXPECT_FALSE(childOfRoot->drawOpacityIsAnimating());
769     EXPECT_TRUE(grandChildOfRoot->drawOpacityIsAnimating());
770     EXPECT_FALSE(renderSurface1->drawOpacityIsAnimating());
771     EXPECT_TRUE(renderSurface1->renderSurface()->drawOpacityIsAnimating());
772     EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating());
773     EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating());
774     EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating());
775     EXPECT_TRUE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
776     EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating());
777     EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating());
778
779     // Verify drawTransformsAnimatingInTarget values
780     //
781     EXPECT_FALSE(parent->drawTransformIsAnimating());
782     EXPECT_TRUE(childOfRoot->drawTransformIsAnimating());
783     EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating());
784     EXPECT_FALSE(renderSurface1->drawTransformIsAnimating());
785     EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnimating());
786     EXPECT_FALSE(childOfRS1->drawTransformIsAnimating());
787     EXPECT_FALSE(grandChildOfRS1->drawTransformIsAnimating());
788     EXPECT_FALSE(renderSurface2->drawTransformIsAnimating());
789     EXPECT_TRUE(renderSurface2->renderSurface()->targetSurfaceTransformsAreAnimating());
790     EXPECT_FALSE(childOfRS2->drawTransformIsAnimating());
791     EXPECT_TRUE(grandChildOfRS2->drawTransformIsAnimating());
792
793     // Verify drawTransformsAnimatingInScreen values
794     //
795     EXPECT_FALSE(parent->screenSpaceTransformIsAnimating());
796     EXPECT_TRUE(childOfRoot->screenSpaceTransformIsAnimating());
797     EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating());
798     EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating());
799     EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimating());
800     EXPECT_FALSE(childOfRS1->screenSpaceTransformIsAnimating());
801     EXPECT_FALSE(grandChildOfRS1->screenSpaceTransformIsAnimating());
802     EXPECT_TRUE(renderSurface2->screenSpaceTransformIsAnimating());
803     EXPECT_TRUE(renderSurface2->renderSurface()->screenSpaceTransformsAreAnimating());
804     EXPECT_TRUE(childOfRS2->screenSpaceTransformIsAnimating());
805     EXPECT_TRUE(grandChildOfRS2->screenSpaceTransformIsAnimating());
806
807
808     // Sanity check. If these fail there is probably a bug in the test itself.
809     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
810     // encodes the "depth" of the layer in the tree.
811     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
812     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
813     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
814
815     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
816     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
817     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
818
819     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
820     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
821     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
822 }
823
824 // FIXME:
825 // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942
826 //  - add a test to verify clipping that changes the "center point"
827 //  - add a case that checks if a render surface's drawTransform is computed correctly. For the general case, and for special cases when clipping.
828 //  - add a case that checks if a render surface's replicaTransform is computed correctly.
829 //  - test all the conditions under which render surfaces are created
830 //  - if possible, test all conditions under which render surfaces are not created
831 //  - verify that the layer lists of render surfaces are correct, verify that "targetRenderSurface" values for each layer are correct.
832 //  - test the computation of clip rects and content rects
833 //  - test the special cases for mask layers and replica layers
834 //  - test the other functions in CCLayerTreeHostCommon
835 //
836
837 } // namespace