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