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 "CCLayerTreeHost.h" | |
8 | |
9 #include "CCGeometryTestUtils.h" | |
10 #include "CCGraphicsContext.h" | |
11 #include "CCLayerTreeHostImpl.h" | |
12 #include "CCOcclusionTrackerTestCommon.h" | |
13 #include "CCSettings.h" | |
14 #include "CCSingleThreadProxy.h" | |
15 #include "CCTextureUpdateQueue.h" | |
16 #include "CCThreadedTest.h" | |
17 #include "CCTimingFunction.h" | |
18 #include "ContentLayerChromium.h" | |
19 #include "ContentLayerChromiumClient.h" | |
20 #include "Extensions3DChromium.h" | |
21 #include "FakeWebCompositorOutputSurface.h" | |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 #include <public/Platform.h> | |
24 #include <public/WebLayerScrollClient.h> | |
25 #include <public/WebSize.h> | |
26 #include <wtf/OwnArrayPtr.h> | |
27 | |
28 using namespace cc; | |
29 using namespace WebKit; | |
30 using namespace WebKitTests; | |
31 | |
32 namespace { | |
33 | |
34 class CCLayerTreeHostTest : public CCThreadedTest { }; | |
35 | |
36 // Shortlived layerTreeHosts shouldn't die. | |
37 class CCLayerTreeHostTestShortlived1 : public CCLayerTreeHostTest { | |
38 public: | |
39 CCLayerTreeHostTestShortlived1() { } | |
40 | |
41 virtual void beginTest() OVERRIDE | |
42 { | |
43 // Kill the layerTreeHost immediately. | |
44 m_layerTreeHost->setRootLayer(0); | |
45 m_layerTreeHost.reset(); | |
46 | |
47 endTest(); | |
48 } | |
49 | |
50 virtual void afterTest() OVERRIDE | |
51 { | |
52 } | |
53 }; | |
54 | |
55 // Shortlived layerTreeHosts shouldn't die with a commit in flight. | |
56 class CCLayerTreeHostTestShortlived2 : public CCLayerTreeHostTest { | |
57 public: | |
58 CCLayerTreeHostTestShortlived2() { } | |
59 | |
60 virtual void beginTest() OVERRIDE | |
61 { | |
62 postSetNeedsCommitToMainThread(); | |
63 | |
64 // Kill the layerTreeHost immediately. | |
65 m_layerTreeHost->setRootLayer(0); | |
66 m_layerTreeHost.reset(); | |
67 | |
68 endTest(); | |
69 } | |
70 | |
71 virtual void afterTest() OVERRIDE | |
72 { | |
73 } | |
74 }; | |
75 | |
76 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestShortlived2) | |
77 | |
78 // Shortlived layerTreeHosts shouldn't die with a redraw in flight. | |
79 class CCLayerTreeHostTestShortlived3 : public CCLayerTreeHostTest { | |
80 public: | |
81 CCLayerTreeHostTestShortlived3() { } | |
82 | |
83 virtual void beginTest() OVERRIDE | |
84 { | |
85 postSetNeedsRedrawToMainThread(); | |
86 | |
87 // Kill the layerTreeHost immediately. | |
88 m_layerTreeHost->setRootLayer(0); | |
89 m_layerTreeHost.reset(); | |
90 | |
91 endTest(); | |
92 } | |
93 | |
94 virtual void afterTest() OVERRIDE | |
95 { | |
96 } | |
97 }; | |
98 | |
99 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestShortlived3) | |
100 | |
101 // Test interleaving of redraws and commits | |
102 class CCLayerTreeHostTestCommitingWithContinuousRedraw : public CCLayerTreeHostT
est { | |
103 public: | |
104 CCLayerTreeHostTestCommitingWithContinuousRedraw() | |
105 : m_numCompleteCommits(0) | |
106 , m_numDraws(0) | |
107 { | |
108 } | |
109 | |
110 virtual void beginTest() OVERRIDE | |
111 { | |
112 postSetNeedsCommitToMainThread(); | |
113 } | |
114 | |
115 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
116 { | |
117 m_numCompleteCommits++; | |
118 if (m_numCompleteCommits == 2) | |
119 endTest(); | |
120 } | |
121 | |
122 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
123 { | |
124 if (m_numDraws == 1) | |
125 postSetNeedsCommitToMainThread(); | |
126 m_numDraws++; | |
127 postSetNeedsRedrawToMainThread(); | |
128 } | |
129 | |
130 virtual void afterTest() OVERRIDE | |
131 { | |
132 } | |
133 | |
134 private: | |
135 int m_numCompleteCommits; | |
136 int m_numDraws; | |
137 }; | |
138 | |
139 TEST_F(CCLayerTreeHostTestCommitingWithContinuousRedraw, runMultiThread) | |
140 { | |
141 runTest(true); | |
142 } | |
143 | |
144 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 | |
145 // draw with frame 0. | |
146 class CCLayerTreeHostTestSetNeedsCommit1 : public CCLayerTreeHostTest { | |
147 public: | |
148 CCLayerTreeHostTestSetNeedsCommit1() | |
149 : m_numCommits(0) | |
150 , m_numDraws(0) | |
151 { | |
152 } | |
153 | |
154 virtual void beginTest() OVERRIDE | |
155 { | |
156 postSetNeedsCommitToMainThread(); | |
157 postSetNeedsCommitToMainThread(); | |
158 } | |
159 | |
160 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
161 { | |
162 m_numDraws++; | |
163 if (!impl->sourceFrameNumber()) | |
164 endTest(); | |
165 } | |
166 | |
167 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
168 { | |
169 m_numCommits++; | |
170 } | |
171 | |
172 virtual void afterTest() OVERRIDE | |
173 { | |
174 EXPECT_GE(1, m_numCommits); | |
175 EXPECT_GE(1, m_numDraws); | |
176 } | |
177 | |
178 private: | |
179 int m_numCommits; | |
180 int m_numDraws; | |
181 }; | |
182 | |
183 TEST_F(CCLayerTreeHostTestSetNeedsCommit1, DISABLED_runMultiThread) | |
184 { | |
185 runTest(true); | |
186 } | |
187 | |
188 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that | |
189 // first committed frame draws should lead to another commit. | |
190 class CCLayerTreeHostTestSetNeedsCommit2 : public CCLayerTreeHostTest { | |
191 public: | |
192 CCLayerTreeHostTestSetNeedsCommit2() | |
193 : m_numCommits(0) | |
194 , m_numDraws(0) | |
195 { | |
196 } | |
197 | |
198 virtual void beginTest() OVERRIDE | |
199 { | |
200 postSetNeedsCommitToMainThread(); | |
201 } | |
202 | |
203 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
204 { | |
205 if (!impl->sourceFrameNumber()) | |
206 postSetNeedsCommitToMainThread(); | |
207 else if (impl->sourceFrameNumber() == 1) | |
208 endTest(); | |
209 } | |
210 | |
211 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
212 { | |
213 m_numCommits++; | |
214 } | |
215 | |
216 virtual void afterTest() OVERRIDE | |
217 { | |
218 EXPECT_EQ(2, m_numCommits); | |
219 EXPECT_GE(2, m_numDraws); | |
220 } | |
221 | |
222 private: | |
223 int m_numCommits; | |
224 int m_numDraws; | |
225 }; | |
226 | |
227 #if OS(WINDOWS) | |
228 // http://webkit.org/b/74623 | |
229 TEST_F(CCLayerTreeHostTestSetNeedsCommit2, FLAKY_runMultiThread) | |
230 #else | |
231 TEST_F(CCLayerTreeHostTestSetNeedsCommit2, runMultiThread) | |
232 #endif | |
233 { | |
234 runTest(true); | |
235 } | |
236 | |
237 // 1 setNeedsRedraw after the first commit has completed should lead to 1 | |
238 // additional draw. | |
239 class CCLayerTreeHostTestSetNeedsRedraw : public CCLayerTreeHostTest { | |
240 public: | |
241 CCLayerTreeHostTestSetNeedsRedraw() | |
242 : m_numCommits(0) | |
243 , m_numDraws(0) | |
244 { | |
245 } | |
246 | |
247 virtual void beginTest() OVERRIDE | |
248 { | |
249 postSetNeedsCommitToMainThread(); | |
250 } | |
251 | |
252 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
253 { | |
254 EXPECT_EQ(0, impl->sourceFrameNumber()); | |
255 if (!m_numDraws) | |
256 postSetNeedsRedrawToMainThread(); // Redraw again to verify that the
second redraw doesn't commit. | |
257 else | |
258 endTest(); | |
259 m_numDraws++; | |
260 } | |
261 | |
262 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
263 { | |
264 EXPECT_EQ(0, m_numDraws); | |
265 m_numCommits++; | |
266 } | |
267 | |
268 virtual void afterTest() OVERRIDE | |
269 { | |
270 EXPECT_GE(2, m_numDraws); | |
271 EXPECT_EQ(1, m_numCommits); | |
272 } | |
273 | |
274 private: | |
275 int m_numCommits; | |
276 int m_numDraws; | |
277 }; | |
278 | |
279 TEST_F(CCLayerTreeHostTestSetNeedsRedraw, runMultiThread) | |
280 { | |
281 runTest(true); | |
282 } | |
283 | |
284 // If the layerTreeHost says it can't draw, then we should not try to draw. | |
285 class CCLayerTreeHostTestCanDrawBlocksDrawing : public CCLayerTreeHostTest { | |
286 public: | |
287 CCLayerTreeHostTestCanDrawBlocksDrawing() | |
288 : m_numCommits(0) | |
289 { | |
290 } | |
291 | |
292 virtual void beginTest() OVERRIDE | |
293 { | |
294 postSetNeedsCommitToMainThread(); | |
295 } | |
296 | |
297 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
298 { | |
299 // Only the initial draw should bring us here. | |
300 EXPECT_TRUE(impl->canDraw()); | |
301 EXPECT_EQ(0, impl->sourceFrameNumber()); | |
302 } | |
303 | |
304 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
305 { | |
306 if (m_numCommits >= 1) { | |
307 // After the first commit, we should not be able to draw. | |
308 EXPECT_FALSE(impl->canDraw()); | |
309 } | |
310 } | |
311 | |
312 virtual void didCommit() OVERRIDE | |
313 { | |
314 m_numCommits++; | |
315 if (m_numCommits == 1) { | |
316 // Make the viewport empty so the host says it can't draw. | |
317 m_layerTreeHost->setViewportSize(IntSize(0, 0), IntSize(0, 0)); | |
318 | |
319 OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4])); | |
320 m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get(
)), IntRect(0, 0, 1, 1)); | |
321 } else if (m_numCommits == 2) { | |
322 m_layerTreeHost->setNeedsRedraw(); | |
323 m_layerTreeHost->setNeedsCommit(); | |
324 } else | |
325 endTest(); | |
326 } | |
327 | |
328 virtual void afterTest() OVERRIDE | |
329 { | |
330 } | |
331 | |
332 private: | |
333 int m_numCommits; | |
334 }; | |
335 | |
336 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCanDrawBlocksDrawing) | |
337 | |
338 // beginLayerWrite should prevent draws from executing until a commit occurs | |
339 class CCLayerTreeHostTestWriteLayersRedraw : public CCLayerTreeHostTest { | |
340 public: | |
341 CCLayerTreeHostTestWriteLayersRedraw() | |
342 : m_numCommits(0) | |
343 , m_numDraws(0) | |
344 { | |
345 } | |
346 | |
347 virtual void beginTest() OVERRIDE | |
348 { | |
349 postAcquireLayerTextures(); | |
350 postSetNeedsRedrawToMainThread(); // should be inhibited without blockin
g | |
351 postSetNeedsCommitToMainThread(); | |
352 } | |
353 | |
354 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
355 { | |
356 m_numDraws++; | |
357 EXPECT_EQ(m_numDraws, m_numCommits); | |
358 } | |
359 | |
360 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
361 { | |
362 m_numCommits++; | |
363 endTest(); | |
364 } | |
365 | |
366 virtual void afterTest() OVERRIDE | |
367 { | |
368 EXPECT_EQ(1, m_numCommits); | |
369 } | |
370 | |
371 private: | |
372 int m_numCommits; | |
373 int m_numDraws; | |
374 }; | |
375 | |
376 TEST_F(CCLayerTreeHostTestWriteLayersRedraw, runMultiThread) | |
377 { | |
378 runTest(true); | |
379 } | |
380 | |
381 // Verify that when resuming visibility, requesting layer write permission | |
382 // will not deadlock the main thread even though there are not yet any | |
383 // scheduled redraws. This behavior is critical for reliably surviving tab | |
384 // switching. There are no failure conditions to this test, it just passes | |
385 // by not timing out. | |
386 class CCLayerTreeHostTestWriteLayersAfterVisible : public CCLayerTreeHostTest { | |
387 public: | |
388 CCLayerTreeHostTestWriteLayersAfterVisible() | |
389 : m_numCommits(0) | |
390 { | |
391 } | |
392 | |
393 virtual void beginTest() OVERRIDE | |
394 { | |
395 postSetNeedsCommitToMainThread(); | |
396 } | |
397 | |
398 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
399 { | |
400 m_numCommits++; | |
401 if (m_numCommits == 2) | |
402 endTest(); | |
403 else { | |
404 postSetVisibleToMainThread(false); | |
405 postSetVisibleToMainThread(true); | |
406 postAcquireLayerTextures(); | |
407 postSetNeedsCommitToMainThread(); | |
408 } | |
409 } | |
410 | |
411 virtual void afterTest() OVERRIDE | |
412 { | |
413 } | |
414 | |
415 private: | |
416 int m_numCommits; | |
417 }; | |
418 | |
419 TEST_F(CCLayerTreeHostTestWriteLayersAfterVisible, runMultiThread) | |
420 { | |
421 runTest(true); | |
422 } | |
423 | |
424 // A compositeAndReadback while invisible should force a normal commit without a
ssertion. | |
425 class CCLayerTreeHostTestCompositeAndReadbackWhileInvisible : public CCLayerTree
HostTest { | |
426 public: | |
427 CCLayerTreeHostTestCompositeAndReadbackWhileInvisible() | |
428 : m_numCommits(0) | |
429 { | |
430 } | |
431 | |
432 virtual void beginTest() OVERRIDE | |
433 { | |
434 } | |
435 | |
436 virtual void didCommitAndDrawFrame() OVERRIDE | |
437 { | |
438 m_numCommits++; | |
439 if (m_numCommits == 1) { | |
440 m_layerTreeHost->setVisible(false); | |
441 m_layerTreeHost->setNeedsCommit(); | |
442 m_layerTreeHost->setNeedsCommit(); | |
443 OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4])); | |
444 m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get(
)), IntRect(0, 0, 1, 1)); | |
445 } else | |
446 endTest(); | |
447 | |
448 } | |
449 | |
450 virtual void afterTest() OVERRIDE | |
451 { | |
452 } | |
453 | |
454 private: | |
455 int m_numCommits; | |
456 }; | |
457 | |
458 TEST_F(CCLayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread) | |
459 { | |
460 runTest(true); | |
461 } | |
462 | |
463 class CCLayerTreeHostTestAbortFrameWhenInvisible : public CCLayerTreeHostTest { | |
464 public: | |
465 CCLayerTreeHostTestAbortFrameWhenInvisible() | |
466 { | |
467 } | |
468 | |
469 virtual void beginTest() OVERRIDE | |
470 { | |
471 // Request a commit (from the main thread), which will trigger the commi
t flow from the impl side. | |
472 m_layerTreeHost->setNeedsCommit(); | |
473 // Then mark ourselves as not visible before processing any more message
s on the main thread. | |
474 m_layerTreeHost->setVisible(false); | |
475 // If we make it without kicking a frame, we pass! | |
476 endTestAfterDelay(1); | |
477 } | |
478 | |
479 virtual void layout() OVERRIDE | |
480 { | |
481 ASSERT_FALSE(true); | |
482 endTest(); | |
483 } | |
484 | |
485 virtual void afterTest() OVERRIDE | |
486 { | |
487 } | |
488 | |
489 private: | |
490 }; | |
491 | |
492 TEST_F(CCLayerTreeHostTestAbortFrameWhenInvisible, runMultiThread) | |
493 { | |
494 runTest(true); | |
495 } | |
496 | |
497 // Makes sure that setNedsAnimate does not cause the commitRequested() state to
be set. | |
498 class CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested : public CCL
ayerTreeHostTest { | |
499 public: | |
500 CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested() | |
501 : m_numCommits(0) | |
502 { | |
503 } | |
504 | |
505 virtual void beginTest() OVERRIDE | |
506 { | |
507 // The tests start up with a commit pending because we give them a root
layer. | |
508 // We need to wait for the commit to happen before doing anything. | |
509 EXPECT_TRUE(m_layerTreeHost->commitRequested()); | |
510 } | |
511 | |
512 virtual void animate(double monotonicTime) OVERRIDE | |
513 { | |
514 // We skip the first commit becasue its the commit that populates the | |
515 // impl thread with a tree. | |
516 if (!m_numCommits) | |
517 return; | |
518 | |
519 m_layerTreeHost->setNeedsAnimate(); | |
520 // Right now, commitRequested is going to be true, because during | |
521 // beginFrame, we force commitRequested to true to prevent requests from | |
522 // hitting the impl thread. But, when the next didCommit happens, we sho
uld | |
523 // verify that commitRequested has gone back to false. | |
524 } | |
525 virtual void didCommit() OVERRIDE | |
526 { | |
527 if (!m_numCommits) { | |
528 EXPECT_FALSE(m_layerTreeHost->commitRequested()); | |
529 m_layerTreeHost->setNeedsAnimate(); | |
530 EXPECT_FALSE(m_layerTreeHost->commitRequested()); | |
531 m_numCommits++; | |
532 } | |
533 | |
534 // Verifies that the setNeedsAnimate we made in ::animate did not | |
535 // trigger commitRequested. | |
536 EXPECT_FALSE(m_layerTreeHost->commitRequested()); | |
537 endTest(); | |
538 } | |
539 | |
540 virtual void afterTest() OVERRIDE | |
541 { | |
542 } | |
543 | |
544 private: | |
545 int m_numCommits; | |
546 }; | |
547 | |
548 TEST_F(CCLayerTreeHostTestSetNeedsAnimateShouldNotSetCommitRequested, runMultiTh
read) | |
549 { | |
550 runTest(true); | |
551 } | |
552 | |
553 | |
554 | |
555 // Trigger a frame with setNeedsCommit. Then, inside the resulting animate | |
556 // callback, requet another frame using setNeedsAnimate. End the test when | |
557 // animate gets called yet-again, indicating that the proxy is correctly | |
558 // handling the case where setNeedsAnimate() is called inside the begin frame | |
559 // flow. | |
560 class CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback : public CCLayer
TreeHostTest { | |
561 public: | |
562 CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback() | |
563 : m_numAnimates(0) | |
564 { | |
565 } | |
566 | |
567 virtual void beginTest() OVERRIDE | |
568 { | |
569 postSetNeedsAnimateToMainThread(); | |
570 } | |
571 | |
572 virtual void animate(double) OVERRIDE | |
573 { | |
574 if (!m_numAnimates) { | |
575 m_layerTreeHost->setNeedsAnimate(); | |
576 m_numAnimates++; | |
577 return; | |
578 } | |
579 endTest(); | |
580 } | |
581 | |
582 virtual void afterTest() OVERRIDE | |
583 { | |
584 } | |
585 | |
586 private: | |
587 int m_numAnimates; | |
588 }; | |
589 | |
590 TEST_F(CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback, runMultiThread
) | |
591 { | |
592 runTest(true); | |
593 } | |
594 | |
595 // Add a layer animation and confirm that CCLayerTreeHostImpl::animateLayers doe
s get | |
596 // called and continues to get called. | |
597 class CCLayerTreeHostTestAddAnimation : public CCLayerTreeHostTest { | |
598 public: | |
599 CCLayerTreeHostTestAddAnimation() | |
600 : m_numAnimates(0) | |
601 , m_receivedAnimationStartedNotification(false) | |
602 , m_startTime(0) | |
603 , m_firstMonotonicTime(0) | |
604 { | |
605 } | |
606 | |
607 virtual void beginTest() OVERRIDE | |
608 { | |
609 postAddInstantAnimationToMainThread(); | |
610 } | |
611 | |
612 virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double mo
notonicTime) OVERRIDE | |
613 { | |
614 if (!m_numAnimates) { | |
615 // The animation had zero duration so layerTreeHostImpl should no | |
616 // longer need to animate its layers. | |
617 EXPECT_FALSE(layerTreeHostImpl->needsAnimateLayers()); | |
618 m_numAnimates++; | |
619 m_firstMonotonicTime = monotonicTime; | |
620 return; | |
621 } | |
622 EXPECT_LT(0, m_startTime); | |
623 EXPECT_LT(0, m_firstMonotonicTime); | |
624 EXPECT_NE(m_startTime, m_firstMonotonicTime); | |
625 EXPECT_TRUE(m_receivedAnimationStartedNotification); | |
626 endTest(); | |
627 } | |
628 | |
629 virtual void notifyAnimationStarted(double wallClockTime) OVERRIDE | |
630 { | |
631 m_receivedAnimationStartedNotification = true; | |
632 m_startTime = wallClockTime; | |
633 } | |
634 | |
635 virtual void afterTest() OVERRIDE | |
636 { | |
637 } | |
638 | |
639 private: | |
640 int m_numAnimates; | |
641 bool m_receivedAnimationStartedNotification; | |
642 double m_startTime; | |
643 double m_firstMonotonicTime; | |
644 }; | |
645 | |
646 TEST_F(CCLayerTreeHostTestAddAnimation, runMultiThread) | |
647 { | |
648 runTest(true); | |
649 } | |
650 | |
651 // Add a layer animation to a layer, but continually fail to draw. Confirm that
after | |
652 // a while, we do eventually force a draw. | |
653 class CCLayerTreeHostTestCheckerboardDoesNotStarveDraws : public CCLayerTreeHost
Test { | |
654 public: | |
655 CCLayerTreeHostTestCheckerboardDoesNotStarveDraws() | |
656 : m_startedAnimating(false) | |
657 { | |
658 } | |
659 | |
660 virtual void beginTest() OVERRIDE | |
661 { | |
662 postAddAnimationToMainThread(); | |
663 } | |
664 | |
665 virtual void afterTest() OVERRIDE | |
666 { | |
667 } | |
668 | |
669 virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double mo
notonicTime) OVERRIDE | |
670 { | |
671 m_startedAnimating = true; | |
672 } | |
673 | |
674 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
675 { | |
676 if (m_startedAnimating) | |
677 endTest(); | |
678 } | |
679 | |
680 virtual bool prepareToDrawOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
681 { | |
682 return false; | |
683 } | |
684 | |
685 private: | |
686 bool m_startedAnimating; | |
687 }; | |
688 | |
689 // Starvation can only be an issue with the MT compositor. | |
690 TEST_F(CCLayerTreeHostTestCheckerboardDoesNotStarveDraws, runMultiThread) | |
691 { | |
692 runTest(true); | |
693 } | |
694 | |
695 // Ensures that animations continue to be ticked when we are backgrounded. | |
696 class CCLayerTreeHostTestTickAnimationWhileBackgrounded : public CCLayerTreeHost
Test { | |
697 public: | |
698 CCLayerTreeHostTestTickAnimationWhileBackgrounded() | |
699 : m_numAnimates(0) | |
700 { | |
701 } | |
702 | |
703 virtual void beginTest() OVERRIDE | |
704 { | |
705 postAddAnimationToMainThread(); | |
706 } | |
707 | |
708 // Use willAnimateLayers to set visible false before the animation runs and | |
709 // causes a commit, so we block the second visible animate in single-thread | |
710 // mode. | |
711 virtual void willAnimateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, doubl
e monotonicTime) OVERRIDE | |
712 { | |
713 if (m_numAnimates < 2) { | |
714 if (!m_numAnimates) { | |
715 // We have a long animation running. It should continue to tick
even if we are not visible. | |
716 postSetVisibleToMainThread(false); | |
717 } | |
718 m_numAnimates++; | |
719 return; | |
720 } | |
721 endTest(); | |
722 } | |
723 | |
724 virtual void afterTest() OVERRIDE | |
725 { | |
726 } | |
727 | |
728 private: | |
729 int m_numAnimates; | |
730 }; | |
731 | |
732 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestTickAnimationWhileBackgrounded
) | |
733 | |
734 // Ensures that animations continue to be ticked when we are backgrounded. | |
735 class CCLayerTreeHostTestAddAnimationWithTimingFunction : public CCLayerTreeHost
Test { | |
736 public: | |
737 CCLayerTreeHostTestAddAnimationWithTimingFunction() | |
738 { | |
739 } | |
740 | |
741 virtual void beginTest() OVERRIDE | |
742 { | |
743 postAddAnimationToMainThread(); | |
744 } | |
745 | |
746 virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double mo
notonicTime) OVERRIDE | |
747 { | |
748 const CCActiveAnimation* animation = m_layerTreeHost->rootLayer()->layer
AnimationController()->getActiveAnimation(0, CCActiveAnimation::Opacity); | |
749 if (!animation) | |
750 return; | |
751 const CCFloatAnimationCurve* curve = animation->curve()->toFloatAnimatio
nCurve(); | |
752 float startOpacity = curve->getValue(0); | |
753 float endOpacity = curve->getValue(curve->duration()); | |
754 float linearlyInterpolatedOpacity = 0.25 * endOpacity + 0.75 * startOpac
ity; | |
755 double time = curve->duration() * 0.25; | |
756 // If the linear timing function associated with this animation was not
picked up, | |
757 // then the linearly interpolated opacity would be different because of
the | |
758 // default ease timing function. | |
759 EXPECT_FLOAT_EQ(linearlyInterpolatedOpacity, curve->getValue(time)); | |
760 endTest(); | |
761 } | |
762 | |
763 virtual void afterTest() OVERRIDE | |
764 { | |
765 } | |
766 | |
767 private: | |
768 }; | |
769 | |
770 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestAddAnimationWithTimingFunction
) | |
771 | |
772 // Ensures that when opacity is being animated, this value does not cause the su
btree to be skipped. | |
773 class CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public CCLayerTree
HostTest { | |
774 public: | |
775 CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity() | |
776 { | |
777 } | |
778 | |
779 virtual void beginTest() OVERRIDE | |
780 { | |
781 m_layerTreeHost->rootLayer()->setDrawOpacity(1); | |
782 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
783 m_layerTreeHost->rootLayer()->setOpacity(0); | |
784 postAddAnimationToMainThread(); | |
785 } | |
786 | |
787 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
788 { | |
789 // If the subtree was skipped when preparing to draw, the layer's draw o
pacity | |
790 // will not have been updated. It should be set to 0 due to the animatio
n. | |
791 // Without the animation, the layer will be skipped since it has zero op
acity. | |
792 EXPECT_EQ(0, m_layerTreeHost->rootLayer()->drawOpacity()); | |
793 endTest(); | |
794 } | |
795 | |
796 virtual void afterTest() OVERRIDE | |
797 { | |
798 } | |
799 }; | |
800 | |
801 #if OS(WINDOWS) | |
802 // http://webkit.org/b/74623 | |
803 TEST_F(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, FLAKY_runMultiThre
ad) | |
804 #else | |
805 TEST_F(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread) | |
806 #endif | |
807 { | |
808 runTest(true); | |
809 } | |
810 | |
811 // Ensures that main thread animations have their start times synchronized with
impl thread animations. | |
812 class CCLayerTreeHostTestSynchronizeAnimationStartTimes : public CCLayerTreeHost
Test { | |
813 public: | |
814 CCLayerTreeHostTestSynchronizeAnimationStartTimes() | |
815 : m_layerTreeHostImpl(0) | |
816 { | |
817 } | |
818 | |
819 virtual void beginTest() OVERRIDE | |
820 { | |
821 postAddAnimationToMainThread(); | |
822 } | |
823 | |
824 // This is guaranteed to be called before CCLayerTreeHostImpl::animateLayers
. | |
825 virtual void willAnimateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, doubl
e monotonicTime) OVERRIDE | |
826 { | |
827 m_layerTreeHostImpl = layerTreeHostImpl; | |
828 } | |
829 | |
830 virtual void notifyAnimationStarted(double time) OVERRIDE | |
831 { | |
832 EXPECT_TRUE(m_layerTreeHostImpl); | |
833 | |
834 CCLayerAnimationController* controllerImpl = m_layerTreeHostImpl->rootLa
yer()->layerAnimationController(); | |
835 CCLayerAnimationController* controller = m_layerTreeHost->rootLayer()->l
ayerAnimationController(); | |
836 CCActiveAnimation* animationImpl = controllerImpl->getActiveAnimation(0,
CCActiveAnimation::Opacity); | |
837 CCActiveAnimation* animation = controller->getActiveAnimation(0, CCActiv
eAnimation::Opacity); | |
838 | |
839 EXPECT_EQ(animationImpl->startTime(), animation->startTime()); | |
840 | |
841 endTest(); | |
842 } | |
843 | |
844 virtual void afterTest() OVERRIDE | |
845 { | |
846 } | |
847 | |
848 private: | |
849 CCLayerTreeHostImpl* m_layerTreeHostImpl; | |
850 }; | |
851 | |
852 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSynchronizeAnimationStartTimes
) | |
853 | |
854 // Ensures that main thread animations have their start times synchronized with
impl thread animations. | |
855 class CCLayerTreeHostTestAnimationFinishedEvents : public CCLayerTreeHostTest { | |
856 public: | |
857 CCLayerTreeHostTestAnimationFinishedEvents() | |
858 { | |
859 } | |
860 | |
861 virtual void beginTest() OVERRIDE | |
862 { | |
863 postAddInstantAnimationToMainThread(); | |
864 } | |
865 | |
866 virtual void notifyAnimationFinished(double time) OVERRIDE | |
867 { | |
868 endTest(); | |
869 } | |
870 | |
871 virtual void afterTest() OVERRIDE | |
872 { | |
873 } | |
874 | |
875 private: | |
876 }; | |
877 | |
878 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestAnimationFinishedEvents) | |
879 | |
880 class CCLayerTreeHostTestScrollSimple : public CCLayerTreeHostTest { | |
881 public: | |
882 CCLayerTreeHostTestScrollSimple() | |
883 : m_initialScroll(IntPoint(10, 20)) | |
884 , m_secondScroll(IntPoint(40, 5)) | |
885 , m_scrollAmount(2, -1) | |
886 , m_scrolls(0) | |
887 { | |
888 } | |
889 | |
890 virtual void beginTest() OVERRIDE | |
891 { | |
892 m_layerTreeHost->rootLayer()->setScrollable(true); | |
893 m_layerTreeHost->rootLayer()->setScrollPosition(m_initialScroll); | |
894 postSetNeedsCommitToMainThread(); | |
895 } | |
896 | |
897 virtual void layout() OVERRIDE | |
898 { | |
899 LayerChromium* root = m_layerTreeHost->rootLayer(); | |
900 if (!m_layerTreeHost->commitNumber()) | |
901 EXPECT_EQ(root->scrollPosition(), m_initialScroll); | |
902 else { | |
903 EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount); | |
904 | |
905 // Pretend like Javascript updated the scroll position itself. | |
906 root->setScrollPosition(m_secondScroll); | |
907 } | |
908 } | |
909 | |
910 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
911 { | |
912 CCLayerImpl* root = impl->rootLayer(); | |
913 EXPECT_EQ(root->scrollDelta(), IntSize()); | |
914 | |
915 root->setScrollable(true); | |
916 root->setMaxScrollPosition(IntSize(100, 100)); | |
917 root->scrollBy(m_scrollAmount); | |
918 | |
919 if (!impl->sourceFrameNumber()) { | |
920 EXPECT_EQ(root->scrollPosition(), m_initialScroll); | |
921 EXPECT_EQ(root->scrollDelta(), m_scrollAmount); | |
922 postSetNeedsCommitToMainThread(); | |
923 } else if (impl->sourceFrameNumber() == 1) { | |
924 EXPECT_EQ(root->scrollPosition(), m_secondScroll); | |
925 EXPECT_EQ(root->scrollDelta(), m_scrollAmount); | |
926 endTest(); | |
927 } | |
928 } | |
929 | |
930 virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale) OV
ERRIDE | |
931 { | |
932 IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition(); | |
933 m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta); | |
934 m_scrolls++; | |
935 } | |
936 | |
937 virtual void afterTest() OVERRIDE | |
938 { | |
939 EXPECT_EQ(1, m_scrolls); | |
940 } | |
941 private: | |
942 IntPoint m_initialScroll; | |
943 IntPoint m_secondScroll; | |
944 IntSize m_scrollAmount; | |
945 int m_scrolls; | |
946 }; | |
947 | |
948 TEST_F(CCLayerTreeHostTestScrollSimple, runMultiThread) | |
949 { | |
950 runTest(true); | |
951 } | |
952 | |
953 class CCLayerTreeHostTestScrollMultipleRedraw : public CCLayerTreeHostTest { | |
954 public: | |
955 CCLayerTreeHostTestScrollMultipleRedraw() | |
956 : m_initialScroll(IntPoint(40, 10)) | |
957 , m_scrollAmount(-3, 17) | |
958 , m_scrolls(0) | |
959 { | |
960 } | |
961 | |
962 virtual void beginTest() OVERRIDE | |
963 { | |
964 m_layerTreeHost->rootLayer()->setScrollable(true); | |
965 m_layerTreeHost->rootLayer()->setScrollPosition(m_initialScroll); | |
966 postSetNeedsCommitToMainThread(); | |
967 } | |
968 | |
969 virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
970 { | |
971 LayerChromium* root = m_layerTreeHost->rootLayer(); | |
972 if (!m_layerTreeHost->commitNumber()) | |
973 EXPECT_EQ(root->scrollPosition(), m_initialScroll); | |
974 else if (m_layerTreeHost->commitNumber() == 1) | |
975 EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount +
m_scrollAmount); | |
976 else if (m_layerTreeHost->commitNumber() == 2) | |
977 EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount +
m_scrollAmount); | |
978 } | |
979 | |
980 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
981 { | |
982 CCLayerImpl* root = impl->rootLayer(); | |
983 root->setScrollable(true); | |
984 root->setMaxScrollPosition(IntSize(100, 100)); | |
985 | |
986 if (!impl->sourceFrameNumber() && impl->sourceAnimationFrameNumber() ==
1) { | |
987 // First draw after first commit. | |
988 EXPECT_EQ(root->scrollDelta(), IntSize()); | |
989 root->scrollBy(m_scrollAmount); | |
990 EXPECT_EQ(root->scrollDelta(), m_scrollAmount); | |
991 | |
992 EXPECT_EQ(root->scrollPosition(), m_initialScroll); | |
993 postSetNeedsRedrawToMainThread(); | |
994 } else if (!impl->sourceFrameNumber() && impl->sourceAnimationFrameNumbe
r() == 2) { | |
995 // Second draw after first commit. | |
996 EXPECT_EQ(root->scrollDelta(), m_scrollAmount); | |
997 root->scrollBy(m_scrollAmount); | |
998 EXPECT_EQ(root->scrollDelta(), m_scrollAmount + m_scrollAmount); | |
999 | |
1000 EXPECT_EQ(root->scrollPosition(), m_initialScroll); | |
1001 postSetNeedsCommitToMainThread(); | |
1002 } else if (impl->sourceFrameNumber() == 1) { | |
1003 // Third or later draw after second commit. | |
1004 EXPECT_GE(impl->sourceAnimationFrameNumber(), 3); | |
1005 EXPECT_EQ(root->scrollDelta(), IntSize()); | |
1006 EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount +
m_scrollAmount); | |
1007 endTest(); | |
1008 } | |
1009 } | |
1010 | |
1011 virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale) OV
ERRIDE | |
1012 { | |
1013 IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition(); | |
1014 m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta); | |
1015 m_scrolls++; | |
1016 } | |
1017 | |
1018 virtual void afterTest() OVERRIDE | |
1019 { | |
1020 EXPECT_EQ(1, m_scrolls); | |
1021 } | |
1022 private: | |
1023 IntPoint m_initialScroll; | |
1024 IntSize m_scrollAmount; | |
1025 int m_scrolls; | |
1026 }; | |
1027 | |
1028 TEST_F(CCLayerTreeHostTestScrollMultipleRedraw, runMultiThread) | |
1029 { | |
1030 runTest(true); | |
1031 } | |
1032 | |
1033 // This test verifies that properties on the layer tree host are commited to the
impl side. | |
1034 class CCLayerTreeHostTestCommit : public CCLayerTreeHostTest { | |
1035 public: | |
1036 | |
1037 CCLayerTreeHostTestCommit() { } | |
1038 | |
1039 virtual void beginTest() OVERRIDE | |
1040 { | |
1041 m_layerTreeHost->setViewportSize(IntSize(20, 20), IntSize(20, 20)); | |
1042 m_layerTreeHost->setBackgroundColor(SK_ColorGRAY); | |
1043 m_layerTreeHost->setPageScaleFactorAndLimits(5, 5, 5); | |
1044 | |
1045 postSetNeedsCommitToMainThread(); | |
1046 } | |
1047 | |
1048 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1049 { | |
1050 EXPECT_EQ(IntSize(20, 20), impl->layoutViewportSize()); | |
1051 EXPECT_EQ(SK_ColorGRAY, impl->backgroundColor()); | |
1052 EXPECT_EQ(5, impl->pageScaleFactor()); | |
1053 | |
1054 endTest(); | |
1055 } | |
1056 | |
1057 virtual void afterTest() OVERRIDE { } | |
1058 }; | |
1059 | |
1060 TEST_F(CCLayerTreeHostTestCommit, runTest) | |
1061 { | |
1062 runTest(true); | |
1063 } | |
1064 | |
1065 // Verifies that startPageScaleAnimation events propagate correctly from CCLayer
TreeHost to | |
1066 // CCLayerTreeHostImpl in the MT compositor. | |
1067 class CCLayerTreeHostTestStartPageScaleAnimation : public CCLayerTreeHostTest { | |
1068 public: | |
1069 | |
1070 CCLayerTreeHostTestStartPageScaleAnimation() | |
1071 : m_animationRequested(false) | |
1072 { | |
1073 } | |
1074 | |
1075 virtual void beginTest() OVERRIDE | |
1076 { | |
1077 m_layerTreeHost->rootLayer()->setScrollable(true); | |
1078 m_layerTreeHost->rootLayer()->setScrollPosition(IntPoint()); | |
1079 postSetNeedsRedrawToMainThread(); | |
1080 } | |
1081 | |
1082 void requestStartPageScaleAnimation() | |
1083 { | |
1084 layerTreeHost()->startPageScaleAnimation(IntSize(), false, 1.25, 0); | |
1085 } | |
1086 | |
1087 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1088 { | |
1089 impl->rootLayer()->setScrollable(true); | |
1090 impl->rootLayer()->setScrollPosition(IntPoint()); | |
1091 impl->setPageScaleFactorAndLimits(impl->pageScaleFactor(), 0.5, 2); | |
1092 | |
1093 // We request animation only once. | |
1094 if (!m_animationRequested) { | |
1095 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCLayerTreeHos
tTestStartPageScaleAnimation::requestStartPageScaleAnimation)); | |
1096 m_animationRequested = true; | |
1097 } | |
1098 } | |
1099 | |
1100 virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale) OV
ERRIDE | |
1101 { | |
1102 IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition(); | |
1103 m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta); | |
1104 m_layerTreeHost->setPageScaleFactorAndLimits(scale, 0.5, 2); | |
1105 } | |
1106 | |
1107 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1108 { | |
1109 impl->processScrollDeltas(); | |
1110 // We get one commit before the first draw, and the animation doesn't ha
ppen until the second draw. | |
1111 if (impl->sourceFrameNumber() == 1) { | |
1112 EXPECT_EQ(1.25, impl->pageScaleFactor()); | |
1113 endTest(); | |
1114 } else | |
1115 postSetNeedsRedrawToMainThread(); | |
1116 } | |
1117 | |
1118 virtual void afterTest() OVERRIDE | |
1119 { | |
1120 } | |
1121 | |
1122 private: | |
1123 bool m_animationRequested; | |
1124 }; | |
1125 | |
1126 TEST_F(CCLayerTreeHostTestStartPageScaleAnimation, runTest) | |
1127 { | |
1128 runTest(true); | |
1129 } | |
1130 | |
1131 class CCLayerTreeHostTestSetVisible : public CCLayerTreeHostTest { | |
1132 public: | |
1133 | |
1134 CCLayerTreeHostTestSetVisible() | |
1135 : m_numDraws(0) | |
1136 { | |
1137 } | |
1138 | |
1139 virtual void beginTest() OVERRIDE | |
1140 { | |
1141 postSetVisibleToMainThread(false); | |
1142 postSetNeedsRedrawToMainThread(); // This is suppressed while we're invi
sible. | |
1143 postSetVisibleToMainThread(true); // Triggers the redraw. | |
1144 } | |
1145 | |
1146 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1147 { | |
1148 EXPECT_TRUE(impl->visible()); | |
1149 ++m_numDraws; | |
1150 endTest(); | |
1151 } | |
1152 | |
1153 virtual void afterTest() OVERRIDE | |
1154 { | |
1155 EXPECT_EQ(1, m_numDraws); | |
1156 } | |
1157 | |
1158 private: | |
1159 int m_numDraws; | |
1160 }; | |
1161 | |
1162 TEST_F(CCLayerTreeHostTestSetVisible, runMultiThread) | |
1163 { | |
1164 runTest(true); | |
1165 } | |
1166 | |
1167 class TestOpacityChangeLayerDelegate : public ContentLayerChromiumClient { | |
1168 public: | |
1169 TestOpacityChangeLayerDelegate(CCLayerTreeHostTest* test) | |
1170 : m_test(test) | |
1171 { | |
1172 } | |
1173 | |
1174 virtual void paintContents(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE | |
1175 { | |
1176 // Set layer opacity to 0. | |
1177 m_test->layerTreeHost()->rootLayer()->setOpacity(0); | |
1178 } | |
1179 | |
1180 private: | |
1181 CCLayerTreeHostTest* m_test; | |
1182 }; | |
1183 | |
1184 class ContentLayerChromiumWithUpdateTracking : public ContentLayerChromium { | |
1185 public: | |
1186 static scoped_refptr<ContentLayerChromiumWithUpdateTracking> create(ContentL
ayerChromiumClient* client) { return make_scoped_refptr(new ContentLayerChromium
WithUpdateTracking(client)); } | |
1187 | |
1188 int paintContentsCount() { return m_paintContentsCount; } | |
1189 void resetPaintContentsCount() { m_paintContentsCount = 0; } | |
1190 | |
1191 virtual void update(CCTextureUpdateQueue& queue, const CCOcclusionTracker* o
cclusion, CCRenderingStats& stats) OVERRIDE | |
1192 { | |
1193 ContentLayerChromium::update(queue, occlusion, stats); | |
1194 m_paintContentsCount++; | |
1195 } | |
1196 | |
1197 private: | |
1198 explicit ContentLayerChromiumWithUpdateTracking(ContentLayerChromiumClient*
client) | |
1199 : ContentLayerChromium(client) | |
1200 , m_paintContentsCount(0) | |
1201 { | |
1202 setAnchorPoint(FloatPoint(0, 0)); | |
1203 setBounds(IntSize(10, 10)); | |
1204 setIsDrawable(true); | |
1205 } | |
1206 virtual ~ContentLayerChromiumWithUpdateTracking() | |
1207 { | |
1208 } | |
1209 | |
1210 int m_paintContentsCount; | |
1211 }; | |
1212 | |
1213 // Layer opacity change during paint should not prevent compositor resources fro
m being updated during commit. | |
1214 class CCLayerTreeHostTestOpacityChange : public CCLayerTreeHostTest { | |
1215 public: | |
1216 CCLayerTreeHostTestOpacityChange() | |
1217 : m_testOpacityChangeDelegate(this) | |
1218 , m_updateCheckLayer(ContentLayerChromiumWithUpdateTracking::create(&m_t
estOpacityChangeDelegate)) | |
1219 { | |
1220 } | |
1221 | |
1222 virtual void beginTest() OVERRIDE | |
1223 { | |
1224 m_layerTreeHost->setRootLayer(m_updateCheckLayer); | |
1225 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
1226 | |
1227 postSetNeedsCommitToMainThread(); | |
1228 } | |
1229 | |
1230 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
1231 { | |
1232 endTest(); | |
1233 } | |
1234 | |
1235 virtual void afterTest() OVERRIDE | |
1236 { | |
1237 // update() should have been called once. | |
1238 EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount()); | |
1239 | |
1240 // clear m_updateCheckLayer so CCLayerTreeHost dies. | |
1241 m_updateCheckLayer = NULL; | |
1242 } | |
1243 | |
1244 private: | |
1245 TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate; | |
1246 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_updateCheckLayer; | |
1247 }; | |
1248 | |
1249 TEST_F(CCLayerTreeHostTestOpacityChange, runMultiThread) | |
1250 { | |
1251 runTest(true); | |
1252 } | |
1253 | |
1254 class MockContentLayerChromiumClient : public ContentLayerChromiumClient { | |
1255 public: | |
1256 bool drawsContent() const { return true; } | |
1257 MOCK_CONST_METHOD0(preserves3D, bool()); | |
1258 void paintContents(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE { } | |
1259 void notifySyncRequired() { } | |
1260 }; | |
1261 | |
1262 class NoScaleContentLayerChromium : public ContentLayerChromium { | |
1263 public: | |
1264 static scoped_refptr<NoScaleContentLayerChromium> create(ContentLayerChromiu
mClient* client) { return make_scoped_refptr(new NoScaleContentLayerChromium(cli
ent)); } | |
1265 | |
1266 virtual bool needsContentsScale() const OVERRIDE { return false; } | |
1267 | |
1268 private: | |
1269 explicit NoScaleContentLayerChromium(ContentLayerChromiumClient* client) | |
1270 : ContentLayerChromium(client) { } | |
1271 virtual ~NoScaleContentLayerChromium() { } | |
1272 }; | |
1273 | |
1274 class CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public CCLay
erTreeHostTest { | |
1275 public: | |
1276 | |
1277 CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers() | |
1278 : m_rootLayer(NoScaleContentLayerChromium::create(&m_client)) | |
1279 , m_childLayer(ContentLayerChromium::create(&m_client)) | |
1280 { | |
1281 } | |
1282 | |
1283 virtual void beginTest() OVERRIDE | |
1284 { | |
1285 m_layerTreeHost->setViewportSize(IntSize(40, 40), IntSize(60, 60)); | |
1286 m_layerTreeHost->setDeviceScaleFactor(1.5); | |
1287 EXPECT_EQ(IntSize(40, 40), m_layerTreeHost->layoutViewportSize()); | |
1288 EXPECT_EQ(IntSize(60, 60), m_layerTreeHost->deviceViewportSize()); | |
1289 | |
1290 m_rootLayer->addChild(m_childLayer); | |
1291 | |
1292 m_rootLayer->setIsDrawable(true); | |
1293 m_rootLayer->setBounds(IntSize(30, 30)); | |
1294 m_rootLayer->setAnchorPoint(FloatPoint(0, 0)); | |
1295 | |
1296 m_childLayer->setIsDrawable(true); | |
1297 m_childLayer->setPosition(IntPoint(2, 2)); | |
1298 m_childLayer->setBounds(IntSize(10, 10)); | |
1299 m_childLayer->setAnchorPoint(FloatPoint(0, 0)); | |
1300 | |
1301 m_layerTreeHost->setRootLayer(m_rootLayer); | |
1302 } | |
1303 | |
1304 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1305 { | |
1306 // Get access to protected methods. | |
1307 MockLayerTreeHostImpl* mockImpl = static_cast<MockLayerTreeHostImpl*>(im
pl); | |
1308 | |
1309 // Should only do one commit. | |
1310 EXPECT_EQ(0, impl->sourceFrameNumber()); | |
1311 // Device scale factor should come over to impl. | |
1312 EXPECT_NEAR(impl->deviceScaleFactor(), 1.5, 0.00001); | |
1313 | |
1314 // Both layers are on impl. | |
1315 ASSERT_EQ(1u, impl->rootLayer()->children().size()); | |
1316 | |
1317 // Device viewport is scaled. | |
1318 EXPECT_EQ(IntSize(40, 40), impl->layoutViewportSize()); | |
1319 EXPECT_EQ(IntSize(60, 60), impl->deviceViewportSize()); | |
1320 | |
1321 CCLayerImpl* root = impl->rootLayer(); | |
1322 CCLayerImpl* child = impl->rootLayer()->children()[0]; | |
1323 | |
1324 // Positions remain in layout pixels. | |
1325 EXPECT_EQ(IntPoint(0, 0), root->position()); | |
1326 EXPECT_EQ(IntPoint(2, 2), child->position()); | |
1327 | |
1328 // Compute all the layer transforms for the frame. | |
1329 MockLayerTreeHostImpl::CCLayerList renderSurfaceLayerList; | |
1330 mockImpl->calculateRenderSurfaceLayerList(renderSurfaceLayerList); | |
1331 | |
1332 // Both layers should be drawing into the root render surface. | |
1333 ASSERT_EQ(1u, renderSurfaceLayerList.size()); | |
1334 ASSERT_EQ(root->renderSurface(), renderSurfaceLayerList[0]->renderSurfac
e()); | |
1335 ASSERT_EQ(2u, root->renderSurface()->layerList().size()); | |
1336 | |
1337 // The root render surface is the size of the viewport. | |
1338 EXPECT_RECT_EQ(IntRect(0, 0, 60, 60), root->renderSurface()->contentRect
()); | |
1339 | |
1340 // The content bounds of the child should be scaled. | |
1341 IntSize childBoundsScaled = child->bounds(); | |
1342 childBoundsScaled.scale(1.5); | |
1343 EXPECT_EQ(childBoundsScaled, child->contentBounds()); | |
1344 | |
1345 WebTransformationMatrix scaleTransform; | |
1346 scaleTransform.scale(impl->deviceScaleFactor()); | |
1347 | |
1348 // The root layer is scaled by 2x. | |
1349 WebTransformationMatrix rootScreenSpaceTransform = scaleTransform; | |
1350 WebTransformationMatrix rootDrawTransform = scaleTransform; | |
1351 | |
1352 EXPECT_EQ(rootDrawTransform, root->drawTransform()); | |
1353 EXPECT_EQ(rootScreenSpaceTransform, root->screenSpaceTransform()); | |
1354 | |
1355 // The child is at position 2,2, which is transformed to 3,3 after the s
cale | |
1356 WebTransformationMatrix childScreenSpaceTransform; | |
1357 childScreenSpaceTransform.translate(3, 3); | |
1358 WebTransformationMatrix childDrawTransform = childScreenSpaceTransform; | |
1359 | |
1360 EXPECT_EQ(childDrawTransform, child->drawTransform()); | |
1361 EXPECT_EQ(childScreenSpaceTransform, child->screenSpaceTransform()); | |
1362 | |
1363 endTest(); | |
1364 } | |
1365 | |
1366 virtual void afterTest() OVERRIDE | |
1367 { | |
1368 m_rootLayer = NULL; | |
1369 m_childLayer = NULL; | |
1370 } | |
1371 | |
1372 private: | |
1373 MockContentLayerChromiumClient m_client; | |
1374 scoped_refptr<NoScaleContentLayerChromium> m_rootLayer; | |
1375 scoped_refptr<ContentLayerChromium> m_childLayer; | |
1376 }; | |
1377 | |
1378 // Test is flaky - http://crbug.com/148490 | |
1379 TEST_F(CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers, DISABLED_run
MultiThread) | |
1380 { | |
1381 runTest(true); | |
1382 } | |
1383 | |
1384 // Verify atomicity of commits and reuse of textures. | |
1385 class CCLayerTreeHostTestAtomicCommit : public CCLayerTreeHostTest { | |
1386 public: | |
1387 CCLayerTreeHostTestAtomicCommit() | |
1388 : m_layer(ContentLayerChromiumWithUpdateTracking::create(&m_client)) | |
1389 { | |
1390 // Make sure partial texture updates are turned off. | |
1391 m_settings.maxPartialTextureUpdates = 0; | |
1392 } | |
1393 | |
1394 virtual void beginTest() OVERRIDE | |
1395 { | |
1396 m_layerTreeHost->setRootLayer(m_layer); | |
1397 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
1398 | |
1399 postSetNeedsCommitToMainThread(); | |
1400 postSetNeedsRedrawToMainThread(); | |
1401 } | |
1402 | |
1403 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1404 { | |
1405 CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_
cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->co
ntext3D()); | |
1406 | |
1407 switch (impl->sourceFrameNumber()) { | |
1408 case 0: | |
1409 // Number of textures should be one. | |
1410 ASSERT_EQ(1, context->numTextures()); | |
1411 // Number of textures used for commit should be one. | |
1412 EXPECT_EQ(1, context->numUsedTextures()); | |
1413 // Verify that used texture is correct. | |
1414 EXPECT_TRUE(context->usedTexture(context->texture(0))); | |
1415 | |
1416 context->resetUsedTextures(); | |
1417 break; | |
1418 case 1: | |
1419 // Number of textures should be two as the first texture | |
1420 // is used by impl thread and cannot by used for update. | |
1421 ASSERT_EQ(2, context->numTextures()); | |
1422 // Number of textures used for commit should still be one. | |
1423 EXPECT_EQ(1, context->numUsedTextures()); | |
1424 // First texture should not have been used. | |
1425 EXPECT_FALSE(context->usedTexture(context->texture(0))); | |
1426 // New texture should have been used. | |
1427 EXPECT_TRUE(context->usedTexture(context->texture(1))); | |
1428 | |
1429 context->resetUsedTextures(); | |
1430 break; | |
1431 default: | |
1432 ASSERT_NOT_REACHED(); | |
1433 break; | |
1434 } | |
1435 } | |
1436 | |
1437 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1438 { | |
1439 CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_
cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->co
ntext3D()); | |
1440 | |
1441 // Number of textures used for draw should always be one. | |
1442 EXPECT_EQ(1, context->numUsedTextures()); | |
1443 | |
1444 if (impl->sourceFrameNumber() < 1) { | |
1445 context->resetUsedTextures(); | |
1446 postSetNeedsAnimateAndCommitToMainThread(); | |
1447 postSetNeedsRedrawToMainThread(); | |
1448 } else | |
1449 endTest(); | |
1450 } | |
1451 | |
1452 virtual void layout() OVERRIDE | |
1453 { | |
1454 m_layer->setNeedsDisplay(); | |
1455 } | |
1456 | |
1457 virtual void afterTest() OVERRIDE | |
1458 { | |
1459 } | |
1460 | |
1461 private: | |
1462 MockContentLayerChromiumClient m_client; | |
1463 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_layer; | |
1464 }; | |
1465 | |
1466 TEST_F(CCLayerTreeHostTestAtomicCommit, runMultiThread) | |
1467 { | |
1468 runTest(true); | |
1469 } | |
1470 | |
1471 static void setLayerPropertiesForTesting(LayerChromium* layer, LayerChromium* pa
rent, const WebTransformationMatrix& transform, const FloatPoint& anchor, const
FloatPoint& position, const IntSize& bounds, bool opaque) | |
1472 { | |
1473 layer->removeAllChildren(); | |
1474 if (parent) | |
1475 parent->addChild(layer); | |
1476 layer->setTransform(transform); | |
1477 layer->setAnchorPoint(anchor); | |
1478 layer->setPosition(position); | |
1479 layer->setBounds(bounds); | |
1480 layer->setContentsOpaque(opaque); | |
1481 } | |
1482 | |
1483 class CCLayerTreeHostTestAtomicCommitWithPartialUpdate : public CCLayerTreeHostT
est { | |
1484 public: | |
1485 CCLayerTreeHostTestAtomicCommitWithPartialUpdate() | |
1486 : m_parent(ContentLayerChromiumWithUpdateTracking::create(&m_client)) | |
1487 , m_child(ContentLayerChromiumWithUpdateTracking::create(&m_client)) | |
1488 , m_numCommits(0) | |
1489 { | |
1490 // Allow one partial texture update. | |
1491 m_settings.maxPartialTextureUpdates = 1; | |
1492 } | |
1493 | |
1494 virtual void beginTest() OVERRIDE | |
1495 { | |
1496 m_layerTreeHost->setRootLayer(m_parent); | |
1497 m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20)); | |
1498 | |
1499 WebTransformationMatrix identityMatrix; | |
1500 setLayerPropertiesForTesting(m_parent.get(), 0, identityMatrix, FloatPoi
nt(0, 0), FloatPoint(0, 0), IntSize(10, 20), true); | |
1501 setLayerPropertiesForTesting(m_child.get(), m_parent.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(0, 10), IntSize(10, 10), false); | |
1502 | |
1503 postSetNeedsCommitToMainThread(); | |
1504 postSetNeedsRedrawToMainThread(); | |
1505 } | |
1506 | |
1507 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1508 { | |
1509 CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_
cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->co
ntext3D()); | |
1510 | |
1511 switch (impl->sourceFrameNumber()) { | |
1512 case 0: | |
1513 // Number of textures should be two. | |
1514 ASSERT_EQ(2, context->numTextures()); | |
1515 // Number of textures used for commit should be two. | |
1516 EXPECT_EQ(2, context->numUsedTextures()); | |
1517 // Verify that used textures are correct. | |
1518 EXPECT_TRUE(context->usedTexture(context->texture(0))); | |
1519 EXPECT_TRUE(context->usedTexture(context->texture(1))); | |
1520 | |
1521 context->resetUsedTextures(); | |
1522 break; | |
1523 case 1: | |
1524 // Number of textures used for commit should still be two. | |
1525 EXPECT_EQ(2, context->numUsedTextures()); | |
1526 // First two textures should not have been used. | |
1527 EXPECT_FALSE(context->usedTexture(context->texture(0))); | |
1528 EXPECT_FALSE(context->usedTexture(context->texture(1))); | |
1529 // New textures should have been used. | |
1530 EXPECT_TRUE(context->usedTexture(context->texture(2))); | |
1531 EXPECT_TRUE(context->usedTexture(context->texture(3))); | |
1532 | |
1533 context->resetUsedTextures(); | |
1534 break; | |
1535 case 2: | |
1536 // Number of textures used for commit should still be two. | |
1537 EXPECT_EQ(2, context->numUsedTextures()); | |
1538 | |
1539 context->resetUsedTextures(); | |
1540 break; | |
1541 case 3: | |
1542 // No textures should be used for commit. | |
1543 EXPECT_EQ(0, context->numUsedTextures()); | |
1544 | |
1545 context->resetUsedTextures(); | |
1546 break; | |
1547 case 4: | |
1548 // Number of textures used for commit should be one. | |
1549 EXPECT_EQ(1, context->numUsedTextures()); | |
1550 | |
1551 context->resetUsedTextures(); | |
1552 break; | |
1553 default: | |
1554 ASSERT_NOT_REACHED(); | |
1555 break; | |
1556 } | |
1557 } | |
1558 | |
1559 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
1560 { | |
1561 CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_
cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->co
ntext3D()); | |
1562 | |
1563 // Number of textures used for drawing should two except for frame 4 | |
1564 // where the viewport only contains one layer. | |
1565 if (impl->sourceFrameNumber() == 3) | |
1566 EXPECT_EQ(1, context->numUsedTextures()); | |
1567 else | |
1568 EXPECT_EQ(2, context->numUsedTextures()); | |
1569 | |
1570 if (impl->sourceFrameNumber() < 4) { | |
1571 context->resetUsedTextures(); | |
1572 postSetNeedsAnimateAndCommitToMainThread(); | |
1573 postSetNeedsRedrawToMainThread(); | |
1574 } else | |
1575 endTest(); | |
1576 } | |
1577 | |
1578 virtual void layout() OVERRIDE | |
1579 { | |
1580 switch (m_numCommits++) { | |
1581 case 0: | |
1582 case 1: | |
1583 m_parent->setNeedsDisplay(); | |
1584 m_child->setNeedsDisplay(); | |
1585 break; | |
1586 case 2: | |
1587 // Damage part of layers. | |
1588 m_parent->setNeedsDisplayRect(FloatRect(0, 0, 5, 5)); | |
1589 m_child->setNeedsDisplayRect(FloatRect(0, 0, 5, 5)); | |
1590 break; | |
1591 case 3: | |
1592 m_child->setNeedsDisplay(); | |
1593 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
1594 break; | |
1595 case 4: | |
1596 m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20)); | |
1597 break; | |
1598 default: | |
1599 ASSERT_NOT_REACHED(); | |
1600 break; | |
1601 } | |
1602 } | |
1603 | |
1604 virtual void afterTest() OVERRIDE | |
1605 { | |
1606 } | |
1607 | |
1608 private: | |
1609 MockContentLayerChromiumClient m_client; | |
1610 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_parent; | |
1611 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_child; | |
1612 int m_numCommits; | |
1613 }; | |
1614 | |
1615 TEST_F(CCLayerTreeHostTestAtomicCommitWithPartialUpdate, runMultiThread) | |
1616 { | |
1617 runTest(true); | |
1618 } | |
1619 | |
1620 class TestLayerChromium : public LayerChromium { | |
1621 public: | |
1622 static scoped_refptr<TestLayerChromium> create() { return make_scoped_refptr
(new TestLayerChromium()); } | |
1623 | |
1624 virtual void update(CCTextureUpdateQueue&, const CCOcclusionTracker* occlusi
on, CCRenderingStats&) OVERRIDE | |
1625 { | |
1626 // Gain access to internals of the CCOcclusionTracker. | |
1627 const TestCCOcclusionTracker* testOcclusion = static_cast<const TestCCOc
clusionTracker*>(occlusion); | |
1628 m_occludedScreenSpace = testOcclusion ? testOcclusion->occlusionInScreen
Space() : Region(); | |
1629 } | |
1630 | |
1631 virtual bool drawsContent() const OVERRIDE { return true; } | |
1632 | |
1633 const Region& occludedScreenSpace() const { return m_occludedScreenSpace; } | |
1634 void clearOccludedScreenSpace() { m_occludedScreenSpace = Region(); } | |
1635 | |
1636 private: | |
1637 TestLayerChromium() : LayerChromium() { } | |
1638 virtual ~TestLayerChromium() { } | |
1639 | |
1640 Region m_occludedScreenSpace; | |
1641 }; | |
1642 | |
1643 static void setTestLayerPropertiesForTesting(TestLayerChromium* layer, LayerChro
mium* parent, const WebTransformationMatrix& transform, const FloatPoint& anchor
, const FloatPoint& position, const IntSize& bounds, bool opaque) | |
1644 { | |
1645 setLayerPropertiesForTesting(layer, parent, transform, anchor, position, bou
nds, opaque); | |
1646 layer->clearOccludedScreenSpace(); | |
1647 } | |
1648 | |
1649 class CCLayerTreeHostTestLayerOcclusion : public CCLayerTreeHostTest { | |
1650 public: | |
1651 CCLayerTreeHostTestLayerOcclusion() { } | |
1652 | |
1653 virtual void beginTest() OVERRIDE | |
1654 { | |
1655 scoped_refptr<TestLayerChromium> rootLayer = TestLayerChromium::create()
; | |
1656 scoped_refptr<TestLayerChromium> child = TestLayerChromium::create(); | |
1657 scoped_refptr<TestLayerChromium> child2 = TestLayerChromium::create(); | |
1658 scoped_refptr<TestLayerChromium> grandChild = TestLayerChromium::create(
); | |
1659 scoped_refptr<TestLayerChromium> mask = TestLayerChromium::create(); | |
1660 | |
1661 WebTransformationMatrix identityMatrix; | |
1662 WebTransformationMatrix childTransform; | |
1663 childTransform.translate(250, 250); | |
1664 childTransform.rotate(90); | |
1665 childTransform.translate(-250, -250); | |
1666 | |
1667 child->setMasksToBounds(true); | |
1668 | |
1669 // See CCLayerTreeHostCommonTest.layerAddsSelfToOccludedRegionWithRotate
dSurface for a nice visual of these layers and how they end up | |
1670 // positioned on the screen. | |
1671 | |
1672 // The child layer is rotated and the grandChild is opaque, but clipped
to the child and rootLayer | |
1673 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1674 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false); | |
1675 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1676 | |
1677 m_layerTreeHost->setRootLayer(rootLayer); | |
1678 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1679 ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded()); | |
1680 CCTextureUpdateQueue queue; | |
1681 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1682 m_layerTreeHost->commitComplete(); | |
1683 | |
1684 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1685 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1686 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1687 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1688 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), rootLayer->occludedScreenSpace
().bounds()); | |
1689 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1690 | |
1691 // If the child layer is opaque, then it adds to the occlusion seen by t
he rootLayer. | |
1692 setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPo
int(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1693 setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransfor
m, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1694 setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1695 | |
1696 m_layerTreeHost->setRootLayer(rootLayer); | |
1697 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1698 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1699 m_layerTreeHost->commitComplete(); | |
1700 | |
1701 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1702 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1703 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1704 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1705 EXPECT_RECT_EQ(IntRect(30, 30, 170, 170), rootLayer->occludedScreenSpace
().bounds()); | |
1706 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1707 | |
1708 // Add a second child to the root layer and the regions should merge | |
1709 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1710 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(70, 20), IntSize(500, 500), true); | |
1711 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1712 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1713 | |
1714 m_layerTreeHost->setRootLayer(rootLayer); | |
1715 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1716 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1717 m_layerTreeHost->commitComplete(); | |
1718 | |
1719 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1720 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1721 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1722 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1723 EXPECT_RECT_EQ(IntRect(30, 30, 170, 170), child2->occludedScreenSpace().
bounds()); | |
1724 EXPECT_EQ(1u, child2->occludedScreenSpace().rects().size()); | |
1725 EXPECT_RECT_EQ(IntRect(30, 20, 170, 180), rootLayer->occludedScreenSpace
().bounds()); | |
1726 EXPECT_EQ(2u, rootLayer->occludedScreenSpace().rects().size()); | |
1727 | |
1728 // Move the second child to be sure. | |
1729 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1730 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1731 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1732 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1733 | |
1734 m_layerTreeHost->setRootLayer(rootLayer); | |
1735 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1736 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1737 m_layerTreeHost->commitComplete(); | |
1738 | |
1739 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1740 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1741 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1742 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1743 EXPECT_RECT_EQ(IntRect(30, 30, 170, 170), child2->occludedScreenSpace().
bounds()); | |
1744 EXPECT_EQ(1u, child2->occludedScreenSpace().rects().size()); | |
1745 EXPECT_RECT_EQ(IntRect(10, 30, 190, 170), rootLayer->occludedScreenSpace
().bounds()); | |
1746 EXPECT_EQ(2u, rootLayer->occludedScreenSpace().rects().size()); | |
1747 | |
1748 // If the child layer has a mask on it, then it shouldn't contribute to
occlusion on stuff below it | |
1749 setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPo
int(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1750 setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1751 setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransfor
m, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1752 setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1753 | |
1754 child->setMaskLayer(mask.get()); | |
1755 | |
1756 m_layerTreeHost->setRootLayer(rootLayer); | |
1757 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1758 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1759 m_layerTreeHost->commitComplete(); | |
1760 | |
1761 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1762 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1763 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1764 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1765 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1766 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1767 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1768 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1769 | |
1770 // If the child layer with a mask is below child2, then child2 should co
ntribute to occlusion on everything, and child shouldn't contribute to the rootL
ayer | |
1771 setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPo
int(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1772 setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransfor
m, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1773 setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1774 setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatr
ix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1775 | |
1776 child->setMaskLayer(mask.get()); | |
1777 | |
1778 m_layerTreeHost->setRootLayer(rootLayer); | |
1779 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1780 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1781 m_layerTreeHost->commitComplete(); | |
1782 | |
1783 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1784 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1785 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpac
e().bounds()); | |
1786 EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size()); | |
1787 EXPECT_RECT_EQ(IntRect(10, 40, 190, 160), child->occludedScreenSpace().b
ounds()); | |
1788 EXPECT_EQ(2u, child->occludedScreenSpace().rects().size()); | |
1789 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1790 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1791 | |
1792 // If the child layer has a non-opaque drawOpacity, then it shouldn't co
ntribute to occlusion on stuff below it | |
1793 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1794 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1795 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1796 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1797 | |
1798 child->setMaskLayer(0); | |
1799 child->setOpacity(0.5); | |
1800 | |
1801 m_layerTreeHost->setRootLayer(rootLayer); | |
1802 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1803 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1804 m_layerTreeHost->commitComplete(); | |
1805 | |
1806 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1807 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1808 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1809 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1810 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1811 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1812 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1813 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1814 | |
1815 // If the child layer with non-opaque drawOpacity is below child2, then
child2 should contribute to occlusion on everything, and child shouldn't contrib
ute to the rootLayer | |
1816 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1817 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1818 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1819 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1820 | |
1821 child->setMaskLayer(0); | |
1822 child->setOpacity(0.5); | |
1823 | |
1824 m_layerTreeHost->setRootLayer(rootLayer); | |
1825 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1826 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1827 m_layerTreeHost->commitComplete(); | |
1828 | |
1829 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1830 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1831 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpac
e().bounds()); | |
1832 EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size()); | |
1833 EXPECT_RECT_EQ(IntRect(10, 40, 190, 160), child->occludedScreenSpace().b
ounds()); | |
1834 EXPECT_EQ(2u, child->occludedScreenSpace().rects().size()); | |
1835 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1836 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1837 | |
1838 // Kill the layerTreeHost immediately. | |
1839 m_layerTreeHost->setRootLayer(0); | |
1840 m_layerTreeHost.reset(); | |
1841 | |
1842 endTest(); | |
1843 } | |
1844 | |
1845 virtual void afterTest() OVERRIDE | |
1846 { | |
1847 } | |
1848 }; | |
1849 | |
1850 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerOcclusion) | |
1851 | |
1852 class CCLayerTreeHostTestLayerOcclusionWithFilters : public CCLayerTreeHostTest
{ | |
1853 public: | |
1854 CCLayerTreeHostTestLayerOcclusionWithFilters() { } | |
1855 | |
1856 virtual void beginTest() OVERRIDE | |
1857 { | |
1858 scoped_refptr<TestLayerChromium> rootLayer = TestLayerChromium::create()
; | |
1859 scoped_refptr<TestLayerChromium> child = TestLayerChromium::create(); | |
1860 scoped_refptr<TestLayerChromium> child2 = TestLayerChromium::create(); | |
1861 scoped_refptr<TestLayerChromium> grandChild = TestLayerChromium::create(
); | |
1862 scoped_refptr<TestLayerChromium> mask = TestLayerChromium::create(); | |
1863 | |
1864 WebTransformationMatrix identityMatrix; | |
1865 WebTransformationMatrix childTransform; | |
1866 childTransform.translate(250, 250); | |
1867 childTransform.rotate(90); | |
1868 childTransform.translate(-250, -250); | |
1869 | |
1870 child->setMasksToBounds(true); | |
1871 | |
1872 // If the child layer has a filter that changes alpha values, and is bel
ow child2, then child2 should contribute to occlusion on everything, | |
1873 // and child shouldn't contribute to the rootLayer | |
1874 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1875 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1876 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1877 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1878 | |
1879 { | |
1880 WebFilterOperations filters; | |
1881 filters.append(WebFilterOperation::createOpacityFilter(0.5)); | |
1882 child->setFilters(filters); | |
1883 } | |
1884 | |
1885 m_layerTreeHost->setRootLayer(rootLayer); | |
1886 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1887 ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded()); | |
1888 CCTextureUpdateQueue queue; | |
1889 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1890 m_layerTreeHost->commitComplete(); | |
1891 | |
1892 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1893 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1894 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpac
e().bounds()); | |
1895 EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size()); | |
1896 EXPECT_RECT_EQ(IntRect(10, 40, 190, 160), child->occludedScreenSpace().b
ounds()); | |
1897 EXPECT_EQ(2u, child->occludedScreenSpace().rects().size()); | |
1898 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1899 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1900 | |
1901 // If the child layer has a filter that moves pixels/changes alpha, and
is below child2, then child should not inherit occlusion from outside its subtre
e, | |
1902 // and should not contribute to the rootLayer | |
1903 setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, Flo
atPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1904 setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTran
sform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true); | |
1905 setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true); | |
1906 setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identity
Matrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true); | |
1907 | |
1908 { | |
1909 WebFilterOperations filters; | |
1910 filters.append(WebFilterOperation::createBlurFilter(10)); | |
1911 child->setFilters(filters); | |
1912 } | |
1913 | |
1914 m_layerTreeHost->setRootLayer(rootLayer); | |
1915 m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds(
)); | |
1916 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1917 m_layerTreeHost->commitComplete(); | |
1918 | |
1919 EXPECT_RECT_EQ(IntRect(), child2->occludedScreenSpace().bounds()); | |
1920 EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size()); | |
1921 EXPECT_RECT_EQ(IntRect(), grandChild->occludedScreenSpace().bounds()); | |
1922 EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size()); | |
1923 EXPECT_RECT_EQ(IntRect(30, 40, 170, 160), child->occludedScreenSpace().b
ounds()); | |
1924 EXPECT_EQ(1u, child->occludedScreenSpace().rects().size()); | |
1925 EXPECT_RECT_EQ(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace
().bounds()); | |
1926 EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size()); | |
1927 | |
1928 // Kill the layerTreeHost immediately. | |
1929 m_layerTreeHost->setRootLayer(0); | |
1930 m_layerTreeHost.reset(); | |
1931 | |
1932 CCLayerTreeHost::setNeedsFilterContext(false); | |
1933 endTest(); | |
1934 } | |
1935 | |
1936 virtual void afterTest() OVERRIDE | |
1937 { | |
1938 } | |
1939 }; | |
1940 | |
1941 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerOcclusionWithFilters) | |
1942 | |
1943 class CCLayerTreeHostTestManySurfaces : public CCLayerTreeHostTest { | |
1944 public: | |
1945 CCLayerTreeHostTestManySurfaces() { } | |
1946 | |
1947 virtual void beginTest() OVERRIDE | |
1948 { | |
1949 // We create enough RenderSurfaces that it will trigger Vector reallocat
ion while computing occlusion. | |
1950 Region occluded; | |
1951 const WebTransformationMatrix identityMatrix; | |
1952 std::vector<scoped_refptr<TestLayerChromium> > layers; | |
1953 std::vector<scoped_refptr<TestLayerChromium> > children; | |
1954 int numSurfaces = 20; | |
1955 scoped_refptr<TestLayerChromium> replica = TestLayerChromium::create(); | |
1956 | |
1957 for (int i = 0; i < numSurfaces; ++i) { | |
1958 layers.push_back(TestLayerChromium::create()); | |
1959 if (!i) { | |
1960 setTestLayerPropertiesForTesting(layers.back().get(), 0, identit
yMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true); | |
1961 layers.back()->createRenderSurface(); | |
1962 } else { | |
1963 setTestLayerPropertiesForTesting(layers.back().get(), layers[lay
ers.size()-2].get(), identityMatrix, FloatPoint(0, 0), FloatPoint(1, 1), IntSize
(200-i, 200-i), true); | |
1964 layers.back()->setMasksToBounds(true); | |
1965 layers.back()->setReplicaLayer(replica.get()); // Make it have a
RenderSurface | |
1966 } | |
1967 } | |
1968 | |
1969 for (int i = 1; i < numSurfaces; ++i) { | |
1970 children.push_back(TestLayerChromium::create()); | |
1971 setTestLayerPropertiesForTesting(children.back().get(), layers[i].ge
t(), identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), fals
e); | |
1972 } | |
1973 | |
1974 m_layerTreeHost->setRootLayer(layers[0].get()); | |
1975 m_layerTreeHost->setViewportSize(layers[0]->bounds(), layers[0]->bounds(
)); | |
1976 ASSERT_TRUE(m_layerTreeHost->initializeRendererIfNeeded()); | |
1977 CCTextureUpdateQueue queue; | |
1978 m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max())
; | |
1979 m_layerTreeHost->commitComplete(); | |
1980 | |
1981 for (int i = 0; i < numSurfaces-1; ++i) { | |
1982 IntRect expectedOcclusion(i+1, i+1, 200-i-1, 200-i-1); | |
1983 | |
1984 EXPECT_RECT_EQ(expectedOcclusion, layers[i]->occludedScreenSpace().b
ounds()); | |
1985 EXPECT_EQ(1u, layers[i]->occludedScreenSpace().rects().size()); | |
1986 } | |
1987 | |
1988 // Kill the layerTreeHost immediately. | |
1989 m_layerTreeHost->setRootLayer(0); | |
1990 m_layerTreeHost.reset(); | |
1991 | |
1992 endTest(); | |
1993 } | |
1994 | |
1995 virtual void afterTest() OVERRIDE | |
1996 { | |
1997 } | |
1998 }; | |
1999 | |
2000 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestManySurfaces) | |
2001 | |
2002 // A loseContext(1) should lead to a didRecreateOutputSurface(true) | |
2003 class CCLayerTreeHostTestSetSingleLostContext : public CCLayerTreeHostTest { | |
2004 public: | |
2005 CCLayerTreeHostTestSetSingleLostContext() | |
2006 { | |
2007 } | |
2008 | |
2009 virtual void beginTest() OVERRIDE | |
2010 { | |
2011 postSetNeedsCommitToMainThread(); | |
2012 } | |
2013 | |
2014 virtual void didCommitAndDrawFrame() OVERRIDE | |
2015 { | |
2016 m_layerTreeHost->loseContext(1); | |
2017 } | |
2018 | |
2019 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE | |
2020 { | |
2021 EXPECT_TRUE(succeeded); | |
2022 endTest(); | |
2023 } | |
2024 | |
2025 virtual void afterTest() OVERRIDE | |
2026 { | |
2027 } | |
2028 }; | |
2029 | |
2030 TEST_F(CCLayerTreeHostTestSetSingleLostContext, runMultiThread) | |
2031 { | |
2032 runTest(true); | |
2033 } | |
2034 | |
2035 // A loseContext(10) should lead to a didRecreateOutputSurface(false), and | |
2036 // a finishAllRendering() should not hang. | |
2037 class CCLayerTreeHostTestSetRepeatedLostContext : public CCLayerTreeHostTest { | |
2038 public: | |
2039 CCLayerTreeHostTestSetRepeatedLostContext() | |
2040 { | |
2041 } | |
2042 | |
2043 virtual void beginTest() OVERRIDE | |
2044 { | |
2045 postSetNeedsCommitToMainThread(); | |
2046 } | |
2047 | |
2048 virtual void didCommitAndDrawFrame() OVERRIDE | |
2049 { | |
2050 m_layerTreeHost->loseContext(10); | |
2051 } | |
2052 | |
2053 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE | |
2054 { | |
2055 EXPECT_FALSE(succeeded); | |
2056 m_layerTreeHost->finishAllRendering(); | |
2057 endTest(); | |
2058 } | |
2059 | |
2060 virtual void afterTest() OVERRIDE | |
2061 { | |
2062 } | |
2063 }; | |
2064 | |
2065 TEST_F(CCLayerTreeHostTestSetRepeatedLostContext, runMultiThread) | |
2066 { | |
2067 runTest(true); | |
2068 } | |
2069 | |
2070 class CCLayerTreeHostTestFractionalScroll : public CCLayerTreeHostTest { | |
2071 public: | |
2072 CCLayerTreeHostTestFractionalScroll() | |
2073 : m_scrollAmount(1.75, 0) | |
2074 { | |
2075 } | |
2076 | |
2077 virtual void beginTest() OVERRIDE | |
2078 { | |
2079 m_layerTreeHost->rootLayer()->setScrollable(true); | |
2080 postSetNeedsCommitToMainThread(); | |
2081 } | |
2082 | |
2083 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2084 { | |
2085 CCLayerImpl* root = impl->rootLayer(); | |
2086 root->setMaxScrollPosition(IntSize(100, 100)); | |
2087 | |
2088 // Check that a fractional scroll delta is correctly accumulated over mu
ltiple commits. | |
2089 if (!impl->sourceFrameNumber()) { | |
2090 EXPECT_EQ(root->scrollPosition(), IntPoint(0, 0)); | |
2091 EXPECT_EQ(root->scrollDelta(), FloatSize(0, 0)); | |
2092 postSetNeedsCommitToMainThread(); | |
2093 } else if (impl->sourceFrameNumber() == 1) { | |
2094 EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount)); | |
2095 EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(m_scrollAmount.width()
, 1), 0)); | |
2096 postSetNeedsCommitToMainThread(); | |
2097 } else if (impl->sourceFrameNumber() == 2) { | |
2098 EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount + m
_scrollAmount)); | |
2099 EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(2 * m_scrollAmount.wid
th(), 1), 0)); | |
2100 endTest(); | |
2101 } | |
2102 root->scrollBy(m_scrollAmount); | |
2103 } | |
2104 | |
2105 virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale) OV
ERRIDE | |
2106 { | |
2107 IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition(); | |
2108 m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta); | |
2109 } | |
2110 | |
2111 virtual void afterTest() OVERRIDE | |
2112 { | |
2113 } | |
2114 private: | |
2115 FloatSize m_scrollAmount; | |
2116 }; | |
2117 | |
2118 TEST_F(CCLayerTreeHostTestFractionalScroll, runMultiThread) | |
2119 { | |
2120 runTest(true); | |
2121 } | |
2122 | |
2123 class CCLayerTreeHostTestFinishAllRendering : public CCLayerTreeHostTest { | |
2124 public: | |
2125 CCLayerTreeHostTestFinishAllRendering() | |
2126 : m_once(false) | |
2127 , m_mutex() | |
2128 , m_drawCount(0) | |
2129 { | |
2130 } | |
2131 | |
2132 virtual void beginTest() OVERRIDE | |
2133 { | |
2134 m_layerTreeHost->setNeedsRedraw(); | |
2135 } | |
2136 | |
2137 virtual void didCommitAndDrawFrame() OVERRIDE | |
2138 { | |
2139 if (m_once) | |
2140 return; | |
2141 m_once = true; | |
2142 m_layerTreeHost->setNeedsRedraw(); | |
2143 m_layerTreeHost->acquireLayerTextures(); | |
2144 { | |
2145 Locker<Mutex> lock(m_mutex); | |
2146 m_drawCount = 0; | |
2147 } | |
2148 m_layerTreeHost->finishAllRendering(); | |
2149 { | |
2150 Locker<Mutex> lock(m_mutex); | |
2151 EXPECT_EQ(0, m_drawCount); | |
2152 } | |
2153 endTest(); | |
2154 } | |
2155 | |
2156 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2157 { | |
2158 Locker<Mutex> lock(m_mutex); | |
2159 ++m_drawCount; | |
2160 } | |
2161 | |
2162 virtual void afterTest() OVERRIDE | |
2163 { | |
2164 } | |
2165 private: | |
2166 | |
2167 bool m_once; | |
2168 Mutex m_mutex; | |
2169 int m_drawCount; | |
2170 }; | |
2171 | |
2172 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestFinishAllRendering) | |
2173 | |
2174 // Layers added to tree with existing active animations should have the animatio
n | |
2175 // correctly recognized. | |
2176 class CCLayerTreeHostTestLayerAddedWithAnimation : public CCLayerTreeHostTest { | |
2177 public: | |
2178 CCLayerTreeHostTestLayerAddedWithAnimation() | |
2179 : m_addedAnimation(false) | |
2180 { | |
2181 } | |
2182 | |
2183 virtual void beginTest() OVERRIDE | |
2184 { | |
2185 EXPECT_FALSE(m_addedAnimation); | |
2186 | |
2187 scoped_refptr<LayerChromium> layer = LayerChromium::create(); | |
2188 layer->setLayerAnimationDelegate(this); | |
2189 | |
2190 // Any valid CCAnimationCurve will do here. | |
2191 scoped_ptr<CCAnimationCurve> curve(CCEaseTimingFunction::create()); | |
2192 scoped_ptr<CCActiveAnimation> animation(CCActiveAnimation::create(curve.
Pass(), 1, 1, CCActiveAnimation::Opacity)); | |
2193 layer->layerAnimationController()->addAnimation(animation.Pass()); | |
2194 | |
2195 // We add the animation *before* attaching the layer to the tree. | |
2196 m_layerTreeHost->rootLayer()->addChild(layer); | |
2197 EXPECT_TRUE(m_addedAnimation); | |
2198 | |
2199 endTest(); | |
2200 } | |
2201 | |
2202 virtual void didAddAnimation() OVERRIDE | |
2203 { | |
2204 m_addedAnimation = true; | |
2205 } | |
2206 | |
2207 virtual void afterTest() OVERRIDE { } | |
2208 | |
2209 private: | |
2210 bool m_addedAnimation; | |
2211 }; | |
2212 | |
2213 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerAddedWithAnimation) | |
2214 | |
2215 class CCLayerTreeHostTestScrollChildLayer : public CCLayerTreeHostTest, public W
ebLayerScrollClient { | |
2216 public: | |
2217 CCLayerTreeHostTestScrollChildLayer() | |
2218 : m_scrollAmount(2, 1) | |
2219 { | |
2220 } | |
2221 | |
2222 virtual void beginTest() OVERRIDE | |
2223 { | |
2224 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
2225 m_layerTreeHost->rootLayer()->setBounds(IntSize(10, 10)); | |
2226 | |
2227 m_rootScrollLayer = ContentLayerChromium::create(&m_mockDelegate); | |
2228 m_rootScrollLayer->setBounds(IntSize(10, 10)); | |
2229 | |
2230 m_rootScrollLayer->setPosition(FloatPoint(0, 0)); | |
2231 m_rootScrollLayer->setAnchorPoint(FloatPoint(0, 0)); | |
2232 | |
2233 m_rootScrollLayer->setIsDrawable(true); | |
2234 m_rootScrollLayer->setScrollable(true); | |
2235 m_rootScrollLayer->setMaxScrollPosition(IntSize(100, 100)); | |
2236 m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer); | |
2237 m_childLayer = ContentLayerChromium::create(&m_mockDelegate); | |
2238 m_childLayer->setLayerScrollClient(this); | |
2239 m_childLayer->setBounds(IntSize(50, 50)); | |
2240 m_childLayer->setIsDrawable(true); | |
2241 m_childLayer->setScrollable(true); | |
2242 m_childLayer->setMaxScrollPosition(IntSize(100, 100)); | |
2243 | |
2244 m_childLayer->setPosition(FloatPoint(0, 0)); | |
2245 m_childLayer->setAnchorPoint(FloatPoint(0, 0)); | |
2246 | |
2247 m_rootScrollLayer->addChild(m_childLayer); | |
2248 postSetNeedsCommitToMainThread(); | |
2249 } | |
2250 | |
2251 virtual void didScroll() OVERRIDE | |
2252 { | |
2253 m_finalScrollPosition = m_childLayer->scrollPosition(); | |
2254 } | |
2255 | |
2256 virtual void applyScrollAndScale(const IntSize& scrollDelta, float) OVERRIDE | |
2257 { | |
2258 IntPoint position = m_rootScrollLayer->scrollPosition(); | |
2259 m_rootScrollLayer->setScrollPosition(position + scrollDelta); | |
2260 } | |
2261 | |
2262 virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2263 { | |
2264 EXPECT_EQ(m_rootScrollLayer->scrollPosition(), IntPoint()); | |
2265 if (!m_layerTreeHost->commitNumber()) | |
2266 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint()); | |
2267 else | |
2268 EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint() + m_scrollAmoun
t); | |
2269 } | |
2270 | |
2271 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2272 { | |
2273 if (impl->sourceAnimationFrameNumber() == 1) { | |
2274 EXPECT_EQ(impl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wh
eel), CCInputHandlerClient::ScrollStarted); | |
2275 impl->scrollBy(IntPoint(), m_scrollAmount); | |
2276 impl->scrollEnd(); | |
2277 } else if (impl->sourceAnimationFrameNumber() == 2) | |
2278 endTest(); | |
2279 } | |
2280 | |
2281 virtual void afterTest() OVERRIDE | |
2282 { | |
2283 EXPECT_EQ(IntPoint(m_scrollAmount), m_finalScrollPosition); | |
2284 } | |
2285 | |
2286 private: | |
2287 const IntSize m_scrollAmount; | |
2288 IntPoint m_finalScrollPosition; | |
2289 MockContentLayerChromiumClient m_mockDelegate; | |
2290 scoped_refptr<LayerChromium> m_childLayer; | |
2291 scoped_refptr<LayerChromium> m_rootScrollLayer; | |
2292 }; | |
2293 | |
2294 TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread) | |
2295 { | |
2296 runTest(true); | |
2297 } | |
2298 | |
2299 class CCLayerTreeHostTestCompositeAndReadbackCleanup : public CCLayerTreeHostTes
t { | |
2300 public: | |
2301 CCLayerTreeHostTestCompositeAndReadbackCleanup() { } | |
2302 | |
2303 virtual void beginTest() OVERRIDE | |
2304 { | |
2305 LayerChromium* rootLayer = m_layerTreeHost->rootLayer(); | |
2306 | |
2307 OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4])); | |
2308 m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()),
IntRect(0, 0, 1, 1)); | |
2309 EXPECT_FALSE(rootLayer->renderSurface()); | |
2310 | |
2311 endTest(); | |
2312 } | |
2313 | |
2314 virtual void afterTest() OVERRIDE | |
2315 { | |
2316 } | |
2317 }; | |
2318 | |
2319 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCompositeAndReadbackCleanup) | |
2320 | |
2321 class CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public
CCLayerTreeHostTest { | |
2322 public: | |
2323 CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit() | |
2324 : m_rootLayer(ContentLayerChromiumWithUpdateTracking::create(&m_mockDele
gate)) | |
2325 , m_surfaceLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mock
Delegate)) | |
2326 , m_replicaLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mock
Delegate)) | |
2327 , m_surfaceLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mock
Delegate)) | |
2328 , m_replicaLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mock
Delegate)) | |
2329 { | |
2330 } | |
2331 | |
2332 virtual void beginTest() OVERRIDE | |
2333 { | |
2334 m_layerTreeHost->setViewportSize(IntSize(100, 100), IntSize(100, 100)); | |
2335 | |
2336 m_rootLayer->setBounds(IntSize(100, 100)); | |
2337 m_surfaceLayer1->setBounds(IntSize(100, 100)); | |
2338 m_surfaceLayer1->setForceRenderSurface(true); | |
2339 m_surfaceLayer1->setOpacity(0.5); | |
2340 m_surfaceLayer2->setBounds(IntSize(100, 100)); | |
2341 m_surfaceLayer2->setForceRenderSurface(true); | |
2342 m_surfaceLayer2->setOpacity(0.5); | |
2343 | |
2344 m_surfaceLayer1->setReplicaLayer(m_replicaLayer1.get()); | |
2345 m_surfaceLayer2->setReplicaLayer(m_replicaLayer2.get()); | |
2346 | |
2347 m_rootLayer->addChild(m_surfaceLayer1); | |
2348 m_surfaceLayer1->addChild(m_surfaceLayer2); | |
2349 m_layerTreeHost->setRootLayer(m_rootLayer); | |
2350 } | |
2351 | |
2352 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* hostImpl) OVERRIDE | |
2353 { | |
2354 CCRenderer* renderer = hostImpl->renderer(); | |
2355 CCRenderPass::Id surface1RenderPassId = hostImpl->rootLayer()->children(
)[0]->renderSurface()->renderPassId(); | |
2356 CCRenderPass::Id surface2RenderPassId = hostImpl->rootLayer()->children(
)[0]->children()[0]->renderSurface()->renderPassId(); | |
2357 | |
2358 switch (hostImpl->sourceFrameNumber()) { | |
2359 case 0: | |
2360 EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface1Ren
derPassId)); | |
2361 EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface2Ren
derPassId)); | |
2362 | |
2363 // Reduce the memory limit to only fit the root layer and one render
surface. This | |
2364 // prevents any contents drawing into surfaces from being allocated. | |
2365 hostImpl->setMemoryAllocationLimitBytes(100 * 100 * 4 * 2); | |
2366 break; | |
2367 case 1: | |
2368 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface1Re
nderPassId)); | |
2369 EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface2Re
nderPassId)); | |
2370 | |
2371 endTest(); | |
2372 break; | |
2373 } | |
2374 } | |
2375 | |
2376 virtual void afterTest() OVERRIDE | |
2377 { | |
2378 EXPECT_EQ(2, m_rootLayer->paintContentsCount()); | |
2379 EXPECT_EQ(2, m_surfaceLayer1->paintContentsCount()); | |
2380 EXPECT_EQ(2, m_surfaceLayer2->paintContentsCount()); | |
2381 | |
2382 // Clear layer references so CCLayerTreeHost dies. | |
2383 m_rootLayer = NULL; | |
2384 m_surfaceLayer1 = NULL; | |
2385 m_replicaLayer1 = NULL; | |
2386 m_surfaceLayer2 = NULL; | |
2387 m_replicaLayer2 = NULL; | |
2388 } | |
2389 | |
2390 private: | |
2391 MockContentLayerChromiumClient m_mockDelegate; | |
2392 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_rootLayer; | |
2393 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer1; | |
2394 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer1; | |
2395 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer2; | |
2396 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer2; | |
2397 }; | |
2398 | |
2399 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSurfaceNotAllocatedForLayersOu
tsideMemoryLimit) | |
2400 | |
2401 | |
2402 class EvictionTrackingTexture : public LayerTextureUpdater::Texture { | |
2403 public: | |
2404 static PassOwnPtr<EvictionTrackingTexture> create(scoped_ptr<CCPrioritizedTe
xture> texture) { return adoptPtr(new EvictionTrackingTexture(texture.Pass()));
} | |
2405 virtual ~EvictionTrackingTexture() { } | |
2406 | |
2407 virtual void updateRect(CCResourceProvider* resourceProvider, const IntRect&
, const IntSize&) OVERRIDE | |
2408 { | |
2409 ASSERT_TRUE(!texture()->haveBackingTexture() || resourceProvider->numRes
ources() > 0); | |
2410 texture()->acquireBackingTexture(resourceProvider); | |
2411 m_updated = true; | |
2412 } | |
2413 void resetUpdated() { m_updated = false; } | |
2414 bool updated() const { return m_updated; } | |
2415 | |
2416 private: | |
2417 explicit EvictionTrackingTexture(scoped_ptr<CCPrioritizedTexture> texture) | |
2418 : LayerTextureUpdater::Texture(texture.Pass()) | |
2419 , m_updated(false) | |
2420 { } | |
2421 bool m_updated; | |
2422 }; | |
2423 | |
2424 class EvictionTestLayer : public LayerChromium { | |
2425 public: | |
2426 static scoped_refptr<EvictionTestLayer> create() { return make_scoped_refptr
(new EvictionTestLayer()); } | |
2427 | |
2428 virtual void update(CCTextureUpdateQueue&, const CCOcclusionTracker*, CCRend
eringStats&) OVERRIDE; | |
2429 virtual bool drawsContent() const OVERRIDE { return true; } | |
2430 | |
2431 virtual scoped_ptr<CCLayerImpl> createCCLayerImpl() OVERRIDE; | |
2432 virtual void pushPropertiesTo(CCLayerImpl*) OVERRIDE; | |
2433 virtual void setTexturePriorities(const CCPriorityCalculator&) OVERRIDE; | |
2434 | |
2435 void resetUpdated() | |
2436 { | |
2437 if (m_texture.get()) | |
2438 m_texture->resetUpdated(); | |
2439 } | |
2440 bool updated() const { return m_texture.get() ? m_texture->updated() : false
; } | |
2441 | |
2442 private: | |
2443 EvictionTestLayer() : LayerChromium() { } | |
2444 virtual ~EvictionTestLayer() { } | |
2445 | |
2446 void createTextureIfNeeded() | |
2447 { | |
2448 if (m_texture.get()) | |
2449 return; | |
2450 m_texture = EvictionTrackingTexture::create(CCPrioritizedTexture::create
(layerTreeHost()->contentsTextureManager())); | |
2451 m_texture->texture()->setDimensions(IntSize(10, 10), cc::GraphicsContext
3D::RGBA); | |
2452 } | |
2453 | |
2454 OwnPtr<EvictionTrackingTexture> m_texture; | |
2455 }; | |
2456 | |
2457 class EvictionTestLayerImpl : public CCLayerImpl { | |
2458 public: | |
2459 static scoped_ptr<EvictionTestLayerImpl> create(int id) | |
2460 { | |
2461 return make_scoped_ptr(new EvictionTestLayerImpl(id)); | |
2462 } | |
2463 virtual ~EvictionTestLayerImpl() { } | |
2464 | |
2465 virtual void appendQuads(CCQuadSink& quadSink, CCAppendQuadsData&) OVERRIDE | |
2466 { | |
2467 ASSERT_TRUE(m_hasTexture); | |
2468 ASSERT_NE(0u, layerTreeHostImpl()->resourceProvider()->numResources()); | |
2469 } | |
2470 | |
2471 void setHasTexture(bool hasTexture) { m_hasTexture = hasTexture; } | |
2472 | |
2473 private: | |
2474 explicit EvictionTestLayerImpl(int id) | |
2475 : CCLayerImpl(id) | |
2476 , m_hasTexture(false) { } | |
2477 | |
2478 bool m_hasTexture; | |
2479 }; | |
2480 | |
2481 void EvictionTestLayer::setTexturePriorities(const CCPriorityCalculator&) | |
2482 { | |
2483 createTextureIfNeeded(); | |
2484 if (!m_texture.get()) | |
2485 return; | |
2486 m_texture->texture()->setRequestPriority(CCPriorityCalculator::uiPriority(tr
ue)); | |
2487 } | |
2488 | |
2489 void EvictionTestLayer::update(CCTextureUpdateQueue& queue, const CCOcclusionTra
cker*, CCRenderingStats&) | |
2490 { | |
2491 createTextureIfNeeded(); | |
2492 if (!m_texture.get()) | |
2493 return; | |
2494 IntRect fullRect(0, 0, 10, 10); | |
2495 TextureUploader::Parameters parameters = { m_texture.get(), fullRect, IntSiz
e() }; | |
2496 queue.appendFullUpload(parameters); | |
2497 } | |
2498 | |
2499 scoped_ptr<CCLayerImpl> EvictionTestLayer::createCCLayerImpl() | |
2500 { | |
2501 return EvictionTestLayerImpl::create(m_layerId).PassAs<CCLayerImpl>(); | |
2502 } | |
2503 | |
2504 void EvictionTestLayer::pushPropertiesTo(CCLayerImpl* layerImpl) | |
2505 { | |
2506 LayerChromium::pushPropertiesTo(layerImpl); | |
2507 | |
2508 EvictionTestLayerImpl* testLayerImpl = static_cast<EvictionTestLayerImpl*>(l
ayerImpl); | |
2509 testLayerImpl->setHasTexture(m_texture->texture()->haveBackingTexture()); | |
2510 } | |
2511 | |
2512 class CCLayerTreeHostTestEvictTextures : public CCLayerTreeHostTest { | |
2513 public: | |
2514 CCLayerTreeHostTestEvictTextures() | |
2515 : m_layer(EvictionTestLayer::create()) | |
2516 , m_implForEvictTextures(0) | |
2517 , m_numCommits(0) | |
2518 { | |
2519 } | |
2520 | |
2521 virtual void beginTest() OVERRIDE | |
2522 { | |
2523 m_layerTreeHost->setRootLayer(m_layer); | |
2524 m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20)); | |
2525 | |
2526 WebTransformationMatrix identityMatrix; | |
2527 setLayerPropertiesForTesting(m_layer.get(), 0, identityMatrix, FloatPoin
t(0, 0), FloatPoint(0, 0), IntSize(10, 20), true); | |
2528 } | |
2529 | |
2530 class EvictTexturesTask : public WebKit::WebThread::Task { | |
2531 public: | |
2532 EvictTexturesTask(CCLayerTreeHostTestEvictTextures* test) : m_test(test)
{ } | |
2533 virtual ~EvictTexturesTask() { } | |
2534 virtual void run() OVERRIDE | |
2535 { | |
2536 ASSERT(m_test->m_implForEvictTextures); | |
2537 m_test->m_implForEvictTextures->releaseContentsTextures(); | |
2538 } | |
2539 | |
2540 private: | |
2541 CCLayerTreeHostTestEvictTextures* m_test; | |
2542 }; | |
2543 | |
2544 void postEvictTextures() | |
2545 { | |
2546 ASSERT(webThread()); | |
2547 webThread()->postTask(new EvictTexturesTask(this)); | |
2548 } | |
2549 | |
2550 // Commit 1: Just commit and draw normally, then post an eviction at the end | |
2551 // that will trigger a commit. | |
2552 // Commit 2: Triggered by the eviction, let it go through and then set | |
2553 // needsCommit. | |
2554 // Commit 3: Triggered by the setNeedsCommit. In layout(), post an eviction | |
2555 // task, which will be handled before the commit. Don't set needsCommit, it | |
2556 // should have been posted. A frame should not be drawn (note, | |
2557 // didCommitAndDrawFrame may be called anyway). | |
2558 // Commit 4: Triggered by the eviction, let it go through and then set | |
2559 // needsCommit. | |
2560 // Commit 5: Triggered by the setNeedsCommit, post an eviction task in | |
2561 // layout(), a frame should not be drawn but a commit will be posted. | |
2562 // Commit 6: Triggered by the eviction, post an eviction task in | |
2563 // layout(), which will be a noop, letting the commit (which recreates the | |
2564 // textures) go through and draw a frame, then end the test. | |
2565 // | |
2566 // Commits 1+2 test the eviction recovery path where eviction happens outsid
e | |
2567 // of the beginFrame/commit pair. | |
2568 // Commits 3+4 test the eviction recovery path where eviction happens inside | |
2569 // the beginFrame/commit pair. | |
2570 // Commits 5+6 test the path where an eviction happens during the eviction | |
2571 // recovery path. | |
2572 virtual void didCommitAndDrawFrame() OVERRIDE | |
2573 { | |
2574 switch (m_numCommits) { | |
2575 case 1: | |
2576 EXPECT_TRUE(m_layer->updated()); | |
2577 postEvictTextures(); | |
2578 break; | |
2579 case 2: | |
2580 EXPECT_TRUE(m_layer->updated()); | |
2581 m_layerTreeHost->setNeedsCommit(); | |
2582 break; | |
2583 case 3: | |
2584 break; | |
2585 case 4: | |
2586 EXPECT_TRUE(m_layer->updated()); | |
2587 m_layerTreeHost->setNeedsCommit(); | |
2588 break; | |
2589 case 5: | |
2590 break; | |
2591 case 6: | |
2592 EXPECT_TRUE(m_layer->updated()); | |
2593 endTest(); | |
2594 break; | |
2595 default: | |
2596 ASSERT_NOT_REACHED(); | |
2597 break; | |
2598 } | |
2599 } | |
2600 | |
2601 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2602 { | |
2603 m_implForEvictTextures = impl; | |
2604 } | |
2605 | |
2606 virtual void layout() OVERRIDE | |
2607 { | |
2608 ++m_numCommits; | |
2609 switch (m_numCommits) { | |
2610 case 1: | |
2611 case 2: | |
2612 break; | |
2613 case 3: | |
2614 postEvictTextures(); | |
2615 break; | |
2616 case 4: | |
2617 // We couldn't check in didCommitAndDrawFrame on commit 3, so check
here. | |
2618 EXPECT_FALSE(m_layer->updated()); | |
2619 break; | |
2620 case 5: | |
2621 postEvictTextures(); | |
2622 break; | |
2623 case 6: | |
2624 // We couldn't check in didCommitAndDrawFrame on commit 5, so check
here. | |
2625 EXPECT_FALSE(m_layer->updated()); | |
2626 postEvictTextures(); | |
2627 break; | |
2628 default: | |
2629 ASSERT_NOT_REACHED(); | |
2630 break; | |
2631 } | |
2632 m_layer->resetUpdated(); | |
2633 } | |
2634 | |
2635 virtual void afterTest() OVERRIDE | |
2636 { | |
2637 } | |
2638 | |
2639 private: | |
2640 MockContentLayerChromiumClient m_client; | |
2641 scoped_refptr<EvictionTestLayer> m_layer; | |
2642 CCLayerTreeHostImpl* m_implForEvictTextures; | |
2643 int m_numCommits; | |
2644 }; | |
2645 | |
2646 TEST_F(CCLayerTreeHostTestEvictTextures, runMultiThread) | |
2647 { | |
2648 runTest(true); | |
2649 } | |
2650 | |
2651 class CCLayerTreeHostTestLostContextAfterEvictTextures : public CCLayerTreeHostT
est { | |
2652 public: | |
2653 CCLayerTreeHostTestLostContextAfterEvictTextures() | |
2654 : m_layer(EvictionTestLayer::create()) | |
2655 , m_implForEvictTextures(0) | |
2656 , m_numCommits(0) | |
2657 { | |
2658 } | |
2659 | |
2660 virtual void beginTest() OVERRIDE | |
2661 { | |
2662 m_layerTreeHost->setRootLayer(m_layer); | |
2663 m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20)); | |
2664 | |
2665 WebTransformationMatrix identityMatrix; | |
2666 setLayerPropertiesForTesting(m_layer.get(), 0, identityMatrix, FloatPoin
t(0, 0), FloatPoint(0, 0), IntSize(10, 20), true); | |
2667 } | |
2668 | |
2669 class EvictTexturesTask : public WebKit::WebThread::Task { | |
2670 public: | |
2671 EvictTexturesTask(CCLayerTreeHostTestLostContextAfterEvictTextures* test
) : m_test(test) { } | |
2672 virtual ~EvictTexturesTask() { } | |
2673 virtual void run() OVERRIDE | |
2674 { | |
2675 m_test->evictTexturesOnImplThread(); | |
2676 } | |
2677 | |
2678 private: | |
2679 CCLayerTreeHostTestLostContextAfterEvictTextures* m_test; | |
2680 }; | |
2681 | |
2682 void postEvictTextures() | |
2683 { | |
2684 if (webThread()) | |
2685 webThread()->postTask(new EvictTexturesTask(this)); | |
2686 else { | |
2687 DebugScopedSetImplThread impl; | |
2688 evictTexturesOnImplThread(); | |
2689 } | |
2690 } | |
2691 | |
2692 void evictTexturesOnImplThread() | |
2693 { | |
2694 ASSERT(m_implForEvictTextures); | |
2695 m_implForEvictTextures->releaseContentsTextures(); | |
2696 } | |
2697 | |
2698 // Commit 1: Just commit and draw normally, then at the end, set ourselves | |
2699 // invisible (to prevent a commit that would recreate textures after | |
2700 // eviction, before the context recovery), and post a task that will evict | |
2701 // textures, then cause the context to be lost, and then set ourselves | |
2702 // visible again (to allow commits, since that's what causes context | |
2703 // recovery in single thread). | |
2704 virtual void didCommitAndDrawFrame() OVERRIDE | |
2705 { | |
2706 ++m_numCommits; | |
2707 switch (m_numCommits) { | |
2708 case 1: | |
2709 EXPECT_TRUE(m_layer->updated()); | |
2710 m_layerTreeHost->setVisible(false); | |
2711 postEvictTextures(); | |
2712 m_layerTreeHost->loseContext(1); | |
2713 m_layerTreeHost->setVisible(true); | |
2714 break; | |
2715 default: | |
2716 break; | |
2717 } | |
2718 } | |
2719 | |
2720 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2721 { | |
2722 m_implForEvictTextures = impl; | |
2723 } | |
2724 | |
2725 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE | |
2726 { | |
2727 EXPECT_TRUE(succeeded); | |
2728 endTest(); | |
2729 } | |
2730 | |
2731 virtual void afterTest() OVERRIDE | |
2732 { | |
2733 } | |
2734 | |
2735 private: | |
2736 MockContentLayerChromiumClient m_client; | |
2737 scoped_refptr<EvictionTestLayer> m_layer; | |
2738 CCLayerTreeHostImpl* m_implForEvictTextures; | |
2739 int m_numCommits; | |
2740 }; | |
2741 | |
2742 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLostContextAfterEvictTextures) | |
2743 | |
2744 class CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext : public
WebKit::CompositorFakeWebGraphicsContext3D { | |
2745 public: | |
2746 static PassOwnPtr<CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostC
ontext> create(Attributes attrs) | |
2747 { | |
2748 return adoptPtr(new CompositorFakeWebGraphicsContext3DWithEndQueryCausin
gLostContext(attrs)); | |
2749 } | |
2750 | |
2751 virtual void setContextLostCallback(WebGraphicsContextLostCallback* callback
) { m_contextLostCallback = callback; } | |
2752 virtual bool isContextLost() { return m_isContextLost; } | |
2753 | |
2754 virtual void beginQueryEXT(GC3Denum, WebGLId) { } | |
2755 virtual void endQueryEXT(GC3Denum) | |
2756 { | |
2757 // Lose context. | |
2758 if (!m_isContextLost) { | |
2759 m_contextLostCallback->onContextLost(); | |
2760 m_isContextLost = true; | |
2761 } | |
2762 } | |
2763 virtual void getQueryObjectuivEXT(WebGLId, GC3Denum pname, GC3Duint* params) | |
2764 { | |
2765 // Context is lost. We need to behave as if result is available. | |
2766 if (pname == Extensions3DChromium::QUERY_RESULT_AVAILABLE_EXT) | |
2767 *params = 1; | |
2768 } | |
2769 | |
2770 private: | |
2771 explicit CompositorFakeWebGraphicsContext3DWithEndQueryCausingLostContext(At
tributes attrs) | |
2772 : CompositorFakeWebGraphicsContext3D(attrs) | |
2773 , m_contextLostCallback(0) | |
2774 , m_isContextLost(false) { } | |
2775 | |
2776 WebGraphicsContextLostCallback* m_contextLostCallback; | |
2777 bool m_isContextLost; | |
2778 }; | |
2779 | |
2780 class CCLayerTreeHostTestLostContextWhileUpdatingResources : public CCLayerTreeH
ostTest { | |
2781 public: | |
2782 CCLayerTreeHostTestLostContextWhileUpdatingResources() | |
2783 : m_parent(ContentLayerChromiumWithUpdateTracking::create(&m_client)) | |
2784 , m_numChildren(50) | |
2785 { | |
2786 for (int i = 0; i < m_numChildren; i++) | |
2787 m_children.push_back(ContentLayerChromiumWithUpdateTracking::create(
&m_client)); | |
2788 } | |
2789 | |
2790 virtual scoped_ptr<WebKit::WebCompositorOutputSurface> createOutputSurface() | |
2791 { | |
2792 return FakeWebCompositorOutputSurface::create(CompositorFakeWebGraphicsC
ontext3DWithEndQueryCausingLostContext::create(WebGraphicsContext3D::Attributes(
))).PassAs<WebKit::WebCompositorOutputSurface>(); | |
2793 } | |
2794 | |
2795 virtual void beginTest() | |
2796 { | |
2797 m_layerTreeHost->setRootLayer(m_parent); | |
2798 m_layerTreeHost->setViewportSize(IntSize(m_numChildren, 1), IntSize(m_nu
mChildren, 1)); | |
2799 | |
2800 WebTransformationMatrix identityMatrix; | |
2801 setLayerPropertiesForTesting(m_parent.get(), 0, identityMatrix, FloatPoi
nt(0, 0), FloatPoint(0, 0), IntSize(m_numChildren, 1), true); | |
2802 for (int i = 0; i < m_numChildren; i++) | |
2803 setLayerPropertiesForTesting(m_children[i].get(), m_parent.get(), id
entityMatrix, FloatPoint(0, 0), FloatPoint(i, 0), IntSize(1, 1), false); | |
2804 | |
2805 postSetNeedsCommitToMainThread(); | |
2806 } | |
2807 | |
2808 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl) | |
2809 { | |
2810 endTest(); | |
2811 } | |
2812 | |
2813 virtual void layout() | |
2814 { | |
2815 m_parent->setNeedsDisplay(); | |
2816 for (int i = 0; i < m_numChildren; i++) | |
2817 m_children[i]->setNeedsDisplay(); | |
2818 } | |
2819 | |
2820 virtual void afterTest() | |
2821 { | |
2822 } | |
2823 | |
2824 private: | |
2825 MockContentLayerChromiumClient m_client; | |
2826 scoped_refptr<ContentLayerChromiumWithUpdateTracking> m_parent; | |
2827 int m_numChildren; | |
2828 std::vector<scoped_refptr<ContentLayerChromiumWithUpdateTracking> > m_childr
en; | |
2829 }; | |
2830 | |
2831 TEST_F(CCLayerTreeHostTestLostContextWhileUpdatingResources, runMultiThread) | |
2832 { | |
2833 runTest(true); | |
2834 } | |
2835 | |
2836 class CCLayerTreeHostTestContinuousCommit : public CCLayerTreeHostTest { | |
2837 public: | |
2838 CCLayerTreeHostTestContinuousCommit() | |
2839 : m_numCommitComplete(0) | |
2840 , m_numDrawLayers(0) | |
2841 { | |
2842 } | |
2843 | |
2844 virtual void beginTest() OVERRIDE | |
2845 { | |
2846 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
2847 m_layerTreeHost->rootLayer()->setBounds(IntSize(10, 10)); | |
2848 | |
2849 postSetNeedsCommitToMainThread(); | |
2850 } | |
2851 | |
2852 virtual void didCommit() OVERRIDE | |
2853 { | |
2854 postSetNeedsCommitToMainThread(); | |
2855 } | |
2856 | |
2857 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
2858 { | |
2859 if (m_numDrawLayers == 1) | |
2860 m_numCommitComplete++; | |
2861 } | |
2862 | |
2863 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2864 { | |
2865 m_numDrawLayers++; | |
2866 if (m_numDrawLayers == 2) | |
2867 endTest(); | |
2868 } | |
2869 | |
2870 virtual void afterTest() OVERRIDE | |
2871 { | |
2872 // Check that we didn't commit twice between first and second draw. | |
2873 EXPECT_EQ(1, m_numCommitComplete); | |
2874 } | |
2875 | |
2876 private: | |
2877 int m_numCommitComplete; | |
2878 int m_numDrawLayers; | |
2879 }; | |
2880 | |
2881 TEST_F(CCLayerTreeHostTestContinuousCommit, runMultiThread) | |
2882 { | |
2883 runTest(true); | |
2884 } | |
2885 | |
2886 class CCLayerTreeHostTestContinuousInvalidate : public CCLayerTreeHostTest { | |
2887 public: | |
2888 CCLayerTreeHostTestContinuousInvalidate() | |
2889 : m_numCommitComplete(0) | |
2890 , m_numDrawLayers(0) | |
2891 { | |
2892 } | |
2893 | |
2894 virtual void beginTest() OVERRIDE | |
2895 { | |
2896 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
2897 m_layerTreeHost->rootLayer()->setBounds(IntSize(10, 10)); | |
2898 | |
2899 m_contentLayer = ContentLayerChromium::create(&m_mockDelegate); | |
2900 m_contentLayer->setBounds(IntSize(10, 10)); | |
2901 m_contentLayer->setPosition(FloatPoint(0, 0)); | |
2902 m_contentLayer->setAnchorPoint(FloatPoint(0, 0)); | |
2903 m_contentLayer->setIsDrawable(true); | |
2904 m_layerTreeHost->rootLayer()->addChild(m_contentLayer); | |
2905 | |
2906 postSetNeedsCommitToMainThread(); | |
2907 } | |
2908 | |
2909 virtual void didCommit() OVERRIDE | |
2910 { | |
2911 m_contentLayer->setNeedsDisplay(); | |
2912 } | |
2913 | |
2914 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
2915 { | |
2916 if (m_numDrawLayers == 1) | |
2917 m_numCommitComplete++; | |
2918 } | |
2919 | |
2920 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2921 { | |
2922 m_numDrawLayers++; | |
2923 if (m_numDrawLayers == 2) | |
2924 endTest(); | |
2925 } | |
2926 | |
2927 virtual void afterTest() OVERRIDE | |
2928 { | |
2929 // Check that we didn't commit twice between first and second draw. | |
2930 EXPECT_EQ(1, m_numCommitComplete); | |
2931 | |
2932 // Clear layer references so CCLayerTreeHost dies. | |
2933 m_contentLayer = NULL; | |
2934 } | |
2935 | |
2936 private: | |
2937 MockContentLayerChromiumClient m_mockDelegate; | |
2938 scoped_refptr<LayerChromium> m_contentLayer; | |
2939 int m_numCommitComplete; | |
2940 int m_numDrawLayers; | |
2941 }; | |
2942 | |
2943 TEST_F(CCLayerTreeHostTestContinuousInvalidate, runMultiThread) | |
2944 { | |
2945 runTest(true); | |
2946 } | |
2947 | |
2948 class CCLayerTreeHostTestContinuousAnimate : public CCLayerTreeHostTest { | |
2949 public: | |
2950 CCLayerTreeHostTestContinuousAnimate() | |
2951 : m_numCommitComplete(0) | |
2952 , m_numDrawLayers(0) | |
2953 { | |
2954 } | |
2955 | |
2956 virtual void beginTest() OVERRIDE | |
2957 { | |
2958 m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10)); | |
2959 m_layerTreeHost->rootLayer()->setBounds(IntSize(10, 10)); | |
2960 | |
2961 postSetNeedsCommitToMainThread(); | |
2962 } | |
2963 | |
2964 virtual void animate(double) OVERRIDE | |
2965 { | |
2966 m_layerTreeHost->setNeedsAnimate(); | |
2967 } | |
2968 | |
2969 virtual void layout() OVERRIDE | |
2970 { | |
2971 m_layerTreeHost->rootLayer()->setNeedsDisplay(); | |
2972 } | |
2973 | |
2974 virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) OVERRIDE | |
2975 { | |
2976 if (m_numDrawLayers == 1) | |
2977 m_numCommitComplete++; | |
2978 } | |
2979 | |
2980 virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE | |
2981 { | |
2982 m_numDrawLayers++; | |
2983 if (m_numDrawLayers == 2) | |
2984 endTest(); | |
2985 } | |
2986 | |
2987 virtual void afterTest() OVERRIDE | |
2988 { | |
2989 // Check that we didn't commit twice between first and second draw. | |
2990 EXPECT_EQ(1, m_numCommitComplete); | |
2991 } | |
2992 | |
2993 private: | |
2994 int m_numCommitComplete; | |
2995 int m_numDrawLayers; | |
2996 }; | |
2997 | |
2998 TEST_F(CCLayerTreeHostTestContinuousAnimate, runMultiThread) | |
2999 { | |
3000 runTest(true); | |
3001 } | |
3002 | |
3003 } // namespace | |
OLD | NEW |