[chromium] Cleanup scissor rect computation/use with damage
[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/CCLayerImpl.h"
35 #include "cc/CCLayerSorter.h"
36 #include "cc/CCMathUtil.h"
37 #include "cc/CCProxy.h"
38 #include "cc/CCSingleThreadProxy.h"
39 #include "cc/CCThread.h"
40
41 #include <gmock/gmock.h>
42 #include <gtest/gtest.h>
43 #include <public/WebTransformationMatrix.h>
44
45 using namespace WebCore;
46 using namespace WebKitTests;
47 using WebKit::WebTransformationMatrix;
48
49 namespace {
50
51 void setLayerPropertiesForTesting(LayerChromium* layer, const WebTransformationMatrix& transform, const WebTransformationMatrix& sublayerTransform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool preserves3D)
52 {
53     layer->setTransform(transform);
54     layer->setSublayerTransform(sublayerTransform);
55     layer->setAnchorPoint(anchor);
56     layer->setPosition(position);
57     layer->setBounds(bounds);
58     layer->setPreserves3D(preserves3D);
59 }
60
61 void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer)
62 {
63     WebTransformationMatrix identityMatrix;
64     Vector<RefPtr<LayerChromium> > dummyRenderSurfaceLayerList;
65     Vector<RefPtr<LayerChromium> > dummyLayerList;
66     int dummyMaxTextureSize = 512;
67     CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, rootLayer, identityMatrix, identityMatrix, dummyRenderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
68     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(dummyRenderSurfaceLayerList, rootLayer->renderSurface()->contentRect());
69 }
70
71 WebTransformationMatrix remove3DComponentOfMatrix(const WebTransformationMatrix& mat)
72 {
73     WebTransformationMatrix ret = mat;
74     ret.setM13(0);
75     ret.setM23(0);
76     ret.setM31(0);
77     ret.setM32(0);
78     ret.setM33(1);
79     ret.setM34(0);
80     ret.setM43(0);
81     return ret;
82 }
83
84 class LayerChromiumWithForcedDrawsContent : public LayerChromium {
85 public:
86     LayerChromiumWithForcedDrawsContent()
87         : LayerChromium()
88     {
89     }
90
91     virtual bool drawsContent() const OVERRIDE { return true; }
92 };
93
94 TEST(CCLayerTreeHostCommonTest, verifyTransformsForNoOpLayer)
95 {
96     // Sanity check: For layers positioned at zero, with zero size,
97     // and with identity transforms, then the drawTransform,
98     // screenSpaceTransform, and the hierarchy passed on to children
99     // layers should also be identity transforms.
100
101     RefPtr<LayerChromium> parent = LayerChromium::create();
102     RefPtr<LayerChromium> child = LayerChromium::create();
103     RefPtr<LayerChromium> grandChild = LayerChromium::create();
104     parent->createRenderSurface();
105     parent->addChild(child);
106     child->addChild(grandChild);
107
108     WebTransformationMatrix identityMatrix;
109     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
110     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
111     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
112
113     executeCalculateDrawTransformsAndVisibility(parent.get());
114
115     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->drawTransform());
116     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, parent->screenSpaceTransform());
117     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
118     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
119     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform());
120     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
121 }
122
123 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleLayer)
124 {
125     // NOTE CAREFULLY:
126     // LayerChromium::position is actually the sum of anchorPoint (in pixel space) and actual position. Because of this, the
127     // value of LayerChromium::position() changes if the anchor changes, even though the layer is not actually located in a
128     // different position. When we initialize layers for testing here, we need to initialize that unintutive position value.
129
130     WebTransformationMatrix identityMatrix;
131     RefPtr<LayerChromium> layer = LayerChromium::create();
132     layer->createRenderSurface();
133
134     // Case 1: setting the sublayer transform should not affect this layer's draw transform or screen-space transform.
135     WebTransformationMatrix arbitraryTranslation;
136     arbitraryTranslation.translate(10.0, 20.0);
137     setLayerPropertiesForTesting(layer.get(), identityMatrix, arbitraryTranslation, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
138     executeCalculateDrawTransformsAndVisibility(layer.get());
139     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform());
140     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
141
142     // Case 2: setting the bounds of the layer should result in a draw transform that translates to half the width and height.
143     //         The screen-space transform should remain as the identity, because it does not deal with transforming to/from the center of the layer.
144     WebTransformationMatrix translationToCenter;
145     translationToCenter.translate(5.0, 6.0);
146     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.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 3: The anchor point by itself (without a layer transform) should have no effect on the transforms.
152     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
153     executeCalculateDrawTransformsAndVisibility(layer.get());
154     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, layer->drawTransform());
155     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
156
157     // Case 4: A change in "actual" position affects both the draw transform and screen space transform.
158     WebTransformationMatrix positionTransform;
159     positionTransform.translate(0.0, 1.2);
160     setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
161     executeCalculateDrawTransformsAndVisibility(layer.get());
162     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform * translationToCenter, layer->drawTransform());
163     EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->screenSpaceTransform());
164
165     // Case 5: In the correct sequence of transforms, the layer transform should pre-multiply the translationToCenter. This is easily tested by
166     //         using a scale transform, because scale and translation are not commutative.
167     WebTransformationMatrix layerTransform;
168     layerTransform.scale3d(2.0, 2.0, 1.0);
169     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(10, 12), false);
170     executeCalculateDrawTransformsAndVisibility(layer.get());
171     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform * translationToCenter, layer->drawTransform());
172     EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->screenSpaceTransform());
173
174     // Case 6: The layer transform should occur with respect to the anchor point.
175     WebTransformationMatrix translationToAnchor;
176     translationToAnchor.translate(5.0, 0.0);
177     WebTransformationMatrix expectedResult = translationToAnchor * layerTransform * translationToAnchor.inverse();
178     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 0.0f), IntSize(10, 12), false);
179     executeCalculateDrawTransformsAndVisibility(layer.get());
180     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
181     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
182
183     // Case 7: Verify that position pre-multiplies the layer transform.
184     //         The current implementation of calculateDrawTransforms does this implicitly, but it is
185     //         still worth testing to detect accidental regressions.
186     expectedResult = positionTransform * translationToAnchor * layerTransform * translationToAnchor.inverse();
187     setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5f, 0.0f), FloatPoint(5.0f, 1.2f), IntSize(10, 12), false);
188     executeCalculateDrawTransformsAndVisibility(layer.get());
189     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult * translationToCenter, layer->drawTransform());
190     EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
191 }
192
193 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
194 {
195     WebTransformationMatrix identityMatrix;
196     RefPtr<LayerChromium> parent = LayerChromium::create();
197     RefPtr<LayerChromium> child = LayerChromium::create();
198     RefPtr<LayerChromium> grandChild = LayerChromium::create();
199     parent->createRenderSurface();
200     parent->addChild(child);
201     child->addChild(grandChild);
202
203     // Case 1: parent's anchorPoint should not affect child or grandChild.
204     WebTransformationMatrix childTranslationToCenter, grandChildTranslationToCenter;
205     childTranslationToCenter.translate(8.0, 9.0);
206     grandChildTranslationToCenter.translate(38.0, 39.0);
207     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
208     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
209     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
210     executeCalculateDrawTransformsAndVisibility(parent.get());
211     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
212     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
213     EXPECT_TRANSFORMATION_MATRIX_EQ(grandChildTranslationToCenter, grandChild->drawTransform());
214     EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->screenSpaceTransform());
215
216     // Case 2: parent's position affects child and grandChild.
217     WebTransformationMatrix parentPositionTransform;
218     parentPositionTransform.translate(0.0, 1.2);
219     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 4.2f), IntSize(10, 12), false);
220     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
221     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
222     executeCalculateDrawTransformsAndVisibility(parent.get());
223     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * childTranslationToCenter, child->drawTransform());
224     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->screenSpaceTransform());
225     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform * grandChildTranslationToCenter, grandChild->drawTransform());
226     EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->screenSpaceTransform());
227
228     // Case 3: parent's local transform affects child and grandchild
229     WebTransformationMatrix parentLayerTransform;
230     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
231     WebTransformationMatrix parentTranslationToAnchor;
232     parentTranslationToAnchor.translate(2.5, 3.0);
233     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse();
234     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, identityMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
235     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
236     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
237     executeCalculateDrawTransformsAndVisibility(parent.get());
238     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
239     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
240     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
241     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
242
243     // Case 4: parent's sublayerMatrix affects child and grandchild
244     //         scaling is used here again so that the correct sequence of transforms is properly tested.
245     //         Note that preserves3D is false, but the sublayer matrix should retain its 3D properties when given to child.
246     //         But then, the child also does not preserve3D. When it gives its hierarchy to the grandChild, it should be flattened to 2D.
247     WebTransformationMatrix parentSublayerMatrix;
248     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
249     WebTransformationMatrix parentTranslationToCenter;
250     parentTranslationToCenter.translate(5.0, 6.0);
251     // Sublayer matrix is applied to the center of the parent layer.
252     parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
253             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
254     WebTransformationMatrix flattenedCompositeTransform = remove3DComponentOfMatrix(parentCompositeTransform);
255     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
256     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
257     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
258     executeCalculateDrawTransformsAndVisibility(parent.get());
259     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
260     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
261     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
262     EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->screenSpaceTransform());
263
264     // Case 5: same as Case 4, except that child does preserve 3D, so the grandChild should receive the non-flattened composite transform.
265     //
266     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
267     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), true);
268     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(76, 78), false);
269     executeCalculateDrawTransformsAndVisibility(parent.get());
270     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * childTranslationToCenter, child->drawTransform());
271     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
272     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform * grandChildTranslationToCenter, grandChild->drawTransform());
273     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->screenSpaceTransform());
274 }
275
276 TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
277 {
278     RefPtr<LayerChromium> parent = LayerChromium::create();
279     RefPtr<LayerChromium> child = LayerChromium::create();
280     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
281     parent->createRenderSurface();
282     parent->addChild(child);
283     child->addChild(grandChild);
284
285     // Child is set up so that a new render surface should be created.
286     child->setOpacity(0.5f);
287
288     WebTransformationMatrix identityMatrix;
289     WebTransformationMatrix parentLayerTransform;
290     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
291     WebTransformationMatrix parentTranslationToAnchor;
292     parentTranslationToAnchor.translate(2.5, 3.0);
293     WebTransformationMatrix parentSublayerMatrix;
294     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
295     WebTransformationMatrix parentTranslationToCenter;
296     parentTranslationToCenter.translate(5.0, 6.0);
297     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
298             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
299     WebTransformationMatrix childTranslationToCenter;
300     childTranslationToCenter.translate(8.0, 9.0);
301
302     // Child's render surface should not exist yet.
303     ASSERT_FALSE(child->renderSurface());
304
305     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
306     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
307     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
308     executeCalculateDrawTransformsAndVisibility(parent.get());
309
310     // Render surface should have been created now.
311     ASSERT_TRUE(child->renderSurface());
312     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
313
314     // The child layer's draw transform should refer to its new render surface; they only differ by a translation to center.
315     // The screen-space transform, however, should still refer to the root.
316     EXPECT_TRANSFORMATION_MATRIX_EQ(childTranslationToCenter, child->drawTransform());
317     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
318
319     // Without clipping, the origin transform and draw transform (in this particular case) should be the same.
320     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->originTransform());
321     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->drawTransform());
322
323     // The screen space is the same as the target since the child surface draws into the root.
324     EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->targetRenderSurface()->screenSpaceTransform());
325 }
326
327 TEST(CCLayerTreeHostCommonTest, scissorRectNoClip)
328 {
329     DebugScopedSetImplThread thisScopeIsOnImplThread;
330
331     /*
332       Layers are created as follows:
333
334          +--------------------+
335          |                  1 |
336          |  +-----------+     |
337          |  |         2 |     |
338          |  | +-------------------+
339          |  | |   3               |
340          |  | +-------------------+
341          |  |           |     |
342          |  +-----------+     |
343          |                    |
344          |                    |
345          +--------------------+
346
347          Layers 1, 2 have render surfaces
348      */
349     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
350     OwnPtr<CCLayerImpl> child = CCLayerImpl::create(2);
351     OwnPtr<CCLayerImpl> grandChild = CCLayerImpl::create(3);
352
353     IntRect rootRect(0, 0, 100, 100);
354     IntRect childRect(10, 10, 50, 50);
355     IntRect grandChildRect(5, 5, 150, 150);
356
357     root->createRenderSurface();
358     root->setAnchorPoint(FloatPoint(0, 0));
359     root->setPosition(FloatPoint(rootRect.x(), rootRect.y()));
360     root->setBounds(IntSize(rootRect.width(), rootRect.height()));
361     root->setDrawsContent(true);
362     root->renderSurface()->setContentRect(IntRect(IntPoint(), IntSize(rootRect.width(), rootRect.height())));
363
364     child->setAnchorPoint(FloatPoint(0, 0));
365     child->setPosition(FloatPoint(childRect.x(), childRect.y()));
366     child->setOpacity(0.5f);
367     child->setBounds(IntSize(childRect.width(), childRect.height()));
368     child->setDrawsContent(true);
369
370     grandChild->setAnchorPoint(FloatPoint(0, 0));
371     grandChild->setPosition(IntPoint(grandChildRect.x(), grandChildRect.y()));
372     grandChild->setBounds(IntSize(grandChildRect.width(), grandChildRect.height()));
373     grandChild->setDrawsContent(true);
374
375     CCLayerImpl* childPtr = child.get();
376     CCLayerImpl* grandChildPtr = grandChild.get();
377
378     child->addChild(grandChild.release());
379     root->addChild(child.release());
380
381     Vector<CCLayerImpl*> renderSurfaceLayerList;
382     {
383         WebTransformationMatrix identityMatrix;
384         Vector<CCLayerImpl*> layerList;
385         int dummyMaxTextureSize = 512;
386         CCLayerSorter layerSorter;
387
388         renderSurfaceLayerList.append(root.get());
389
390         CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, layerList, &layerSorter, dummyMaxTextureSize);
391
392         FloatRect dummyDamageRect;
393         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, dummyDamageRect);
394     }
395     
396     ASSERT_TRUE(childPtr->renderSurface());
397     ASSERT_TRUE(root->renderSurface());
398     ASSERT_FALSE(grandChildPtr->renderSurface());
399     
400     EXPECT_EQ(renderSurfaceLayerList.size(), 2U);
401     
402     ASSERT_EQ(root->clipRect(), IntRect(0, 0, 0, 0));
403
404     // Layer's clipRect is a union of all its children's bounds
405     ASSERT_EQ(childPtr->clipRect(), IntRect(0, 0, grandChildRect.x() + grandChildRect.width(), grandChildRect.y() + grandChildRect.height()));
406     ASSERT_EQ(grandChildPtr->clipRect(), IntRect(0, 0, 0, 0));
407
408     ASSERT_EQ(root->renderSurface()->clipRect(), IntRect(0, 0, 0, 0));
409     ASSERT_EQ(childPtr->renderSurface()->clipRect(), IntRect(0, 0, 0, 0));
410     
411     ASSERT_FALSE(root->usesLayerClipping());
412     ASSERT_FALSE(childPtr->usesLayerClipping());
413     ASSERT_FALSE(grandChildPtr->usesLayerClipping());
414     
415     // Damage the entire screen
416     IntRect rootDamage(rootRect);
417     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
418     
419     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
420
421     // child surface doesn't have a clip rect, therefore it will be computed as intersection
422     // between root surface's contentrect and child surface's drawable content rect.
423     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(childRect.x(), childRect.y(), rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
424
425     EXPECT_EQ(root->scissorRect(), IntRect(rootRect));
426
427     // The damage is the entire rootRect, but child layer starts at an offset.
428     // Even though it has bounds, it is not clipping to bounds so its children
429     // (which extend beyond the bounds) extend the scissor rect
430     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
431
432     // Grand child will have the same scissor rect as it doesn't have a surface
433     // of its own
434     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
435     
436     // Empty damage
437     rootDamage = IntRect(0, 0, 0, 0);
438     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
439     
440     // Empty damage == empty scissor
441     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
442     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
443     
444     EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0));
445     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0));
446     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, 0, 0));
447     
448     // Partial damage within child
449     rootDamage = IntRect(10, 10, 20, 20);
450     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
451     
452     // Scissors are not computed for root
453     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
454
455     // Entire damage rect is within the root surface
456     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
457     
458     // Entire damage rect is within the layer
459     EXPECT_EQ(root->scissorRect(), rootDamage);
460
461     // Entire damage rect is within the layer, but with different offset
462     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
463
464     // Grand child does not have its own surface, so its scissor rect is identical to child's
465     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
466
467     // Partial damage beyond child
468     rootDamage = IntRect(10, 10, 80, 80);
469     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
470     
471     // Scissors are not computed for root
472     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
473
474     // Entire damage rect is within the root surface
475     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
476     
477     // Entire damage rect is within the layer
478     EXPECT_EQ(root->scissorRect(), rootDamage);
479
480     // Entire damage rect is within the layer, but with different offset
481     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
482
483     // Grand child does not have its own surface, so its scissor rect is identical to child's
484     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
485
486     // Partial damage beyond root
487     rootDamage = IntRect(10, 10, 110, 110);
488     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
489     
490     // Scissors are not computed for root
491     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
492
493     // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage.
494     // Result is that root damage rect is clipped at root layer boundary
495     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
496     
497     // Root does not use layer clipping, so its content rect will be used to intersect with damage
498     // Result is that root damage rect is clipped at root layer boundary
499     EXPECT_EQ(root->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
500
501     // Children's content rects are bigger than the root's so they don't clip the damage rect, but change its offset.
502     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
503     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
504 }
505
506 TEST(CCLayerTreeHostCommonTest, scissorRectWithClip)
507 {
508     DebugScopedSetImplThread thisScopeIsOnImplThread;
509
510     /*
511       Layers are created as follows:
512
513          +--------------------+
514          |                  1 |
515          |  +-----------+     |
516          |  |         2 |     |
517          |  | +-------------------+
518          |  | |   3               |
519          |  | +-------------------+
520          |  |           |     |
521          |  +-----------+     |
522          |                    |
523          |                    |
524          +--------------------+
525
526          Layers 1, 2 have render surfaces
527      */
528     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
529     OwnPtr<CCLayerImpl> child = CCLayerImpl::create(2);
530     OwnPtr<CCLayerImpl> grandChild = CCLayerImpl::create(3);
531
532     IntRect rootRect(0, 0, 100, 100);
533     IntRect childRect(10, 10, 50, 50);
534     IntRect grandChildRect(5, 5, 150, 150);
535
536     root->createRenderSurface();
537     root->setAnchorPoint(FloatPoint(0, 0));
538     root->setPosition(FloatPoint(rootRect.x(), rootRect.y()));
539     root->setBounds(IntSize(rootRect.width(), rootRect.height()));
540     root->setDrawsContent(true);
541     root->renderSurface()->setContentRect(IntRect(IntPoint(), IntSize(rootRect.width(), rootRect.height())));
542
543     child->setAnchorPoint(FloatPoint(0, 0));
544     child->setPosition(FloatPoint(childRect.x(), childRect.y()));
545     child->setOpacity(0.5f);
546     child->setBounds(IntSize(childRect.width(), childRect.height()));
547     child->setDrawsContent(true);
548
549     grandChild->setAnchorPoint(FloatPoint(0, 0));
550     grandChild->setPosition(IntPoint(grandChildRect.x(), grandChildRect.y()));
551     grandChild->setBounds(IntSize(grandChildRect.width(), grandChildRect.height()));
552     grandChild->setDrawsContent(true);
553
554     CCLayerImpl* childPtr = child.get();
555     CCLayerImpl* grandChildPtr = grandChild.get();
556
557     child->addChild(grandChild.release());
558     root->addChild(child.release());
559
560     root->setMasksToBounds(true);
561
562     Vector<CCLayerImpl*> renderSurfaceLayerList;
563     {
564         WebTransformationMatrix identityMatrix;
565         Vector<CCLayerImpl*> layerList;
566         int dummyMaxTextureSize = 512;
567         CCLayerSorter layerSorter;
568
569         renderSurfaceLayerList.append(root.get());
570
571         CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, layerList, &layerSorter, dummyMaxTextureSize);
572
573         FloatRect dummyDamageRect;
574         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, dummyDamageRect);
575     }
576     
577     ASSERT_TRUE(childPtr->renderSurface());
578     ASSERT_TRUE(root->renderSurface());
579     ASSERT_FALSE(grandChildPtr->renderSurface());
580     
581     EXPECT_EQ(renderSurfaceLayerList.size(), 2U);
582     
583     // Now root is clipping to its bounds
584     ASSERT_EQ(root->clipRect(), rootRect);
585
586     // Layer's clipRect is a union of all its children's bounds
587     ASSERT_EQ(childPtr->clipRect(), IntRect(0, 0, grandChildRect.x() + grandChildRect.width(), grandChildRect.y() + grandChildRect.height()));
588     ASSERT_EQ(grandChildPtr->clipRect(), IntRect(0, 0, 0, 0));
589
590     ASSERT_EQ(root->renderSurface()->clipRect(), IntRect(0, 0, 0, 0));
591
592     // Child surface's clipping rect is now set to root's
593     ASSERT_EQ(childPtr->renderSurface()->clipRect(), rootRect);
594     
595     ASSERT_TRUE(root->usesLayerClipping());
596     ASSERT_FALSE(childPtr->usesLayerClipping());
597     ASSERT_FALSE(grandChildPtr->usesLayerClipping());
598     
599     // Damage the entire screen
600     IntRect rootDamage(rootRect);
601     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
602     
603     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
604     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootRect));
605     
606     EXPECT_EQ(root->scissorRect(), IntRect(rootRect));
607
608     // The damage is the entire rootRect, but child layer starts at an offset.
609     // Even though it has bounds, it is not clipping to bounds so its children
610     // (which extend beyond the bounds) extend the scissor rect
611     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
612
613     // Grand child will have the same scissor rect as it doesn't have a surface
614     // of its own
615     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
616     
617     // Empty damage
618     rootDamage = IntRect(0, 0, 0, 0);
619     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
620     
621     // Empty damage == empty scissor
622     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
623     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
624     
625     EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0));
626     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0));
627     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, 0, 0));
628     
629     // Partial damage within child
630     rootDamage = IntRect(10, 10, 20, 20);
631     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
632     
633     // Scissors are not computed for root
634     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
635
636     // Entire damage rect is within the root surface
637     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
638     
639     // Entire damage rect is within the layer
640     EXPECT_EQ(root->scissorRect(), rootDamage);
641
642     // Entire damage rect is within the layer, but with different offset
643     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
644
645     // Grand child does not have its own surface, so its scissor rect is identical to child's
646     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
647
648     // Partial damage beyond child
649     rootDamage = IntRect(10, 10, 80, 80);
650     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
651     
652     // Scissors are not computed for root
653     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
654
655     // Entire damage rect is within the root surface
656     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
657     
658     // Entire damage rect is within the layer
659     EXPECT_EQ(root->scissorRect(), rootDamage);
660
661     // Entire damage rect is within the layer, but with different offset
662     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
663
664     // Grand child does not have its own surface, so its scissor rect is identical to child's
665     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
666
667     // Partial damage beyond root
668     rootDamage = IntRect(10, 10, 110, 110);
669     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
670     
671     // Scissors are not computed for root
672     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
673
674     // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage.
675     // Result is that root damage rect is clipped at root layer boundary
676     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
677     
678     // Root does not use layer clipping, so its content rect will be used to intersect with damage
679     // Result is that root damage rect is clipped at root layer boundary
680     EXPECT_EQ(root->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
681
682     // Now the scissor rects are clipped by surfaces contentRect
683     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
684     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
685 }
686
687 TEST(CCLayerTreeHostCommonTest, scissorRectWithClipAndSpaceTransform)
688 {
689     DebugScopedSetImplThread thisScopeIsOnImplThread;
690
691     /*
692       Layers are created as follows:
693
694          +--------------------+
695          |                  1 |
696          |  +-----------+     |
697          |  |         2 |     |
698          |  | +-------------------+
699          |  | |   3,4             |
700          |  | +-------------------+
701          |  |           |     |
702          |  +-----------+     |
703          |                    |
704          |                    |
705          +--------------------+
706
707          Layers 1, 2 and 3 have render surfaces
708      */
709     OwnPtr<CCLayerImpl> root = CCLayerImpl::create(1);
710     OwnPtr<CCLayerImpl> child = CCLayerImpl::create(2);
711     OwnPtr<CCLayerImpl> grandChild = CCLayerImpl::create(3);
712     OwnPtr<CCLayerImpl> grandChild2 = CCLayerImpl::create(4);
713
714     IntRect rootRect(0, 0, 100, 100);
715     IntRect childRect(10, 10, 50, 50);
716     IntRect grandChildRect(5, 5, 150, 150);
717
718     root->createRenderSurface();
719     root->setAnchorPoint(FloatPoint(0, 0));
720     root->setPosition(FloatPoint(rootRect.x(), rootRect.y()));
721     root->setBounds(IntSize(rootRect.width(), rootRect.height()));
722     root->setDrawsContent(true);
723     root->renderSurface()->setContentRect(IntRect(IntPoint(), IntSize(rootRect.width(), rootRect.height())));
724
725     child->setAnchorPoint(FloatPoint(0, 0));
726     child->setPosition(FloatPoint(childRect.x(), childRect.y()));
727     child->setOpacity(0.5f);
728     child->setBounds(IntSize(childRect.width(), childRect.height()));
729     child->setDrawsContent(true);
730
731     grandChild->setAnchorPoint(FloatPoint(0, 0));
732     grandChild->setPosition(IntPoint(grandChildRect.x(), grandChildRect.y()));
733     grandChild->setOpacity(0.5f);
734     grandChild->setBounds(IntSize(grandChildRect.width(), grandChildRect.height()));
735     grandChild->setDrawsContent(true);
736
737     grandChild2->setAnchorPoint(FloatPoint(0, 0));
738     grandChild2->setPosition(IntPoint(grandChildRect.x(), grandChildRect.y()));
739     grandChild2->setOpacity(0.5f);
740     grandChild2->setBounds(IntSize(grandChildRect.width(), grandChildRect.height()));
741     grandChild2->setDrawsContent(true);
742
743     CCLayerImpl* childPtr = child.get();
744     CCLayerImpl* grandChildPtr = grandChild.get();
745
746     grandChild->addChild(grandChild2.release());
747     child->addChild(grandChild.release());
748     root->addChild(child.release());
749
750     root->setMasksToBounds(true);
751
752     Vector<CCLayerImpl*> renderSurfaceLayerList;
753     {
754         WebTransformationMatrix identityMatrix;
755         Vector<CCLayerImpl*> layerList;
756         int dummyMaxTextureSize = 512;
757         CCLayerSorter layerSorter;
758
759         renderSurfaceLayerList.append(root.get());
760
761         CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, layerList, &layerSorter, dummyMaxTextureSize);
762
763         FloatRect dummyDamageRect;
764         CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, dummyDamageRect);
765     }
766     
767     ASSERT_TRUE(childPtr->renderSurface());
768     ASSERT_TRUE(root->renderSurface());
769     ASSERT_TRUE(grandChildPtr->renderSurface());
770     
771     EXPECT_EQ(renderSurfaceLayerList.size(), 3U);
772     
773     // Now root is clipping to its bounds
774     ASSERT_EQ(root->clipRect(), rootRect);
775
776     ASSERT_EQ(childPtr->clipRect(), IntRect(0, 0, childRect.x() + grandChildRect.width() , childRect.y() + grandChildRect.height()));
777
778     // Grandchild now clips
779     ASSERT_EQ(grandChildPtr->clipRect(), IntRect(0, 0, grandChildRect.x() + grandChildRect.width(), grandChildRect.y() + grandChildRect.height()));
780
781     ASSERT_EQ(root->renderSurface()->clipRect(), IntRect(0, 0, 0, 0));
782
783     // Child surface's clipping rect is now set to root's
784     ASSERT_EQ(childPtr->renderSurface()->clipRect(), rootRect);
785     
786     ASSERT_TRUE(root->usesLayerClipping());
787     ASSERT_FALSE(childPtr->usesLayerClipping());
788     ASSERT_FALSE(grandChildPtr->usesLayerClipping());
789     
790     // Damage the entire screen
791     IntRect rootDamage(rootRect);
792     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
793     
794     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
795     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootRect));
796     
797     EXPECT_EQ(root->scissorRect(), IntRect(rootRect));
798
799     // The damage is the entire rootRect, but child layer starts at an offset.
800     // Even though it has bounds, it is not clipping to bounds so its children
801     // (which extend beyond the bounds) extend the scissor rect
802     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x(), rootRect.height() - childRect.y()));
803
804     // Grand child is now scissored by the render surface
805     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, rootRect.width() - childRect.x() - grandChildRect.x(), rootRect.height() - childRect.y() - grandChildRect.y()));
806     
807     // Empty damage
808     rootDamage = IntRect(0, 0, 0, 0);
809     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
810     
811     // Empty damage == empty scissor
812     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
813     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
814     
815     EXPECT_EQ(root->scissorRect(), IntRect(0, 0, 0, 0));
816     EXPECT_EQ(childPtr->scissorRect(), IntRect(0, 0, 0, 0));
817     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(0, 0, 0, 0));
818     
819     // Partial damage within child
820     rootDamage = IntRect(10, 10, 20, 20);
821     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
822     
823     // Scissors are not computed for root
824     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
825
826     // Entire damage rect is within the root surface
827     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
828     
829     // Entire damage rect is within the layer
830     EXPECT_EQ(root->scissorRect(), rootDamage);
831
832     // Entire damage rect is within the layer, but with different offset
833     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
834
835     // Grand child now gets scissored by its target surface as well as root
836     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width() - grandChildRect.x(), rootDamage.height() - grandChildRect.y()));
837
838     // Partial damage beyond child
839     rootDamage = IntRect(10, 10, 80, 80);
840     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
841     
842     // Scissors are not computed for root
843     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
844
845     // Entire damage rect is within the root surface
846     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), rootDamage);
847     
848     // Entire damage rect is within the layer
849     EXPECT_EQ(root->scissorRect(), rootDamage);
850
851     // Entire damage rect is within the layer, but with different offset
852     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width(), rootDamage.height()));
853
854     // Grand child now gets scissored by its target surface as well as root
855     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width() - grandChildRect.x(), rootDamage.height() - grandChildRect.y()));
856
857     // Partial damage beyond root
858     rootDamage = IntRect(10, 10, 110, 110);
859     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, rootDamage);
860     
861     // Scissors are not computed for root
862     EXPECT_EQ(root->targetRenderSurface()->scissorRect(), IntRect(0, 0, 0, 0));
863
864     // Root surface does not have a clipRect, so its contentRect will be used to intersect with damage.
865     // Result is that root damage rect is clipped at root layer boundary
866     EXPECT_EQ(childPtr->targetRenderSurface()->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
867     
868     // Root does not use layer clipping, so its content rect will be used to intersect with damage
869     // Result is that root damage rect is clipped at root layer boundary
870     EXPECT_EQ(root->scissorRect(), IntRect(rootDamage.x(), rootDamage.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
871
872     // Now the scissor rects are clipped by surfaces contentRect
873     EXPECT_EQ(childPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootRect.width() - rootDamage.x(), rootRect.height() - rootDamage.y()));
874
875     // Grandchild's scissor rect is clipped by its target surface
876     EXPECT_EQ(grandChildPtr->scissorRect(), IntRect(rootDamage.x() - childRect.x(), rootDamage.y() - childRect.y(), rootDamage.width() - grandChildRect.x(), rootDamage.height() - grandChildRect.y()));
877 }
878
879 TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica)
880 {
881     RefPtr<LayerChromium> parent = LayerChromium::create();
882     RefPtr<LayerChromium> child = LayerChromium::create();
883     RefPtr<LayerChromium> childReplica = LayerChromium::create();
884     RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
885     parent->createRenderSurface();
886     parent->addChild(child);
887     child->addChild(grandChild);
888     child->setReplicaLayer(childReplica.get());
889
890     // Child is set up so that a new render surface should be created.
891     child->setOpacity(0.5f);
892
893     WebTransformationMatrix identityMatrix;
894     WebTransformationMatrix parentLayerTransform;
895     parentLayerTransform.scale3d(2.0, 2.0, 1.0);
896     WebTransformationMatrix parentTranslationToAnchor;
897     parentTranslationToAnchor.translate(2.5, 3.0);
898     WebTransformationMatrix parentSublayerMatrix;
899     parentSublayerMatrix.scale3d(10.0, 10.0, 3.3);
900     WebTransformationMatrix parentTranslationToCenter;
901     parentTranslationToCenter.translate(5.0, 6.0);
902     WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
903             * parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
904     WebTransformationMatrix childTranslationToCenter;
905     childTranslationToCenter.translate(8.0, 9.0);
906     WebTransformationMatrix replicaLayerTransform;
907     replicaLayerTransform.scale3d(3.0, 3.0, 1.0);
908     WebTransformationMatrix replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform;
909
910     // Child's render surface should not exist yet.
911     ASSERT_FALSE(child->renderSurface());
912
913     setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25f, 0.25f), FloatPoint(2.5f, 3.0f), IntSize(10, 12), false);
914     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(16, 18), false);
915     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(-0.5f, -0.5f), IntSize(1, 1), false);
916     setLayerPropertiesForTesting(childReplica.get(), replicaLayerTransform, identityMatrix, FloatPoint(0.0f, 0.0f), FloatPoint(0.0f, 0.0f), IntSize(0, 0), false);
917     executeCalculateDrawTransformsAndVisibility(parent.get());
918
919     // Render surface should have been created now.
920     ASSERT_TRUE(child->renderSurface());
921     ASSERT_EQ(child->renderSurface(), child->targetRenderSurface());
922
923     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaOriginTransform());
924     EXPECT_TRANSFORMATION_MATRIX_EQ(replicaCompositeTransform, child->targetRenderSurface()->replicaScreenSpaceTransform());
925 }
926
927 TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
928 {
929     // This test creates a more complex tree and verifies it all at once. This covers the following cases:
930     //   - layers that are described w.r.t. a render surface: should have draw transforms described w.r.t. that surface
931     //   - A render surface described w.r.t. an ancestor render surface: should have a draw transform described w.r.t. that ancestor surface
932     //   - Replicas of a render surface are described w.r.t. the replica's transform around its anchor, along with the surface itself.
933     //   - 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.
934     //   - verifying that each layer has a reference to the correct renderSurface and targetRenderSurface values.
935
936     RefPtr<LayerChromium> parent = LayerChromium::create();
937     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
938     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
939     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
940     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
941     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
942     RefPtr<LayerChromium> replicaOfRS1 = LayerChromium::create();
943     RefPtr<LayerChromium> replicaOfRS2 = LayerChromium::create();
944     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
945     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
946     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
947     parent->createRenderSurface();
948     parent->addChild(renderSurface1);
949     parent->addChild(childOfRoot);
950     renderSurface1->addChild(childOfRS1);
951     renderSurface1->addChild(renderSurface2);
952     renderSurface2->addChild(childOfRS2);
953     childOfRoot->addChild(grandChildOfRoot);
954     childOfRS1->addChild(grandChildOfRS1);
955     childOfRS2->addChild(grandChildOfRS2);
956     renderSurface1->setReplicaLayer(replicaOfRS1.get());
957     renderSurface2->setReplicaLayer(replicaOfRS2.get());
958
959     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
960     renderSurface1->setOpacity(0.5f);
961     renderSurface2->setOpacity(0.33f);
962
963     // All layers in the tree are initialized with an anchor at 2.5 and a size of (10,10).
964     // matrix "A" is the composite layer transform used in all layers, centered about the anchor point
965     // matrix "B" is the sublayer transform used in all layers, centered about the center position of the layer.
966     // matrix "R" is the composite replica transform used in all replica layers.
967     //
968     // x component tests that layerTransform and sublayerTransform are done in the right order (translation and scale are noncommutative).
969     // y component has a translation by 1.0 for every ancestor, which indicates the "depth" of the layer in the hierarchy.
970     WebTransformationMatrix translationToAnchor;
971     translationToAnchor.translate(2.5, 0.0);
972     WebTransformationMatrix translationToCenter;
973     translationToCenter.translate(5.0, 5.0);
974     WebTransformationMatrix layerTransform;
975     layerTransform.translate(1.0, 1.0);
976     WebTransformationMatrix sublayerTransform;
977     sublayerTransform.scale3d(10.0, 1.0, 1.0);
978     WebTransformationMatrix replicaLayerTransform;
979     replicaLayerTransform.scale3d(-2.0, 5.0, 1.0);
980
981     WebTransformationMatrix A = translationToAnchor * layerTransform * translationToAnchor.inverse();
982     WebTransformationMatrix B = translationToCenter * sublayerTransform * translationToCenter.inverse();
983     WebTransformationMatrix R = A * translationToAnchor * replicaLayerTransform * translationToAnchor.inverse();
984
985     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
986     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
987     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
988     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
989     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
990     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
991     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
992     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
993     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
994     setLayerPropertiesForTesting(replicaOfRS1.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
995     setLayerPropertiesForTesting(replicaOfRS2.get(), replicaLayerTransform, sublayerTransform, FloatPoint(), FloatPoint(2.5f, 0.0f), IntSize(), false);
996
997     executeCalculateDrawTransformsAndVisibility(parent.get());
998
999     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
1000     //
1001     ASSERT_TRUE(parent->renderSurface());
1002     ASSERT_FALSE(childOfRoot->renderSurface());
1003     ASSERT_FALSE(grandChildOfRoot->renderSurface());
1004
1005     ASSERT_TRUE(renderSurface1->renderSurface());
1006     ASSERT_FALSE(childOfRS1->renderSurface());
1007     ASSERT_FALSE(grandChildOfRS1->renderSurface());
1008
1009     ASSERT_TRUE(renderSurface2->renderSurface());
1010     ASSERT_FALSE(childOfRS2->renderSurface());
1011     ASSERT_FALSE(grandChildOfRS2->renderSurface());
1012
1013     // Verify all targetRenderSurface accessors
1014     //
1015     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
1016     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
1017     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
1018
1019     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
1020     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
1021     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
1022
1023     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
1024     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
1025     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
1026
1027     // Verify layer draw transforms
1028     //  note that draw transforms are described with respect to the nearest ancestor render surface
1029     //  but screen space transforms are described with respect to the root.
1030     //
1031     EXPECT_TRANSFORMATION_MATRIX_EQ(A * translationToCenter, parent->drawTransform());
1032     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * translationToCenter, childOfRoot->drawTransform());
1033     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * translationToCenter, grandChildOfRoot->drawTransform());
1034
1035     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface1->drawTransform());
1036     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS1->drawTransform());
1037     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS1->drawTransform());
1038
1039     EXPECT_TRANSFORMATION_MATRIX_EQ(translationToCenter, renderSurface2->drawTransform());
1040     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * translationToCenter, childOfRS2->drawTransform());
1041     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A * translationToCenter, grandChildOfRS2->drawTransform());
1042
1043     // Verify layer screen-space transforms
1044     //
1045     EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screenSpaceTransform());
1046     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->screenSpaceTransform());
1047     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->screenSpaceTransform());
1048
1049     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->screenSpaceTransform());
1050     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, childOfRS1->screenSpaceTransform());
1051     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, grandChildOfRS1->screenSpaceTransform());
1052
1053     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->screenSpaceTransform());
1054     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A, childOfRS2->screenSpaceTransform());
1055     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A, grandChildOfRS2->screenSpaceTransform());
1056
1057     // Verify render surface transforms.
1058     //
1059     // Origin transform of render surface 1 is described with respect to root.
1060     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->originTransform());
1061     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaOriginTransform());
1062     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->screenSpaceTransform());
1063     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaScreenSpaceTransform());
1064     // Origin transform of render surface 2 is described with respect to render surface 2.
1065     EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, renderSurface2->renderSurface()->originTransform());
1066     EXPECT_TRANSFORMATION_MATRIX_EQ(B * R, renderSurface2->renderSurface()->replicaOriginTransform());
1067     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->renderSurface()->screenSpaceTransform());
1068     EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R, renderSurface2->renderSurface()->replicaScreenSpaceTransform());
1069
1070     // Sanity check. If these fail there is probably a bug in the test itself.
1071     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
1072     // encodes the "depth" of the layer in the tree.
1073     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
1074     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
1075     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
1076
1077     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
1078     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
1079     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
1080
1081     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
1082     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
1083     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
1084 }
1085
1086 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForClipLayer)
1087 {
1088     RefPtr<LayerChromium> parent = LayerChromium::create();
1089     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
1090     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
1091     renderSurface1->setOpacity(0.9f);
1092
1093     const WebTransformationMatrix identityMatrix;
1094     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
1095     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint(30, 30), IntSize(10, 10), false);
1096
1097     parent->createRenderSurface();
1098     parent->setClipRect(IntRect(0, 0, 10, 10));
1099     parent->addChild(renderSurface1);
1100     renderSurface1->createRenderSurface();
1101     renderSurface1->addChild(child);
1102
1103     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1104     Vector<RefPtr<LayerChromium> > dummyLayerList;
1105     int dummyMaxTextureSize = 512;
1106     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1107
1108     FloatRect dummyDamageRect;
1109     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1110
1111     // The child layer's content is entirely outside the parent's clip rect, so the intermediate
1112     // render surface should have been removed. Render surfaces without children or visible
1113     // content are unexpected at draw time (e.g. we might try to create a content texture of size 0).
1114     ASSERT_FALSE(renderSurface1->renderSurface());
1115     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
1116 }
1117
1118 TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
1119 {
1120     RefPtr<LayerChromium> parent = LayerChromium::create();
1121     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
1122     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
1123     renderSurface1->setOpacity(0);
1124
1125     const WebTransformationMatrix identityMatrix;
1126     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
1127     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
1128
1129     parent->createRenderSurface();
1130     parent->addChild(renderSurface1);
1131     renderSurface1->createRenderSurface();
1132     renderSurface1->addChild(child);
1133
1134     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1135     Vector<RefPtr<LayerChromium> > dummyLayerList;
1136     int dummyMaxTextureSize = 512;
1137     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1138
1139     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1140
1141     // Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
1142     // Also, the drawable content rect should not have been extended by the children.
1143     EXPECT_EQ(parent->renderSurface()->layerList().size(), 0U);
1144     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
1145     EXPECT_EQ(parent->drawableContentRect(), IntRect());
1146 }
1147
1148 TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
1149 {
1150     RefPtr<LayerChromium> parent = LayerChromium::create();
1151     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
1152     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
1153     renderSurface1->setForceRenderSurface(true);
1154
1155     const WebTransformationMatrix identityMatrix;
1156     setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
1157     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
1158
1159     parent->createRenderSurface();
1160     parent->setClipRect(IntRect(0, 0, 10, 10));
1161     parent->addChild(renderSurface1);
1162     renderSurface1->addChild(child);
1163
1164     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1165     Vector<RefPtr<LayerChromium> > dummyLayerList;
1166     int dummyMaxTextureSize = 512;
1167     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1168
1169     EXPECT_TRUE(renderSurface1->renderSurface());
1170     EXPECT_EQ(renderSurfaceLayerList.size(), 1U);
1171
1172     renderSurfaceLayerList.clear();
1173     renderSurface1->setForceRenderSurface(false);
1174     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1175     EXPECT_FALSE(renderSurface1->renderSurface());
1176     EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
1177 }
1178
1179 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
1180 {
1181     // The entire subtree of layers that are outside the clipRect should be culled away,
1182     // and should not affect the renderSurfaceLayerList.
1183     //
1184     // The test tree is set up as follows:
1185     //  - all layers except the leafNodes are forced to be a new renderSurface that have something to draw.
1186     //  - parent is a large container layer.
1187     //  - child has masksToBounds=true to cause clipping.
1188     //  - grandChild is positioned outside of the child's bounds
1189     //  - greatGrandChild is also kept outside child's bounds.
1190     //
1191     // In this configuration, grandChild and greatGrandChild are completely outside the
1192     // clipRect, and they should never get scheduled on the list of renderSurfaces.
1193     //
1194
1195     const WebTransformationMatrix identityMatrix;
1196     RefPtr<LayerChromium> parent = LayerChromium::create();
1197     RefPtr<LayerChromium> child = LayerChromium::create();
1198     RefPtr<LayerChromium> grandChild = LayerChromium::create();
1199     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
1200     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1201     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1202     parent->createRenderSurface();
1203     parent->addChild(child);
1204     child->addChild(grandChild);
1205     grandChild->addChild(greatGrandChild);
1206
1207     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
1208     // even though grandChild and greatGrandChild should be clipped.
1209     child->addChild(leafNode1);
1210     greatGrandChild->addChild(leafNode2);
1211
1212     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1213     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1214     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1215     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1216     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1217     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1218
1219     child->setMasksToBounds(true);
1220     child->setOpacity(0.4f);
1221     grandChild->setOpacity(0.5f);
1222     greatGrandChild->setOpacity(0.4f);
1223
1224     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1225     Vector<RefPtr<LayerChromium> > dummyLayerList;
1226     int dummyMaxTextureSize = 512;
1227
1228     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
1229     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1230     renderSurfaceLayerList.append(parent.get());
1231
1232     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1233
1234     FloatRect dummyDamageRect;
1235     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1236
1237
1238     ASSERT_EQ(2U, renderSurfaceLayerList.size());
1239     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1240     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
1241 }
1242
1243 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfacesCrashRepro)
1244 {
1245     // This is a similar situation as verifyClipRectCullsRenderSurfaces, except that
1246     // it reproduces a crash bug http://code.google.com/p/chromium/issues/detail?id=106734.
1247
1248     const WebTransformationMatrix identityMatrix;
1249     RefPtr<LayerChromium> parent = LayerChromium::create();
1250     RefPtr<LayerChromium> child = LayerChromium::create();
1251     RefPtr<LayerChromium> grandChild = LayerChromium::create();
1252     RefPtr<LayerChromium> greatGrandChild = LayerChromium::create();
1253     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1254     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1255     parent->createRenderSurface();
1256     parent->addChild(child);
1257     child->addChild(grandChild);
1258     grandChild->addChild(greatGrandChild);
1259
1260     // leafNode1 ensures that parent and child are kept on the renderSurfaceLayerList,
1261     // even though grandChild and greatGrandChild should be clipped.
1262     child->addChild(leafNode1);
1263     greatGrandChild->addChild(leafNode2);
1264
1265     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1266     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1267     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1268     setLayerPropertiesForTesting(greatGrandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1269     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1270     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1271
1272     child->setMasksToBounds(true);
1273     child->setOpacity(0.4f);
1274     grandChild->setOpacity(0.5f);
1275     greatGrandChild->setOpacity(0.4f);
1276
1277     // Contaminate the grandChild and greatGrandChild's clipRect to reproduce the crash
1278     // bug found in http://code.google.com/p/chromium/issues/detail?id=106734. In this
1279     // bug, the clipRect was not re-computed for layers that create RenderSurfaces, and
1280     // therefore leafNode2 thinks it should draw itself. As a result, an extra
1281     // renderSurface remains on the renderSurfaceLayerList, which violates the assumption
1282     // that an empty renderSurface will always be the last item on the list, which
1283     // ultimately caused the crash.
1284     child->setClipRect(IntRect(IntPoint::zero(), IntSize(20, 20)));
1285     greatGrandChild->setClipRect(IntRect(IntPoint::zero(), IntSize(1234, 1234)));
1286
1287     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1288     Vector<RefPtr<LayerChromium> > dummyLayerList;
1289     int dummyMaxTextureSize = 512;
1290
1291     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
1292     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1293     renderSurfaceLayerList.append(parent.get());
1294
1295     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1296
1297     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1298
1299     ASSERT_EQ(2U, renderSurfaceLayerList.size());
1300     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1301     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
1302 }
1303
1304 TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
1305 {
1306     // When a renderSurface has a clipRect, it is used to clip the contentRect
1307     // of the surface. When the renderSurface is animating its transforms, then
1308     // the contentRect's position in the clipRect is not defined on the main
1309     // thread, and its contentRect should not be clipped.
1310
1311     // The test tree is set up as follows:
1312     //  - parent is a container layer that masksToBounds=true to cause clipping.
1313     //  - child is a renderSurface, which has a clipRect set to the bounds of the parent.
1314     //  - grandChild is a renderSurface, and the only visible content in child. It is positioned outside of the clipRect from parent.
1315
1316     // In this configuration, grandChild should be outside the clipped
1317     // contentRect of the child, making grandChild not appear in the
1318     // renderSurfaceLayerList. However, when we place an animation on the child,
1319     // this clipping should be avoided and we should keep the grandChild
1320     // in the renderSurfaceLayerList.
1321
1322     const WebTransformationMatrix identityMatrix;
1323     RefPtr<LayerChromium> parent = LayerChromium::create();
1324     RefPtr<LayerChromium> child = LayerChromium::create();
1325     RefPtr<LayerChromium> grandChild = LayerChromium::create();
1326     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode = adoptRef(new LayerChromiumWithForcedDrawsContent());
1327     parent->addChild(child);
1328     child->addChild(grandChild);
1329     grandChild->addChild(leafNode);
1330
1331     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1332     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1333     setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false);
1334     setLayerPropertiesForTesting(leafNode.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1335
1336     parent->setMasksToBounds(true);
1337     child->setOpacity(0.4f);
1338     grandChild->setOpacity(0.4f);
1339
1340     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1341     Vector<RefPtr<LayerChromium> > dummyLayerList;
1342     int dummyMaxTextureSize = 512;
1343
1344     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1345     parent->createRenderSurface();
1346     renderSurfaceLayerList.append(parent.get());
1347
1348     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1349
1350     // Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
1351     ASSERT_EQ(1U, renderSurfaceLayerList.size());
1352     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1353
1354     // Now put an animating transform on child.
1355     addAnimatedTransformToController(*child->layerAnimationController(), 10, 30, 0);
1356
1357     parent->clearRenderSurface();
1358     child->clearRenderSurface();
1359     grandChild->clearRenderSurface();
1360     renderSurfaceLayerList.clear();
1361     dummyLayerList.clear();
1362
1363     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1364     parent->createRenderSurface();
1365     renderSurfaceLayerList.append(parent.get());
1366
1367     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1368
1369     // With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
1370     ASSERT_EQ(3U, renderSurfaceLayerList.size());
1371     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
1372     EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
1373     EXPECT_EQ(grandChild->id(), renderSurfaceLayerList[2]->id());
1374 }
1375
1376 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToLayers)
1377 {
1378     // Verify that layers get the appropriate clipRects when their parent masksToBounds is true.
1379     //
1380     //   grandChild1 - completely inside the region; clipRect should be the mask region (larger than this layer's bounds).
1381     //   grandChild2 - partially clipped but NOT masksToBounds; the clipRect should be the parent's clipRect regardless of the layer's bounds.
1382     //   grandChild3 - partially clipped and masksToBounds; the clipRect will be the intersection of layerBounds and the mask region.
1383     //   grandChild4 - outside parent's clipRect, and masksToBounds; the clipRect should be empty.
1384     //
1385
1386     const WebTransformationMatrix identityMatrix;
1387     RefPtr<LayerChromium> parent = LayerChromium::create();
1388     RefPtr<LayerChromium> child = LayerChromium::create();
1389     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
1390     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
1391     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
1392     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
1393
1394     parent->createRenderSurface();
1395     parent->addChild(child);
1396     child->addChild(grandChild1);
1397     child->addChild(grandChild2);
1398     child->addChild(grandChild3);
1399     child->addChild(grandChild4);
1400
1401     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1402     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1403     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1404     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1405     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1406     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1407
1408     child->setMasksToBounds(true);
1409     grandChild3->setMasksToBounds(true);
1410     grandChild4->setMasksToBounds(true);
1411
1412     // Force everyone to be a render surface.
1413     child->setOpacity(0.4f);
1414     grandChild1->setOpacity(0.5f);
1415     grandChild2->setOpacity(0.5f);
1416     grandChild3->setOpacity(0.5f);
1417     grandChild4->setOpacity(0.5f);
1418
1419     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1420     Vector<RefPtr<LayerChromium> > dummyLayerList;
1421     int dummyMaxTextureSize = 512;
1422
1423     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
1424     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1425     renderSurfaceLayerList.append(parent.get());
1426
1427     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1428
1429     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1430
1431
1432     EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild1->clipRect());
1433     EXPECT_INT_RECT_EQ(IntRect(IntPoint::zero(), IntSize(20, 20)), grandChild2->clipRect());
1434     EXPECT_INT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->clipRect());
1435     EXPECT_TRUE(grandChild4->clipRect().isEmpty());
1436 }
1437
1438 TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
1439 {
1440     // Verify that renderSurfaces (and their layers) get the appropriate clipRects when their parent masksToBounds is true.
1441     //
1442     // Layers that own renderSurfaces (at least for now) do not inherit any clipRect;
1443     // instead the surface will enforce the clip for the entire subtree. They may still
1444     // have a clipRect of their own layer bounds, however, if masksToBounds was true.
1445     //
1446
1447     const WebTransformationMatrix identityMatrix;
1448     RefPtr<LayerChromium> parent = LayerChromium::create();
1449     RefPtr<LayerChromium> child = LayerChromium::create();
1450     RefPtr<LayerChromium> grandChild1 = LayerChromium::create();
1451     RefPtr<LayerChromium> grandChild2 = LayerChromium::create();
1452     RefPtr<LayerChromium> grandChild3 = LayerChromium::create();
1453     RefPtr<LayerChromium> grandChild4 = LayerChromium::create();
1454     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1455     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1456     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode3 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1457     RefPtr<LayerChromiumWithForcedDrawsContent> leafNode4 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1458
1459     parent->createRenderSurface();
1460     parent->addChild(child);
1461     child->addChild(grandChild1);
1462     child->addChild(grandChild2);
1463     child->addChild(grandChild3);
1464     child->addChild(grandChild4);
1465
1466     // the leaf nodes ensure that these grandChildren become renderSurfaces for this test.
1467     grandChild1->addChild(leafNode1);
1468     grandChild2->addChild(leafNode2);
1469     grandChild3->addChild(leafNode3);
1470     grandChild4->addChild(leafNode4);
1471
1472     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1473     setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
1474     setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(5, 5), IntSize(10, 10), false);
1475     setLayerPropertiesForTesting(grandChild2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1476     setLayerPropertiesForTesting(grandChild3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(15, 15), IntSize(10, 10), false);
1477     setLayerPropertiesForTesting(grandChild4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(45, 45), IntSize(10, 10), false);
1478     setLayerPropertiesForTesting(leafNode1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1479     setLayerPropertiesForTesting(leafNode2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1480     setLayerPropertiesForTesting(leafNode3.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1481     setLayerPropertiesForTesting(leafNode4.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
1482
1483     child->setMasksToBounds(true);
1484     grandChild3->setMasksToBounds(true);
1485     grandChild4->setMasksToBounds(true);
1486
1487     // Force everyone to be a render surface.
1488     child->setOpacity(0.4f);
1489     grandChild1->setOpacity(0.5f);
1490     grandChild2->setOpacity(0.5f);
1491     grandChild3->setOpacity(0.5f);
1492     grandChild4->setOpacity(0.5f);
1493
1494     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1495     Vector<RefPtr<LayerChromium> > dummyLayerList;
1496     int dummyMaxTextureSize = 512;
1497
1498     // FIXME: when we fix this "root-layer special case" behavior in CCLayerTreeHost, we will have to fix it here, too.
1499     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1500     renderSurfaceLayerList.append(parent.get());
1501
1502     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1503
1504     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
1505
1506     ASSERT_TRUE(grandChild1->renderSurface());
1507     ASSERT_TRUE(grandChild2->renderSurface());
1508     ASSERT_TRUE(grandChild3->renderSurface());
1509     EXPECT_FALSE(grandChild4->renderSurface()); // Because grandChild4 is entirely clipped, it is expected to not have a renderSurface.
1510
1511     // Surfaces are clipped by their parent, but un-affected by the owning layer's masksToBounds.
1512     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild1->renderSurface()->clipRect());
1513     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild2->renderSurface()->clipRect());
1514     EXPECT_INT_RECT_EQ(IntRect(IntPoint(0, 0), IntSize(20, 20)), grandChild3->renderSurface()->clipRect());
1515
1516     // Layers do not inherit the clipRect from their owned surfaces, but if masksToBounds is true, they do create their own clipRect.
1517     EXPECT_FALSE(grandChild1->usesLayerClipping());
1518     EXPECT_FALSE(grandChild2->usesLayerClipping());
1519     EXPECT_TRUE(grandChild3->usesLayerClipping());
1520     EXPECT_TRUE(grandChild4->usesLayerClipping());
1521 }
1522
1523 TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
1524 {
1525     RefPtr<LayerChromium> parent = LayerChromium::create();
1526     RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
1527     RefPtr<LayerChromium> renderSurface2 = LayerChromium::create();
1528     RefPtr<LayerChromium> childOfRoot = LayerChromium::create();
1529     RefPtr<LayerChromium> childOfRS1 = LayerChromium::create();
1530     RefPtr<LayerChromium> childOfRS2 = LayerChromium::create();
1531     RefPtr<LayerChromium> grandChildOfRoot = LayerChromium::create();
1532     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1533     RefPtr<LayerChromiumWithForcedDrawsContent> grandChildOfRS2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
1534     parent->createRenderSurface();
1535     parent->addChild(renderSurface1);
1536     parent->addChild(childOfRoot);
1537     renderSurface1->addChild(childOfRS1);
1538     renderSurface1->addChild(renderSurface2);
1539     renderSurface2->addChild(childOfRS2);
1540     childOfRoot->addChild(grandChildOfRoot);
1541     childOfRS1->addChild(grandChildOfRS1);
1542     childOfRS2->addChild(grandChildOfRS2);
1543
1544     // In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
1545     addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false);
1546
1547     // Also put an animated opacity on a layer without descendants.
1548     addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false);
1549
1550     WebTransformationMatrix layerTransform;
1551     layerTransform.translate(1.0, 1.0);
1552     WebTransformationMatrix sublayerTransform;
1553     sublayerTransform.scale3d(10.0, 1.0, 1.0);
1554
1555     // In combination with descendantDrawsContent and masksToBounds, an animated transform forces the layer to have a new renderSurface.
1556     addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
1557     renderSurface2->setMasksToBounds(true);
1558
1559     // Also put transform animations on grandChildOfRoot, and grandChildOfRS2
1560     addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0);
1561     addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0);
1562
1563     setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1564     setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1565     setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1566     setLayerPropertiesForTesting(childOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1567     setLayerPropertiesForTesting(childOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1568     setLayerPropertiesForTesting(childOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1569     setLayerPropertiesForTesting(grandChildOfRoot.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1570     setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1571     setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
1572
1573     executeCalculateDrawTransformsAndVisibility(parent.get());
1574
1575     // Only layers that are associated with render surfaces should have an actual renderSurface() value.
1576     //
1577     ASSERT_TRUE(parent->renderSurface());
1578     ASSERT_FALSE(childOfRoot->renderSurface());
1579     ASSERT_FALSE(grandChildOfRoot->renderSurface());
1580
1581     ASSERT_TRUE(renderSurface1->renderSurface());
1582     ASSERT_FALSE(childOfRS1->renderSurface());
1583     ASSERT_FALSE(grandChildOfRS1->renderSurface());
1584
1585     ASSERT_TRUE(renderSurface2->renderSurface());
1586     ASSERT_FALSE(childOfRS2->renderSurface());
1587     ASSERT_FALSE(grandChildOfRS2->renderSurface());
1588
1589     // Verify all targetRenderSurface accessors
1590     //
1591     EXPECT_EQ(parent->renderSurface(), parent->targetRenderSurface());
1592     EXPECT_EQ(parent->renderSurface(), childOfRoot->targetRenderSurface());
1593     EXPECT_EQ(parent->renderSurface(), grandChildOfRoot->targetRenderSurface());
1594
1595     EXPECT_EQ(renderSurface1->renderSurface(), renderSurface1->targetRenderSurface());
1596     EXPECT_EQ(renderSurface1->renderSurface(), childOfRS1->targetRenderSurface());
1597     EXPECT_EQ(renderSurface1->renderSurface(), grandChildOfRS1->targetRenderSurface());
1598
1599     EXPECT_EQ(renderSurface2->renderSurface(), renderSurface2->targetRenderSurface());
1600     EXPECT_EQ(renderSurface2->renderSurface(), childOfRS2->targetRenderSurface());
1601     EXPECT_EQ(renderSurface2->renderSurface(), grandChildOfRS2->targetRenderSurface());
1602
1603     // Verify drawOpacityIsAnimating values
1604     //
1605     EXPECT_FALSE(parent->drawOpacityIsAnimating());
1606     EXPECT_FALSE(childOfRoot->drawOpacityIsAnimating());
1607     EXPECT_TRUE(grandChildOfRoot->drawOpacityIsAnimating());
1608     EXPECT_FALSE(renderSurface1->drawOpacityIsAnimating());
1609     EXPECT_TRUE(renderSurface1->renderSurface()->drawOpacityIsAnimating());
1610     EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating());
1611     EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating());
1612     EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating());
1613     EXPECT_FALSE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
1614     EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating());
1615     EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating());
1616
1617     // Verify drawTransformsAnimatingInTarget values
1618     //
1619     EXPECT_FALSE(parent->drawTransformIsAnimating());
1620     EXPECT_FALSE(childOfRoot->drawTransformIsAnimating());
1621     EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating());
1622     EXPECT_FALSE(renderSurface1->drawTransformIsAnimating());
1623     EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnimating());
1624     EXPECT_FALSE(childOfRS1->drawTransformIsAnimating());
1625     EXPECT_FALSE(grandChildOfRS1->drawTransformIsAnimating());
1626     EXPECT_FALSE(renderSurface2->drawTransformIsAnimating());
1627     EXPECT_TRUE(renderSurface2->renderSurface()->targetSurfaceTransformsAreAnimating());
1628     EXPECT_FALSE(childOfRS2->drawTransformIsAnimating());
1629     EXPECT_TRUE(grandChildOfRS2->drawTransformIsAnimating());
1630
1631     // Verify drawTransformsAnimatingInScreen values
1632     //
1633     EXPECT_FALSE(parent->screenSpaceTransformIsAnimating());
1634     EXPECT_FALSE(childOfRoot->screenSpaceTransformIsAnimating());
1635     EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating());
1636     EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating());
1637     EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimating());
1638     EXPECT_FALSE(childOfRS1->screenSpaceTransformIsAnimating());
1639     EXPECT_FALSE(grandChildOfRS1->screenSpaceTransformIsAnimating());
1640     EXPECT_TRUE(renderSurface2->screenSpaceTransformIsAnimating());
1641     EXPECT_TRUE(renderSurface2->renderSurface()->screenSpaceTransformsAreAnimating());
1642     EXPECT_TRUE(childOfRS2->screenSpaceTransformIsAnimating());
1643     EXPECT_TRUE(grandChildOfRS2->screenSpaceTransformIsAnimating());
1644
1645
1646     // Sanity check. If these fail there is probably a bug in the test itself.
1647     // It is expected that we correctly set up transforms so that the y-component of the screen-space transform
1648     // encodes the "depth" of the layer in the tree.
1649     EXPECT_FLOAT_EQ(1.0, parent->screenSpaceTransform().m42());
1650     EXPECT_FLOAT_EQ(2.0, childOfRoot->screenSpaceTransform().m42());
1651     EXPECT_FLOAT_EQ(3.0, grandChildOfRoot->screenSpaceTransform().m42());
1652
1653     EXPECT_FLOAT_EQ(2.0, renderSurface1->screenSpaceTransform().m42());
1654     EXPECT_FLOAT_EQ(3.0, childOfRS1->screenSpaceTransform().m42());
1655     EXPECT_FLOAT_EQ(4.0, grandChildOfRS1->screenSpaceTransform().m42());
1656
1657     EXPECT_FLOAT_EQ(3.0, renderSurface2->screenSpaceTransform().m42());
1658     EXPECT_FLOAT_EQ(4.0, childOfRS2->screenSpaceTransform().m42());
1659     EXPECT_FLOAT_EQ(5.0, grandChildOfRS2->screenSpaceTransform().m42());
1660 }
1661
1662 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForIdentityTransform)
1663 {
1664     // Test the calculateVisibleRect() function works correctly for identity transforms.
1665
1666     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1667     WebTransformationMatrix layerToSurfaceTransform;
1668
1669     // Case 1: Layer is contained within the surface.
1670     IntRect layerContentRect = IntRect(IntPoint(10, 10), IntSize(30, 30));
1671     IntRect expected = IntRect(IntPoint(10, 10), IntSize(30, 30));
1672     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1673     EXPECT_INT_RECT_EQ(expected, actual);
1674
1675     // Case 2: Layer is outside the surface rect.
1676     layerContentRect = IntRect(IntPoint(120, 120), IntSize(30, 30));
1677     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1678     EXPECT_TRUE(actual.isEmpty());
1679
1680     // Case 3: Layer is partially overlapping the surface rect.
1681     layerContentRect = IntRect(IntPoint(80, 80), IntSize(30, 30));
1682     expected = IntRect(IntPoint(80, 80), IntSize(20, 20));
1683     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1684     EXPECT_INT_RECT_EQ(expected, actual);
1685 }
1686
1687 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForTranslations)
1688 {
1689     // Test the calculateVisibleRect() function works correctly for scaling transforms.
1690
1691     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1692     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1693     WebTransformationMatrix layerToSurfaceTransform;
1694
1695     // Case 1: Layer is contained within the surface.
1696     layerToSurfaceTransform.makeIdentity();
1697     layerToSurfaceTransform.translate(10, 10);
1698     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1699     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1700     EXPECT_INT_RECT_EQ(expected, actual);
1701
1702     // Case 2: Layer is outside the surface rect.
1703     layerToSurfaceTransform.makeIdentity();
1704     layerToSurfaceTransform.translate(120, 120);
1705     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1706     EXPECT_TRUE(actual.isEmpty());
1707
1708     // Case 3: Layer is partially overlapping the surface rect.
1709     layerToSurfaceTransform.makeIdentity();
1710     layerToSurfaceTransform.translate(80, 80);
1711     expected = IntRect(IntPoint(0, 0), IntSize(20, 20));
1712     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1713     EXPECT_INT_RECT_EQ(expected, actual);
1714 }
1715
1716 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor2DRotations)
1717 {
1718     // Test the calculateVisibleRect() function works correctly for rotations about z-axis (i.e. 2D rotations).
1719     // Remember that calculateVisibleRect() should return the visible rect in the layer's space.
1720
1721     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1722     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(30, 30));
1723     WebTransformationMatrix layerToSurfaceTransform;
1724
1725     // Case 1: Layer is contained within the surface.
1726     layerToSurfaceTransform.makeIdentity();
1727     layerToSurfaceTransform.translate(50, 50);
1728     layerToSurfaceTransform.rotate(45);
1729     IntRect expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1730     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1731     EXPECT_INT_RECT_EQ(expected, actual);
1732
1733     // Case 2: Layer is outside the surface rect.
1734     layerToSurfaceTransform.makeIdentity();
1735     layerToSurfaceTransform.translate(-50, 0);
1736     layerToSurfaceTransform.rotate(45);
1737     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1738     EXPECT_TRUE(actual.isEmpty());
1739
1740     // Case 3: The layer is rotated about its top-left corner. In surface space, the layer
1741     //         is oriented diagonally, with the left half outside of the renderSurface. In
1742     //         this case, the visible rect should still be the entire layer (remember the
1743     //         visible rect is computed in layer space); both the top-left and
1744     //         bottom-right corners of the layer are still visible.
1745     layerToSurfaceTransform.makeIdentity();
1746     layerToSurfaceTransform.rotate(45);
1747     expected = IntRect(IntPoint(0, 0), IntSize(30, 30));
1748     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1749     EXPECT_INT_RECT_EQ(expected, actual);
1750
1751     // Case 4: The layer is rotated about its top-left corner, and translated upwards. In
1752     //         surface space, the layer is oriented diagonally, with only the top corner
1753     //         of the surface overlapping the layer. In layer space, the render surface
1754     //         overlaps the right side of the layer. The visible rect should be the
1755     //         layer's right half.
1756     layerToSurfaceTransform.makeIdentity();
1757     layerToSurfaceTransform.translate(0, -sqrt(2.0) * 15);
1758     layerToSurfaceTransform.rotate(45);
1759     expected = IntRect(IntPoint(15, 0), IntSize(15, 30)); // right half of layer bounds.
1760     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1761     EXPECT_INT_RECT_EQ(expected, actual);
1762 }
1763
1764 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicTransform)
1765 {
1766     // Test that the calculateVisibleRect() function works correctly for 3d transforms.
1767
1768     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1769     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1770     WebTransformationMatrix layerToSurfaceTransform;
1771
1772     // Case 1: Orthographic projection of a layer rotated about y-axis by 45 degrees, should be fully contained in the renderSurface.
1773     layerToSurfaceTransform.makeIdentity();
1774     layerToSurfaceTransform.rotate3d(0, 45, 0);
1775     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1776     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1777     EXPECT_INT_RECT_EQ(expected, actual);
1778
1779     // Case 2: Orthographic projection of a layer rotated about y-axis by 45 degrees, but
1780     //         shifted to the side so only the right-half the layer would be visible on
1781     //         the surface.
1782     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.
1783     layerToSurfaceTransform.makeIdentity();
1784     layerToSurfaceTransform.translate(-halfWidthOfRotatedLayer, 0);
1785     layerToSurfaceTransform.rotate3d(0, 45, 0); // rotates about the left edge of the layer
1786     expected = IntRect(IntPoint(50, 0), IntSize(50, 100)); // right half of the layer.
1787     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1788     EXPECT_INT_RECT_EQ(expected, actual);
1789 }
1790
1791 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveTransform)
1792 {
1793     // Test the calculateVisibleRect() function works correctly when the layer has a
1794     // perspective projection onto the target surface.
1795
1796     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1797     IntRect layerContentRect = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1798     WebTransformationMatrix layerToSurfaceTransform;
1799
1800     // Case 1: Even though the layer is twice as large as the surface, due to perspective
1801     //         foreshortening, the layer will fit fully in the surface when its translated
1802     //         more than the perspective amount.
1803     layerToSurfaceTransform.makeIdentity();
1804
1805     // The following sequence of transforms applies the perspective about the center of the surface.
1806     layerToSurfaceTransform.translate(50, 50);
1807     layerToSurfaceTransform.applyPerspective(9);
1808     layerToSurfaceTransform.translate(-50, -50);
1809
1810     // This translate places the layer in front of the surface's projection plane.
1811     layerToSurfaceTransform.translate3d(0, 0, -27);
1812
1813     IntRect expected = IntRect(IntPoint(-50, -50), IntSize(200, 200));
1814     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1815     EXPECT_INT_RECT_EQ(expected, actual);
1816
1817     // Case 2: same projection as before, except that the layer is also translated to the
1818     //         side, so that only the right half of the layer should be visible.
1819     //
1820     // Explanation of expected result:
1821     // The perspective ratio is (z distance between layer and camera origin) / (z distance between projection plane and camera origin) == ((-27 - 9) / 9)
1822     // 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
1823     // visible), then we would need to translate by (-36 / 9) * -50 == -200 in the layer's units.
1824     //
1825     layerToSurfaceTransform.translate3d(-200, 0, 0);
1826     expected = IntRect(IntPoint(50, -50), IntSize(100, 200)); // The right half of the layer's bounding rect.
1827     actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1828     EXPECT_INT_RECT_EQ(expected, actual);
1829 }
1830
1831 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dOrthographicIsNotClippedBehindSurface)
1832 {
1833     // There is currently no explicit concept of an orthographic projection plane in our
1834     // code (nor in the CSS spec to my knowledge). Therefore, layers that are technically
1835     // behind the surface in an orthographic world should not be clipped when they are
1836     // flattened to the surface.
1837
1838     IntRect targetSurfaceRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1839     IntRect layerContentRect = IntRect(IntPoint(0, 0), IntSize(100, 100));
1840     WebTransformationMatrix layerToSurfaceTransform;
1841
1842     // This sequence of transforms effectively rotates the layer about the y-axis at the
1843     // center of the layer.
1844     layerToSurfaceTransform.makeIdentity();
1845     layerToSurfaceTransform.translate(50, 0);
1846     layerToSurfaceTransform.rotate3d(0, 45, 0);
1847     layerToSurfaceTransform.translate(-50, 0);
1848
1849     IntRect expected = IntRect(IntPoint(0, 0), IntSize(100, 100));
1850     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1851     EXPECT_INT_RECT_EQ(expected, actual);
1852 }
1853
1854 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectFor3dPerspectiveWhenClippedByW)
1855 {
1856     // Test the calculateVisibleRect() function works correctly when projecting a surface
1857     // onto a layer, but the layer is partially behind the camera (not just behind the
1858     // projection plane). In this case, the cartesian coordinates may seem to be valid,
1859     // but actually they are not. The visibleRect needs to be properly clipped by the
1860     // w = 0 plane in homogeneous coordinates before converting to cartesian coordinates.
1861
1862     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1863     IntRect layerContentRect = IntRect(IntPoint(-10, -1), IntSize(20, 2));
1864     WebTransformationMatrix layerToSurfaceTransform;
1865
1866     // The layer is positioned so that the right half of the layer should be in front of
1867     // the camera, while the other half is behind the surface's projection plane. The
1868     // following sequence of transforms applies the perspective and rotation about the
1869     // center of the layer.
1870     layerToSurfaceTransform.makeIdentity();
1871     layerToSurfaceTransform.applyPerspective(1);
1872     layerToSurfaceTransform.translate3d(-2, 0, 1);
1873     layerToSurfaceTransform.rotate3d(0, 45, 0);
1874
1875     // Sanity check that this transform does indeed cause w < 0 when applying the
1876     // transform, otherwise this code is not testing the intended scenario.
1877     bool clipped = false;
1878     CCMathUtil::mapQuad(layerToSurfaceTransform, FloatQuad(FloatRect(layerContentRect)), clipped);
1879     ASSERT_TRUE(clipped);
1880
1881     int expectedXPosition = 0;
1882     int expectedWidth = 10;
1883     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1884     EXPECT_EQ(expectedXPosition, actual.x());
1885     EXPECT_EQ(expectedWidth, actual.width());
1886 }
1887
1888 TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection)
1889 {
1890     // To determine visibleRect in layer space, there needs to be an un-projection from
1891     // surface space to layer space. When the original transform was a perspective
1892     // projection that was clipped, it returns a rect that encloses the clipped bounds.
1893     // Un-projecting this new rect may require clipping again.
1894
1895     // This sequence of transforms causes one corner of the layer to protrude across the w = 0 plane, and should be clipped.
1896     IntRect targetSurfaceRect = IntRect(IntPoint(-50, -50), IntSize(100, 100));
1897     IntRect layerContentRect = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1898     WebTransformationMatrix layerToSurfaceTransform;
1899     layerToSurfaceTransform.makeIdentity();
1900     layerToSurfaceTransform.applyPerspective(1);
1901     layerToSurfaceTransform.translate3d(0, 0, -5);
1902     layerToSurfaceTransform.rotate3d(0, 45, 0);
1903     layerToSurfaceTransform.rotate3d(80, 0, 0);
1904
1905     // Sanity check that un-projection does indeed cause w < 0, otherwise this code is not
1906     // testing the intended scenario.
1907     bool clipped = false;
1908     FloatRect clippedRect = CCMathUtil::mapClippedRect(layerToSurfaceTransform, layerContentRect);
1909     CCMathUtil::projectQuad(layerToSurfaceTransform.inverse(), FloatQuad(clippedRect), clipped);
1910     ASSERT_TRUE(clipped);
1911
1912     // Only the corner of the layer is not visible on the surface because of being
1913     // clipped. But, the net result of rounding visible region to an axis-aligned rect is
1914     // that the entire layer should still be considered visible.
1915     IntRect expected = IntRect(IntPoint(-10, -10), IntSize(20, 20));
1916     IntRect actual = CCLayerTreeHostCommon::calculateVisibleRect(targetSurfaceRect, layerContentRect, layerToSurfaceTransform);
1917     EXPECT_INT_RECT_EQ(expected, actual);
1918 }
1919
1920 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d)
1921 {
1922     // Verify the behavior of back-face culling when there are no preserve-3d layers. Note
1923     // that 3d transforms still apply in this case, but they are "flattened" to each
1924     // parent layer according to current W3C spec.
1925
1926     const WebTransformationMatrix identityMatrix;
1927     RefPtr<LayerChromium> parent = LayerChromium::create();
1928     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1929     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
1930     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1931     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1932     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1933     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1934     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1935     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
1936
1937     parent->createRenderSurface();
1938     parent->addChild(frontFacingChild);
1939     parent->addChild(backFacingChild);
1940     parent->addChild(frontFacingSurface);
1941     parent->addChild(backFacingSurface);
1942     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
1943     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
1944     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
1945     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
1946
1947     // Nothing is double-sided
1948     frontFacingChild->setDoubleSided(false);
1949     backFacingChild->setDoubleSided(false);
1950     frontFacingSurface->setDoubleSided(false);
1951     backFacingSurface->setDoubleSided(false);
1952     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
1953     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
1954     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
1955     backFacingChildOfBackFacingSurface->setDoubleSided(false);
1956
1957     WebTransformationMatrix backfaceMatrix;
1958     backfaceMatrix.translate(50, 50);
1959     backfaceMatrix.rotate3d(0, 1, 0, 180);
1960     backfaceMatrix.translate(-50, -50);
1961
1962     // Having a descendant and opacity will force these to have render surfaces.
1963     frontFacingSurface->setOpacity(0.5f);
1964     backFacingSurface->setOpacity(0.5f);
1965
1966     // Nothing preserves 3d. According to current W3C CSS Transforms spec, these layers
1967     // should blindly use their own local transforms to determine back-face culling.
1968     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1969     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1970     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1971     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1972     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1973     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1974     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1975     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1976     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
1977
1978     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
1979     Vector<RefPtr<LayerChromium> > dummyLayerList;
1980     int dummyMaxTextureSize = 512;
1981     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
1982     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
1983     renderSurfaceLayerList.append(parent.get());
1984
1985     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
1986
1987     // Verify which renderSurfaces were created.
1988     EXPECT_FALSE(frontFacingChild->renderSurface());
1989     EXPECT_FALSE(backFacingChild->renderSurface());
1990     EXPECT_TRUE(frontFacingSurface->renderSurface());
1991     EXPECT_TRUE(backFacingSurface->renderSurface());
1992     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
1993     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
1994     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
1995     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
1996
1997     // Verify the renderSurfaceLayerList.
1998     ASSERT_EQ(3u, renderSurfaceLayerList.size());
1999     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2000     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2001     // Even though the back facing surface LAYER gets culled, the other descendants should still be added, so the SURFACE should not be culled.
2002     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[2]->id());
2003
2004     // Verify root surface's layerList.
2005     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2006     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2007     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2008     EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
2009
2010     // Verify frontFacingSurface's layerList.
2011     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2012     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2013     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2014
2015     // Verify backFacingSurface's layerList; its own layer should be culled from the surface list.
2016     ASSERT_EQ(1u, renderSurfaceLayerList[2]->renderSurface()->layerList().size());
2017     EXPECT_EQ(frontFacingChildOfBackFacingSurface->id(), renderSurfaceLayerList[2]->renderSurface()->layerList()[0]->id());
2018 }
2019
2020 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d)
2021 {
2022     // Verify the behavior of back-face culling when preserves-3d transform style is used.
2023
2024     const WebTransformationMatrix identityMatrix;
2025     RefPtr<LayerChromium> parent = LayerChromium::create();
2026     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2027     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2028     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2029     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2030     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2031     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2032     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2033     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2034     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2035     RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2036
2037     parent->createRenderSurface();
2038     parent->addChild(frontFacingChild);
2039     parent->addChild(backFacingChild);
2040     parent->addChild(frontFacingSurface);
2041     parent->addChild(backFacingSurface);
2042     frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
2043     frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
2044     backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
2045     backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
2046
2047     // Nothing is double-sided
2048     frontFacingChild->setDoubleSided(false);
2049     backFacingChild->setDoubleSided(false);
2050     frontFacingSurface->setDoubleSided(false);
2051     backFacingSurface->setDoubleSided(false);
2052     frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
2053     backFacingChildOfFrontFacingSurface->setDoubleSided(false);
2054     frontFacingChildOfBackFacingSurface->setDoubleSided(false);
2055     backFacingChildOfBackFacingSurface->setDoubleSided(false);
2056
2057     WebTransformationMatrix backfaceMatrix;
2058     backfaceMatrix.translate(50, 50);
2059     backfaceMatrix.rotate3d(0, 1, 0, 180);
2060     backfaceMatrix.translate(-50, -50);
2061
2062     // Opacity will not force creation of renderSurfaces in this case because of the
2063     // preserve-3d transform style. Instead, an example of when a surface would be
2064     // created with preserve-3d is when there is a replica layer.
2065     frontFacingSurface->setReplicaLayer(dummyReplicaLayer1.get());
2066     backFacingSurface->setReplicaLayer(dummyReplicaLayer2.get());
2067
2068     // Each surface creates its own new 3d rendering context (as defined by W3C spec).
2069     // According to current W3C CSS Transforms spec, layers in a 3d rendering context
2070     // should use the transform with respect to that context. This 3d rendering context
2071     // occurs when (a) parent's transform style is flat and (b) the layer's transform
2072     // style is preserve-3d.
2073     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transform style is flat.
2074     setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2075     setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2076     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2077     setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
2078     setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2079     setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2080     setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2081     setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2082
2083     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2084     Vector<RefPtr<LayerChromium> > dummyLayerList;
2085     int dummyMaxTextureSize = 512;
2086     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
2087     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
2088     renderSurfaceLayerList.append(parent.get());
2089
2090     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
2091
2092     // Verify which renderSurfaces were created.
2093     EXPECT_FALSE(frontFacingChild->renderSurface());
2094     EXPECT_FALSE(backFacingChild->renderSurface());
2095     EXPECT_TRUE(frontFacingSurface->renderSurface());
2096     EXPECT_FALSE(backFacingSurface->renderSurface());
2097     EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
2098     EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
2099     EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
2100     EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
2101
2102     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2103     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2104     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2105     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2106
2107     // Verify root surface's layerList.
2108     ASSERT_EQ(2u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2109     EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2110     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2111
2112     // Verify frontFacingSurface's layerList.
2113     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2114     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2115     EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2116 }
2117
2118 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms)
2119 {
2120     // Verify that layers are appropriately culled when their back face is showing and
2121     // they are not double sided, while animations are going on.
2122     //
2123     // Layers that are animating do not get culled on the main thread, as their transforms should be
2124     // treated as "unknown" so we can not be sure that their back face is really showing.
2125     //
2126
2127     const WebTransformationMatrix identityMatrix;
2128     RefPtr<LayerChromium> parent = LayerChromium::create();
2129     RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
2130     RefPtr<LayerChromiumWithForcedDrawsContent> animatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2131     RefPtr<LayerChromiumWithForcedDrawsContent> childOfAnimatingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2132     RefPtr<LayerChromiumWithForcedDrawsContent> animatingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
2133     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2134
2135     parent->createRenderSurface();
2136     parent->addChild(child);
2137     parent->addChild(animatingSurface);
2138     animatingSurface->addChild(childOfAnimatingSurface);
2139     parent->addChild(animatingChild);
2140     parent->addChild(child2);
2141
2142     // Nothing is double-sided
2143     child->setDoubleSided(false);
2144     child2->setDoubleSided(false);
2145     animatingSurface->setDoubleSided(false);
2146     childOfAnimatingSurface->setDoubleSided(false);
2147     animatingChild->setDoubleSided(false);
2148
2149     WebTransformationMatrix backfaceMatrix;
2150     backfaceMatrix.translate(50, 50);
2151     backfaceMatrix.rotate3d(0, 1, 0, 180);
2152     backfaceMatrix.translate(-50, -50);
2153
2154     // Having a descendant that draws, masksToBounds, and animating transforms, will make the animatingSurface own a render surface.
2155     addAnimatedTransformToController(*animatingSurface->layerAnimationController(), 10, 30, 0);
2156     animatingSurface->setMasksToBounds(true);
2157     // This is just an animating layer, not a surface.
2158     addAnimatedTransformToController(*animatingChild->layerAnimationController(), 10, 30, 0);
2159
2160     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2161     setLayerPropertiesForTesting(child.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2162     setLayerPropertiesForTesting(animatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2163     setLayerPropertiesForTesting(childOfAnimatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2164     setLayerPropertiesForTesting(animatingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2165     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2166
2167     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2168     Vector<RefPtr<LayerChromium> > dummyLayerList;
2169     int dummyMaxTextureSize = 512;
2170
2171     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
2172     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
2173     renderSurfaceLayerList.append(parent.get());
2174
2175     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
2176
2177     CCLayerTreeHostCommon::calculateVisibleAndScissorRects(renderSurfaceLayerList, parent->renderSurface()->contentRect());
2178
2179     EXPECT_FALSE(child->renderSurface());
2180     EXPECT_TRUE(animatingSurface->renderSurface());
2181     EXPECT_FALSE(childOfAnimatingSurface->renderSurface());
2182     EXPECT_FALSE(animatingChild->renderSurface());
2183     EXPECT_FALSE(child2->renderSurface());
2184
2185     // Verify that the animatingChild and childOfAnimatingSurface were not culled, but that child was.
2186     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2187     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2188     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->id());
2189
2190     // The non-animating child be culled from the layer list for the parent render surface.
2191     ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2192     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2193     EXPECT_EQ(animatingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
2194     EXPECT_EQ(child2->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
2195
2196     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2197     EXPECT_EQ(animatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2198     EXPECT_EQ(childOfAnimatingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2199
2200     EXPECT_FALSE(child2->visibleLayerRect().isEmpty());
2201
2202     // The animating layers should have a visibleLayerRect that represents the area of the front face that is within the viewport.
2203     EXPECT_EQ(animatingChild->visibleLayerRect(), IntRect(IntPoint(), animatingChild->contentBounds()));
2204     EXPECT_EQ(animatingSurface->visibleLayerRect(), IntRect(IntPoint(), animatingSurface->contentBounds()));
2205     // And layers in the subtree of the animating layer should have valid visibleLayerRects also.
2206     EXPECT_EQ(childOfAnimatingSurface->visibleLayerRect(), IntRect(IntPoint(), childOfAnimatingSurface->contentBounds()));
2207 }
2208
2209 TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlatteningSurface)
2210 {
2211     // Verify the behavior of back-face culling for a renderSurface that is created
2212     // when it flattens its subtree, and its parent has preserves-3d.
2213
2214     const WebTransformationMatrix identityMatrix;
2215     RefPtr<LayerChromium> parent = LayerChromium::create();
2216     RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2217     RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
2218     RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2219     RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
2220
2221     parent->createRenderSurface();
2222     parent->addChild(frontFacingSurface);
2223     parent->addChild(backFacingSurface);
2224     frontFacingSurface->addChild(child1);
2225     backFacingSurface->addChild(child2);
2226
2227     // RenderSurfaces are not double-sided
2228     frontFacingSurface->setDoubleSided(false);
2229     backFacingSurface->setDoubleSided(false);
2230
2231     WebTransformationMatrix backfaceMatrix;
2232     backfaceMatrix.translate(50, 50);
2233     backfaceMatrix.rotate3d(0, 1, 0, 180);
2234     backfaceMatrix.translate(-50, -50);
2235
2236     setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
2237     setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2238     setLayerPropertiesForTesting(backFacingSurface.get(),  backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
2239     setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2240     setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
2241
2242     Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
2243     Vector<RefPtr<LayerChromium> > dummyLayerList;
2244     int dummyMaxTextureSize = 512;
2245     parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
2246     parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
2247     renderSurfaceLayerList.append(parent.get());
2248
2249     CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
2250
2251     // Verify which renderSurfaces were created.
2252     EXPECT_TRUE(frontFacingSurface->renderSurface());
2253     EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be culled
2254     EXPECT_FALSE(child1->renderSurface());
2255     EXPECT_FALSE(child2->renderSurface());
2256
2257     // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
2258     ASSERT_EQ(2u, renderSurfaceLayerList.size());
2259     EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
2260     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
2261
2262     // Verify root surface's layerList.
2263     ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
2264     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
2265
2266     // Verify frontFacingSurface's layerList.
2267     ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
2268     EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
2269     EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
2270 }
2271
2272 // FIXME:
2273 // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942
2274 //  - add a test to verify clipping that changes the "center point"
2275 //  - add a case that checks if a render surface's drawTransform is computed correctly. For the general case, and for special cases when clipping.
2276 //  - add a case that checks if a render surface's replicaTransform is computed correctly.
2277 //  - test all the conditions under which render surfaces are created
2278 //  - if possible, test all conditions under which render surfaces are not created
2279 //  - verify that the layer lists of render surfaces are correct, verify that "targetRenderSurface" values for each layer are correct.
2280 //  - test the computation of clip rects and content rects
2281 //  - test the special cases for mask layers and replica layers
2282 //  - test the other functions in CCLayerTreeHostCommon
2283 //
2284
2285 } // namespace