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