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