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