Home | History | Annotate | Download | only in trees
      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:
     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:
     35   LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
     36       : num_commits_(0) {}
     37 
     38   virtual void BeginTest() OVERRIDE {
     39     PostSetNeedsCommitToMainThread();
     40   }
     41 
     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 
     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 
     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:
     86   LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
     87       : num_animates_(0) {}
     88 
     89   virtual void BeginTest() OVERRIDE {
     90     PostSetNeedsCommitToMainThread();
     91   }
     92 
     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 
    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:
    117   LayerTreeHostAnimationTestAddAnimation()
    118       : num_animates_(0),
    119         received_animation_started_notification_(false) {
    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(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 
    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 
    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:
    186   LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
    187       : started_animating_(false) {}
    188 
    189   virtual void BeginTest() OVERRIDE {
    190     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
    191   }
    192 
    193   virtual void AnimateLayers(
    194       LayerTreeHostImpl* host_impl,
    195       base::TimeTicks monotonic_time) OVERRIDE {
    196     started_animating_ = true;
    197   }
    198 
    199   virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
    200     if (started_animating_)
    201       EndTest();
    202   }
    203 
    204   virtual bool PrepareToDrawOnThread(
    205       LayerTreeHostImpl* host_impl,
    206       LayerTreeHostImpl::FrameData* frame,
    207       bool result) OVERRIDE {
    208     return false;
    209   }
    210 
    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:
    224   LayerTreeHostAnimationTestAnimationsGetDeleted()
    225       : started_animating_(false) {}
    226 
    227   virtual void BeginTest() OVERRIDE {
    228     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
    229   }
    230 
    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 
    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 
    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:
    266   LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
    267       : num_animates_(0) {}
    268 
    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.
    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 
    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:
    307   LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
    308       : active_tree_was_animated_(false) {}
    309 
    310   virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
    311     return base::TimeDelta::FromMilliseconds(4);
    312   }
    313 
    314   virtual void BeginTest() OVERRIDE {
    315     PostAddAnimationToMainThread(layer_tree_host()->root_layer());
    316   }
    317 
    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 
    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 
    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 
    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 
    378   virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
    379     host_impl->BlockNotifyReadyToActivateForTesting(false);
    380   }
    381 
    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 
    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 
    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 
    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:
    442   LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
    443 
    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 
    451   virtual void BeginTest() OVERRIDE {
    452     PostAddAnimationToMainThread(content_.get());
    453   }
    454 
    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 
    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:
    495   LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
    496       : main_start_time_(-1.0),
    497         impl_start_time_(-1.0) {}
    498 
    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 
    507   virtual void BeginTest() OVERRIDE {
    508     PostAddAnimationToMainThread(content_.get());
    509   }
    510 
    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 
    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 
    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:
    563   LayerTreeHostAnimationTestAnimationFinishedEvents() {}
    564 
    565   virtual void BeginTest() OVERRIDE {
    566     PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
    567   }
    568 
    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 
    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:
    593   LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
    594       : update_check_layer_(FakeContentLayer::Create(&client_)) {
    595   }
    596 
    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 
    603   virtual void BeginTest() OVERRIDE {
    604     PostAddAnimationToMainThread(update_check_layer_.get());
    605   }
    606 
    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 
    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:
    638   LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
    639 
    640   virtual void BeginTest() OVERRIDE {
    641     PostSetNeedsCommitToMainThread();
    642   }
    643 
    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 
    661   virtual void AnimateLayers(
    662       LayerTreeHostImpl* impl_host,
    663       base::TimeTicks monotonic_time) OVERRIDE {
    664     EndTest();
    665   }
    666 
    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:
    676   LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount()
    677       : animated_commit_(-1) {
    678   }
    679 
    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 
    687   virtual void BeginTest() OVERRIDE {
    688     PostSetNeedsCommitToMainThread();
    689   }
    690 
    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 
    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:
    726   LayerTreeHostAnimationTestContinuousAnimate()
    727       : num_commit_complete_(0),
    728         num_draw_layers_(0) {
    729   }
    730 
    731   virtual void BeginTest() OVERRIDE {
    732     PostSetNeedsCommitToMainThread();
    733   }
    734 
    735   virtual void Animate(base::TimeTicks) OVERRIDE {
    736     if (num_draw_layers_ == 2)
    737       return;
    738     layer_tree_host()->SetNeedsAnimate();
    739   }
    740 
    741   virtual void Layout() OVERRIDE {
    742     layer_tree_host()->root_layer()->SetNeedsDisplay();
    743   }
    744 
    745   virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE {
    746     if (num_draw_layers_ == 1)
    747       num_commit_complete_++;
    748   }
    749 
    750   virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
    751     num_draw_layers_++;
    752     if (num_draw_layers_ == 2)
    753       EndTest();
    754   }
    755 
    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:
    773   LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
    774 
    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 
    783   virtual void BeginTest() OVERRIDE {
    784     layer_tree_host()->SetViewportSize(gfx::Size());
    785     PostAddAnimationToMainThread(content_.get());
    786   }
    787 
    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 
    795   virtual void NotifyAnimationFinished(
    796       double wall_clock_time,
    797       base::TimeTicks monotonic_time,
    798       Animation::TargetProperty target_property) OVERRIDE {
    799     EndTest();
    800   }
    801 
    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:
    820   LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
    821 
    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 
    830   virtual void BeginTest() OVERRIDE {
    831     visible_ = true;
    832     PostAddAnimationToMainThread(content_.get());
    833   }
    834 
    835   virtual void DidCommit() OVERRIDE {
    836     visible_ = false;
    837     layer_tree_host()->SetVisible(false);
    838   }
    839 
    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 
    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 
    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 {
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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:
    969   LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
    970 
    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 
    981   virtual void BeginTest() OVERRIDE {
    982     PostSetNeedsCommitToMainThread();
    983   }
    984 
    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 
   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