- add sources.
[platform/framework/web/crosswalk.git] / src / cc / trees / layer_tree_host_unittest_animation.cc
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/trees/layer_tree_host.h"
6
7 #include "cc/animation/animation_curve.h"
8 #include "cc/animation/layer_animation_controller.h"
9 #include "cc/animation/timing_function.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/test/animation_test_common.h"
13 #include "cc/test/fake_content_layer.h"
14 #include "cc/test/fake_content_layer_client.h"
15 #include "cc/test/layer_tree_test.h"
16 #include "cc/trees/layer_tree_impl.h"
17
18 namespace cc {
19 namespace {
20
21 class LayerTreeHostAnimationTest : public LayerTreeTest {
22  public:
23   virtual void SetupTree() OVERRIDE {
24     LayerTreeTest::SetupTree();
25     layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
26   }
27 };
28
29 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
30 // be set.
31 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
32     : public LayerTreeHostAnimationTest {
33  public:
34   LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
35       : num_commits_(0) {}
36
37   virtual void BeginTest() OVERRIDE {
38     PostSetNeedsCommitToMainThread();
39   }
40
41   virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
42     // We skip the first commit becasue its the commit that populates the
43     // impl thread with a tree. After the second commit, the test is done.
44     if (num_commits_ != 1)
45       return;
46
47     layer_tree_host()->SetNeedsAnimate();
48     // Right now, CommitRequested is going to be true, because during
49     // BeginFrame, we force CommitRequested to true to prevent requests from
50     // hitting the impl thread. But, when the next DidCommit happens, we should
51     // verify that CommitRequested has gone back to false.
52   }
53
54   virtual void DidCommit() OVERRIDE {
55     if (!num_commits_) {
56       EXPECT_FALSE(layer_tree_host()->CommitRequested());
57       layer_tree_host()->SetNeedsAnimate();
58       EXPECT_FALSE(layer_tree_host()->CommitRequested());
59     }
60
61     // Verifies that the SetNeedsAnimate we made in ::Animate did not
62     // trigger CommitRequested.
63     EXPECT_FALSE(layer_tree_host()->CommitRequested());
64     EndTest();
65     num_commits_++;
66   }
67
68   virtual void AfterTest() OVERRIDE {}
69
70  private:
71   int num_commits_;
72 };
73
74 MULTI_THREAD_TEST_F(
75     LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
76
77 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
78 // callback, request another frame using SetNeedsAnimate. End the test when
79 // animate gets called yet-again, indicating that the proxy is correctly
80 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
81 // flow.
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
83     : public LayerTreeHostAnimationTest {
84  public:
85   LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
86       : num_animates_(0) {}
87
88   virtual void BeginTest() OVERRIDE {
89     PostSetNeedsCommitToMainThread();
90   }
91
92   virtual void Animate(base::TimeTicks) OVERRIDE {
93     if (!num_animates_) {
94       layer_tree_host()->SetNeedsAnimate();
95       num_animates_++;
96       return;
97     }
98     EndTest();
99   }
100
101   virtual void AfterTest() OVERRIDE {}
102
103  private:
104   int num_animates_;
105 };
106
107 MULTI_THREAD_TEST_F(
108     LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
109
110 // Add a layer animation and confirm that
111 // LayerTreeHostImpl::updateAnimationState does get called and continues to
112 // get called.
113 class LayerTreeHostAnimationTestAddAnimation
114     : public LayerTreeHostAnimationTest {
115  public:
116   LayerTreeHostAnimationTestAddAnimation()
117       : num_animates_(0),
118         received_animation_started_notification_(false),
119         start_time_(0.0) {
120   }
121
122   virtual void BeginTest() OVERRIDE {
123     PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
124   }
125
126   virtual void UpdateAnimationState(
127       LayerTreeHostImpl* host_impl,
128       bool has_unfinished_animation) OVERRIDE {
129     if (!num_animates_) {
130       // The animation had zero duration so LayerTreeHostImpl should no
131       // longer need to animate its layers.
132       EXPECT_FALSE(has_unfinished_animation);
133       num_animates_++;
134       return;
135     }
136
137     if (received_animation_started_notification_) {
138       EXPECT_LT(0.0, start_time_);
139
140       LayerAnimationController* controller_impl =
141           host_impl->active_tree()->root_layer()->layer_animation_controller();
142       Animation* animation_impl =
143           controller_impl->GetAnimation(Animation::Opacity);
144       if (animation_impl)
145         controller_impl->RemoveAnimation(animation_impl->id());
146
147       EndTest();
148     }
149   }
150
151   virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE {
152     received_animation_started_notification_ = true;
153     start_time_ = wall_clock_time;
154     if (num_animates_) {
155       EXPECT_LT(0.0, start_time_);
156
157       LayerAnimationController* controller =
158           layer_tree_host()->root_layer()->layer_animation_controller();
159       Animation* animation =
160           controller->GetAnimation(Animation::Opacity);
161       if (animation)
162         controller->RemoveAnimation(animation->id());
163
164       EndTest();
165     }
166   }
167
168   virtual void AfterTest() OVERRIDE {}
169
170  private:
171   int num_animates_;
172   bool received_animation_started_notification_;
173   double start_time_;
174 };
175
176 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
177
178 // Add a layer animation to a layer, but continually fail to draw. Confirm that
179 // after a while, we do eventually force a draw.
180 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
181     : public LayerTreeHostAnimationTest {
182  public:
183   LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
184       : started_animating_(false) {}
185
186   virtual void BeginTest() OVERRIDE {
187     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
188   }
189
190   virtual void AnimateLayers(
191       LayerTreeHostImpl* host_impl,
192       base::TimeTicks monotonic_time) OVERRIDE {
193     started_animating_ = true;
194   }
195
196   virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
197     if (started_animating_)
198       EndTest();
199   }
200
201   virtual bool PrepareToDrawOnThread(
202       LayerTreeHostImpl* host_impl,
203       LayerTreeHostImpl::FrameData* frame,
204       bool result) OVERRIDE {
205     return false;
206   }
207
208   virtual void AfterTest() OVERRIDE { }
209
210  private:
211   bool started_animating_;
212 };
213
214 // Starvation can only be an issue with the MT compositor.
215 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
216
217 // Ensures that animations eventually get deleted.
218 class LayerTreeHostAnimationTestAnimationsGetDeleted
219     : public LayerTreeHostAnimationTest {
220  public:
221   LayerTreeHostAnimationTestAnimationsGetDeleted()
222       : started_animating_(false) {}
223
224   virtual void BeginTest() OVERRIDE {
225     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
226   }
227
228   virtual void AnimateLayers(
229       LayerTreeHostImpl* host_impl,
230       base::TimeTicks monotonic_time) OVERRIDE {
231     bool have_animations = !host_impl->animation_registrar()->
232         active_animation_controllers().empty();
233     if (!started_animating_ && have_animations) {
234       started_animating_ = true;
235       return;
236     }
237
238     if (started_animating_ && !have_animations)
239       EndTest();
240   }
241
242   virtual void NotifyAnimationFinished(double time) OVERRIDE {
243     // Animations on the impl-side controller only get deleted during a commit,
244     // so we need to schedule a commit.
245     layer_tree_host()->SetNeedsCommit();
246   }
247
248   virtual void AfterTest() OVERRIDE {}
249
250  private:
251   bool started_animating_;
252 };
253
254 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
255
256 // Ensures that animations continue to be ticked when we are backgrounded.
257 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
258     : public LayerTreeHostAnimationTest {
259  public:
260   LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
261       : num_animates_(0) {}
262
263   virtual void BeginTest() OVERRIDE {
264     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
265   }
266
267   // Use WillAnimateLayers to set visible false before the animation runs and
268   // causes a commit, so we block the second visible animate in single-thread
269   // mode.
270   virtual void WillAnimateLayers(
271       LayerTreeHostImpl* host_impl,
272       base::TimeTicks monotonic_time) OVERRIDE {
273     // Verify that the host can draw, it's just not visible.
274     EXPECT_TRUE(host_impl->CanDraw());
275     if (num_animates_ < 2) {
276       if (!num_animates_) {
277         // We have a long animation running. It should continue to tick even
278         // if we are not visible.
279         PostSetVisibleToMainThread(false);
280       }
281       num_animates_++;
282       return;
283     }
284     EndTest();
285   }
286
287   virtual void AfterTest() OVERRIDE {}
288
289  private:
290   int num_animates_;
291 };
292
293 SINGLE_AND_MULTI_THREAD_TEST_F(
294     LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
295
296 // Ensures that animations do not tick when we are backgrounded and
297 // and we have an empty active tree.
298 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
299     : public LayerTreeHostAnimationTest {
300  protected:
301   LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
302       : active_tree_was_animated_(false) {}
303
304   virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
305     return base::TimeDelta::FromMilliseconds(4);
306   }
307
308   virtual void BeginTest() OVERRIDE {
309     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
310   }
311
312   virtual void NotifyAnimationFinished(double time) OVERRIDE {
313     // Replace animated commits with an empty tree.
314     layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
315   }
316
317   virtual void DidCommit() OVERRIDE {
318     // This alternates setting an empty tree and a non-empty tree with an
319     // animation.
320     switch (layer_tree_host()->source_frame_number()) {
321       case 1:
322         // Wait for NotifyAnimationFinished to commit an empty tree.
323         break;
324       case 2:
325         SetupTree();
326         AddOpacityTransitionToLayer(
327             layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
328         break;
329       case 3:
330         // Wait for NotifyAnimationFinished to commit an empty tree.
331         break;
332       case 4:
333         EndTest();
334         break;
335     }
336   }
337
338   virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
339     // At the start of every commit, block activations and make sure
340     // we are backgrounded.
341     host_impl->BlockNotifyReadyToActivateForTesting(true);
342     PostSetVisibleToMainThread(false);
343   }
344
345   virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
346     if (!host_impl->settings().impl_side_painting) {
347       // There are no activations to block if we're not impl-side-painting,
348       // so just advance the test immediately.
349       if (host_impl->active_tree()->source_frame_number() < 3)
350         UnblockActivations(host_impl);
351       return;
352     }
353
354     // We block activation for several ticks to make sure that, even though
355     // there is a pending tree with animations, we still do not background
356     // tick if the active tree is empty.
357     if (host_impl->pending_tree()->source_frame_number() < 3) {
358       base::MessageLoopProxy::current()->PostDelayedTask(
359           FROM_HERE,
360           base::Bind(
361               &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
362                    UnblockActivations,
363               base::Unretained(this),
364               host_impl),
365           4 * LowFrequencyAnimationInterval());
366     }
367   }
368
369   virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
370     host_impl->BlockNotifyReadyToActivateForTesting(false);
371   }
372
373   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
374     active_tree_was_animated_ = false;
375
376     // Verify that commits are actually alternating with empty / non-empty
377     // trees.
378     int frame_number = host_impl->active_tree()->source_frame_number();
379     switch (frame_number) {
380       case 0:
381       case 2:
382         EXPECT_TRUE(host_impl->active_tree()->root_layer())
383             << "frame: " << frame_number;
384         break;
385       case 1:
386       case 3:
387         EXPECT_FALSE(host_impl->active_tree()->root_layer())
388             << "frame: " << frame_number;
389         break;
390     }
391
392     if (host_impl->active_tree()->source_frame_number() < 3) {
393       // Initiate the next commit after a delay to give us a chance to
394       // background tick if the active tree isn't empty.
395       base::MessageLoopProxy::current()->PostDelayedTask(
396           FROM_HERE,
397           base::Bind(
398               &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
399                    InitiateNextCommit,
400               base::Unretained(this),
401               host_impl),
402           4 * LowFrequencyAnimationInterval());
403     }
404   }
405
406   virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
407                                  base::TimeTicks monotonic_time) OVERRIDE {
408     EXPECT_TRUE(host_impl->active_tree()->root_layer());
409     active_tree_was_animated_ = true;
410   }
411
412   void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
413     // Verify that we actually animated when we should have.
414     bool has_active_tree = host_impl->active_tree()->root_layer();
415     EXPECT_EQ(has_active_tree, active_tree_was_animated_);
416
417     // The next commit is blocked until we become visible again.
418     PostSetVisibleToMainThread(true);
419   }
420
421   virtual void AfterTest() OVERRIDE {}
422
423   bool active_tree_was_animated_;
424 };
425
426 SINGLE_AND_MULTI_THREAD_TEST_F(
427     LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
428
429 // Ensure that an animation's timing function is respected.
430 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
431     : public LayerTreeHostAnimationTest {
432  public:
433   LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
434
435   virtual void SetupTree() OVERRIDE {
436     LayerTreeHostAnimationTest::SetupTree();
437     content_ = FakeContentLayer::Create(&client_);
438     content_->SetBounds(gfx::Size(4, 4));
439     layer_tree_host()->root_layer()->AddChild(content_);
440   }
441
442   virtual void BeginTest() OVERRIDE {
443     PostAddAnimationToMainThread(content_.get());
444   }
445
446   virtual void AnimateLayers(
447       LayerTreeHostImpl* host_impl,
448       base::TimeTicks monotonic_time) OVERRIDE {
449     LayerAnimationController* controller_impl =
450         host_impl->active_tree()->root_layer()->children()[0]->
451         layer_animation_controller();
452     Animation* animation =
453         controller_impl->GetAnimation(Animation::Opacity);
454     if (!animation)
455       return;
456
457     const FloatAnimationCurve* curve =
458         animation->curve()->ToFloatAnimationCurve();
459     float start_opacity = curve->GetValue(0.0);
460     float end_opacity = curve->GetValue(curve->Duration());
461     float linearly_interpolated_opacity =
462         0.25f * end_opacity + 0.75f * start_opacity;
463     double time = curve->Duration() * 0.25;
464     // If the linear timing function associated with this animation was not
465     // picked up, then the linearly interpolated opacity would be different
466     // because of the default ease timing function.
467     EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
468
469     EndTest();
470   }
471
472   virtual void AfterTest() OVERRIDE {}
473
474   FakeContentLayerClient client_;
475   scoped_refptr<FakeContentLayer> content_;
476 };
477
478 SINGLE_AND_MULTI_THREAD_TEST_F(
479     LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
480
481 // Ensures that main thread animations have their start times synchronized with
482 // impl thread animations.
483 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
484     : public LayerTreeHostAnimationTest {
485  public:
486   LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
487       : main_start_time_(-1.0),
488         impl_start_time_(-1.0) {}
489
490   virtual void SetupTree() OVERRIDE {
491     LayerTreeHostAnimationTest::SetupTree();
492     content_ = FakeContentLayer::Create(&client_);
493     content_->SetBounds(gfx::Size(4, 4));
494     content_->set_layer_animation_delegate(this);
495     layer_tree_host()->root_layer()->AddChild(content_);
496   }
497
498   virtual void BeginTest() OVERRIDE {
499     PostAddAnimationToMainThread(content_.get());
500   }
501
502   virtual void NotifyAnimationStarted(double time) OVERRIDE {
503     LayerAnimationController* controller =
504         layer_tree_host()->root_layer()->children()[0]->
505         layer_animation_controller();
506     Animation* animation =
507         controller->GetAnimation(Animation::Opacity);
508     main_start_time_ = animation->start_time();
509     controller->RemoveAnimation(animation->id());
510
511     if (impl_start_time_ > 0.0)
512       EndTest();
513   }
514
515   virtual void UpdateAnimationState(
516       LayerTreeHostImpl* impl_host,
517       bool has_unfinished_animation) OVERRIDE {
518     LayerAnimationController* controller =
519         impl_host->active_tree()->root_layer()->children()[0]->
520         layer_animation_controller();
521     Animation* animation =
522         controller->GetAnimation(Animation::Opacity);
523     if (!animation)
524       return;
525
526     impl_start_time_ = animation->start_time();
527     controller->RemoveAnimation(animation->id());
528
529     if (main_start_time_ > 0.0)
530       EndTest();
531   }
532
533   virtual void AfterTest() OVERRIDE {
534     EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_);
535   }
536
537  private:
538   double main_start_time_;
539   double impl_start_time_;
540   FakeContentLayerClient client_;
541   scoped_refptr<FakeContentLayer> content_;
542 };
543
544 SINGLE_AND_MULTI_THREAD_TEST_F(
545     LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
546
547 // Ensures that notify animation finished is called.
548 class LayerTreeHostAnimationTestAnimationFinishedEvents
549     : public LayerTreeHostAnimationTest {
550  public:
551   LayerTreeHostAnimationTestAnimationFinishedEvents() {}
552
553   virtual void BeginTest() OVERRIDE {
554     PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
555   }
556
557   virtual void NotifyAnimationFinished(double time) OVERRIDE {
558     LayerAnimationController* controller =
559         layer_tree_host()->root_layer()->layer_animation_controller();
560     Animation* animation =
561         controller->GetAnimation(Animation::Opacity);
562     if (animation)
563       controller->RemoveAnimation(animation->id());
564     EndTest();
565   }
566
567   virtual void AfterTest() OVERRIDE {}
568 };
569
570 SINGLE_AND_MULTI_THREAD_TEST_F(
571     LayerTreeHostAnimationTestAnimationFinishedEvents);
572
573 // Ensures that when opacity is being animated, this value does not cause the
574 // subtree to be skipped.
575 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
576     : public LayerTreeHostAnimationTest {
577  public:
578   LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
579       : update_check_layer_(FakeContentLayer::Create(&client_)) {
580   }
581
582   virtual void SetupTree() OVERRIDE {
583     update_check_layer_->SetOpacity(0.f);
584     layer_tree_host()->SetRootLayer(update_check_layer_);
585     LayerTreeHostAnimationTest::SetupTree();
586   }
587
588   virtual void BeginTest() OVERRIDE {
589     PostAddAnimationToMainThread(update_check_layer_.get());
590   }
591
592   virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
593     LayerAnimationController* controller_impl =
594         host_impl->active_tree()->root_layer()->layer_animation_controller();
595     Animation* animation_impl =
596         controller_impl->GetAnimation(Animation::Opacity);
597     controller_impl->RemoveAnimation(animation_impl->id());
598     EndTest();
599   }
600
601   virtual void AfterTest() OVERRIDE {
602     // Update() should have been called once, proving that the layer was not
603     // skipped.
604     EXPECT_EQ(1u, update_check_layer_->update_count());
605
606     // clear update_check_layer_ so LayerTreeHost dies.
607     update_check_layer_ = NULL;
608   }
609
610  private:
611   FakeContentLayerClient client_;
612   scoped_refptr<FakeContentLayer> update_check_layer_;
613 };
614
615 SINGLE_AND_MULTI_THREAD_TEST_F(
616     LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
617
618 // Layers added to tree with existing active animations should have the
619 // animation correctly recognized.
620 class LayerTreeHostAnimationTestLayerAddedWithAnimation
621     : public LayerTreeHostAnimationTest {
622  public:
623   LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
624
625   virtual void BeginTest() OVERRIDE {
626     PostSetNeedsCommitToMainThread();
627   }
628
629   virtual void DidCommit() OVERRIDE {
630     if (layer_tree_host()->source_frame_number() == 1) {
631       scoped_refptr<Layer> layer = Layer::Create();
632       layer->set_layer_animation_delegate(this);
633
634       // Any valid AnimationCurve will do here.
635       scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create());
636       scoped_ptr<Animation> animation(
637           Animation::Create(curve.Pass(), 1, 1,
638                                   Animation::Opacity));
639       layer->layer_animation_controller()->AddAnimation(animation.Pass());
640
641       // We add the animation *before* attaching the layer to the tree.
642       layer_tree_host()->root_layer()->AddChild(layer);
643     }
644   }
645
646   virtual void AnimateLayers(
647       LayerTreeHostImpl* impl_host,
648       base::TimeTicks monotonic_time) OVERRIDE {
649     EndTest();
650   }
651
652   virtual void AfterTest() OVERRIDE {}
653 };
654
655 SINGLE_AND_MULTI_THREAD_TEST_F(
656     LayerTreeHostAnimationTestLayerAddedWithAnimation);
657
658 class LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount
659     : public LayerTreeHostAnimationTest {
660  public:
661   LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount()
662       : animated_commit_(-1) {
663   }
664
665   virtual void Animate(base::TimeTicks) OVERRIDE {
666     // We shouldn't animate on the CompositeAndReadback-forced commit, but we
667     // should for the SetNeedsCommit-triggered commit.
668     animated_commit_ = layer_tree_host()->source_frame_number();
669     EXPECT_NE(2, animated_commit_);
670   }
671
672   virtual void BeginTest() OVERRIDE {
673     PostSetNeedsCommitToMainThread();
674   }
675
676   virtual void DidCommit() OVERRIDE {
677     switch (layer_tree_host()->source_frame_number()) {
678       case 1:
679         layer_tree_host()->SetNeedsCommit();
680         break;
681       case 2: {
682         char pixels[4];
683         layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
684         break;
685       }
686       case 3:
687         // This is finishing the readback's commit.
688         break;
689       case 4:
690         // This is finishing the followup commit.
691         EndTest();
692         break;
693       default:
694         NOTREACHED();
695     }
696   }
697
698   virtual void AfterTest() OVERRIDE {
699     EXPECT_EQ(3, animated_commit_);
700   }
701
702  private:
703   int animated_commit_;
704 };
705
706 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount);
707
708 class LayerTreeHostAnimationTestContinuousAnimate
709     : public LayerTreeHostAnimationTest {
710  public:
711   LayerTreeHostAnimationTestContinuousAnimate()
712       : num_commit_complete_(0),
713         num_draw_layers_(0) {
714   }
715
716   virtual void BeginTest() OVERRIDE {
717     PostSetNeedsCommitToMainThread();
718   }
719
720   virtual void Animate(base::TimeTicks) OVERRIDE {
721     if (num_draw_layers_ == 2)
722       return;
723     layer_tree_host()->SetNeedsAnimate();
724   }
725
726   virtual void Layout() OVERRIDE {
727     layer_tree_host()->root_layer()->SetNeedsDisplay();
728   }
729
730   virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE {
731     if (num_draw_layers_ == 1)
732       num_commit_complete_++;
733   }
734
735   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
736     num_draw_layers_++;
737     if (num_draw_layers_ == 2)
738       EndTest();
739   }
740
741   virtual void AfterTest() OVERRIDE {
742     // Check that we didn't commit twice between first and second draw.
743     EXPECT_EQ(1, num_commit_complete_);
744   }
745
746  private:
747   int num_commit_complete_;
748   int num_draw_layers_;
749 };
750
751 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate);
752
753 // Make sure the main thread can still execute animations when CanDraw() is not
754 // true.
755 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
756     : public LayerTreeHostAnimationTest {
757  public:
758   LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
759
760   virtual void SetupTree() OVERRIDE {
761     LayerTreeHostAnimationTest::SetupTree();
762     content_ = FakeContentLayer::Create(&client_);
763     content_->SetBounds(gfx::Size(4, 4));
764     content_->set_layer_animation_delegate(this);
765     layer_tree_host()->root_layer()->AddChild(content_);
766   }
767
768   virtual void BeginTest() OVERRIDE {
769     layer_tree_host()->SetViewportSize(gfx::Size());
770     PostAddAnimationToMainThread(content_.get());
771   }
772
773   virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE {
774     started_times_++;
775   }
776
777   virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE {
778     EndTest();
779   }
780
781   virtual void AfterTest() OVERRIDE {
782     EXPECT_EQ(1, started_times_);
783   }
784
785  private:
786   int started_times_;
787   FakeContentLayerClient client_;
788   scoped_refptr<FakeContentLayer> content_;
789 };
790
791 SINGLE_AND_MULTI_THREAD_TEST_F(
792     LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
793
794 // Make sure the main thread can still execute animations when the renderer is
795 // backgrounded.
796 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
797     : public LayerTreeHostAnimationTest {
798  public:
799   LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
800
801   virtual void SetupTree() OVERRIDE {
802     LayerTreeHostAnimationTest::SetupTree();
803     content_ = FakeContentLayer::Create(&client_);
804     content_->SetBounds(gfx::Size(4, 4));
805     content_->set_layer_animation_delegate(this);
806     layer_tree_host()->root_layer()->AddChild(content_);
807   }
808
809   virtual void BeginTest() OVERRIDE {
810     visible_ = true;
811     PostAddAnimationToMainThread(content_.get());
812   }
813
814   virtual void DidCommit() OVERRIDE {
815     visible_ = false;
816     layer_tree_host()->SetVisible(false);
817   }
818
819   virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE {
820     EXPECT_FALSE(visible_);
821     started_times_++;
822   }
823
824   virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE {
825     EXPECT_FALSE(visible_);
826     EXPECT_EQ(1, started_times_);
827     EndTest();
828   }
829
830   virtual void AfterTest() OVERRIDE {}
831
832  private:
833   bool visible_;
834   int started_times_;
835   FakeContentLayerClient client_;
836   scoped_refptr<FakeContentLayer> content_;
837 };
838
839 SINGLE_AND_MULTI_THREAD_TEST_F(
840     LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
841
842 // Animations should not be started when frames are being skipped due to
843 // checkerboard.
844 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
845     : public LayerTreeHostAnimationTest {
846   virtual void SetupTree() OVERRIDE {
847     LayerTreeHostAnimationTest::SetupTree();
848     content_ = FakeContentLayer::Create(&client_);
849     content_->SetBounds(gfx::Size(4, 4));
850     content_->set_layer_animation_delegate(this);
851     layer_tree_host()->root_layer()->AddChild(content_);
852   }
853
854   virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
855     // Make sure that drawing many times doesn't cause a checkerboarded
856     // animation to start so we avoid flake in this test.
857     settings->timeout_and_draw_when_animation_checkerboards = false;
858   }
859
860   virtual void BeginTest() OVERRIDE {
861     prevented_draw_ = 0;
862     added_animations_ = 0;
863     started_times_ = 0;
864     finished_times_ = 0;
865
866     PostSetNeedsCommitToMainThread();
867   }
868
869   virtual void DispatchAddInstantAnimation(Layer* layer_to_receive_animation)
870       OVERRIDE {
871     LayerTreeHostAnimationTest::DispatchAddInstantAnimation(
872         layer_to_receive_animation);
873     added_animations_++;
874   }
875
876   virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
877                                      LayerTreeHostImpl::FrameData* frame_data,
878                                      bool result) OVERRIDE {
879     if (added_animations_ < 2)
880       return result;
881     if (TestEnded())
882       return result;
883     // Act like there is checkerboard when the second animation wants to draw.
884     ++prevented_draw_;
885     return false;
886   }
887
888   virtual void DidCommitAndDrawFrame() OVERRIDE {
889     switch (layer_tree_host()->source_frame_number()) {
890       case 1:
891         // The animation is longer than 1 BeginFrame interval.
892         AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
893         added_animations_++;
894         break;
895       case 2:
896         // This second animation will not be drawn so it should not start.
897         AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
898         added_animations_++;
899         break;
900     }
901   }
902
903   virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE {
904     if (TestEnded())
905       return;
906     started_times_++;
907   }
908
909   virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE {
910     // We should be checkerboarding already, but it should still finish the
911     // first animation.
912     EXPECT_EQ(2, added_animations_);
913     finished_times_++;
914     EndTest();
915   }
916
917   virtual void AfterTest() OVERRIDE {
918     // Make sure we tried to draw the second animation but failed.
919     EXPECT_LT(0, prevented_draw_);
920     // The first animation should be started, but the second should not because
921     // of checkerboard.
922     EXPECT_EQ(1, started_times_);
923     // The first animation should still be finished.
924     EXPECT_EQ(1, finished_times_);
925   }
926
927   int prevented_draw_;
928   int added_animations_;
929   int started_times_;
930   int finished_times_;
931   FakeContentLayerClient client_;
932   scoped_refptr<FakeContentLayer> content_;
933 };
934
935 MULTI_THREAD_TEST_F(
936     LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
937
938 }  // namespace
939 }  // namespace cc