2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "LayerChromium.h"
29 #include "CCLayerTreeTestCommon.h"
30 #include <gmock/gmock.h>
31 #include <gtest/gtest.h>
33 using namespace WebCore;
34 using namespace WebKitTests;
35 using ::testing::Mock;
37 using ::testing::AtLeast;
38 using ::testing::AnyNumber;
40 #define EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(delegate, numTimesExpectedNotifySync, codeToTest) \
41 EXPECT_CALL((delegate), notifySyncRequired()).Times((numTimesExpectedNotifySync)); \
43 Mock::VerifyAndClearExpectations(&(delegate))
47 class MockLayerDelegate : public CCLayerDelegate {
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());
55 class LayerChromiumWithInstrumentedDestructor : public LayerChromium {
57 explicit LayerChromiumWithInstrumentedDestructor(CCLayerDelegate* delegate)
58 : LayerChromium(delegate)
62 virtual ~LayerChromiumWithInstrumentedDestructor()
64 s_numInstancesDestroyed++;
67 static int getNumInstancesDestroyed() { return s_numInstancesDestroyed; }
68 static void resetNumInstancesDestroyed() { s_numInstancesDestroyed = 0; }
71 static int s_numInstancesDestroyed;
74 int LayerChromiumWithInstrumentedDestructor::s_numInstancesDestroyed = 0;
76 class LayerChromiumTest : public testing::Test {
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());
88 // Static variables need to be reset for every new test case
89 LayerChromiumWithInstrumentedDestructor::resetNumInstancesDestroyed();
92 void verifyTestTreeInitialState() const
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());
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());
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());
112 ASSERT_EQ(static_cast<size_t>(0), m_child3->children().size());
115 void createSimpleTestTree()
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);
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);
134 verifyTestTreeInitialState();
137 MockLayerDelegate m_silentDelegate, m_parentDelegate;
138 RefPtr<LayerChromium> m_parent, m_child1, m_child2, m_child3, m_grandChild1, m_grandChild2, m_grandChild3;
141 TEST_F(LayerChromiumTest, basicCreateAndDestroy)
143 MockLayerDelegate mockDelegate;
145 // notifySyncRequired should not be called just because the layer is created or destroyed.
146 EXPECT_CALL(mockDelegate, notifySyncRequired()).Times(0);
148 RefPtr<LayerChromiumWithInstrumentedDestructor> testLayer = adoptRef(new LayerChromiumWithInstrumentedDestructor(&mockDelegate));
149 ASSERT_TRUE(testLayer.get());
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());
155 ASSERT_EQ(1, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
158 TEST_F(LayerChromiumTest, addAndRemoveChild)
160 MockLayerDelegate parentDelegate;
161 MockLayerDelegate childDelegate;
162 RefPtr<LayerChromium> parent = LayerChromium::create(&parentDelegate);
163 RefPtr<LayerChromium> child = LayerChromium::create(&childDelegate);
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());
169 // Parent calls notifySyncRequired exactly once when adding child.
170 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->addChild(child));
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());
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());
183 TEST_F(LayerChromiumTest, verifyDestructorSemantics)
185 MockLayerDelegate parentDelegate;
186 MockLayerDelegate childDelegate;
187 RefPtr<LayerChromiumWithInstrumentedDestructor> parent = adoptRef(new LayerChromiumWithInstrumentedDestructor(&parentDelegate));
188 RefPtr<LayerChromium> child = LayerChromium::create(&childDelegate);
190 // Set up initial test conditions
191 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->addChild(child));
192 EXPECT_TRUE(child->parent());
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);
199 ASSERT_EQ(0, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
201 ASSERT_EQ(1, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
203 // Child should have been un-parented correctly, but not yet destroyed since we have a reference to it.
204 EXPECT_FALSE(child->parent());
207 TEST_F(LayerChromiumTest, verifyDestructorDoesNotLeak)
209 // In this test we explicitly instantiate a special subclass of
210 // LayerChromium so we can track the number of destructors called.
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));
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);
229 // Clear all the children RefPtrs here. But since they are attached to the tree, no destructors should be called yet.
237 // releasing the parent should cause all destructors to be invoked.
238 ASSERT_EQ(0, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
240 ASSERT_EQ(7, LayerChromiumWithInstrumentedDestructor::getNumInstancesDestroyed());
243 TEST_F(LayerChromiumTest, insertChild)
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);
253 ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
255 // The child delegate notifySyncRequired should not be called when inserting.
256 EXPECT_CALL(childDelegate, notifySyncRequired()).Times(0);
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());
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());
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());
279 // Case 4: inserting to end of list
280 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(parentDelegate, 1, parent->insertChild(child4, 3));
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());
289 // parent's destructor will invoke notifySyncRequired as it removes its children.
290 EXPECT_CALL(parentDelegate, notifySyncRequired()).Times(AtLeast(1));
293 TEST_F(LayerChromiumTest, insertChildPastEndOfList)
295 RefPtr<LayerChromium> parent = LayerChromium::create(&m_silentDelegate);
296 RefPtr<LayerChromium> child1 = LayerChromium::create(&m_silentDelegate);
297 RefPtr<LayerChromium> child2 = LayerChromium::create(&m_silentDelegate);
299 ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
301 // insert to an out-of-bounds index
302 parent->insertChild(child1, 53);
304 ASSERT_EQ(static_cast<size_t>(1), parent->children().size());
305 EXPECT_EQ(child1, parent->children()[0]);
307 // insert another child to out-of-bounds, when list is not already empty.
308 parent->insertChild(child2, 2459);
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]);
315 TEST_F(LayerChromiumTest, insertSameChildTwice)
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);
322 ASSERT_EQ(static_cast<size_t>(0), parent->children().size());
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));
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]);
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));
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]);
340 // parent's destructor will invoke notifySyncRequired as it removes leftover children
341 EXPECT_CALL(parentDelegate, notifySyncRequired()).Times(AtLeast(1));
344 TEST_F(LayerChromiumTest, insertChildThatAlreadyHadParent)
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);
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());
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));
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());
368 TEST_F(LayerChromiumTest, replaceChildWithNewChild)
370 createSimpleTestTree();
371 RefPtr<LayerChromium> child4 = LayerChromium::create(&m_silentDelegate);
373 EXPECT_FALSE(child4->parent());
375 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
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());
383 EXPECT_FALSE(m_child2->parent());
385 // parent's destructor will invoke notifySyncRequired as it removes leftover children
386 EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
389 TEST_F(LayerChromiumTest, replaceChildWithNewChildThatHasOtherParent)
391 createSimpleTestTree();
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());
401 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->replaceChild(m_child2.get(), child4));
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());
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());
414 // parent's destructor will invoke notifySyncRequired as it removes leftover children
415 EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
418 TEST_F(LayerChromiumTest, replaceChildWithSameChild)
420 createSimpleTestTree();
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));
425 verifyTestTreeInitialState();
427 // parent's destructor will invoke notifySyncRequired as it removes leftover children
428 EXPECT_CALL(m_parentDelegate, notifySyncRequired()).Times(AtLeast(1));
431 TEST_F(LayerChromiumTest, removeAllChildren)
433 createSimpleTestTree();
435 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(m_parentDelegate, AtLeast(1), m_parent->removeAllChildren());
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());
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());
446 TEST_F(LayerChromiumTest, setChildren)
448 MockLayerDelegate newParentDelegate;
449 RefPtr<LayerChromium> oldParent = LayerChromium::create(&m_silentDelegate);
450 RefPtr<LayerChromium> newParent = LayerChromium::create(&newParentDelegate);
452 RefPtr<LayerChromium> child1 = LayerChromium::create(&m_silentDelegate);
453 RefPtr<LayerChromium> child2 = LayerChromium::create(&m_silentDelegate);
455 Vector<RefPtr<LayerChromium> > newChildren;
456 newChildren.append(child1);
457 newChildren.append(child2);
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());
465 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(newParentDelegate, AtLeast(1), newParent->setChildren(newChildren));
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());
471 // parent's destructor will invoke notifySyncRequired as it removes its children.
472 EXPECT_CALL(newParentDelegate, notifySyncRequired()).Times(AtLeast(1));
475 TEST_F(LayerChromiumTest, getRootLayerAfterTreeManipulations)
477 createSimpleTestTree();
478 RefPtr<LayerChromium> child4 = LayerChromium::create(&m_silentDelegate);
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());
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());
492 m_child1->removeFromParent();
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());
504 m_grandChild3->addChild(child4);
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());
515 m_child2->replaceChild(m_grandChild3.get(), m_child1);
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());
528 // FIXME: need to add a test for getDescendantDrawsContent after resolving
529 // some issues with LayerChromium::descendantDrawsContent().
530 // see discussion on issue 67750
532 TEST_F(LayerChromiumTest, checkSetNeedsDisplayCausesCorrectBehavior)
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.
538 MockLayerDelegate mockDelegate;
539 RefPtr<LayerChromium> testLayer = LayerChromium::create(&mockDelegate);
540 IntSize testBounds = IntSize(501, 508);
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);
547 // Before anything, testLayer should have an empty dirty rect.
548 EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
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());
555 // The real test begins here.
558 EXECUTE_AND_VERIFY_NOTIFY_SYNC_BEHAVIOR(mockDelegate, 1, testLayer->setNeedsDisplay(dirty1));
559 EXPECT_FLOAT_RECT_EQ(dirty1, testLayer->dirtyRect());
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());
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());
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());
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());
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());
583 TEST_F(LayerChromiumTest, checkSetNeedsDisplayWithNullDelegate)
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);
590 FloatRect dirty = FloatRect(10.0f, 15.0f, 1.0f, 2.0f);
592 testLayer->setBounds(testBounds);
593 EXPECT_FLOAT_RECT_EQ(FloatRect(0.0f, 0.0f, 501.0f, 508.0f), testLayer->dirtyRect());
595 testLayer->resetNeedsDisplay();
596 EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
598 testLayer->setNeedsDisplay(dirty);
599 EXPECT_FLOAT_RECT_EQ(dirty, testLayer->dirtyRect());
602 TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior)
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.
609 // sanity check of initial test condition
610 EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
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());
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));
647 // The above tests should not have caused a non-empty dirty rect.
648 EXPECT_TRUE(testLayer->dirtyRect().isEmpty());
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());
657 // FIXME: need to add a test for setLayerTreeHost with a non-null stubbed CCLayerTreeHost.