OLD | NEW |
| (Empty) |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 | |
7 #include "LayerChromium.h" | |
8 | |
9 #include "CCGeometryTestUtils.h" | |
10 #include "CCLayerImpl.h" | |
11 #include "CCLayerTreeHost.h" | |
12 #include "CCSingleThreadProxy.h" | |
13 #include "FakeCCLayerTreeHostClient.h" | |
14 #include "LayerPainterChromium.h" | |
15 #include <gmock/gmock.h> | |
16 #include <gtest/gtest.h> | |
17 #include <public/WebCompositor.h> | |
18 #include <public/WebTransformationMatrix.h> | |
19 | |
20 using namespace WebCore; | |
21 using namespace WebKitTests; | |
22 using WebKit::WebTransformationMatrix; | |
23 using ::testing::Mock; | |
24 using ::testing::_; | |
25 using ::testing::AtLeast; | |
26 using ::testing::AnyNumber; | |
27 | |
28 #define EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(numTimesExpectedSetNeedsCom
mit, codeToTest) do { \ | |
29 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times((numTimesExpectedS
etNeedsCommit)); \ | |
30 codeToTest;
\ | |
31 Mock::VerifyAndClearExpectations(m_layerTreeHost.get());
\ | |
32 } while (0) | |
33 | |
34 namespace { | |
35 | |
36 class MockCCLayerTreeHost : public CCLayerTreeHost { | |
37 public: | |
38 MockCCLayerTreeHost() | |
39 : CCLayerTreeHost(&m_fakeClient, CCLayerTreeSettings()) | |
40 { | |
41 initialize(); | |
42 } | |
43 | |
44 MOCK_METHOD0(setNeedsCommit, void()); | |
45 | |
46 private: | |
47 FakeCCLayerTreeHostClient m_fakeClient; | |
48 }; | |
49 | |
50 class MockLayerPainterChromium : public LayerPainterChromium { | |
51 public: | |
52 virtual void paint(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE { } | |
53 }; | |
54 | |
55 | |
56 class LayerChromiumTest : public testing::Test { | |
57 protected: | |
58 virtual void SetUp() | |
59 { | |
60 // Initialize without threading support. | |
61 WebKit::WebCompositor::initialize(0); | |
62 m_layerTreeHost = adoptPtr(new MockCCLayerTreeHost); | |
63 } | |
64 | |
65 virtual void TearDown() | |
66 { | |
67 Mock::VerifyAndClearExpectations(m_layerTreeHost.get()); | |
68 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber()); | |
69 m_parent.clear(); | |
70 m_child1.clear(); | |
71 m_child2.clear(); | |
72 m_child3.clear(); | |
73 m_grandChild1.clear(); | |
74 m_grandChild2.clear(); | |
75 m_grandChild3.clear(); | |
76 | |
77 m_layerTreeHost->setRootLayer(0); | |
78 m_layerTreeHost.clear(); | |
79 WebKit::WebCompositor::shutdown(); | |
80 } | |
81 | |
82 void verifyTestTreeInitialState() const | |
83 { | |
84 ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size()); | |
85 EXPECT_EQ(m_child1, m_parent->children()[0]); | |
86 EXPECT_EQ(m_child2, m_parent->children()[1]); | |
87 EXPECT_EQ(m_child3, m_parent->children()[2]); | |
88 EXPECT_EQ(m_parent.get(), m_child1->parent()); | |
89 EXPECT_EQ(m_parent.get(), m_child2->parent()); | |
90 EXPECT_EQ(m_parent.get(), m_child3->parent()); | |
91 | |
92 ASSERT_EQ(static_cast<size_t>(2), m_child1->children().size()); | |
93 EXPECT_EQ(m_grandChild1, m_child1->children()[0]); | |
94 EXPECT_EQ(m_grandChild2, m_child1->children()[1]); | |
95 EXPECT_EQ(m_child1.get(), m_grandChild1->parent()); | |
96 EXPECT_EQ(m_child1.get(), m_grandChild2->parent()); | |
97 | |
98 ASSERT_EQ(static_cast<size_t>(1), m_child2->children().size()); | |
99 EXPECT_EQ(m_grandChild3, m_child2->children()[0]); | |
100 EXPECT_EQ(m_child2.get(), m_grandChild3->parent()); | |
101 | |
102 ASSERT_EQ(static_cast<size_t>(0), m_child3->children().size()); | |
103 } | |
104 | |
105 void createSimpleTestTree() | |
106 { | |
107 m_parent = LayerChromium::create(); | |
108 m_child1 = LayerChromium::create(); | |
109 m_child2 = LayerChromium::create(); | |
110 m_child3 = LayerChromium::create(); | |
111 m_grandChild1 = LayerChromium::create(); | |
112 m_grandChild2 = LayerChromium::create(); | |
113 m_grandChild3 = LayerChromium::create(); | |
114 | |
115 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AnyNumber()); | |
116 m_layerTreeHost->setRootLayer(m_parent); | |
117 | |
118 m_parent->addChild(m_child1); | |
119 m_parent->addChild(m_child2); | |
120 m_parent->addChild(m_child3); | |
121 m_child1->addChild(m_grandChild1); | |
122 m_child1->addChild(m_grandChild2); | |
123 m_child2->addChild(m_grandChild3); | |
124 | |
125 Mock::VerifyAndClearExpectations(m_layerTreeHost.get()); | |
126 | |
127 verifyTestTreeInitialState(); | |
128 } | |
129 | |
130 OwnPtr<MockCCLayerTreeHost> m_layerTreeHost; | |
131 RefPtr<LayerChromium> m_parent, m_child1, m_child2, m_child3, m_grandChild1,
m_grandChild2, m_grandChild3; | |
132 }; | |
133 | |
134 TEST_F(LayerChromiumTest, basicCreateAndDestroy) | |
135 { | |
136 RefPtr<LayerChromium> testLayer = LayerChromium::create(); | |
137 ASSERT_TRUE(testLayer); | |
138 | |
139 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(0); | |
140 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
141 } | |
142 | |
143 TEST_F(LayerChromiumTest, addAndRemoveChild) | |
144 { | |
145 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
146 RefPtr<LayerChromium> child = LayerChromium::create(); | |
147 | |
148 // Upon creation, layers should not have children or parent. | |
149 ASSERT_EQ(static_cast<size_t>(0), parent->children().size()); | |
150 EXPECT_FALSE(child->parent()); | |
151 | |
152 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, m_layerTreeHost->setRootLaye
r(parent)); | |
153 | |
154 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->addChild(child)); | |
155 | |
156 ASSERT_EQ(static_cast<size_t>(1), parent->children().size()); | |
157 EXPECT_EQ(child.get(), parent->children()[0]); | |
158 EXPECT_EQ(parent.get(), child->parent()); | |
159 EXPECT_EQ(parent.get(), child->rootLayer()); | |
160 | |
161 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), child->removeFromPa
rent()); | |
162 } | |
163 | |
164 TEST_F(LayerChromiumTest, insertChild) | |
165 { | |
166 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
167 RefPtr<LayerChromium> child1 = LayerChromium::create(); | |
168 RefPtr<LayerChromium> child2 = LayerChromium::create(); | |
169 RefPtr<LayerChromium> child3 = LayerChromium::create(); | |
170 RefPtr<LayerChromium> child4 = LayerChromium::create(); | |
171 | |
172 parent->setLayerTreeHost(m_layerTreeHost.get()); | |
173 | |
174 ASSERT_EQ(static_cast<size_t>(0), parent->children().size()); | |
175 | |
176 // Case 1: inserting to empty list. | |
177 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child3,
0)); | |
178 ASSERT_EQ(static_cast<size_t>(1), parent->children().size()); | |
179 EXPECT_EQ(child3, parent->children()[0]); | |
180 EXPECT_EQ(parent.get(), child3->parent()); | |
181 | |
182 // Case 2: inserting to beginning of list | |
183 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child1,
0)); | |
184 ASSERT_EQ(static_cast<size_t>(2), parent->children().size()); | |
185 EXPECT_EQ(child1, parent->children()[0]); | |
186 EXPECT_EQ(child3, parent->children()[1]); | |
187 EXPECT_EQ(parent.get(), child1->parent()); | |
188 | |
189 // Case 3: inserting to middle of list | |
190 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child2,
1)); | |
191 ASSERT_EQ(static_cast<size_t>(3), parent->children().size()); | |
192 EXPECT_EQ(child1, parent->children()[0]); | |
193 EXPECT_EQ(child2, parent->children()[1]); | |
194 EXPECT_EQ(child3, parent->children()[2]); | |
195 EXPECT_EQ(parent.get(), child2->parent()); | |
196 | |
197 // Case 4: inserting to end of list | |
198 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child4,
3)); | |
199 | |
200 ASSERT_EQ(static_cast<size_t>(4), parent->children().size()); | |
201 EXPECT_EQ(child1, parent->children()[0]); | |
202 EXPECT_EQ(child2, parent->children()[1]); | |
203 EXPECT_EQ(child3, parent->children()[2]); | |
204 EXPECT_EQ(child4, parent->children()[3]); | |
205 EXPECT_EQ(parent.get(), child4->parent()); | |
206 | |
207 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1)); | |
208 } | |
209 | |
210 TEST_F(LayerChromiumTest, insertChildPastEndOfList) | |
211 { | |
212 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
213 RefPtr<LayerChromium> child1 = LayerChromium::create(); | |
214 RefPtr<LayerChromium> child2 = LayerChromium::create(); | |
215 | |
216 ASSERT_EQ(static_cast<size_t>(0), parent->children().size()); | |
217 | |
218 // insert to an out-of-bounds index | |
219 parent->insertChild(child1, 53); | |
220 | |
221 ASSERT_EQ(static_cast<size_t>(1), parent->children().size()); | |
222 EXPECT_EQ(child1, parent->children()[0]); | |
223 | |
224 // insert another child to out-of-bounds, when list is not already empty. | |
225 parent->insertChild(child2, 2459); | |
226 | |
227 ASSERT_EQ(static_cast<size_t>(2), parent->children().size()); | |
228 EXPECT_EQ(child1, parent->children()[0]); | |
229 EXPECT_EQ(child2, parent->children()[1]); | |
230 } | |
231 | |
232 TEST_F(LayerChromiumTest, insertSameChildTwice) | |
233 { | |
234 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
235 RefPtr<LayerChromium> child1 = LayerChromium::create(); | |
236 RefPtr<LayerChromium> child2 = LayerChromium::create(); | |
237 | |
238 parent->setLayerTreeHost(m_layerTreeHost.get()); | |
239 | |
240 ASSERT_EQ(static_cast<size_t>(0), parent->children().size()); | |
241 | |
242 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child1,
0)); | |
243 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, parent->insertChild(child2,
1)); | |
244 | |
245 ASSERT_EQ(static_cast<size_t>(2), parent->children().size()); | |
246 EXPECT_EQ(child1, parent->children()[0]); | |
247 EXPECT_EQ(child2, parent->children()[1]); | |
248 | |
249 // Inserting the same child again should cause the child to be removed and r
e-inserted at the new location. | |
250 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), parent->insertChild
(child1, 1)); | |
251 | |
252 // child1 should now be at the end of the list. | |
253 ASSERT_EQ(static_cast<size_t>(2), parent->children().size()); | |
254 EXPECT_EQ(child2, parent->children()[0]); | |
255 EXPECT_EQ(child1, parent->children()[1]); | |
256 | |
257 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1)); | |
258 } | |
259 | |
260 TEST_F(LayerChromiumTest, replaceChildWithNewChild) | |
261 { | |
262 createSimpleTestTree(); | |
263 RefPtr<LayerChromium> child4 = LayerChromium::create(); | |
264 | |
265 EXPECT_FALSE(child4->parent()); | |
266 | |
267 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), m_parent->replaceCh
ild(m_child2.get(), child4)); | |
268 | |
269 ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size()); | |
270 EXPECT_EQ(m_child1, m_parent->children()[0]); | |
271 EXPECT_EQ(child4, m_parent->children()[1]); | |
272 EXPECT_EQ(m_child3, m_parent->children()[2]); | |
273 EXPECT_EQ(m_parent.get(), child4->parent()); | |
274 | |
275 EXPECT_FALSE(m_child2->parent()); | |
276 } | |
277 | |
278 TEST_F(LayerChromiumTest, replaceChildWithNewChildThatHasOtherParent) | |
279 { | |
280 createSimpleTestTree(); | |
281 | |
282 // create another simple tree with testLayer and child4. | |
283 RefPtr<LayerChromium> testLayer = LayerChromium::create(); | |
284 RefPtr<LayerChromium> child4 = LayerChromium::create(); | |
285 testLayer->addChild(child4); | |
286 ASSERT_EQ(static_cast<size_t>(1), testLayer->children().size()); | |
287 EXPECT_EQ(child4, testLayer->children()[0]); | |
288 EXPECT_EQ(testLayer.get(), child4->parent()); | |
289 | |
290 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), m_parent->replaceCh
ild(m_child2.get(), child4)); | |
291 | |
292 ASSERT_EQ(static_cast<size_t>(3), m_parent->children().size()); | |
293 EXPECT_EQ(m_child1, m_parent->children()[0]); | |
294 EXPECT_EQ(child4, m_parent->children()[1]); | |
295 EXPECT_EQ(m_child3, m_parent->children()[2]); | |
296 EXPECT_EQ(m_parent.get(), child4->parent()); | |
297 | |
298 // testLayer should no longer have child4, | |
299 // and child2 should no longer have a parent. | |
300 ASSERT_EQ(static_cast<size_t>(0), testLayer->children().size()); | |
301 EXPECT_FALSE(m_child2->parent()); | |
302 } | |
303 | |
304 TEST_F(LayerChromiumTest, replaceChildWithSameChild) | |
305 { | |
306 createSimpleTestTree(); | |
307 | |
308 // setNeedsCommit should not be called because its the same child | |
309 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, m_parent->replaceChild(m_chi
ld2.get(), m_child2)); | |
310 | |
311 verifyTestTreeInitialState(); | |
312 } | |
313 | |
314 TEST_F(LayerChromiumTest, removeAllChildren) | |
315 { | |
316 createSimpleTestTree(); | |
317 | |
318 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(3), m_parent->removeAll
Children()); | |
319 | |
320 ASSERT_EQ(static_cast<size_t>(0), m_parent->children().size()); | |
321 EXPECT_FALSE(m_child1->parent()); | |
322 EXPECT_FALSE(m_child2->parent()); | |
323 EXPECT_FALSE(m_child3->parent()); | |
324 } | |
325 | |
326 TEST_F(LayerChromiumTest, setChildren) | |
327 { | |
328 RefPtr<LayerChromium> oldParent = LayerChromium::create(); | |
329 RefPtr<LayerChromium> newParent = LayerChromium::create(); | |
330 | |
331 RefPtr<LayerChromium> child1 = LayerChromium::create(); | |
332 RefPtr<LayerChromium> child2 = LayerChromium::create(); | |
333 | |
334 Vector<RefPtr<LayerChromium> > newChildren; | |
335 newChildren.append(child1); | |
336 newChildren.append(child2); | |
337 | |
338 // Set up and verify initial test conditions: child1 has a parent, child2 ha
s no parent. | |
339 oldParent->addChild(child1); | |
340 ASSERT_EQ(static_cast<size_t>(0), newParent->children().size()); | |
341 EXPECT_EQ(oldParent.get(), child1->parent()); | |
342 EXPECT_FALSE(child2->parent()); | |
343 | |
344 newParent->setLayerTreeHost(m_layerTreeHost.get()); | |
345 | |
346 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(AtLeast(1), newParent->setChild
ren(newChildren)); | |
347 | |
348 ASSERT_EQ(static_cast<size_t>(2), newParent->children().size()); | |
349 EXPECT_EQ(newParent.get(), child1->parent()); | |
350 EXPECT_EQ(newParent.get(), child2->parent()); | |
351 | |
352 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1)); | |
353 } | |
354 | |
355 TEST_F(LayerChromiumTest, getRootLayerAfterTreeManipulations) | |
356 { | |
357 createSimpleTestTree(); | |
358 | |
359 // For this test we don't care about setNeedsCommit calls. | |
360 EXPECT_CALL(*m_layerTreeHost, setNeedsCommit()).Times(AtLeast(1)); | |
361 | |
362 RefPtr<LayerChromium> child4 = LayerChromium::create(); | |
363 | |
364 EXPECT_EQ(m_parent.get(), m_parent->rootLayer()); | |
365 EXPECT_EQ(m_parent.get(), m_child1->rootLayer()); | |
366 EXPECT_EQ(m_parent.get(), m_child2->rootLayer()); | |
367 EXPECT_EQ(m_parent.get(), m_child3->rootLayer()); | |
368 EXPECT_EQ(child4.get(), child4->rootLayer()); | |
369 EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer()); | |
370 EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer()); | |
371 EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer()); | |
372 | |
373 m_child1->removeFromParent(); | |
374 | |
375 // child1 and its children, grandChild1 and grandChild2 are now on a separat
e subtree. | |
376 EXPECT_EQ(m_parent.get(), m_parent->rootLayer()); | |
377 EXPECT_EQ(m_child1.get(), m_child1->rootLayer()); | |
378 EXPECT_EQ(m_parent.get(), m_child2->rootLayer()); | |
379 EXPECT_EQ(m_parent.get(), m_child3->rootLayer()); | |
380 EXPECT_EQ(child4.get(), child4->rootLayer()); | |
381 EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer()); | |
382 EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer()); | |
383 EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer()); | |
384 | |
385 m_grandChild3->addChild(child4); | |
386 | |
387 EXPECT_EQ(m_parent.get(), m_parent->rootLayer()); | |
388 EXPECT_EQ(m_child1.get(), m_child1->rootLayer()); | |
389 EXPECT_EQ(m_parent.get(), m_child2->rootLayer()); | |
390 EXPECT_EQ(m_parent.get(), m_child3->rootLayer()); | |
391 EXPECT_EQ(m_parent.get(), child4->rootLayer()); | |
392 EXPECT_EQ(m_child1.get(), m_grandChild1->rootLayer()); | |
393 EXPECT_EQ(m_child1.get(), m_grandChild2->rootLayer()); | |
394 EXPECT_EQ(m_parent.get(), m_grandChild3->rootLayer()); | |
395 | |
396 m_child2->replaceChild(m_grandChild3.get(), m_child1); | |
397 | |
398 // grandChild3 gets orphaned and the child1 subtree gets planted back into t
he tree under child2. | |
399 EXPECT_EQ(m_parent.get(), m_parent->rootLayer()); | |
400 EXPECT_EQ(m_parent.get(), m_child1->rootLayer()); | |
401 EXPECT_EQ(m_parent.get(), m_child2->rootLayer()); | |
402 EXPECT_EQ(m_parent.get(), m_child3->rootLayer()); | |
403 EXPECT_EQ(m_grandChild3.get(), child4->rootLayer()); | |
404 EXPECT_EQ(m_parent.get(), m_grandChild1->rootLayer()); | |
405 EXPECT_EQ(m_parent.get(), m_grandChild2->rootLayer()); | |
406 EXPECT_EQ(m_grandChild3.get(), m_grandChild3->rootLayer()); | |
407 } | |
408 | |
409 TEST_F(LayerChromiumTest, checkSetNeedsDisplayCausesCorrectBehavior) | |
410 { | |
411 // The semantics for setNeedsDisplay which are tested here: | |
412 // 1. sets needsDisplay flag appropriately. | |
413 // 2. indirectly calls setNeedsCommit, exactly once for each call to setNe
edsDisplay. | |
414 | |
415 RefPtr<LayerChromium> testLayer = LayerChromium::create(); | |
416 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
417 | |
418 IntSize testBounds = IntSize(501, 508); | |
419 | |
420 FloatRect dirty1 = FloatRect(10, 15, 1, 2); | |
421 FloatRect dirty2 = FloatRect(20, 25, 3, 4); | |
422 FloatRect emptyDirtyRect = FloatRect(40, 45, 0, 0); | |
423 FloatRect outOfBoundsDirtyRect = FloatRect(400, 405, 500, 502); | |
424 | |
425 // Before anything, testLayer should not be dirty. | |
426 EXPECT_FALSE(testLayer->needsDisplay()); | |
427 | |
428 // This is just initialization, but setNeedsCommit behavior is verified anyw
ay to avoid warnings. | |
429 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBou
nds)); | |
430 testLayer = LayerChromium::create(); | |
431 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
432 EXPECT_FALSE(testLayer->needsDisplay()); | |
433 | |
434 // The real test begins here. | |
435 | |
436 // Case 1: needsDisplay flag should not change because of an empty dirty rec
t. | |
437 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRe
ct(emptyDirtyRect)); | |
438 EXPECT_FALSE(testLayer->needsDisplay()); | |
439 | |
440 // Case 2: basic. | |
441 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRe
ct(dirty1)); | |
442 EXPECT_TRUE(testLayer->needsDisplay()); | |
443 | |
444 // Case 3: a second dirty rect. | |
445 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRe
ct(dirty2)); | |
446 EXPECT_TRUE(testLayer->needsDisplay()); | |
447 | |
448 // Case 4: LayerChromium should accept dirty rects that go beyond its bounds
. | |
449 testLayer = LayerChromium::create(); | |
450 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
451 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBou
nds)); | |
452 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplayRe
ct(outOfBoundsDirtyRect)); | |
453 EXPECT_TRUE(testLayer->needsDisplay()); | |
454 | |
455 // Case 5: setNeedsDisplay() without the dirty rect arg. | |
456 testLayer = LayerChromium::create(); | |
457 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
458 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBou
nds)); | |
459 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNeedsDisplay()
); | |
460 EXPECT_TRUE(testLayer->needsDisplay()); | |
461 } | |
462 | |
463 TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior) | |
464 { | |
465 RefPtr<LayerChromium> testLayer = LayerChromium::create(); | |
466 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
467 | |
468 RefPtr<LayerChromium> dummyLayer = LayerChromium::create(); // just a dummy
layer for this test case. | |
469 | |
470 // sanity check of initial test condition | |
471 EXPECT_FALSE(testLayer->needsDisplay()); | |
472 | |
473 // Test properties that should not call needsDisplay and needsCommit when ch
anged. | |
474 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setVisibleContent
Rect(IntRect(0, 0, 40, 50))); | |
475 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setUseLCDText(tru
e)); | |
476 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawOpacity(0.
5)); | |
477 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setRenderTarget(0
)); | |
478 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawTransform(
WebTransformationMatrix())); | |
479 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setScreenSpaceTra
nsform(WebTransformationMatrix())); | |
480 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(0, testLayer->setDrawableConten
tRect(IntRect(4, 5, 6, 7))); | |
481 EXPECT_FALSE(testLayer->needsDisplay()); | |
482 | |
483 // Next, test properties that should call setNeedsCommit (but not setNeedsDi
splay) | |
484 // All properties need to be set to new values in order for setNeedsCommit t
o be called. | |
485 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setAnchorPoint(Fl
oatPoint(1.23f, 4.56f))); | |
486 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setAnchorPointZ(0
.7f)); | |
487 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBackgroundColo
r(SK_ColorLTGRAY)); | |
488 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setMasksToBounds(
true)); | |
489 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setMaskLayer(dumm
yLayer.get())); | |
490 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setOpacity(0.5)); | |
491 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setOpaque(true)); | |
492 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setPosition(Float
Point(4, 9))); | |
493 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setReplicaLayer(d
ummyLayer.get())); | |
494 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setSublayerTransf
orm(WebTransformationMatrix(0, 0, 0, 0, 0, 0))); | |
495 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setScrollable(tru
e)); | |
496 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setShouldScrollOn
MainThread(true)); | |
497 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setNonFastScrolla
bleRegion(Region(IntRect(1, 1, 2, 2)))); | |
498 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setHaveWheelEvent
Handlers(true)); | |
499 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setScrollPosition
(IntPoint(10, 10))); | |
500 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setTransform(WebT
ransformationMatrix(0, 0, 0, 0, 0, 0))); | |
501 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDoubleSided(fa
lse)); | |
502 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDebugName("Tes
t Layer")); | |
503 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDrawCheckerboa
rdForMissingTiles(!testLayer->drawCheckerboardForMissingTiles())); | |
504 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setForceRenderSur
face(true)); | |
505 | |
506 // The above tests should not have caused a change to the needsDisplay flag. | |
507 EXPECT_FALSE(testLayer->needsDisplay()); | |
508 | |
509 // Test properties that should call setNeedsDisplay and setNeedsCommit | |
510 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(IntSize
(5, 10))); | |
511 EXPECT_TRUE(testLayer->needsDisplay()); | |
512 } | |
513 | |
514 TEST_F(LayerChromiumTest, verifyPushPropertiesAccumulatesUpdateRect) | |
515 { | |
516 DebugScopedSetImplThread setImplThread; | |
517 | |
518 RefPtr<LayerChromium> testLayer = LayerChromium::create(); | |
519 OwnPtr<CCLayerImpl> implLayer = CCLayerImpl::create(1); | |
520 | |
521 testLayer->setNeedsDisplayRect(FloatRect(FloatPoint::zero(), FloatSize(5, 5)
)); | |
522 testLayer->pushPropertiesTo(implLayer.get()); | |
523 EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint::zero(), FloatSize(5, 5)), implLay
er->updateRect()); | |
524 | |
525 // The CCLayerImpl's updateRect should be accumulated here, since we did not
do anything to clear it. | |
526 testLayer->setNeedsDisplayRect(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)
)); | |
527 testLayer->pushPropertiesTo(implLayer.get()); | |
528 EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint::zero(), FloatSize(15, 15)), implL
ayer->updateRect()); | |
529 | |
530 // If we do clear the CCLayerImpl side, then the next updateRect should be f
resh without accumulation. | |
531 implLayer->resetAllChangeTrackingForSubtree(); | |
532 testLayer->setNeedsDisplayRect(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)
)); | |
533 testLayer->pushPropertiesTo(implLayer.get()); | |
534 EXPECT_FLOAT_RECT_EQ(FloatRect(FloatPoint(10, 10), FloatSize(5, 5)), implLay
er->updateRect()); | |
535 } | |
536 | |
537 class LayerChromiumWithContentScaling : public LayerChromium { | |
538 public: | |
539 explicit LayerChromiumWithContentScaling() | |
540 : LayerChromium() | |
541 { | |
542 } | |
543 | |
544 virtual bool needsContentsScale() const OVERRIDE | |
545 { | |
546 return true; | |
547 } | |
548 | |
549 virtual void setNeedsDisplayRect(const FloatRect& dirtyRect) OVERRIDE | |
550 { | |
551 m_lastNeedsDisplayRect = dirtyRect; | |
552 LayerChromium::setNeedsDisplayRect(dirtyRect); | |
553 } | |
554 | |
555 void resetNeedsDisplay() | |
556 { | |
557 m_needsDisplay = false; | |
558 } | |
559 | |
560 const FloatRect& lastNeedsDisplayRect() const { return m_lastNeedsDisplayRec
t; } | |
561 | |
562 private: | |
563 FloatRect m_lastNeedsDisplayRect; | |
564 }; | |
565 | |
566 TEST_F(LayerChromiumTest, checkContentsScaleChangeTriggersNeedsDisplay) | |
567 { | |
568 RefPtr<LayerChromiumWithContentScaling> testLayer = adoptRef(new LayerChromi
umWithContentScaling()); | |
569 testLayer->setLayerTreeHost(m_layerTreeHost.get()); | |
570 | |
571 IntSize testBounds = IntSize(320, 240); | |
572 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setBounds(testBou
nds)); | |
573 | |
574 testLayer->resetNeedsDisplay(); | |
575 EXPECT_FALSE(testLayer->needsDisplay()); | |
576 | |
577 EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setContentsScale(
testLayer->contentsScale() + 1.f)); | |
578 EXPECT_TRUE(testLayer->needsDisplay()); | |
579 EXPECT_FLOAT_RECT_EQ(FloatRect(0, 0, 320, 240), testLayer->lastNeedsDisplayR
ect()); | |
580 } | |
581 | |
582 class FakeCCLayerTreeHost : public CCLayerTreeHost { | |
583 public: | |
584 static PassOwnPtr<FakeCCLayerTreeHost> create() | |
585 { | |
586 OwnPtr<FakeCCLayerTreeHost> host(adoptPtr(new FakeCCLayerTreeHost)); | |
587 // The initialize call will fail, since our client doesn't provide a val
id GraphicsContext3D, but it doesn't matter in the tests that use this fake so i
gnore the return value. | |
588 host->initialize(); | |
589 return host.release(); | |
590 } | |
591 | |
592 private: | |
593 FakeCCLayerTreeHost() | |
594 : CCLayerTreeHost(&m_client, CCLayerTreeSettings()) | |
595 { | |
596 } | |
597 | |
598 FakeCCLayerTreeHostClient m_client; | |
599 }; | |
600 | |
601 void assertLayerTreeHostMatchesForSubtree(LayerChromium* layer, CCLayerTreeHost*
host) | |
602 { | |
603 EXPECT_EQ(host, layer->layerTreeHost()); | |
604 | |
605 for (size_t i = 0; i < layer->children().size(); ++i) | |
606 assertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host); | |
607 | |
608 if (layer->maskLayer()) | |
609 assertLayerTreeHostMatchesForSubtree(layer->maskLayer(), host); | |
610 | |
611 if (layer->replicaLayer()) | |
612 assertLayerTreeHostMatchesForSubtree(layer->replicaLayer(), host); | |
613 } | |
614 | |
615 | |
616 TEST(LayerChromiumLayerTreeHostTest, enteringTree) | |
617 { | |
618 WebKit::WebCompositor::initialize(0); | |
619 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
620 RefPtr<LayerChromium> child = LayerChromium::create(); | |
621 RefPtr<LayerChromium> mask = LayerChromium::create(); | |
622 RefPtr<LayerChromium> replica = LayerChromium::create(); | |
623 RefPtr<LayerChromium> replicaMask = LayerChromium::create(); | |
624 | |
625 // Set up a detached tree of layers. The host pointer should be nil for thes
e layers. | |
626 parent->addChild(child); | |
627 child->setMaskLayer(mask.get()); | |
628 child->setReplicaLayer(replica.get()); | |
629 replica->setMaskLayer(mask.get()); | |
630 | |
631 assertLayerTreeHostMatchesForSubtree(parent.get(), 0); | |
632 | |
633 OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create()); | |
634 // Setting the root layer should set the host pointer for all layers in the
tree. | |
635 layerTreeHost->setRootLayer(parent.get()); | |
636 | |
637 assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get()); | |
638 | |
639 // Clearing the root layer should also clear out the host pointers for all l
ayers in the tree. | |
640 layerTreeHost->setRootLayer(0); | |
641 | |
642 assertLayerTreeHostMatchesForSubtree(parent.get(), 0); | |
643 | |
644 layerTreeHost.clear(); | |
645 WebKit::WebCompositor::shutdown(); | |
646 } | |
647 | |
648 TEST(LayerChromiumLayerTreeHostTest, addingLayerSubtree) | |
649 { | |
650 WebKit::WebCompositor::initialize(0); | |
651 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
652 OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create()); | |
653 | |
654 layerTreeHost->setRootLayer(parent.get()); | |
655 | |
656 EXPECT_EQ(parent->layerTreeHost(), layerTreeHost.get()); | |
657 | |
658 // Adding a subtree to a layer already associated with a host should set the
host pointer on all layers in that subtree. | |
659 RefPtr<LayerChromium> child = LayerChromium::create(); | |
660 RefPtr<LayerChromium> grandChild = LayerChromium::create(); | |
661 child->addChild(grandChild); | |
662 | |
663 // Masks, replicas, and replica masks should pick up the new host too. | |
664 RefPtr<LayerChromium> childMask = LayerChromium::create(); | |
665 child->setMaskLayer(childMask.get()); | |
666 RefPtr<LayerChromium> childReplica = LayerChromium::create(); | |
667 child->setReplicaLayer(childReplica.get()); | |
668 RefPtr<LayerChromium> childReplicaMask = LayerChromium::create(); | |
669 childReplica->setMaskLayer(childReplicaMask.get()); | |
670 | |
671 parent->addChild(child); | |
672 assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get()); | |
673 | |
674 layerTreeHost->setRootLayer(0); | |
675 layerTreeHost.clear(); | |
676 WebKit::WebCompositor::shutdown(); | |
677 } | |
678 | |
679 TEST(LayerChromiumLayerTreeHostTest, changeHost) | |
680 { | |
681 WebKit::WebCompositor::initialize(0); | |
682 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
683 RefPtr<LayerChromium> child = LayerChromium::create(); | |
684 RefPtr<LayerChromium> mask = LayerChromium::create(); | |
685 RefPtr<LayerChromium> replica = LayerChromium::create(); | |
686 RefPtr<LayerChromium> replicaMask = LayerChromium::create(); | |
687 | |
688 // Same setup as the previous test. | |
689 parent->addChild(child); | |
690 child->setMaskLayer(mask.get()); | |
691 child->setReplicaLayer(replica.get()); | |
692 replica->setMaskLayer(mask.get()); | |
693 | |
694 OwnPtr<FakeCCLayerTreeHost> firstLayerTreeHost(FakeCCLayerTreeHost::create()
); | |
695 firstLayerTreeHost->setRootLayer(parent.get()); | |
696 | |
697 assertLayerTreeHostMatchesForSubtree(parent.get(), firstLayerTreeHost.get())
; | |
698 | |
699 // Now re-root the tree to a new host (simulating what we do on a context lo
st event). | |
700 // This should update the host pointers for all layers in the tree. | |
701 OwnPtr<FakeCCLayerTreeHost> secondLayerTreeHost(FakeCCLayerTreeHost::create(
)); | |
702 secondLayerTreeHost->setRootLayer(parent.get()); | |
703 | |
704 assertLayerTreeHostMatchesForSubtree(parent.get(), secondLayerTreeHost.get()
); | |
705 | |
706 secondLayerTreeHost->setRootLayer(0); | |
707 firstLayerTreeHost.clear(); | |
708 secondLayerTreeHost.clear(); | |
709 WebKit::WebCompositor::shutdown(); | |
710 } | |
711 | |
712 TEST(LayerChromiumLayerTreeHostTest, changeHostInSubtree) | |
713 { | |
714 WebKit::WebCompositor::initialize(0); | |
715 RefPtr<LayerChromium> firstParent = LayerChromium::create(); | |
716 RefPtr<LayerChromium> firstChild = LayerChromium::create(); | |
717 RefPtr<LayerChromium> secondParent = LayerChromium::create(); | |
718 RefPtr<LayerChromium> secondChild = LayerChromium::create(); | |
719 RefPtr<LayerChromium> secondGrandChild = LayerChromium::create(); | |
720 | |
721 // First put all children under the first parent and set the first host. | |
722 firstParent->addChild(firstChild); | |
723 secondChild->addChild(secondGrandChild); | |
724 firstParent->addChild(secondChild); | |
725 | |
726 OwnPtr<FakeCCLayerTreeHost> firstLayerTreeHost(FakeCCLayerTreeHost::create()
); | |
727 firstLayerTreeHost->setRootLayer(firstParent.get()); | |
728 | |
729 assertLayerTreeHostMatchesForSubtree(firstParent.get(), firstLayerTreeHost.g
et()); | |
730 | |
731 // Now reparent the subtree starting at secondChild to a layer in a differen
t tree. | |
732 OwnPtr<FakeCCLayerTreeHost> secondLayerTreeHost(FakeCCLayerTreeHost::create(
)); | |
733 secondLayerTreeHost->setRootLayer(secondParent.get()); | |
734 | |
735 secondParent->addChild(secondChild); | |
736 | |
737 // The moved layer and its children should point to the new host. | |
738 EXPECT_EQ(secondLayerTreeHost.get(), secondChild->layerTreeHost()); | |
739 EXPECT_EQ(secondLayerTreeHost.get(), secondGrandChild->layerTreeHost()); | |
740 | |
741 // Test over, cleanup time. | |
742 firstLayerTreeHost->setRootLayer(0); | |
743 secondLayerTreeHost->setRootLayer(0); | |
744 firstLayerTreeHost.clear(); | |
745 secondLayerTreeHost.clear(); | |
746 WebKit::WebCompositor::shutdown(); | |
747 } | |
748 | |
749 TEST(LayerChromiumLayerTreeHostTest, replaceMaskAndReplicaLayer) | |
750 { | |
751 WebKit::WebCompositor::initialize(0); | |
752 RefPtr<LayerChromium> parent = LayerChromium::create(); | |
753 RefPtr<LayerChromium> mask = LayerChromium::create(); | |
754 RefPtr<LayerChromium> replica = LayerChromium::create(); | |
755 RefPtr<LayerChromium> maskChild = LayerChromium::create(); | |
756 RefPtr<LayerChromium> replicaChild = LayerChromium::create(); | |
757 RefPtr<LayerChromium> maskReplacement = LayerChromium::create(); | |
758 RefPtr<LayerChromium> replicaReplacement = LayerChromium::create(); | |
759 | |
760 parent->setMaskLayer(mask.get()); | |
761 parent->setReplicaLayer(replica.get()); | |
762 mask->addChild(maskChild); | |
763 replica->addChild(replicaChild); | |
764 | |
765 OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create()); | |
766 layerTreeHost->setRootLayer(parent.get()); | |
767 | |
768 assertLayerTreeHostMatchesForSubtree(parent.get(), layerTreeHost.get()); | |
769 | |
770 // Replacing the mask should clear out the old mask's subtree's host pointer
s. | |
771 parent->setMaskLayer(maskReplacement.get()); | |
772 EXPECT_EQ(0, mask->layerTreeHost()); | |
773 EXPECT_EQ(0, maskChild->layerTreeHost()); | |
774 | |
775 // Same for replacing a replica layer. | |
776 parent->setReplicaLayer(replicaReplacement.get()); | |
777 EXPECT_EQ(0, replica->layerTreeHost()); | |
778 EXPECT_EQ(0, replicaChild->layerTreeHost()); | |
779 | |
780 // Test over, cleanup time. | |
781 layerTreeHost->setRootLayer(0); | |
782 layerTreeHost.clear(); | |
783 WebKit::WebCompositor::shutdown(); | |
784 } | |
785 | |
786 TEST(LayerChromiumLayerTreeHostTest, destroyHostWithNonNullRootLayer) | |
787 { | |
788 WebKit::WebCompositor::initialize(0); | |
789 RefPtr<LayerChromium> root = LayerChromium::create(); | |
790 RefPtr<LayerChromium> child = LayerChromium::create(); | |
791 root->addChild(child); | |
792 OwnPtr<FakeCCLayerTreeHost> layerTreeHost(FakeCCLayerTreeHost::create()); | |
793 layerTreeHost->setRootLayer(root); | |
794 layerTreeHost.clear(); | |
795 WebKit::WebCompositor::shutdown(); | |
796 } | |
797 | |
798 class MockLayerChromium : public LayerChromium { | |
799 public: | |
800 bool needsDisplay() const { return m_needsDisplay; } | |
801 }; | |
802 | |
803 TEST(LayerChromiumTestWithoutFixture, setBoundsTriggersSetNeedsRedrawAfterGettin
gNonEmptyBounds) | |
804 { | |
805 RefPtr<MockLayerChromium> layer(adoptRef(new MockLayerChromium)); | |
806 EXPECT_FALSE(layer->needsDisplay()); | |
807 layer->setBounds(IntSize(0, 10)); | |
808 EXPECT_FALSE(layer->needsDisplay()); | |
809 layer->setBounds(IntSize(10, 10)); | |
810 EXPECT_TRUE(layer->needsDisplay()); | |
811 } | |
812 | |
813 | |
814 } // namespace | |
OLD | NEW |