Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: cc/CCLayerTreeHostTest.cpp

Issue 11108020: [cc] Change cc_tests.gyp filenames to Chromium style (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/CCLayerTreeHostImplTest.cpp ('k') | cc/CCMathUtilTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « cc/CCLayerTreeHostImplTest.cpp ('k') | cc/CCMathUtilTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698