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