tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebKit / chromium / tests / LayerChromiumTest.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 "LayerChromium.h"
28
29 #include "CCLayerTreeTestCommon.h"
30 #include <gmock/gmock.h>
31 #include <gtest/gtest.h>
32
33 using namespace WebCore;
34 using namespace WebKitTests;
35 using ::testing::Mock;
36 using ::testing::_;
37 using ::testing::AtLeast;
38 using ::testing::AnyNumber;
39
40 #define EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(delegate, numTimesExpectedNotifySync, codeToTest) \
41     EXPECT_CALL((delegate), notifySyncRequired()).Times((numTimesExpectedNotifySync)); \
42     codeToTest;                                                         \
43     Mock::VerifyAndClearExpectations(&(delegate))
44
45 namespace {
46
47 class MockLayerDelegate : public CCLayerDelegate {
48 public:
49     MOCK_CONST_METHOD0(drawsContent, bool());
50     MOCK_CONST_METHOD0(preserves3D, bool());
51     MOCK_METHOD2(paintContents, void(GraphicsContext&, const IntRect&));
52     MOCK_METHOD0(notifySyncRequired, void());
53 };
54
55 class LayerChromiumWithInstrumentedDestructor : public LayerChromium {
56 public:
57     explicit LayerChromiumWithInstrumentedDestructor(CCLayerDelegate* delegate)
58         : LayerChromium(delegate)
59     {
60     }
61
62     virtual ~LayerChromiumWithInstrumentedDestructor()
63     {
64         s_numInstancesDestroyed++;
65     }
66
67     static int getNumInstancesDestroyed() { return s_numInstancesDestroyed; }
68     static void resetNumInstancesDestroyed() { s_numInstancesDestroyed = 0; }
69
70 private:
71     static int s_numInstancesDestroyed;
72 };
73
74 int LayerChromiumWithInstrumentedDestructor::s_numInstancesDestroyed = 0;
75
76 class LayerChromiumTest : public testing::Test {
77 protected:
78     virtual void SetUp()
79     {
80         // m_silentDelegate is initialized to be just a stub and will
81         // not print any warnings. It is used when we are not worried
82         // about testing how the delegate is called.
83         EXPECT_CALL(m_silentDelegate, drawsContent()).Times(AnyNumber());
84         EXPECT_CALL(m_silentDelegate, preserves3D()).Times(AnyNumber());
85         EXPECT_CALL(m_silentDelegate, paintContents(_, _)).Times(AnyNumber());
86         EXPECT_CALL(m_silentDelegate, notifySyncRequired()).Times(AnyNumber());
87
88         // Static variables need to be reset for every new test case
89         LayerChromiumWithInstrumentedDestructor::resetNumInstancesDestroyed();
90     }
91
92     void verifyTestTreeInitialState() const
93     {
94         ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
95         EXPECT_EQ(m_child1, m_parent->children()[0]);
96         EXPECT_EQ(m_child2, m_parent->children()[1]);
97         EXPECT_EQ(m_child3, m_parent->children()[2]);
98         EXPECT_EQ(m_parent.get(), m_child1->parent());
99         EXPECT_EQ(m_parent.get(), m_child2->parent());
100         EXPECT_EQ(m_parent.get(), m_child3->parent());
101
102         ASSERT_EQ(static_cast<size_t>(2), m_child1->children().size());
103         EXPECT_EQ(m_grandChild1, m_child1->children()[0]);
104         EXPECT_EQ(m_grandChild2, m_child1->children()[1]);
105         EXPECT_EQ(m_child1.get(), m_grandChild1->parent());
106         EXPECT_EQ(m_child1.get(), m_grandChild2->parent());
107
108         ASSERT_EQ(static_cast<size_t>(1), m_child2->children().size());
109         EXPECT_EQ(m_grandChild3, m_child2->children()[0]);
110         EXPECT_EQ(m_child2.get(), m_grandChild3->parent());
111
112         ASSERT_EQ(static_cast<size_t>(0), m_child3->children().size());
113     }
114
115     void createSimpleTestTree()
116     {
117         m_parent = LayerChromium::create(&m_parentDelegate);
118         m_child1 = LayerChromium::create(&m_silentDelegate);
119         m_child2 = LayerChromium::create(&m_silentDelegate);
120         m_child3 = LayerChromium::create(&m_silentDelegate);
121         m_grandChild1 = LayerChromium::create(&m_silentDelegate);
122         m_grandChild2 = LayerChromium::create(&m_silentDelegate);
123         m_grandChild3 = LayerChromium::create(&m_silentDelegate);
124
125         EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(3);
126         m_parent->addChild(m_child1);
127         m_parent->addChild(m_child2);
128         m_parent->addChild(m_child3);
129         Mock::VerifyAndClearExpectations(&m_parentDelegate);
130         m_child1->addChild(m_grandChild1);
131         m_child1->addChild(m_grandChild2);
132         m_child2->addChild(m_grandChild3);
133
134         verifyTestTreeInitialState();
135     }
136
137     MockLayerDelegate m_silentDelegate, m_parentDelegate;
138     RefPtr<LayerChromium> m_parent, m_child1, m_child2, m_child3, m_grandChild1, m_grandChild2, m_grandChild3;
139 };
140
141 TEST_F(LayerChromiumTest, basicCreateAndDestroy)
142 {
143     MockLayerDelegate mockDelegate;
144
145     // notifySyncRequired should not be called just because the layer is created or destroyed.
146     EXPECT_CALL(mockDelegate, notifySyncRequired()).Times(0);
147
148     RefPtr<LayerChromiumWithInstrumentedDestructor> testLayer = adoptRef(new LayerChromiumWithInstrumentedDestructor(&mockDelegate));
149     ASSERT_TRUE(testLayer.get());
150
151     // notifySyncRequired should also not be called on the destructor when the layer has no children.
152     // so we need to make sure the layer is destroyed before the mock delegate.
153     ASSERT_EQ(0, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
154     testLayer.release();
155     ASSERT_EQ(1, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
156 }
157
158 TEST_F(LayerChromiumTest, addAndRemoveChild)
159 {
160     MockLayerDelegate parentDelegate;
161     MockLayerDelegate childDelegate;
162     RefPtr<LayerChromium> parent = LayerChromium::create(&parentDelegate);
163     RefPtr<LayerChromium> child = LayerChromium::create(&childDelegate);
164
165     // Upon creation, layers should not have children or parent.
166     ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
167     EXPECT_FALSE(child->parent());
168
169     // Parent calls notifySyncRequired exactly once when adding child.
170     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->addChild(child));
171
172     ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
173     EXPECT_EQ(child.get(), parent->children()[0]);
174     EXPECT_EQ(parent.get(), child->parent());
175     EXPECT_EQ(parent.get(), child->rootLayer());
176
177     // removeFromParent should cause the parent's notifySyncRequired to be called exactly once.
178     // The childDelegate notifySyncRequired should remain un-used.
179     EXPECT_CALL(childDelegate, notifySyncRequired()).Times(0);
180     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, child->removeFromParent());
181 }
182
183 TEST_F(LayerChromiumTest, verifyDestructorSemantics)
184 {
185     MockLayerDelegate parentDelegate;
186     MockLayerDelegate childDelegate;
187     RefPtr<LayerChromiumWithInstrumentedDestructor> parent = adoptRef(new LayerChromiumWithInstrumentedDestructor(&parentDelegate));
188     RefPtr<LayerChromium> child = LayerChromium::create(&childDelegate);
189
190     // Set up initial test conditions
191     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->addChild(child));
192     EXPECT_TRUE(child->parent());
193
194     // When being destroyed, notifySyncRequired is called once for the parent, because it has one child,
195     // but should not be called for the child which has no children.
196     EXPECT_CALL(parentDelegate, notifySyncRequired()).Times(1);
197     EXPECT_CALL(childDelegate, notifySyncRequired()).Times(0);
198
199     ASSERT_EQ(0, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
200     parent.release();
201     ASSERT_EQ(1, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
202
203     // Child should have been un-parented correctly, but not yet destroyed since we have a reference to it.
204     EXPECT_FALSE(child->parent());
205 }
206
207 TEST_F(LayerChromiumTest, verifyDestructorDoesNotLeak)
208 {
209     // In this test we explicitly instantiate a special subclass of
210     // LayerChromium so we can track the number of destructors called.
211
212     RefPtr<LayerChromiumWithInstrumentedDestructor> parent, child1, child2, child3, grandChild1, grandChild2, grandChild3;
213     parent = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
214     child1 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
215     child2 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
216     child3 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
217     grandChild1 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
218     grandChild2 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
219     grandChild3 = adoptRef(new LayerChromiumWithInstrumentedDestructor(&m_silentDelegate));
220
221     // set up a simple tree.
222     parent->addChild(child1);
223     parent->addChild(child2);
224     parent->addChild(child3);
225     child1->addChild(grandChild1);
226     child1->addChild(grandChild2);
227     child2->addChild(grandChild3);
228
229     // Clear all the children RefPtrs here. But since they are attached to the tree, no destructors should be called yet.
230     child1.clear();
231     child2.clear();
232     child3.clear();
233     grandChild1.clear();
234     grandChild2.clear();
235     grandChild3.clear();
236
237     // releasing the parent should cause all destructors to be invoked.
238     ASSERT_EQ(0, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
239     parent.release();
240     ASSERT_EQ(7, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
241 }
242
243 TEST_F(LayerChromiumTest, insertChild)
244 {
245     MockLayerDelegate parentDelegate;
246     MockLayerDelegate childDelegate;
247     RefPtr<LayerChromium>parent = LayerChromium::create(&parentDelegate);
248     RefPtr<LayerChromium>child1 = LayerChromium::create(&childDelegate);
249     RefPtr<LayerChromium>child2 = LayerChromium::create(&childDelegate);
250     RefPtr<LayerChromium>child3 = LayerChromium::create(&childDelegate);
251     RefPtr<LayerChromium>child4 = LayerChromium::create(&childDelegate);
252
253     ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
254
255     // The child delegate notifySyncRequired should not be called when inserting.
256     EXPECT_CALL(childDelegate, notifySyncRequired()).Times(0);
257
258     // Case 1: inserting to empty list.
259     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child3, 0));
260     ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
261     EXPECT_EQ(child3, parent->children()[0]);
262     EXPECT_EQ(parent.get(), child3->parent());
263
264     // Case 2: inserting to beginning of list
265     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child1, 0));
266     ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
267     EXPECT_EQ(child1, parent->children()[0]);
268     EXPECT_EQ(child3, parent->children()[1]);
269     EXPECT_EQ(parent.get(), child1->parent());
270
271     // Case 3: inserting to middle of list
272     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child2, 1));
273     ASSERT_EQ(static_cast<size_t>(3), parent->children().size());
274     EXPECT_EQ(child1, parent->children()[0]);
275     EXPECT_EQ(child2, parent->children()[1]);
276     EXPECT_EQ(child3, parent->children()[2]);
277     EXPECT_EQ(parent.get(), child2->parent());
278
279     // Case 4: inserting to end of list
280     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child4, 3));
281
282     ASSERT_EQ(static_cast<size_t>(4), parent->children().size());
283     EXPECT_EQ(child1, parent->children()[0]);
284     EXPECT_EQ(child2, parent->children()[1]);
285     EXPECT_EQ(child3, parent->children()[2]);
286     EXPECT_EQ(child4, parent->children()[3]);
287     EXPECT_EQ(parent.get(), child4->parent());
288
289     // parent's destructor will invoke notifySyncRequired as it removes its children.
290     EXPECT_CALL(parentDelegate, notifySyncRequired()).Times(AtLeast(1));
291 }
292
293 TEST_F(LayerChromiumTest, insertChildPastEndOfList)
294 {
295     RefPtr<LayerChromium> parent = LayerChromium::create(&m_silentDelegate);
296     RefPtr<LayerChromium> child1 = LayerChromium::create(&m_silentDelegate);
297     RefPtr<LayerChromium> child2 = LayerChromium::create(&m_silentDelegate);
298
299     ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
300
301     // insert to an out-of-bounds index
302     parent->insertChild(child1, 53);
303
304     ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
305     EXPECT_EQ(child1, parent->children()[0]);
306
307     // insert another child to out-of-bounds, when list is not already empty.
308     parent->insertChild(child2, 2459);
309
310     ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
311     EXPECT_EQ(child1, parent->children()[0]);
312     EXPECT_EQ(child2, parent->children()[1]);
313 }
314
315 TEST_F(LayerChromiumTest, insertSameChildTwice)
316 {
317     MockLayerDelegate parentDelegate;
318     RefPtr<LayerChromium> parent = LayerChromium::create(&parentDelegate);
319     RefPtr<LayerChromium> child1 = LayerChromium::create(&m_silentDelegate);
320     RefPtr<LayerChromium> child2 = LayerChromium::create(&m_silentDelegate);
321
322     ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
323
324     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child1, 0));
325     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child2, 1));
326
327     ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
328     EXPECT_EQ(child1, parent->children()[0]);
329     EXPECT_EQ(child2, parent->children()[1]);
330
331     // Inserting the same child again should cause the child to be removed and re-inserted at the new location.
332     // So the parent's notifySyncRequired would be called one or more times.
333     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, AtLeast(1), parent->insertChild(child1, 1));
334
335     // child1 should now be at the end of the list.
336     ASSERT_EQ(static_cast<size_t>(2), parent->children().size());
337     EXPECT_EQ(child2, parent->children()[0]);
338     EXPECT_EQ(child1, parent->children()[1]);
339
340     // parent's destructor will invoke notifySyncRequired as it removes leftover children
341     EXPECT_CALL(parentDelegate, notifySyncRequired()).Times(AtLeast(1));
342 }
343
344 TEST_F(LayerChromiumTest, insertChildThatAlreadyHadParent)
345 {
346     MockLayerDelegate oldParentDelegate;
347     RefPtr<LayerChromium> oldParent = LayerChromium::create(&oldParentDelegate);
348     RefPtr<LayerChromium> parent = LayerChromium::create(&m_silentDelegate);
349     RefPtr<LayerChromium> child = LayerChromium::create(&m_silentDelegate);
350
351     // set up and sanity-check initial test conditions
352     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(oldParentDelegate, 1, oldParent->addChild(child));
353     ASSERT_EQ(static_cast<size_t>(1), oldParent->children().size());
354     ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
355     EXPECT_EQ(child, oldParent->children()[0]);
356     EXPECT_EQ(oldParent.get(), child->parent());
357
358     // Inserting to new parent causes old parent's notifySyncRequired to be called.
359     // Note that it also causes parent's notifySyncRequired to be called, but that is tested elsewhere.
360     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(oldParentDelegate, 1, parent->insertChild(child, 0));
361
362     ASSERT_EQ(static_cast<size_t>(0), oldParent->children().size());
363     ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
364     EXPECT_EQ(child, parent->children()[0]);
365     EXPECT_EQ(parent.get(), child->parent());
366 }
367
368 TEST_F(LayerChromiumTest, replaceChildWithNewChild)
369 {
370     createSimpleTestTree();
371     RefPtr<LayerChromium> child4 = LayerChromium::create(&m_silentDelegate);
372
373     EXPECT_FALSE(child4->parent());
374
375     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
376
377     ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
378     EXPECT_EQ(m_child1, m_parent->children()[0]);
379     EXPECT_EQ(child4, m_parent->children()[1]);
380     EXPECT_EQ(m_child3, m_parent->children()[2]);
381     EXPECT_EQ(m_parent.get(), child4->parent());
382
383     EXPECT_FALSE(m_child2->parent());
384
385     // parent's destructor will invoke notifySyncRequired as it removes leftover children
386     EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
387 }
388
389 TEST_F(LayerChromiumTest, replaceChildWithNewChildThatHasOtherParent)
390 {
391     createSimpleTestTree();
392
393     // create another simple tree with testLayer and child4.
394     RefPtr<LayerChromium> testLayer = LayerChromium::create(&m_silentDelegate);
395     RefPtr<LayerChromium> child4 = LayerChromium::create(&m_silentDelegate);
396     testLayer->addChild(child4);
397     ASSERT_EQ(static_cast<size_t>(1), testLayer->children().size());
398     EXPECT_EQ(child4, testLayer->children()[0]);
399     EXPECT_EQ(testLayer.get(), child4->parent());
400
401     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
402
403     ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size());
404     EXPECT_EQ(m_child1, m_parent->children()[0]);
405     EXPECT_EQ(child4, m_parent->children()[1]);
406     EXPECT_EQ(m_child3, m_parent->children()[2]);
407     EXPECT_EQ(m_parent.get(), child4->parent());
408
409     // testLayer should no longer have child4,
410     // and child2 should no longer have a parent.
411     ASSERT_EQ(static_cast<size_t>(0), testLayer->children().size());
412     EXPECT_FALSE(m_child2->parent());
413
414     // parent's destructor will invoke notifySyncRequired as it removes leftover children
415     EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
416 }
417
418 TEST_F(LayerChromiumTest, replaceChildWithSameChild)
419 {
420     createSimpleTestTree();
421
422     // notifySyncRequired should not be called because its the same child
423     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, 0, m_parent->replaceChild(m_child2.get(), m_child2));
424
425     verifyTestTreeInitialState();
426
427     // parent's destructor will invoke notifySyncRequired as it removes leftover children
428     EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
429 }
430
431 TEST_F(LayerChromiumTest, removeAllChildren)
432 {
433     createSimpleTestTree();
434
435     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->removeAllChildren());
436
437     ASSERT_EQ(static_cast<size_t>(0), m_parent->children().size());
438     EXPECT_FALSE(m_child1->parent());
439     EXPECT_FALSE(m_child2->parent());
440     EXPECT_FALSE(m_child3->parent());
441
442     // notifySyncRequired should not be called if trying to removeAllChildren when there are no children.
443     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, 0, m_parent->removeAllChildren());
444 }
445
446 TEST_F(LayerChromiumTest, setChildren)
447 {
448     MockLayerDelegate newParentDelegate;
449     RefPtr<LayerChromium> oldParent = LayerChromium::create(&m_silentDelegate);
450     RefPtr<LayerChromium> newParent = LayerChromium::create(&newParentDelegate);
451
452     RefPtr<LayerChromium> child1 = LayerChromium::create(&m_silentDelegate);
453     RefPtr<LayerChromium> child2 = LayerChromium::create(&m_silentDelegate);
454
455     Vector<RefPtr<LayerChromium> > newChildren;
456     newChildren.append(child1);
457     newChildren.append(child2);
458
459     // Set up and verify initial test conditions: child1 has a parent, child2 has no parent.
460     oldParent->addChild(child1);
461     ASSERT_EQ(static_cast<size_t>(0), newParent->children().size());
462     EXPECT_EQ(oldParent.get(), child1->parent());
463     EXPECT_FALSE(child2->parent());
464
465     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(newParentDelegate, AtLeast(1), newParent->setChildren(newChildren));
466
467     ASSERT_EQ(static_cast<size_t>(2), newParent->children().size());
468     EXPECT_EQ(newParent.get(), child1->parent());
469     EXPECT_EQ(newParent.get(), child2->parent());
470
471     // parent's destructor will invoke notifySyncRequired as it removes its children.
472     EXPECT_CALL(newParentDelegate, notifySyncRequired()).Times(AtLeast(1));
473 }
474
475 TEST_F(LayerChromiumTest, getRootLayerAfterTreeManipulations)
476 {
477     createSimpleTestTree();
478     RefPtr<LayerChromium> child4 = LayerChromium::create(&m_silentDelegate);
479
480     // In this test case, we don't care about how the parent's notifySyncRequired is called.
481     EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AnyNumber());
482
483     EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
484     EXPECT_EQ(m_parent.get(), m_child1->rootLayer());
485     EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
486     EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
487     EXPECT_EQ(child4.get(),   child4->rootLayer());
488     EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer());
489     EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer());
490     EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
491
492     m_child1->removeFromParent();
493
494     // child1 and its children, grandChild1 and grandChild2 are now on a separate subtree.
495     EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
496     EXPECT_EQ(m_child1.get(), m_child1->rootLayer());
497     EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
498     EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
499     EXPECT_EQ(child4.get(), child4->rootLayer());
500     EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer());
501     EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer());
502     EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
503
504     m_grandChild3->addChild(child4);
505
506     EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
507     EXPECT_EQ(m_child1.get(), m_child1->rootLayer());
508     EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
509     EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
510     EXPECT_EQ(m_parent.get(), child4->rootLayer());
511     EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer());
512     EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer());
513     EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer());
514
515     m_child2->replaceChild(m_grandChild3.get(), m_child1);
516
517     // grandChild3 gets orphaned and the child1 subtree gets planted back into the tree under child2.
518     EXPECT_EQ(m_parent.get(), m_parent->rootLayer());
519     EXPECT_EQ(m_parent.get(), m_child1->rootLayer());
520     EXPECT_EQ(m_parent.get(), m_child2->rootLayer());
521     EXPECT_EQ(m_parent.get(), m_child3->rootLayer());
522     EXPECT_EQ(m_grandChild3.get(), child4->rootLayer());
523     EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer());
524     EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer());
525     EXPECT_EQ(m_grandChild3.get(), m_grandChild3->rootLayer());
526 }
527
528 // FIXME: need to add a test for getDescendantDrawsContent after resolving
529 //        some issues with LayerChromium::descendantDrawsContent().
530 //        see discussion on issue 67750
531
532 TEST_F(LayerChromiumTest, checkSetNeedsDisplayCausesCorrectBehavior)
533 {
534     // The semantics for setNeedsDisplay which are tested here:
535     //   1. creates a unioned dirtyRect appropriately.
536     //   2. indirectly calls notifySyncRequired, exactly once for each call to setNeedsDisplay.
537
538     MockLayerDelegate mockDelegate;
539     RefPtr<LayerChromium> testLayer = LayerChromium::create(&mockDelegate);
540     IntSize testBounds = IntSize(501, 508);
541
542     FloatRect dirty1 = FloatRect(10.0f, 15.0f, 1.0f, 2.0f);
543     FloatRect dirty2 = FloatRect(20.0f, 25.0f, 3.0f, 4.0f);
544     FloatRect emptyDirtyRect = FloatRect(40.0f, 45.0f, 0, 0);
545     FloatRect outOfBoundsDirtyRect = FloatRect(400.0f, 405.0f, 500.0f, 502.0f);
546
547     // Before anything, testLayer should have an empty dirty rect.
548     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
549
550     // This is just initialization, but notifySyncRequired behavior is verified anyway to avoid warnings.
551     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setBounds(testBounds));
552     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->resetNeedsDisplay());
553     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
554
555     // The real test begins here.
556
557     // Case 1: basic
558     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay(dirty1));
559     EXPECT_FLOAT_RECT_EQ(dirty1, testLayer->dirtyRect());
560
561     // Case 2: a second dirty rect should be unioned of dirty1 and dirty2.
562     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay(dirty2));
563     EXPECT_FLOAT_RECT_EQ(FloatRect(10.0f, 15.0f, 13.0f, 14.0f), testLayer->dirtyRect());
564
565     // Case 3: dirty rect should not change because of an empty dirty rect.
566     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay(emptyDirtyRect));
567     EXPECT_FLOAT_RECT_EQ(FloatRect(10.0f, 15.0f, 13.0f, 14.0f), testLayer->dirtyRect());
568
569     // Case 4: LayerChromium should accept dirty rects that go beyond its bounds
570     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay(outOfBoundsDirtyRect));
571     EXPECT_FLOAT_RECT_EQ(FloatRect(10.0f, 15.0f, 890.0f, 892.0f), testLayer->dirtyRect());
572
573     // Case 5: setNeedsDisplay() without the dirty rect arg should cause the entire bounds to be dirty,
574     //         overriding any existing dirty rect.
575     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay());
576     EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, testBounds.width(), testBounds.height()), testLayer->dirtyRect());
577
578     // resetNeedsDisplay should empty the dirty rect, and NOT call notifySyncRequired.
579     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->resetNeedsDisplay());
580     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
581 }
582
583 TEST_F(LayerChromiumTest, checkSetNeedsDisplayWithNullDelegate)
584 {
585     // Without a delegate, the layer should still mark itself dirty as appropriate,
586     // and it should not crash trying to use a non-existing delegate.
587     RefPtr<LayerChromium> testLayer = LayerChromium::create(0);
588     IntSize testBounds = IntSize(501, 508);
589
590     FloatRect dirty = FloatRect(10.0f, 15.0f, 1.0f, 2.0f);
591
592     testLayer->setBounds(testBounds);
593     EXPECT_FLOAT_RECT_EQ(FloatRect(0.0f, 0.0f, 501.0f, 508.0f), testLayer->dirtyRect());
594
595     testLayer->resetNeedsDisplay();
596     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
597
598     testLayer->setNeedsDisplay(dirty);
599     EXPECT_FLOAT_RECT_EQ(dirty, testLayer->dirtyRect());
600 }
601
602 TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior)
603 {
604     MockLayerDelegate initialDelegate;
605     MockLayerDelegate mockDelegate;
606     RefPtr<LayerChromium> testLayer = LayerChromium::create(&initialDelegate);
607     RefPtr<LayerChromium> dummyLayer = LayerChromium::create(&m_silentDelegate); // just a dummy layer for this test case.
608
609     // sanity check of initial test condition
610     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
611
612     // Test properties that should not call needsDisplay and needsCommit when changed.
613     // notifySyncRequired should not be called, and the dirtyRect should remain still empty.
614     EXPECT_CALL(initialDelegate, notifySyncRequired()).Times(0); // old delegate should not be used when setDelegate gives a new delegate.
615     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setDelegate(&mockDelegate));
616     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setName("Test Layer"));
617     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setVisibleLayerRect(IntRect(0, 0, 40, 50)));
618     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setScrollPosition(IntPoint(10, 10)));
619     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setUsesLayerClipping(true));
620     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setIsNonCompositedContent(true));
621     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setReplicaLayer(dummyLayer.get()));
622     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setDrawOpacity(0.5f));
623     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setClipRect(IntRect(3, 3, 8, 8)));
624     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setTargetRenderSurface(0));
625     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setDrawTransform(TransformationMatrix()));
626     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setScreenSpaceTransform(TransformationMatrix()));
627     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 0, testLayer->setDrawableContentRect(IntRect(4, 5, 6, 7)));
628     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
629
630     // Next, test properties that should call setNeedsCommit (but not setNeedsDisplay)
631     // These properties should indirectly call notifySyncRequired, but the dirty rect should not change.
632     // Note that for many of these properties it is important to test setting the property to a value that
633     // is different than what the constructor initializes it to.
634     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setAnchorPoint(FloatPoint(1.23f, 4.56f)));
635     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setAnchorPointZ(0.7f));
636     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setBackgroundColor(Color(0.4f, 0.4f, 0.4f)));
637     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setMasksToBounds(true));
638     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setMaskLayer(dummyLayer.get()));
639     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setOpacity(0.5f));
640     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setOpaque(false));
641     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setPosition(FloatPoint(4.0f, 9.0f)));
642     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setSublayerTransform(TransformationMatrix()));
643     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setScrollable(true));
644     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setTransform(TransformationMatrix()));
645     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setDoubleSided(false));
646
647     // The above tests should not have caused a non-empty dirty rect.
648     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
649
650     // Test properties that should call setNeedsDisplay
651     // These properties will call notifySyncRequired and change the dirty rect.
652     EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setBounds(IntSize(5, 10)));
653     EXPECT_FLOAT_RECT_EQ(FloatRect(0.0f, 0.0f, 5.0f, 10.0f), testLayer->dirtyRect());
654     testLayer->resetNeedsDisplay();
655     EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
656
657     // FIXME: need to add a test for setLayerTreeHost with a non-null stubbed CCLayerTreeHost.
658 }
659
660 } // namespace