d671c938f489a73f269342fe2c3a33243b3203e7
[WebKit-https.git] / Source / WebKit / chromium / tests / CCLayerTreeHostTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCLayerTreeHost.h"
28
29 #include "AnimationIdVendor.h"
30 #include "CCOcclusionTrackerTestCommon.h"
31 #include "CCThreadedTest.h"
32 #include "ContentLayerChromium.h"
33 #include "GraphicsContext3DPrivate.h"
34 #include "cc/CCGraphicsContext.h"
35 #include "cc/CCLayerTreeHostImpl.h"
36 #include "cc/CCSettings.h"
37 #include "cc/CCTextureUpdateQueue.h"
38 #include "cc/CCTimingFunction.h"
39 #include "platform/WebThread.h"
40 #include <gmock/gmock.h>
41 #include <gtest/gtest.h>
42 #include <public/Platform.h>
43 #include <wtf/MainThread.h>
44 #include <wtf/OwnArrayPtr.h>
45
46 using namespace WebCore;
47 using namespace WebKit;
48 using namespace WebKitTests;
49 using namespace WTF;
50
51 #define EXPECT_EQ_RECT(a, b) \
52     EXPECT_EQ(a.x(), b.x()); \
53     EXPECT_EQ(a.y(), b.y()); \
54     EXPECT_EQ(a.width(), b.width()); \
55     EXPECT_EQ(a.height(), b.height());
56
57 namespace {
58
59 class CCLayerTreeHostTest : public CCThreadedTest { };
60
61 // Shortlived layerTreeHosts shouldn't die.
62 class CCLayerTreeHostTestShortlived1 : public CCLayerTreeHostTest {
63 public:
64     CCLayerTreeHostTestShortlived1() { }
65
66     virtual void beginTest()
67     {
68         // Kill the layerTreeHost immediately.
69         m_layerTreeHost->setRootLayer(0);
70         m_layerTreeHost.clear();
71
72         endTest();
73     }
74
75     virtual void afterTest()
76     {
77     }
78 };
79
80 // Shortlived layerTreeHosts shouldn't die with a commit in flight.
81 class CCLayerTreeHostTestShortlived2 : public CCLayerTreeHostTest {
82 public:
83     CCLayerTreeHostTestShortlived2() { }
84
85     virtual void beginTest()
86     {
87         postSetNeedsCommitToMainThread();
88
89         // Kill the layerTreeHost immediately.
90         m_layerTreeHost->setRootLayer(0);
91         m_layerTreeHost.clear();
92
93         endTest();
94     }
95
96     virtual void afterTest()
97     {
98     }
99 };
100
101 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestShortlived2)
102
103 // Shortlived layerTreeHosts shouldn't die with a redraw in flight.
104 class CCLayerTreeHostTestShortlived3 : public CCLayerTreeHostTest {
105 public:
106     CCLayerTreeHostTestShortlived3() { }
107
108     virtual void beginTest()
109     {
110         postSetNeedsRedrawToMainThread();
111
112         // Kill the layerTreeHost immediately.
113         m_layerTreeHost->setRootLayer(0);
114         m_layerTreeHost.clear();
115
116         endTest();
117     }
118
119     virtual void afterTest()
120     {
121     }
122 };
123
124 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestShortlived3)
125
126 // Test interleaving of redraws and commits
127 class CCLayerTreeHostTestCommitingWithContinuousRedraw : public CCLayerTreeHostTest {
128 public:
129     CCLayerTreeHostTestCommitingWithContinuousRedraw()
130         : m_numCompleteCommits(0)
131         , m_numDraws(0)
132     {
133     }
134
135     virtual void beginTest()
136     {
137         postSetNeedsCommitToMainThread();
138     }
139
140     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
141     {
142         m_numCompleteCommits++;
143         if (m_numCompleteCommits == 2)
144             endTest();
145     }
146
147     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*)
148     {
149         if (m_numDraws == 1)
150           postSetNeedsCommitToMainThread();
151         m_numDraws++;
152         postSetNeedsRedrawToMainThread();
153     }
154
155     virtual void afterTest()
156     {
157     }
158
159 private:
160     int m_numCompleteCommits;
161     int m_numDraws;
162 };
163
164 TEST_F(CCLayerTreeHostTestCommitingWithContinuousRedraw, runMultiThread)
165 {
166     runTest(true);
167 }
168
169 // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1
170 // draw with frame 0.
171 class CCLayerTreeHostTestSetNeedsCommit1 : public CCLayerTreeHostTest {
172 public:
173     CCLayerTreeHostTestSetNeedsCommit1()
174         : m_numCommits(0)
175         , m_numDraws(0)
176     {
177     }
178
179     virtual void beginTest()
180     {
181         postSetNeedsCommitToMainThread();
182         postSetNeedsCommitToMainThread();
183     }
184
185     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
186     {
187         m_numDraws++;
188         if (!impl->sourceFrameNumber())
189             endTest();
190     }
191
192     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
193     {
194         m_numCommits++;
195     }
196
197     virtual void afterTest()
198     {
199         EXPECT_GE(1, m_numCommits);
200         EXPECT_GE(1, m_numDraws);
201     }
202
203 private:
204     int m_numCommits;
205     int m_numDraws;
206 };
207
208 TEST_F(CCLayerTreeHostTestSetNeedsCommit1, DISABLED_runMultiThread)
209 {
210     runTest(true);
211 }
212
213 // A setNeedsCommit should lead to 1 commit. Issuing a second commit after that
214 // first committed frame draws should lead to another commit.
215 class CCLayerTreeHostTestSetNeedsCommit2 : public CCLayerTreeHostTest {
216 public:
217     CCLayerTreeHostTestSetNeedsCommit2()
218         : m_numCommits(0)
219         , m_numDraws(0)
220     {
221     }
222
223     virtual void beginTest()
224     {
225         postSetNeedsCommitToMainThread();
226     }
227
228     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
229     {
230         if (!impl->sourceFrameNumber())
231             postSetNeedsCommitToMainThread();
232         else if (impl->sourceFrameNumber() == 1)
233             endTest();
234     }
235
236     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
237     {
238         m_numCommits++;
239     }
240
241     virtual void afterTest()
242     {
243         EXPECT_EQ(2, m_numCommits);
244         EXPECT_GE(2, m_numDraws);
245     }
246
247 private:
248     int m_numCommits;
249     int m_numDraws;
250 };
251
252 #if OS(WINDOWS)
253 // http://webkit.org/b/74623
254 TEST_F(CCLayerTreeHostTestSetNeedsCommit2, FLAKY_runMultiThread)
255 #else
256 TEST_F(CCLayerTreeHostTestSetNeedsCommit2, runMultiThread)
257 #endif
258 {
259     runTest(true);
260 }
261
262 // 1 setNeedsRedraw after the first commit has completed should lead to 1
263 // additional draw.
264 class CCLayerTreeHostTestSetNeedsRedraw : public CCLayerTreeHostTest {
265 public:
266     CCLayerTreeHostTestSetNeedsRedraw()
267         : m_numCommits(0)
268         , m_numDraws(0)
269     {
270     }
271
272     virtual void beginTest()
273     {
274         postSetNeedsCommitToMainThread();
275     }
276
277     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
278     {
279         EXPECT_EQ(0, impl->sourceFrameNumber());
280         if (!m_numDraws)
281             postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
282         else
283             endTest();
284         m_numDraws++;
285     }
286
287     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
288     {
289         EXPECT_EQ(0, m_numDraws);
290         m_numCommits++;
291     }
292
293     virtual void afterTest()
294     {
295         EXPECT_GE(2, m_numDraws);
296         EXPECT_EQ(1, m_numCommits);
297     }
298
299 private:
300     int m_numCommits;
301     int m_numDraws;
302 };
303
304 TEST_F(CCLayerTreeHostTestSetNeedsRedraw, runMultiThread)
305 {
306     runTest(true);
307 }
308
309 // If the layerTreeHost says it can't draw, then we should not try to draw.
310 class CCLayerTreeHostTestCanDrawBlocksDrawing : public CCLayerTreeHostTest {
311 public:
312     CCLayerTreeHostTestCanDrawBlocksDrawing()
313         : m_numCommits(0)
314     {
315     }
316
317     virtual void beginTest()
318     {
319         postSetNeedsCommitToMainThread();
320     }
321
322     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
323     {
324         // Only the initial draw should bring us here.
325         EXPECT_TRUE(impl->canDraw());
326         EXPECT_EQ(0, impl->sourceFrameNumber());
327     }
328
329     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
330     {
331         if (m_numCommits >= 1) {
332             // After the first commit, we should not be able to draw.
333             EXPECT_FALSE(impl->canDraw());
334         }
335     }
336
337     virtual void didCommit()
338     {
339         m_numCommits++;
340         if (m_numCommits == 1) {
341             // Make the viewport empty so the host says it can't draw.
342             m_layerTreeHost->setViewportSize(IntSize(0, 0), IntSize(0, 0));
343
344             OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4]));
345             m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()), IntRect(0, 0, 1, 1));
346         } else if (m_numCommits == 2) {
347             m_layerTreeHost->setNeedsRedraw();
348             m_layerTreeHost->setNeedsCommit();
349         } else
350             endTest();
351     }
352
353     virtual void afterTest()
354     {
355     }
356
357 private:
358     int m_numCommits;
359 };
360
361 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCanDrawBlocksDrawing)
362
363 // beginLayerWrite should prevent draws from executing until a commit occurs
364 class CCLayerTreeHostTestWriteLayersRedraw : public CCLayerTreeHostTest {
365 public:
366     CCLayerTreeHostTestWriteLayersRedraw()
367         : m_numCommits(0)
368         , m_numDraws(0)
369     {
370     }
371
372     virtual void beginTest()
373     {
374         postAcquireLayerTextures();
375         postSetNeedsRedrawToMainThread(); // should be inhibited without blocking
376         postSetNeedsCommitToMainThread();
377     }
378
379     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
380     {
381         m_numDraws++;
382         EXPECT_EQ(m_numDraws, m_numCommits);
383     }
384
385     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
386     {
387         m_numCommits++;
388         endTest();
389     }
390
391     virtual void afterTest()
392     {
393         EXPECT_EQ(1, m_numCommits);
394     }
395
396 private:
397     int m_numCommits;
398     int m_numDraws;
399 };
400
401 TEST_F(CCLayerTreeHostTestWriteLayersRedraw, runMultiThread)
402 {
403     runTest(true);
404 }
405
406 // Verify that when resuming visibility, requesting layer write permission
407 // will not deadlock the main thread even though there are not yet any
408 // scheduled redraws. This behavior is critical for reliably surviving tab
409 // switching. There are no failure conditions to this test, it just passes
410 // by not timing out.
411 class CCLayerTreeHostTestWriteLayersAfterVisible : public CCLayerTreeHostTest {
412 public:
413     CCLayerTreeHostTestWriteLayersAfterVisible()
414         : m_numCommits(0)
415     {
416     }
417
418     virtual void beginTest()
419     {
420         postSetNeedsCommitToMainThread();
421     }
422
423     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
424     {
425         m_numCommits++;
426         if (m_numCommits == 2)
427             endTest();
428         else {
429             postSetVisibleToMainThread(false);
430             postSetVisibleToMainThread(true);
431             postAcquireLayerTextures();
432             postSetNeedsCommitToMainThread();
433         }
434     }
435
436     virtual void afterTest()
437     {
438     }
439
440 private:
441     int m_numCommits;
442 };
443
444 TEST_F(CCLayerTreeHostTestWriteLayersAfterVisible, runMultiThread)
445 {
446     runTest(true);
447 }
448
449 // A compositeAndReadback while invisible should force a normal commit without assertion.
450 class CCLayerTreeHostTestCompositeAndReadbackWhileInvisible : public CCLayerTreeHostTest {
451 public:
452     CCLayerTreeHostTestCompositeAndReadbackWhileInvisible()
453         : m_numCommits(0)
454     {
455     }
456
457     virtual void beginTest()
458     {
459     }
460
461     virtual void didCommitAndDrawFrame()
462     {
463         m_numCommits++;
464         if (m_numCommits == 1) {
465             m_layerTreeHost->setVisible(false);
466             m_layerTreeHost->setNeedsCommit();
467             m_layerTreeHost->setNeedsCommit();
468             OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4]));
469             m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()), IntRect(0, 0, 1, 1));
470         } else
471             endTest();
472
473     }
474
475     virtual void afterTest()
476     {
477     }
478
479 private:
480     int m_numCommits;
481 };
482
483 TEST_F(CCLayerTreeHostTestCompositeAndReadbackWhileInvisible, runMultiThread)
484 {
485     runTest(true);
486 }
487
488 class CCLayerTreeHostTestAbortFrameWhenInvisible : public CCLayerTreeHostTest {
489 public:
490     CCLayerTreeHostTestAbortFrameWhenInvisible()
491     {
492     }
493
494     virtual void beginTest()
495     {
496         // Request a commit (from the main thread), which will trigger the commit flow from the impl side.
497         m_layerTreeHost->setNeedsCommit();
498         // Then mark ourselves as not visible before processing any more messages on the main thread.
499         m_layerTreeHost->setVisible(false);
500         // If we make it without kicking a frame, we pass!
501         endTestAfterDelay(1);
502     }
503
504     virtual void layout() OVERRIDE
505     {
506         ASSERT_FALSE(true);
507         endTest();
508     }
509
510     virtual void afterTest()
511     {
512     }
513
514 private:
515 };
516
517 TEST_F(CCLayerTreeHostTestAbortFrameWhenInvisible, runMultiThread)
518 {
519     runTest(true);
520 }
521
522
523 // Trigger a frame with setNeedsCommit. Then, inside the resulting animate
524 // callback, requet another frame using setNeedsAnimate. End the test when
525 // animate gets called yet-again, indicating that the proxy is correctly
526 // handling the case where setNeedsAnimate() is called inside the begin frame
527 // flow.
528 class CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback : public CCLayerTreeHostTest {
529 public:
530     CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback()
531         : m_numAnimates(0)
532     {
533     }
534
535     virtual void beginTest()
536     {
537         postSetNeedsAnimateToMainThread();
538     }
539
540     virtual void updateAnimations(double)
541     {
542         if (!m_numAnimates) {
543             m_layerTreeHost->setNeedsAnimate();
544             m_numAnimates++;
545             return;
546         }
547         endTest();
548     }
549
550     virtual void afterTest()
551     {
552     }
553
554 private:
555     int m_numAnimates;
556 };
557
558 TEST_F(CCLayerTreeHostTestSetNeedsAnimateInsideAnimationCallback, runMultiThread)
559 {
560     runTest(true);
561 }
562
563 // Add a layer animation and confirm that CCLayerTreeHostImpl::animateLayers does get
564 // called and continues to get called.
565 class CCLayerTreeHostTestAddAnimation : public CCLayerTreeHostTest {
566 public:
567     CCLayerTreeHostTestAddAnimation()
568         : m_numAnimates(0)
569         , m_receivedAnimationStartedNotification(false)
570         , m_startTime(0)
571         , m_firstMonotonicTime(0)
572     {
573     }
574
575     virtual void beginTest()
576     {
577         postAddInstantAnimationToMainThread();
578     }
579
580     virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
581     {
582         if (!m_numAnimates) {
583             // The animation had zero duration so layerTreeHostImpl should no
584             // longer need to animate its layers.
585             EXPECT_FALSE(layerTreeHostImpl->needsAnimateLayers());
586             m_numAnimates++;
587             m_firstMonotonicTime = monotonicTime;
588             return;
589         }
590         EXPECT_LT(0, m_startTime);
591         EXPECT_LT(0, m_firstMonotonicTime);
592         EXPECT_NE(m_startTime, m_firstMonotonicTime);
593         EXPECT_TRUE(m_receivedAnimationStartedNotification);
594         endTest();
595     }
596
597     virtual void notifyAnimationStarted(double wallClockTime)
598     {
599         m_receivedAnimationStartedNotification = true;
600         m_startTime = wallClockTime;
601     }
602
603     virtual void afterTest()
604     {
605     }
606
607 private:
608     int m_numAnimates;
609     bool m_receivedAnimationStartedNotification;
610     double m_startTime;
611     double m_firstMonotonicTime;
612 };
613
614 TEST_F(CCLayerTreeHostTestAddAnimation, runMultiThread)
615 {
616     runTest(true);
617 }
618
619 // Add a layer animation to a layer, but continually fail to draw. Confirm that after
620 // a while, we do eventually force a draw.
621 class CCLayerTreeHostTestCheckerboardDoesNotStarveDraws : public CCLayerTreeHostTest {
622 public:
623     CCLayerTreeHostTestCheckerboardDoesNotStarveDraws()
624         : m_startedAnimating(false)
625     {
626     }
627
628     virtual void beginTest()
629     {
630         postAddAnimationToMainThread();
631     }
632
633     virtual void afterTest()
634     {
635     }
636
637     virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
638     {
639         m_startedAnimating = true;
640     }
641
642     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*)
643     {
644         if (m_startedAnimating)
645             endTest();
646     }
647
648     virtual bool prepareToDrawOnCCThread(CCLayerTreeHostImpl*)
649     {
650         return false;
651     }
652
653 private:
654     bool m_startedAnimating;
655 };
656
657 // Starvation can only be an issue with the MT compositor.
658 TEST_F(CCLayerTreeHostTestCheckerboardDoesNotStarveDraws, runMultiThread)
659 {
660     runTest(true);
661 }
662
663 // Ensures that animations continue to be ticked when we are backgrounded.
664 class CCLayerTreeHostTestTickAnimationWhileBackgrounded : public CCLayerTreeHostTest {
665 public:
666     CCLayerTreeHostTestTickAnimationWhileBackgrounded()
667         : m_numAnimates(0)
668     {
669     }
670
671     virtual void beginTest()
672     {
673         postAddAnimationToMainThread();
674     }
675
676     // Use willAnimateLayers to set visible false before the animation runs and
677     // causes a commit, so we block the second visible animate in single-thread
678     // mode.
679     virtual void willAnimateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
680     {
681         if (m_numAnimates < 2) {
682             if (!m_numAnimates) {
683                 // We have a long animation running. It should continue to tick even if we are not visible.
684                 postSetVisibleToMainThread(false);
685             }
686             m_numAnimates++;
687             return;
688         }
689         endTest();
690     }
691
692     virtual void afterTest()
693     {
694     }
695
696 private:
697     int m_numAnimates;
698 };
699
700 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestTickAnimationWhileBackgrounded)
701
702 // Ensures that animations continue to be ticked when we are backgrounded.
703 class CCLayerTreeHostTestAddAnimationWithTimingFunction : public CCLayerTreeHostTest {
704 public:
705     CCLayerTreeHostTestAddAnimationWithTimingFunction()
706     {
707     }
708
709     virtual void beginTest()
710     {
711         postAddAnimationToMainThread();
712     }
713
714     virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
715     {
716         const CCActiveAnimation* animation = m_layerTreeHost->rootLayer()->layerAnimationController()->getActiveAnimation(0, CCActiveAnimation::Opacity);
717         if (!animation)
718             return;
719         const CCFloatAnimationCurve* curve = animation->curve()->toFloatAnimationCurve();
720         float startOpacity = curve->getValue(0);
721         float endOpacity = curve->getValue(curve->duration());
722         float linearlyInterpolatedOpacity = 0.25 * endOpacity + 0.75 * startOpacity;
723         double time = curve->duration() * 0.25;
724         // If the linear timing function associated with this animation was not picked up,
725         // then the linearly interpolated opacity would be different because of the
726         // default ease timing function.
727         EXPECT_FLOAT_EQ(linearlyInterpolatedOpacity, curve->getValue(time));
728         endTest();
729     }
730
731     virtual void afterTest()
732     {
733     }
734
735 private:
736 };
737
738 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestAddAnimationWithTimingFunction)
739
740 // Ensures that when opacity is being animated, this value does not cause the subtree to be skipped.
741 class CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public CCLayerTreeHostTest {
742 public:
743     CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity()
744     {
745     }
746
747     virtual void beginTest()
748     {
749         m_layerTreeHost->rootLayer()->setDrawOpacity(1);
750         m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
751         m_layerTreeHost->rootLayer()->setOpacity(0);
752         postAddAnimationToMainThread();
753     }
754
755     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
756     {
757         // If the subtree was skipped when preparing to draw, the layer's draw opacity
758         // will not have been updated. It should be set to 0 due to the animation.
759         // Without the animation, the layer will be skipped since it has zero opacity.
760         EXPECT_EQ(0, m_layerTreeHost->rootLayer()->drawOpacity());
761         endTest();
762     }
763
764     virtual void afterTest()
765     {
766     }
767 };
768
769 #if OS(WINDOWS)
770 // http://webkit.org/b/74623
771 TEST_F(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, FLAKY_runMultiThread)
772 #else
773 TEST_F(CCLayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread)
774 #endif
775 {
776     runTest(true);
777 }
778
779 // Ensures that main thread animations have their start times synchronized with impl thread animations.
780 class CCLayerTreeHostTestSynchronizeAnimationStartTimes : public CCLayerTreeHostTest {
781 public:
782     CCLayerTreeHostTestSynchronizeAnimationStartTimes()
783         : m_layerTreeHostImpl(0)
784     {
785     }
786
787     virtual void beginTest()
788     {
789         postAddAnimationToMainThread();
790     }
791
792     // This is guaranteed to be called before CCLayerTreeHostImpl::animateLayers.
793     virtual void willAnimateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
794     {
795         m_layerTreeHostImpl = layerTreeHostImpl;
796     }
797
798     virtual void notifyAnimationStarted(double time)
799     {
800         EXPECT_TRUE(m_layerTreeHostImpl);
801
802         CCLayerAnimationController* controllerImpl = m_layerTreeHostImpl->rootLayer()->layerAnimationController();
803         CCLayerAnimationController* controller = m_layerTreeHost->rootLayer()->layerAnimationController();
804         CCActiveAnimation* animationImpl = controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity);
805         CCActiveAnimation* animation = controller->getActiveAnimation(0, CCActiveAnimation::Opacity);
806
807         EXPECT_EQ(animationImpl->startTime(), animation->startTime());
808
809         endTest();
810     }
811
812     virtual void afterTest()
813     {
814     }
815
816 private:
817     CCLayerTreeHostImpl* m_layerTreeHostImpl;
818 };
819
820 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSynchronizeAnimationStartTimes)
821
822 // Ensures that main thread animations have their start times synchronized with impl thread animations.
823 class CCLayerTreeHostTestAnimationFinishedEvents : public CCLayerTreeHostTest {
824 public:
825     CCLayerTreeHostTestAnimationFinishedEvents()
826     {
827     }
828
829     virtual void beginTest()
830     {
831         postAddInstantAnimationToMainThread();
832     }
833
834     virtual void notifyAnimationFinished(double time)
835     {
836         endTest();
837     }
838
839     virtual void afterTest()
840     {
841     }
842
843 private:
844 };
845
846 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestAnimationFinishedEvents)
847
848 class CCLayerTreeHostTestScrollSimple : public CCLayerTreeHostTest {
849 public:
850     CCLayerTreeHostTestScrollSimple()
851         : m_initialScroll(IntPoint(10, 20))
852         , m_secondScroll(IntPoint(40, 5))
853         , m_scrollAmount(2, -1)
854         , m_scrolls(0)
855     {
856     }
857
858     virtual void beginTest()
859     {
860         m_layerTreeHost->rootLayer()->setScrollable(true);
861         m_layerTreeHost->rootLayer()->setScrollPosition(m_initialScroll);
862         postSetNeedsCommitToMainThread();
863     }
864
865     virtual void layout()
866     {
867         LayerChromium* root = m_layerTreeHost->rootLayer();
868         if (!m_layerTreeHost->commitNumber())
869             EXPECT_EQ(root->scrollPosition(), m_initialScroll);
870         else {
871             EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount);
872
873             // Pretend like Javascript updated the scroll position itself.
874             root->setScrollPosition(m_secondScroll);
875         }
876     }
877
878     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
879     {
880         CCLayerImpl* root = impl->rootLayer();
881         EXPECT_EQ(root->scrollDelta(), IntSize());
882
883         root->setScrollable(true);
884         root->setMaxScrollPosition(IntSize(100, 100));
885         root->scrollBy(m_scrollAmount);
886
887         if (!impl->sourceFrameNumber()) {
888             EXPECT_EQ(root->scrollPosition(), m_initialScroll);
889             EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
890             postSetNeedsCommitToMainThread();
891         } else if (impl->sourceFrameNumber() == 1) {
892             EXPECT_EQ(root->scrollPosition(), m_secondScroll);
893             EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
894             endTest();
895         }
896     }
897
898     virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale)
899     {
900         IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition();
901         m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta);
902         m_scrolls++;
903     }
904
905     virtual void afterTest()
906     {
907         EXPECT_EQ(1, m_scrolls);
908     }
909 private:
910     IntPoint m_initialScroll;
911     IntPoint m_secondScroll;
912     IntSize m_scrollAmount;
913     int m_scrolls;
914 };
915
916 TEST_F(CCLayerTreeHostTestScrollSimple, DISABLED_runMultiThread)
917 {
918     runTest(true);
919 }
920
921 class CCLayerTreeHostTestScrollMultipleRedraw : public CCLayerTreeHostTest {
922 public:
923     CCLayerTreeHostTestScrollMultipleRedraw()
924         : m_initialScroll(IntPoint(40, 10))
925         , m_scrollAmount(-3, 17)
926         , m_scrolls(0)
927     {
928     }
929
930     virtual void beginTest()
931     {
932         m_layerTreeHost->rootLayer()->setScrollable(true);
933         m_layerTreeHost->rootLayer()->setScrollPosition(m_initialScroll);
934         postSetNeedsCommitToMainThread();
935     }
936
937     virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl)
938     {
939         LayerChromium* root = m_layerTreeHost->rootLayer();
940         if (!impl->sourceFrameNumber())
941             EXPECT_EQ(root->scrollPosition(), m_initialScroll);
942         else if (impl->sourceFrameNumber() == 1)
943             EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount + m_scrollAmount);
944         else if (impl->sourceFrameNumber() == 2)
945             EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount + m_scrollAmount);
946     }
947
948     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
949     {
950         CCLayerImpl* root = impl->rootLayer();
951         root->setScrollable(true);
952         root->setMaxScrollPosition(IntSize(100, 100));
953
954         if (!impl->sourceFrameNumber() && impl->sourceAnimationFrameNumber() == 1) {
955             // First draw after first commit.
956             EXPECT_EQ(root->scrollDelta(), IntSize());
957             root->scrollBy(m_scrollAmount);
958             EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
959
960             EXPECT_EQ(root->scrollPosition(), m_initialScroll);
961             postSetNeedsRedrawToMainThread();
962         } else if (!impl->sourceFrameNumber() && impl->sourceAnimationFrameNumber() == 2) {
963             // Second draw after first commit.
964             EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
965             root->scrollBy(m_scrollAmount);
966             EXPECT_EQ(root->scrollDelta(), m_scrollAmount + m_scrollAmount);
967
968             EXPECT_EQ(root->scrollPosition(), m_initialScroll);
969             postSetNeedsCommitToMainThread();
970         } else if (impl->sourceFrameNumber() == 1) {
971             // Third or later draw after second commit.
972             EXPECT_GE(impl->sourceAnimationFrameNumber(), 3);
973             EXPECT_EQ(root->scrollDelta(), IntSize());
974             EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount + m_scrollAmount);
975             endTest();
976         }
977     }
978
979     virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale)
980     {
981         IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition();
982         m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta);
983         m_scrolls++;
984     }
985
986     virtual void afterTest()
987     {
988         EXPECT_EQ(1, m_scrolls);
989     }
990 private:
991     IntPoint m_initialScroll;
992     IntSize m_scrollAmount;
993     int m_scrolls;
994 };
995
996 TEST_F(CCLayerTreeHostTestScrollMultipleRedraw, DISABLED_runMultiThread)
997 {
998     runTest(true);
999 }
1000
1001 // This test verifies that properties on the layer tree host are commited to the impl side.
1002 class CCLayerTreeHostTestCommit : public CCLayerTreeHostTest {
1003 public:
1004
1005     CCLayerTreeHostTestCommit() { }
1006
1007     virtual void beginTest()
1008     {
1009         m_layerTreeHost->setViewportSize(IntSize(20, 20), IntSize(20, 20));
1010         m_layerTreeHost->setBackgroundColor(Color::gray);
1011         m_layerTreeHost->setPageScaleFactorAndLimits(5, 5, 5);
1012
1013         postSetNeedsCommitToMainThread();
1014     }
1015
1016     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
1017     {
1018         EXPECT_EQ(IntSize(20, 20), impl->layoutViewportSize());
1019         EXPECT_EQ(Color::gray, impl->backgroundColor());
1020         EXPECT_EQ(5, impl->pageScale());
1021
1022         endTest();
1023     }
1024
1025     virtual void afterTest() { }
1026 };
1027
1028 TEST_F(CCLayerTreeHostTestCommit, runTest)
1029 {
1030     runTest(true);
1031 }
1032
1033 // Verifies that startPageScaleAnimation events propagate correctly from CCLayerTreeHost to
1034 // CCLayerTreeHostImpl in the MT compositor.
1035 class CCLayerTreeHostTestStartPageScaleAnimation : public CCLayerTreeHostTest {
1036 public:
1037
1038     CCLayerTreeHostTestStartPageScaleAnimation()
1039         : m_animationRequested(false)
1040     {
1041     }
1042
1043     virtual void beginTest()
1044     {
1045         m_layerTreeHost->rootLayer()->setScrollable(true);
1046         m_layerTreeHost->rootLayer()->setScrollPosition(IntPoint());
1047         postSetNeedsRedrawToMainThread();
1048     }
1049
1050     static void requestStartPageScaleAnimation(void* self)
1051     {
1052         CCLayerTreeHostTestStartPageScaleAnimation* test = static_cast<CCLayerTreeHostTestStartPageScaleAnimation*>(self);
1053         if (test->layerTreeHost())
1054             test->layerTreeHost()->startPageScaleAnimation(IntSize(), false, 1.25, 0);
1055     }
1056
1057     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
1058     {
1059         impl->rootLayer()->setScrollable(true);
1060         impl->rootLayer()->setScrollPosition(IntPoint());
1061         impl->setPageScaleFactorAndLimits(impl->pageScale(), 0.5, 2);
1062
1063         // We request animation only once.
1064         if (!m_animationRequested) {
1065             callOnMainThread(CCLayerTreeHostTestStartPageScaleAnimation::requestStartPageScaleAnimation, this);
1066             m_animationRequested = true;
1067         }
1068     }
1069
1070     virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale)
1071     {
1072         IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition();
1073         m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta);
1074         m_layerTreeHost->setPageScaleFactorAndLimits(scale, 0.5, 2);
1075     }
1076
1077     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
1078     {
1079         impl->processScrollDeltas();
1080         // We get one commit before the first draw, and the animation doesn't happen until the second draw.
1081         if (impl->sourceFrameNumber() == 1) {
1082             EXPECT_EQ(1.25, impl->pageScale());
1083             endTest();
1084         } else
1085             postSetNeedsRedrawToMainThread();
1086     }
1087
1088     virtual void afterTest()
1089     {
1090     }
1091
1092 private:
1093     bool m_animationRequested;
1094 };
1095
1096 TEST_F(CCLayerTreeHostTestStartPageScaleAnimation, runTest)
1097 {
1098     runTest(true);
1099 }
1100
1101 class CCLayerTreeHostTestSetVisible : public CCLayerTreeHostTest {
1102 public:
1103
1104     CCLayerTreeHostTestSetVisible()
1105         : m_numDraws(0)
1106     {
1107     }
1108
1109     virtual void beginTest()
1110     {
1111         postSetVisibleToMainThread(false);
1112         postSetNeedsRedrawToMainThread(); // This is suppressed while we're invisible.
1113         postSetVisibleToMainThread(true); // Triggers the redraw.
1114     }
1115
1116     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
1117     {
1118         EXPECT_TRUE(impl->visible());
1119         ++m_numDraws;
1120         endTest();
1121     }
1122
1123     virtual void afterTest()
1124     {
1125         EXPECT_EQ(1, m_numDraws);
1126     }
1127
1128 private:
1129     int m_numDraws;
1130 };
1131
1132 TEST_F(CCLayerTreeHostTestSetVisible, runMultiThread)
1133 {
1134     runTest(true);
1135 }
1136
1137 class TestOpacityChangeLayerDelegate : public ContentLayerDelegate {
1138 public:
1139     TestOpacityChangeLayerDelegate(CCLayerTreeHostTest* test)
1140         : m_test(test)
1141     {
1142     }
1143
1144     virtual void paintContents(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE
1145     {
1146         // Set layer opacity to 0.
1147         m_test->layerTreeHost()->rootLayer()->setOpacity(0);
1148     }
1149
1150     virtual bool preserves3D() { return false; }
1151
1152 private:
1153     CCLayerTreeHostTest* m_test;
1154 };
1155
1156 class ContentLayerChromiumWithUpdateTracking : public ContentLayerChromium {
1157 public:
1158     static PassRefPtr<ContentLayerChromiumWithUpdateTracking> create(ContentLayerDelegate *delegate) { return adoptRef(new ContentLayerChromiumWithUpdateTracking(delegate)); }
1159
1160     int paintContentsCount() { return m_paintContentsCount; }
1161     void resetPaintContentsCount() { m_paintContentsCount = 0; }
1162
1163     virtual void update(CCTextureUpdateQueue& queue, const CCOcclusionTracker* occlusion, CCRenderingStats& stats) OVERRIDE
1164     {
1165         ContentLayerChromium::update(queue, occlusion, stats);
1166         m_paintContentsCount++;
1167     }
1168
1169 private:
1170     explicit ContentLayerChromiumWithUpdateTracking(ContentLayerDelegate* delegate)
1171         : ContentLayerChromium(delegate)
1172         , m_paintContentsCount(0)
1173     {
1174         setAnchorPoint(FloatPoint(0, 0));
1175         setBounds(IntSize(10, 10));
1176         setIsDrawable(true);
1177     }
1178
1179     int m_paintContentsCount;
1180 };
1181
1182 // Layer opacity change during paint should not prevent compositor resources from being updated during commit.
1183 class CCLayerTreeHostTestOpacityChange : public CCLayerTreeHostTest {
1184 public:
1185     CCLayerTreeHostTestOpacityChange()
1186         : m_testOpacityChangeDelegate(this)
1187         , m_updateCheckLayer(ContentLayerChromiumWithUpdateTracking::create(&m_testOpacityChangeDelegate))
1188     {
1189     }
1190
1191     virtual void beginTest()
1192     {
1193         m_layerTreeHost->setRootLayer(m_updateCheckLayer);
1194         m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
1195
1196         postSetNeedsCommitToMainThread();
1197     }
1198
1199     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
1200     {
1201         endTest();
1202     }
1203
1204     virtual void afterTest()
1205     {
1206         // update() should have been called once.
1207         EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount());
1208
1209         // clear m_updateCheckLayer so CCLayerTreeHost dies.
1210         m_updateCheckLayer.clear();
1211     }
1212
1213 private:
1214     TestOpacityChangeLayerDelegate m_testOpacityChangeDelegate;
1215     RefPtr<ContentLayerChromiumWithUpdateTracking> m_updateCheckLayer;
1216 };
1217
1218 TEST_F(CCLayerTreeHostTestOpacityChange, runMultiThread)
1219 {
1220     runTest(true);
1221 }
1222
1223 class MockContentLayerDelegate : public ContentLayerDelegate {
1224 public:
1225     bool drawsContent() const { return true; }
1226     MOCK_CONST_METHOD0(preserves3D, bool());
1227     void paintContents(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE { }
1228     void notifySyncRequired() { }
1229 };
1230
1231 class CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public CCLayerTreeHostTest {
1232 public:
1233
1234     CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers()
1235         : m_rootLayer(ContentLayerChromium::create(&m_delegate))
1236         , m_childLayer(ContentLayerChromium::create(&m_delegate))
1237     {
1238     }
1239
1240     virtual void beginTest()
1241     {
1242         m_layerTreeHost->setViewportSize(IntSize(40, 40), IntSize(60, 60));
1243         m_layerTreeHost->setDeviceScaleFactor(1.5);
1244         EXPECT_EQ(IntSize(40, 40), m_layerTreeHost->layoutViewportSize());
1245         EXPECT_EQ(IntSize(60, 60), m_layerTreeHost->deviceViewportSize());
1246
1247         m_rootLayer->addChild(m_childLayer);
1248
1249         m_rootLayer->setIsDrawable(true);
1250         m_rootLayer->setBounds(IntSize(30, 30));
1251         m_rootLayer->setAnchorPoint(FloatPoint(0, 0));
1252
1253         m_childLayer->setIsDrawable(true);
1254         m_childLayer->setPosition(IntPoint(2, 2));
1255         m_childLayer->setBounds(IntSize(10, 10));
1256         m_childLayer->setAnchorPoint(FloatPoint(0, 0));
1257
1258         m_layerTreeHost->setRootLayer(m_rootLayer);
1259     }
1260
1261     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
1262     {
1263         // Get access to protected methods.
1264         MockLayerTreeHostImpl* mockImpl = static_cast<MockLayerTreeHostImpl*>(impl);
1265
1266         // Should only do one commit.
1267         EXPECT_EQ(0, impl->sourceFrameNumber());
1268         // Device scale factor should come over to impl.
1269         EXPECT_NEAR(impl->deviceScaleFactor(), 1.5, 0.00001);
1270
1271         // Both layers are on impl.
1272         ASSERT_EQ(1u, impl->rootLayer()->children().size());
1273
1274         // Device viewport is scaled.
1275         EXPECT_EQ(IntSize(40, 40), impl->layoutViewportSize());
1276         EXPECT_EQ(IntSize(60, 60), impl->deviceViewportSize());
1277
1278         CCLayerImpl* root = impl->rootLayer();
1279         CCLayerImpl* child = impl->rootLayer()->children()[0].get();
1280
1281         // Positions remain in layout pixels.
1282         EXPECT_EQ(IntPoint(0, 0), root->position());
1283         EXPECT_EQ(IntPoint(2, 2), child->position());
1284
1285         // Compute all the layer transforms for the frame.
1286         MockLayerTreeHostImpl::CCLayerList renderSurfaceLayerList;
1287         mockImpl->calculateRenderSurfaceLayerList(renderSurfaceLayerList);
1288
1289         // Both layers should be drawing into the root render surface.
1290         ASSERT_EQ(1u, renderSurfaceLayerList.size());
1291         ASSERT_EQ(root->renderSurface(), renderSurfaceLayerList[0]->renderSurface());
1292         ASSERT_EQ(2u, root->renderSurface()->layerList().size());
1293
1294         // The root render surface is the size of the viewport.
1295         EXPECT_EQ_RECT(IntRect(0, 0, 60, 60), root->renderSurface()->contentRect());
1296
1297         WebTransformationMatrix scaleTransform;
1298         scaleTransform.scale(impl->deviceScaleFactor());
1299
1300         // The root layer is scaled by 2x.
1301         WebTransformationMatrix rootScreenSpaceTransform = scaleTransform;
1302         WebTransformationMatrix rootDrawTransform = scaleTransform;
1303
1304         EXPECT_EQ(rootDrawTransform, root->drawTransform());
1305         EXPECT_EQ(rootScreenSpaceTransform, root->screenSpaceTransform());
1306
1307         // The child is at position 2,2, so translate by 2,2 before applying the scale by 2x.
1308         WebTransformationMatrix childScreenSpaceTransform = scaleTransform;
1309         childScreenSpaceTransform.translate(2, 2);
1310         WebTransformationMatrix childDrawTransform = scaleTransform;
1311         childDrawTransform.translate(2, 2);
1312
1313         EXPECT_EQ(childDrawTransform, child->drawTransform());
1314         EXPECT_EQ(childScreenSpaceTransform, child->screenSpaceTransform());
1315
1316         endTest();
1317     }
1318
1319     virtual void afterTest()
1320     {
1321         m_rootLayer.clear();
1322         m_childLayer.clear();
1323     }
1324
1325 private:
1326     MockContentLayerDelegate m_delegate;
1327     RefPtr<ContentLayerChromium> m_rootLayer;
1328     RefPtr<ContentLayerChromium> m_childLayer;
1329 };
1330
1331 TEST_F(CCLayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers, runMultiThread)
1332 {
1333     runTest(true);
1334 }
1335
1336 // Verify atomicity of commits and reuse of textures.
1337 class CCLayerTreeHostTestAtomicCommit : public CCLayerTreeHostTest {
1338 public:
1339     CCLayerTreeHostTestAtomicCommit()
1340         : m_layer(ContentLayerChromiumWithUpdateTracking::create(&m_delegate))
1341     {
1342         // Make sure partial texture updates are turned off.
1343         m_settings.maxPartialTextureUpdates = 0;
1344     }
1345
1346     virtual void beginTest()
1347     {
1348         m_layerTreeHost->setRootLayer(m_layer);
1349         m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
1350
1351         postSetNeedsCommitToMainThread();
1352         postSetNeedsRedrawToMainThread();
1353     }
1354
1355     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
1356     {
1357         CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->context3D());
1358
1359         switch (impl->sourceFrameNumber()) {
1360         case 0:
1361             // Number of textures should be one.
1362             ASSERT_EQ(1, context->numTextures());
1363             // Number of textures used for commit should be one.
1364             EXPECT_EQ(1, context->numUsedTextures());
1365             // Verify that used texture is correct.
1366             EXPECT_TRUE(context->usedTexture(context->texture(0)));
1367
1368             context->resetUsedTextures();
1369             break;
1370         case 1:
1371             // Number of textures should be two as the first texture
1372             // is used by impl thread and cannot by used for update.
1373             ASSERT_EQ(2, context->numTextures());
1374             // Number of textures used for commit should still be one.
1375             EXPECT_EQ(1, context->numUsedTextures());
1376             // First texture should not have been used.
1377             EXPECT_FALSE(context->usedTexture(context->texture(0)));
1378             // New texture should have been used.
1379             EXPECT_TRUE(context->usedTexture(context->texture(1)));
1380
1381             context->resetUsedTextures();
1382             break;
1383         default:
1384             ASSERT_NOT_REACHED();
1385             break;
1386         }
1387     }
1388
1389     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
1390     {
1391         CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->context3D());
1392
1393         // Number of textures used for draw should always be one.
1394         EXPECT_EQ(1, context->numUsedTextures());
1395
1396         if (impl->sourceFrameNumber() < 1) {
1397             context->resetUsedTextures();
1398             postSetNeedsAnimateAndCommitToMainThread();
1399             postSetNeedsRedrawToMainThread();
1400         } else
1401             endTest();
1402     }
1403
1404     virtual void layout()
1405     {
1406         m_layer->setNeedsDisplay();
1407     }
1408
1409     virtual void afterTest()
1410     {
1411     }
1412
1413 private:
1414     MockContentLayerDelegate m_delegate;
1415     RefPtr<ContentLayerChromiumWithUpdateTracking> m_layer;
1416 };
1417
1418 TEST_F(CCLayerTreeHostTestAtomicCommit, runMultiThread)
1419 {
1420     runTest(true);
1421 }
1422
1423 static void setLayerPropertiesForTesting(LayerChromium* layer, LayerChromium* parent, const WebTransformationMatrix& transform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool opaque)
1424 {
1425     layer->removeAllChildren();
1426     if (parent)
1427         parent->addChild(layer);
1428     layer->setTransform(transform);
1429     layer->setAnchorPoint(anchor);
1430     layer->setPosition(position);
1431     layer->setBounds(bounds);
1432     layer->setOpaque(opaque);
1433 }
1434
1435 class CCLayerTreeHostTestAtomicCommitWithPartialUpdate : public CCLayerTreeHostTest {
1436 public:
1437     CCLayerTreeHostTestAtomicCommitWithPartialUpdate()
1438         : m_parent(ContentLayerChromiumWithUpdateTracking::create(&m_delegate))
1439         , m_child(ContentLayerChromiumWithUpdateTracking::create(&m_delegate))
1440         , m_numCommits(0)
1441     {
1442         // Allow one partial texture update.
1443         m_settings.maxPartialTextureUpdates = 1;
1444     }
1445
1446     virtual void beginTest()
1447     {
1448         m_layerTreeHost->setRootLayer(m_parent);
1449         m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20));
1450
1451         WebTransformationMatrix identityMatrix;
1452         setLayerPropertiesForTesting(m_parent.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 20), true);
1453         setLayerPropertiesForTesting(m_child.get(), m_parent.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(0, 10), IntSize(10, 10), false);
1454
1455         postSetNeedsCommitToMainThread();
1456         postSetNeedsRedrawToMainThread();
1457     }
1458
1459     virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
1460     {
1461         CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->context3D());
1462
1463         switch (impl->sourceFrameNumber()) {
1464         case 0:
1465             // Number of textures should be two.
1466             ASSERT_EQ(2, context->numTextures());
1467             // Number of textures used for commit should be two.
1468             EXPECT_EQ(2, context->numUsedTextures());
1469             // Verify that used textures are correct.
1470             EXPECT_TRUE(context->usedTexture(context->texture(0)));
1471             EXPECT_TRUE(context->usedTexture(context->texture(1)));
1472
1473             context->resetUsedTextures();
1474             break;
1475         case 1:
1476             // Number of textures used for commit should still be two.
1477             EXPECT_EQ(2, context->numUsedTextures());
1478             // First two textures should not have been used.
1479             EXPECT_FALSE(context->usedTexture(context->texture(0)));
1480             EXPECT_FALSE(context->usedTexture(context->texture(1)));
1481             // New textures should have been used.
1482             EXPECT_TRUE(context->usedTexture(context->texture(2)));
1483             EXPECT_TRUE(context->usedTexture(context->texture(3)));
1484
1485             context->resetUsedTextures();
1486             break;
1487         case 2:
1488             // Number of textures used for commit should still be two.
1489             EXPECT_EQ(2, context->numUsedTextures());
1490
1491             context->resetUsedTextures();
1492             break;
1493         case 3:
1494             // No textures should be used for commit.
1495             EXPECT_EQ(0, context->numUsedTextures());
1496
1497             context->resetUsedTextures();
1498             break;
1499         case 4:
1500             // Number of textures used for commit should be one.
1501             EXPECT_EQ(1, context->numUsedTextures());
1502
1503             context->resetUsedTextures();
1504             break;
1505         default:
1506             ASSERT_NOT_REACHED();
1507             break;
1508         }
1509     }
1510
1511     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
1512     {
1513         CompositorFakeWebGraphicsContext3DWithTextureTracking* context = static_cast<CompositorFakeWebGraphicsContext3DWithTextureTracking*>(impl->context()->context3D());
1514
1515         // Number of textures used for drawing should two except for frame 4
1516         // where the viewport only contains one layer.
1517         if (impl->sourceFrameNumber() == 3)
1518             EXPECT_EQ(1, context->numUsedTextures());
1519         else
1520             EXPECT_EQ(2, context->numUsedTextures());
1521
1522         if (impl->sourceFrameNumber() < 4) {
1523             context->resetUsedTextures();
1524             postSetNeedsAnimateAndCommitToMainThread();
1525             postSetNeedsRedrawToMainThread();
1526         } else
1527             endTest();
1528     }
1529
1530     virtual void layout()
1531     {
1532         switch (m_numCommits++) {
1533         case 0:
1534         case 1:
1535             m_parent->setNeedsDisplay();
1536             m_child->setNeedsDisplay();
1537             break;
1538         case 2:
1539             // Damage part of layers.
1540             m_parent->setNeedsDisplayRect(FloatRect(0, 0, 5, 5));
1541             m_child->setNeedsDisplayRect(FloatRect(0, 0, 5, 5));
1542             break;
1543         case 3:
1544             m_child->setNeedsDisplay();
1545             m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
1546             break;
1547         case 4:
1548             m_layerTreeHost->setViewportSize(IntSize(10, 20), IntSize(10, 20));
1549             break;
1550         default:
1551             ASSERT_NOT_REACHED();
1552             break;
1553         }
1554     }
1555
1556     virtual void afterTest()
1557     {
1558     }
1559
1560 private:
1561     MockContentLayerDelegate m_delegate;
1562     RefPtr<ContentLayerChromiumWithUpdateTracking> m_parent;
1563     RefPtr<ContentLayerChromiumWithUpdateTracking> m_child;
1564     int m_numCommits;
1565 };
1566
1567 TEST_F(CCLayerTreeHostTestAtomicCommitWithPartialUpdate, runMultiThread)
1568 {
1569     runTest(true);
1570 }
1571
1572 class TestLayerChromium : public LayerChromium {
1573 public:
1574     static PassRefPtr<TestLayerChromium> create() { return adoptRef(new TestLayerChromium()); }
1575
1576     virtual void update(CCTextureUpdateQueue&, const CCOcclusionTracker* occlusion, CCRenderingStats&) OVERRIDE
1577     {
1578         // Gain access to internals of the CCOcclusionTracker.
1579         const TestCCOcclusionTracker* testOcclusion = static_cast<const TestCCOcclusionTracker*>(occlusion);
1580         m_occludedScreenSpace = testOcclusion ? testOcclusion->occlusionInScreenSpace() : Region();
1581     }
1582
1583     virtual bool drawsContent() const OVERRIDE { return true; }
1584
1585     const Region& occludedScreenSpace() const { return m_occludedScreenSpace; }
1586     void clearOccludedScreenSpace() { m_occludedScreenSpace = Region(); }
1587
1588 private:
1589     TestLayerChromium() : LayerChromium() { }
1590
1591     Region m_occludedScreenSpace;
1592 };
1593
1594 static void setTestLayerPropertiesForTesting(TestLayerChromium* layer, LayerChromium* parent, const WebTransformationMatrix& transform, const FloatPoint& anchor, const FloatPoint& position, const IntSize& bounds, bool opaque)
1595 {
1596     setLayerPropertiesForTesting(layer, parent, transform, anchor, position, bounds, opaque);
1597     layer->clearOccludedScreenSpace();
1598 }
1599
1600 class CCLayerTreeHostTestLayerOcclusion : public CCLayerTreeHostTest {
1601 public:
1602     CCLayerTreeHostTestLayerOcclusion() { }
1603
1604     virtual void beginTest()
1605     {
1606         RefPtr<TestLayerChromium> rootLayer = TestLayerChromium::create();
1607         RefPtr<TestLayerChromium> child = TestLayerChromium::create();
1608         RefPtr<TestLayerChromium> child2 = TestLayerChromium::create();
1609         RefPtr<TestLayerChromium> grandChild = TestLayerChromium::create();
1610         RefPtr<TestLayerChromium> mask = TestLayerChromium::create();
1611
1612         WebTransformationMatrix identityMatrix;
1613         WebTransformationMatrix childTransform;
1614         childTransform.translate(250, 250);
1615         childTransform.rotate(90);
1616         childTransform.translate(-250, -250);
1617
1618         child->setMasksToBounds(true);
1619
1620         // See CCLayerTreeHostCommonTest.layerAddsSelfToOccludedRegionWithRotatedSurface for a nice visual of these layers and how they end up
1621         // positioned on the screen.
1622
1623         // The child layer is rotated and the grandChild is opaque, but clipped to the child and rootLayer
1624         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1625         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), false);
1626         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1627
1628         m_layerTreeHost->setRootLayer(rootLayer);
1629         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1630         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
1631         CCTextureUpdateQueue queue;
1632         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1633         m_layerTreeHost->commitComplete();
1634
1635         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1636         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1637         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1638         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1639         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), rootLayer->occludedScreenSpace().bounds());
1640         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1641
1642         // If the child layer is opaque, then it adds to the occlusion seen by the rootLayer.
1643         setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1644         setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1645         setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1646
1647         m_layerTreeHost->setRootLayer(rootLayer);
1648         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1649         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1650         m_layerTreeHost->commitComplete();
1651
1652         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1653         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1654         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1655         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1656         EXPECT_EQ_RECT(IntRect(30, 30, 170, 170), rootLayer->occludedScreenSpace().bounds());
1657         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1658
1659         // Add a second child to the root layer and the regions should merge
1660         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1661         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(70, 20), IntSize(500, 500), true);
1662         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1663         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1664
1665         m_layerTreeHost->setRootLayer(rootLayer);
1666         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1667         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1668         m_layerTreeHost->commitComplete();
1669
1670         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1671         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1672         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1673         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1674         EXPECT_EQ_RECT(IntRect(30, 30, 170, 170), child2->occludedScreenSpace().bounds());
1675         EXPECT_EQ(1u, child2->occludedScreenSpace().rects().size());
1676         EXPECT_EQ_RECT(IntRect(30, 20, 170, 180), rootLayer->occludedScreenSpace().bounds());
1677         EXPECT_EQ(2u, rootLayer->occludedScreenSpace().rects().size());
1678
1679         // Move the second child to be sure.
1680         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1681         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1682         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1683         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1684
1685         m_layerTreeHost->setRootLayer(rootLayer);
1686         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1687         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1688         m_layerTreeHost->commitComplete();
1689
1690         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1691         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1692         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1693         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1694         EXPECT_EQ_RECT(IntRect(30, 30, 170, 170), child2->occludedScreenSpace().bounds());
1695         EXPECT_EQ(1u, child2->occludedScreenSpace().rects().size());
1696         EXPECT_EQ_RECT(IntRect(10, 30, 190, 170), rootLayer->occludedScreenSpace().bounds());
1697         EXPECT_EQ(2u, rootLayer->occludedScreenSpace().rects().size());
1698
1699         // If the child layer has a mask on it, then it shouldn't contribute to occlusion on stuff below it
1700         setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1701         setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1702         setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1703         setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1704
1705         child->setMaskLayer(mask.get());
1706
1707         m_layerTreeHost->setRootLayer(rootLayer);
1708         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1709         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1710         m_layerTreeHost->commitComplete();
1711
1712         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1713         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1714         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1715         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1716         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1717         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1718         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1719         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1720
1721         // If the child layer with a mask is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer
1722         setLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1723         setLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1724         setLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1725         setLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1726
1727         child->setMaskLayer(mask.get());
1728
1729         m_layerTreeHost->setRootLayer(rootLayer);
1730         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1731         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1732         m_layerTreeHost->commitComplete();
1733
1734         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1735         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1736         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpace().bounds());
1737         EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size());
1738         EXPECT_EQ_RECT(IntRect(10, 40, 190, 160), child->occludedScreenSpace().bounds());
1739         EXPECT_EQ(2u, child->occludedScreenSpace().rects().size());
1740         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1741         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1742
1743         // If the child layer has a non-opaque drawOpacity, then it shouldn't contribute to occlusion on stuff below it
1744         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1745         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1746         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1747         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1748
1749         child->setMaskLayer(0);
1750         child->setOpacity(0.5);
1751
1752         m_layerTreeHost->setRootLayer(rootLayer);
1753         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1754         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1755         m_layerTreeHost->commitComplete();
1756
1757         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1758         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1759         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1760         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1761         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1762         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1763         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1764         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1765
1766         // If the child layer with non-opaque drawOpacity is below child2, then child2 should contribute to occlusion on everything, and child shouldn't contribute to the rootLayer
1767         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1768         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1769         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1770         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1771
1772         child->setMaskLayer(0);
1773         child->setOpacity(0.5);
1774
1775         m_layerTreeHost->setRootLayer(rootLayer);
1776         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1777         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1778         m_layerTreeHost->commitComplete();
1779
1780         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1781         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1782         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpace().bounds());
1783         EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size());
1784         EXPECT_EQ_RECT(IntRect(10, 40, 190, 160), child->occludedScreenSpace().bounds());
1785         EXPECT_EQ(2u, child->occludedScreenSpace().rects().size());
1786         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1787         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1788
1789         // Kill the layerTreeHost immediately.
1790         m_layerTreeHost->setRootLayer(0);
1791         m_layerTreeHost.clear();
1792
1793         endTest();
1794     }
1795
1796     virtual void afterTest()
1797     {
1798     }
1799 };
1800
1801 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerOcclusion)
1802
1803 class CCLayerTreeHostTestLayerOcclusionWithFilters : public CCLayerTreeHostTest {
1804 public:
1805     CCLayerTreeHostTestLayerOcclusionWithFilters() { }
1806
1807     virtual void beginTest()
1808     {
1809         RefPtr<TestLayerChromium> rootLayer = TestLayerChromium::create();
1810         RefPtr<TestLayerChromium> child = TestLayerChromium::create();
1811         RefPtr<TestLayerChromium> child2 = TestLayerChromium::create();
1812         RefPtr<TestLayerChromium> grandChild = TestLayerChromium::create();
1813         RefPtr<TestLayerChromium> mask = TestLayerChromium::create();
1814
1815         WebTransformationMatrix identityMatrix;
1816         WebTransformationMatrix childTransform;
1817         childTransform.translate(250, 250);
1818         childTransform.rotate(90);
1819         childTransform.translate(-250, -250);
1820
1821         child->setMasksToBounds(true);
1822
1823         // If the child layer has a filter that changes alpha values, and is below child2, then child2 should contribute to occlusion on everything,
1824         // and child shouldn't contribute to the rootLayer
1825         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1826         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1827         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1828         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1829
1830         {
1831             WebFilterOperations filters;
1832             filters.append(WebFilterOperation::createOpacityFilter(0.5));
1833             child->setFilters(filters);
1834         }
1835
1836         m_layerTreeHost->setRootLayer(rootLayer);
1837         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1838         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
1839         CCTextureUpdateQueue queue;
1840         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1841         m_layerTreeHost->commitComplete();
1842
1843         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1844         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1845         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), grandChild->occludedScreenSpace().bounds());
1846         EXPECT_EQ(1u, grandChild->occludedScreenSpace().rects().size());
1847         EXPECT_EQ_RECT(IntRect(10, 40, 190, 160), child->occludedScreenSpace().bounds());
1848         EXPECT_EQ(2u, child->occludedScreenSpace().rects().size());
1849         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1850         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1851
1852         // 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 subtree,
1853         // and should not contribute to the rootLayer
1854         setTestLayerPropertiesForTesting(rootLayer.get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1855         setTestLayerPropertiesForTesting(child.get(), rootLayer.get(), childTransform, FloatPoint(0, 0), FloatPoint(30, 30), IntSize(500, 500), true);
1856         setTestLayerPropertiesForTesting(grandChild.get(), child.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 10), IntSize(500, 500), true);
1857         setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
1858
1859         {
1860             WebFilterOperations filters;
1861             filters.append(WebFilterOperation::createBlurFilter(10));
1862             child->setFilters(filters);
1863         }
1864
1865         m_layerTreeHost->setRootLayer(rootLayer);
1866         m_layerTreeHost->setViewportSize(rootLayer->bounds(), rootLayer->bounds());
1867         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1868         m_layerTreeHost->commitComplete();
1869
1870         EXPECT_EQ_RECT(IntRect(), child2->occludedScreenSpace().bounds());
1871         EXPECT_EQ(0u, child2->occludedScreenSpace().rects().size());
1872         EXPECT_EQ_RECT(IntRect(), grandChild->occludedScreenSpace().bounds());
1873         EXPECT_EQ(0u, grandChild->occludedScreenSpace().rects().size());
1874         EXPECT_EQ_RECT(IntRect(30, 40, 170, 160), child->occludedScreenSpace().bounds());
1875         EXPECT_EQ(1u, child->occludedScreenSpace().rects().size());
1876         EXPECT_EQ_RECT(IntRect(10, 70, 190, 130), rootLayer->occludedScreenSpace().bounds());
1877         EXPECT_EQ(1u, rootLayer->occludedScreenSpace().rects().size());
1878
1879         // Kill the layerTreeHost immediately.
1880         m_layerTreeHost->setRootLayer(0);
1881         m_layerTreeHost.clear();
1882
1883         CCLayerTreeHost::setNeedsFilterContext(false);
1884         endTest();
1885     }
1886
1887     virtual void afterTest()
1888     {
1889     }
1890 };
1891
1892 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerOcclusionWithFilters)
1893
1894 class CCLayerTreeHostTestManySurfaces : public CCLayerTreeHostTest {
1895 public:
1896     CCLayerTreeHostTestManySurfaces() { }
1897
1898     virtual void beginTest()
1899     {
1900         // We create enough RenderSurfaces that it will trigger Vector reallocation while computing occlusion.
1901         Region occluded;
1902         const WebTransformationMatrix identityMatrix;
1903         Vector<RefPtr<TestLayerChromium> > layers;
1904         Vector<RefPtr<TestLayerChromium> > children;
1905         int numSurfaces = 20;
1906         RefPtr<TestLayerChromium> replica = TestLayerChromium::create();
1907
1908         for (int i = 0; i < numSurfaces; ++i) {
1909             layers.append(TestLayerChromium::create());
1910             if (!i) {
1911                 setTestLayerPropertiesForTesting(layers.last().get(), 0, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(200, 200), true);
1912                 layers.last()->createRenderSurface();
1913             } else {
1914                 setTestLayerPropertiesForTesting(layers.last().get(), layers[layers.size()-2].get(), identityMatrix, FloatPoint(0, 0), FloatPoint(1, 1), IntSize(200-i, 200-i), true);
1915                 layers.last()->setMasksToBounds(true);
1916                 layers.last()->setReplicaLayer(replica.get()); // Make it have a RenderSurface
1917             }
1918         }
1919
1920         for (int i = 1; i < numSurfaces; ++i) {
1921             children.append(TestLayerChromium::create());
1922             setTestLayerPropertiesForTesting(children.last().get(), layers[i].get(), identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(500, 500), false);
1923         }
1924
1925         m_layerTreeHost->setRootLayer(layers[0].get());
1926         m_layerTreeHost->setViewportSize(layers[0]->bounds(), layers[0]->bounds());
1927         ASSERT_TRUE(m_layerTreeHost->initializeLayerRendererIfNeeded());
1928         CCTextureUpdateQueue queue;
1929         m_layerTreeHost->updateLayers(queue, std::numeric_limits<size_t>::max());
1930         m_layerTreeHost->commitComplete();
1931
1932         for (int i = 0; i < numSurfaces-1; ++i) {
1933             IntRect expectedOcclusion(i+1, i+1, 200-i-1, 200-i-1);
1934
1935             EXPECT_EQ_RECT(expectedOcclusion, layers[i]->occludedScreenSpace().bounds());
1936             EXPECT_EQ(1u, layers[i]->occludedScreenSpace().rects().size());
1937         }
1938
1939         // Kill the layerTreeHost immediately.
1940         m_layerTreeHost->setRootLayer(0);
1941         m_layerTreeHost.clear();
1942
1943         endTest();
1944     }
1945
1946     virtual void afterTest()
1947     {
1948     }
1949 };
1950
1951 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestManySurfaces)
1952
1953 // A loseContext(1) should lead to a didRecreateContext(true)
1954 class CCLayerTreeHostTestSetSingleLostContext : public CCLayerTreeHostTest {
1955 public:
1956     CCLayerTreeHostTestSetSingleLostContext()
1957     {
1958     }
1959
1960     virtual void beginTest()
1961     {
1962         postSetNeedsCommitToMainThread();
1963     }
1964
1965     virtual void didCommitAndDrawFrame()
1966     {
1967         m_layerTreeHost->loseContext(1);
1968     }
1969
1970     virtual void didRecreateContext(bool succeeded)
1971     {
1972         EXPECT_TRUE(succeeded);
1973         endTest();
1974     }
1975
1976     virtual void afterTest()
1977     {
1978     }
1979 };
1980
1981 TEST_F(CCLayerTreeHostTestSetSingleLostContext, runMultiThread)
1982 {
1983     runTest(true);
1984 }
1985
1986 // A loseContext(10) should lead to a didRecreateContext(false), and
1987 // a finishAllRendering() should not hang.
1988 class CCLayerTreeHostTestSetRepeatedLostContext : public CCLayerTreeHostTest {
1989 public:
1990     CCLayerTreeHostTestSetRepeatedLostContext()
1991     {
1992     }
1993
1994     virtual void beginTest()
1995     {
1996         postSetNeedsCommitToMainThread();
1997     }
1998
1999     virtual void didCommitAndDrawFrame()
2000     {
2001         m_layerTreeHost->loseContext(10);
2002     }
2003
2004     virtual void didRecreateContext(bool succeeded)
2005     {
2006         EXPECT_FALSE(succeeded);
2007         m_layerTreeHost->finishAllRendering();
2008         endTest();
2009     }
2010
2011     virtual void afterTest()
2012     {
2013     }
2014 };
2015
2016 TEST_F(CCLayerTreeHostTestSetRepeatedLostContext, runMultiThread)
2017 {
2018     runTest(true);
2019 }
2020
2021 class CCLayerTreeHostTestFractionalScroll : public CCLayerTreeHostTest {
2022 public:
2023     CCLayerTreeHostTestFractionalScroll()
2024         : m_scrollAmount(1.75, 0)
2025     {
2026     }
2027
2028     virtual void beginTest()
2029     {
2030         m_layerTreeHost->rootLayer()->setScrollable(true);
2031         postSetNeedsCommitToMainThread();
2032     }
2033
2034     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
2035     {
2036         CCLayerImpl* root = impl->rootLayer();
2037         root->setMaxScrollPosition(IntSize(100, 100));
2038
2039         // Check that a fractional scroll delta is correctly accumulated over multiple commits.
2040         if (!impl->sourceFrameNumber()) {
2041             EXPECT_EQ(root->scrollPosition(), IntPoint(0, 0));
2042             EXPECT_EQ(root->scrollDelta(), FloatSize(0, 0));
2043             postSetNeedsCommitToMainThread();
2044         } else if (impl->sourceFrameNumber() == 1) {
2045             EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount));
2046             EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(m_scrollAmount.width(), 1), 0));
2047             postSetNeedsCommitToMainThread();
2048         } else if (impl->sourceFrameNumber() == 2) {
2049             EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount + m_scrollAmount));
2050             EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(2 * m_scrollAmount.width(), 1), 0));
2051             endTest();
2052         }
2053         root->scrollBy(m_scrollAmount);
2054     }
2055
2056     virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale)
2057     {
2058         IntPoint position = m_layerTreeHost->rootLayer()->scrollPosition();
2059         m_layerTreeHost->rootLayer()->setScrollPosition(position + scrollDelta);
2060     }
2061
2062     virtual void afterTest()
2063     {
2064     }
2065 private:
2066     FloatSize m_scrollAmount;
2067 };
2068
2069 TEST_F(CCLayerTreeHostTestFractionalScroll, runMultiThread)
2070 {
2071     runTest(true);
2072 }
2073
2074 class CCLayerTreeHostTestFinishAllRendering : public CCLayerTreeHostTest {
2075 public:
2076     CCLayerTreeHostTestFinishAllRendering()
2077         : m_once(false)
2078         , m_mutex()
2079         , m_drawCount(0)
2080     {
2081     }
2082
2083     virtual void beginTest()
2084     {
2085         m_layerTreeHost->setNeedsRedraw();
2086     }
2087
2088     virtual void didCommitAndDrawFrame()
2089     {
2090         if (m_once)
2091             return;
2092         m_once = true;
2093         m_layerTreeHost->setNeedsRedraw();
2094         m_layerTreeHost->acquireLayerTextures();
2095         {
2096             Locker<Mutex> lock(m_mutex);
2097             m_drawCount = 0;
2098         }
2099         m_layerTreeHost->finishAllRendering();
2100         {
2101             Locker<Mutex> lock(m_mutex);
2102             EXPECT_EQ(0, m_drawCount);
2103         }
2104         endTest();
2105     }
2106
2107     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
2108     {
2109         Locker<Mutex> lock(m_mutex);
2110         ++m_drawCount;
2111     }
2112
2113     virtual void afterTest()
2114     {
2115     }
2116 private:
2117
2118     bool m_once;
2119     Mutex m_mutex;
2120     int m_drawCount;
2121 };
2122
2123 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestFinishAllRendering)
2124
2125 // Layers added to tree with existing active animations should have the animation
2126 // correctly recognized.
2127 class CCLayerTreeHostTestLayerAddedWithAnimation : public CCLayerTreeHostTest {
2128 public:
2129     CCLayerTreeHostTestLayerAddedWithAnimation()
2130         : m_addedAnimation(false)
2131     {
2132     }
2133
2134     virtual void beginTest()
2135     {
2136         EXPECT_FALSE(m_addedAnimation);
2137
2138         RefPtr<LayerChromium> layer = LayerChromium::create();
2139         layer->setLayerAnimationDelegate(this);
2140
2141         // Any valid CCAnimationCurve will do here.
2142         OwnPtr<CCAnimationCurve> curve(CCEaseTimingFunction::create());
2143         OwnPtr<CCActiveAnimation> animation(CCActiveAnimation::create(curve.release(), AnimationIdVendor::getNextAnimationId(), AnimationIdVendor::getNextGroupId(), CCActiveAnimation::Opacity));
2144         layer->layerAnimationController()->addAnimation(animation.release());
2145
2146         // We add the animation *before* attaching the layer to the tree.
2147         m_layerTreeHost->rootLayer()->addChild(layer);
2148         EXPECT_TRUE(m_addedAnimation);
2149
2150         endTest();
2151     }
2152
2153     virtual void didAddAnimation()
2154     {
2155         m_addedAnimation = true;
2156     }
2157
2158     virtual void afterTest() { }
2159
2160 private:
2161     bool m_addedAnimation;
2162 };
2163
2164 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestLayerAddedWithAnimation)
2165
2166 class CCLayerTreeHostTestScrollChildLayer : public CCLayerTreeHostTest, public LayerChromiumScrollDelegate {
2167 public:
2168     CCLayerTreeHostTestScrollChildLayer()
2169         : m_scrollAmount(2, 1)
2170     {
2171     }
2172
2173     virtual void beginTest() OVERRIDE
2174     {
2175         m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
2176         m_layerTreeHost->rootLayer()->setBounds(IntSize(10, 10));
2177         
2178         m_rootScrollLayer = ContentLayerChromium::create(&m_mockDelegate);
2179         m_rootScrollLayer->setBounds(IntSize(10, 10));
2180
2181         m_rootScrollLayer->setPosition(FloatPoint(0, 0));
2182         m_rootScrollLayer->setAnchorPoint(FloatPoint(0, 0));
2183
2184         m_rootScrollLayer->setIsDrawable(true);
2185         m_rootScrollLayer->setScrollable(true);
2186         m_rootScrollLayer->setMaxScrollPosition(IntSize(100, 100));
2187         m_layerTreeHost->rootLayer()->addChild(m_rootScrollLayer);
2188         m_childLayer = ContentLayerChromium::create(&m_mockDelegate);
2189         m_childLayer->setLayerScrollDelegate(this);
2190         m_childLayer->setBounds(IntSize(50, 50));
2191         m_childLayer->setIsDrawable(true);
2192         m_childLayer->setScrollable(true);
2193         m_childLayer->setMaxScrollPosition(IntSize(100, 100));
2194
2195         m_childLayer->setPosition(FloatPoint(0, 0));
2196         m_childLayer->setAnchorPoint(FloatPoint(0, 0));
2197
2198         m_rootScrollLayer->addChild(m_childLayer);
2199         postSetNeedsCommitToMainThread();
2200     }
2201
2202     virtual void didScroll(const IntSize& scrollDelta) OVERRIDE
2203     {
2204         m_reportedScrollAmount = scrollDelta;
2205     }
2206
2207     virtual void applyScrollAndScale(const IntSize& scrollDelta, float) OVERRIDE
2208     {
2209         IntPoint position = m_rootScrollLayer->scrollPosition();
2210         m_rootScrollLayer->setScrollPosition(position + scrollDelta);
2211     }
2212
2213     virtual void beginCommitOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE
2214     {
2215         EXPECT_EQ(m_rootScrollLayer->scrollPosition(), IntPoint());
2216         if (!m_layerTreeHost->commitNumber())
2217             EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint());
2218         else
2219             EXPECT_EQ(m_childLayer->scrollPosition(), IntPoint() + m_scrollAmount);
2220     }
2221
2222     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl) OVERRIDE
2223     {
2224         if (impl->sourceAnimationFrameNumber() == 1) {
2225             EXPECT_EQ(impl->scrollBegin(IntPoint(5, 5), CCInputHandlerClient::Wheel), CCInputHandlerClient::ScrollStarted);
2226             impl->scrollBy(m_scrollAmount);
2227             impl->scrollEnd();
2228         } else if (impl->sourceAnimationFrameNumber() == 2)
2229             endTest();
2230     }
2231
2232     virtual void afterTest() OVERRIDE
2233     {
2234         EXPECT_EQ(m_scrollAmount, m_reportedScrollAmount);
2235     }
2236
2237 private:
2238     const IntSize m_scrollAmount;
2239     IntSize m_reportedScrollAmount;
2240     MockContentLayerDelegate m_mockDelegate;
2241     RefPtr<LayerChromium> m_childLayer;
2242     RefPtr<LayerChromium> m_rootScrollLayer;
2243 };
2244
2245 TEST_F(CCLayerTreeHostTestScrollChildLayer, runMultiThread)
2246 {
2247     runTest(true);
2248 }
2249
2250 class CCLayerTreeHostTestCompositeAndReadbackCleanup : public CCLayerTreeHostTest {
2251 public:
2252     CCLayerTreeHostTestCompositeAndReadbackCleanup() { }
2253
2254     virtual void beginTest()
2255     {
2256         LayerChromium* rootLayer = m_layerTreeHost->rootLayer();
2257
2258         OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4]));
2259         m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()), IntRect(0, 0, 1, 1));
2260         EXPECT_FALSE(rootLayer->renderSurface());
2261
2262         endTest();
2263     }
2264
2265     virtual void afterTest()
2266     {
2267     }
2268 };
2269
2270 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCompositeAndReadbackCleanup)
2271
2272 class CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit : public CCLayerTreeHostTest {
2273 public:
2274     CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit()
2275         : m_rootLayer(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate))
2276         , m_surfaceLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate))
2277         , m_replicaLayer1(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate))
2278         , m_surfaceLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate))
2279         , m_replicaLayer2(ContentLayerChromiumWithUpdateTracking::create(&m_mockDelegate))
2280     {
2281     }
2282
2283     virtual void beginTest()
2284     {
2285         m_layerTreeHost->setViewportSize(IntSize(100, 100), IntSize(100, 100));
2286
2287         m_rootLayer->setBounds(IntSize(100, 100));
2288         m_surfaceLayer1->setBounds(IntSize(100, 100));
2289         m_surfaceLayer1->setForceRenderSurface(true);
2290         m_surfaceLayer1->setOpacity(0.5);
2291         m_surfaceLayer2->setBounds(IntSize(100, 100));
2292         m_surfaceLayer2->setForceRenderSurface(true);
2293         m_surfaceLayer2->setOpacity(0.5);
2294
2295         m_surfaceLayer1->setReplicaLayer(m_replicaLayer1.get());
2296         m_surfaceLayer2->setReplicaLayer(m_replicaLayer2.get());
2297
2298         m_rootLayer->addChild(m_surfaceLayer1);
2299         m_surfaceLayer1->addChild(m_surfaceLayer2);
2300         m_layerTreeHost->setRootLayer(m_rootLayer);
2301     }
2302
2303     virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* hostImpl)
2304     {
2305         CCRenderer* renderer = hostImpl->layerRenderer();
2306         unsigned surface1RenderPassId = hostImpl->rootLayer()->children()[0]->id();
2307         unsigned surface2RenderPassId = hostImpl->rootLayer()->children()[0]->children()[0]->id();
2308
2309         switch (hostImpl->sourceFrameNumber()) {
2310         case 0:
2311             EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId));
2312             EXPECT_TRUE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId));
2313
2314             // Reduce the memory limit to only fit the root layer and one render surface. This
2315             // prevents any contents drawing into surfaces from being allocated.
2316             hostImpl->setMemoryAllocationLimitBytes(100 * 100 * 4 * 2);
2317             break;
2318         case 1:
2319             EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface1RenderPassId));
2320             EXPECT_FALSE(renderer->haveCachedResourcesForRenderPassId(surface2RenderPassId));
2321
2322             endTest();
2323             break;
2324         }
2325     }
2326
2327     virtual void afterTest()
2328     {
2329         EXPECT_EQ(2, m_rootLayer->paintContentsCount());
2330         EXPECT_EQ(2, m_surfaceLayer1->paintContentsCount());
2331         EXPECT_EQ(2, m_surfaceLayer2->paintContentsCount());
2332
2333         // Clear layer references so CCLayerTreeHost dies.
2334         m_rootLayer.clear();
2335         m_surfaceLayer1.clear();
2336         m_replicaLayer1.clear();
2337         m_surfaceLayer2.clear();
2338         m_replicaLayer2.clear();
2339     }
2340
2341 private:
2342     MockContentLayerDelegate m_mockDelegate;
2343     RefPtr<ContentLayerChromiumWithUpdateTracking> m_rootLayer;
2344     RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer1;
2345     RefPtr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer1;
2346     RefPtr<ContentLayerChromiumWithUpdateTracking> m_surfaceLayer2;
2347     RefPtr<ContentLayerChromiumWithUpdateTracking> m_replicaLayer2;
2348 };
2349
2350 SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit)
2351
2352 } // namespace