Task Manager: Remove goat teleporter.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobfff628b1cb352c4fa098aad77114422b27216568
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.
5 #include "cc/trees/layer_tree_host.h"
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"
19 namespace cc {
20 namespace {
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);
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) {}
38 virtual void BeginTest() OVERRIDE {
39 PostSetNeedsCommitToMainThread();
42 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
43 // We skip the first commit because 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;
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.
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());
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_++;
69 virtual void AfterTest() OVERRIDE {}
71 private:
72 int num_commits_;
75 MULTI_THREAD_TEST_F(
76 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
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_begin_frames_(0) {}
89 virtual void BeginTest() OVERRIDE {
90 PostSetNeedsCommitToMainThread();
93 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
94 if (!num_begin_frames_) {
95 layer_tree_host()->SetNeedsAnimate();
96 num_begin_frames_++;
97 return;
99 EndTest();
102 virtual void AfterTest() OVERRIDE {}
104 private:
105 int num_begin_frames_;
108 MULTI_THREAD_TEST_F(
109 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
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_begin_frames_(0), received_animation_started_notification_(false) {}
120 virtual void BeginTest() OVERRIDE {
121 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
124 virtual void UpdateAnimationState(
125 LayerTreeHostImpl* host_impl,
126 bool has_unfinished_animation) OVERRIDE {
127 if (!num_begin_frames_) {
128 // The animation had zero duration so LayerTreeHostImpl should no
129 // longer need to animate its layers.
130 EXPECT_FALSE(has_unfinished_animation);
131 num_begin_frames_++;
132 return;
135 if (received_animation_started_notification_) {
136 EXPECT_LT(base::TimeTicks(), start_time_);
138 LayerAnimationController* controller_impl =
139 host_impl->active_tree()->root_layer()->layer_animation_controller();
140 Animation* animation_impl =
141 controller_impl->GetAnimation(Animation::Opacity);
142 if (animation_impl)
143 controller_impl->RemoveAnimation(animation_impl->id());
145 EndTest();
149 virtual void NotifyAnimationStarted(
150 base::TimeTicks monotonic_time,
151 Animation::TargetProperty target_property) OVERRIDE {
152 received_animation_started_notification_ = true;
153 start_time_ = monotonic_time;
154 if (num_begin_frames_) {
155 EXPECT_LT(base::TimeTicks(), start_time_);
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());
164 EndTest();
168 virtual void AfterTest() OVERRIDE {}
170 private:
171 int num_begin_frames_;
172 bool received_animation_started_notification_;
173 base::TimeTicks start_time_;
176 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
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) {}
186 virtual void BeginTest() OVERRIDE {
187 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
190 virtual void AnimateLayers(
191 LayerTreeHostImpl* host_impl,
192 base::TimeTicks monotonic_time) OVERRIDE {
193 started_animating_ = true;
196 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
197 if (started_animating_)
198 EndTest();
201 virtual DrawResult PrepareToDrawOnThread(
202 LayerTreeHostImpl* host_impl,
203 LayerTreeHostImpl::FrameData* frame,
204 DrawResult draw_result) OVERRIDE {
205 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
208 virtual void AfterTest() OVERRIDE { }
210 private:
211 bool started_animating_;
214 // Starvation can only be an issue with the MT compositor.
215 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
217 // Ensures that animations eventually get deleted.
218 class LayerTreeHostAnimationTestAnimationsGetDeleted
219 : public LayerTreeHostAnimationTest {
220 public:
221 LayerTreeHostAnimationTestAnimationsGetDeleted()
222 : started_animating_(false) {}
224 virtual void BeginTest() OVERRIDE {
225 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
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;
238 if (started_animating_ && !have_animations)
239 EndTest();
242 virtual void NotifyAnimationFinished(
243 base::TimeTicks monotonic_time,
244 Animation::TargetProperty target_property) OVERRIDE {
245 // Animations on the impl-side controller only get deleted during a commit,
246 // so we need to schedule a commit.
247 layer_tree_host()->SetNeedsCommit();
250 virtual void AfterTest() OVERRIDE {}
252 private:
253 bool started_animating_;
256 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
258 // Ensures that animations continue to be ticked when we are backgrounded.
259 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
260 : public LayerTreeHostAnimationTest {
261 public:
262 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
263 : num_begin_frames_(0) {}
265 virtual void BeginTest() OVERRIDE {
266 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
269 // Use WillAnimateLayers to set visible false before the animation runs and
270 // causes a commit, so we block the second visible animate in single-thread
271 // mode.
272 virtual void WillAnimateLayers(
273 LayerTreeHostImpl* host_impl,
274 base::TimeTicks monotonic_time) OVERRIDE {
275 // Verify that the host can draw, it's just not visible.
276 EXPECT_TRUE(host_impl->CanDraw());
277 if (num_begin_frames_ < 2) {
278 if (!num_begin_frames_) {
279 // We have a long animation running. It should continue to tick even
280 // if we are not visible.
281 PostSetVisibleToMainThread(false);
283 num_begin_frames_++;
284 return;
286 EndTest();
289 virtual void AfterTest() OVERRIDE {}
291 private:
292 int num_begin_frames_;
295 SINGLE_AND_MULTI_THREAD_TEST_F(
296 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
298 // Ensures that animation time remains monotonic when we switch from foreground
299 // to background ticking and back, even if we're skipping draws due to
300 // checkerboarding when in the foreground.
301 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
302 : public LayerTreeHostAnimationTest {
303 public:
304 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
305 : has_background_ticked_(false), num_foreground_animates_(0) {}
307 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
308 // Make sure that drawing many times doesn't cause a checkerboarded
309 // animation to start so we avoid flake in this test.
310 settings->timeout_and_draw_when_animation_checkerboards = false;
313 virtual void BeginTest() OVERRIDE {
314 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
317 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
318 base::TimeTicks monotonic_time) OVERRIDE {
319 EXPECT_GE(monotonic_time, last_tick_time_);
320 last_tick_time_ = monotonic_time;
321 if (host_impl->visible()) {
322 num_foreground_animates_++;
323 if (num_foreground_animates_ > 1 && !has_background_ticked_)
324 PostSetVisibleToMainThread(false);
325 else if (has_background_ticked_)
326 EndTest();
327 } else {
328 has_background_ticked_ = true;
329 PostSetVisibleToMainThread(true);
333 virtual DrawResult PrepareToDrawOnThread(
334 LayerTreeHostImpl* host_impl,
335 LayerTreeHostImpl::FrameData* frame,
336 DrawResult draw_result) OVERRIDE {
337 if (TestEnded())
338 return draw_result;
339 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
342 virtual void AfterTest() OVERRIDE {}
344 private:
345 bool has_background_ticked_;
346 int num_foreground_animates_;
347 base::TimeTicks last_tick_time_;
350 SINGLE_AND_MULTI_THREAD_TEST_F(
351 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic);
353 // Ensures that animations do not tick when we are backgrounded and
354 // and we have an empty active tree.
355 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
356 : public LayerTreeHostAnimationTest {
357 protected:
358 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
359 : active_tree_was_animated_(false) {}
361 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
362 return base::TimeDelta::FromMilliseconds(4);
365 virtual void BeginTest() OVERRIDE {
366 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
369 virtual void NotifyAnimationFinished(
370 base::TimeTicks monotonic_time,
371 Animation::TargetProperty target_property) OVERRIDE {
372 // Replace animated commits with an empty tree.
373 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
376 virtual void DidCommit() OVERRIDE {
377 // This alternates setting an empty tree and a non-empty tree with an
378 // animation.
379 switch (layer_tree_host()->source_frame_number()) {
380 case 1:
381 // Wait for NotifyAnimationFinished to commit an empty tree.
382 break;
383 case 2:
384 SetupTree();
385 AddOpacityTransitionToLayer(
386 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
387 break;
388 case 3:
389 // Wait for NotifyAnimationFinished to commit an empty tree.
390 break;
391 case 4:
392 EndTest();
393 break;
397 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
398 // At the start of every commit, block activations and make sure
399 // we are backgrounded.
400 host_impl->BlockNotifyReadyToActivateForTesting(true);
401 PostSetVisibleToMainThread(false);
404 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
405 if (!host_impl->settings().impl_side_painting) {
406 // There are no activations to block if we're not impl-side-painting,
407 // so just advance the test immediately.
408 if (host_impl->active_tree()->source_frame_number() < 3)
409 UnblockActivations(host_impl);
410 return;
413 // We block activation for several ticks to make sure that, even though
414 // there is a pending tree with animations, we still do not background
415 // tick if the active tree is empty.
416 if (host_impl->pending_tree()->source_frame_number() < 3) {
417 base::MessageLoopProxy::current()->PostDelayedTask(
418 FROM_HERE,
419 base::Bind(
420 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
421 UnblockActivations,
422 base::Unretained(this),
423 host_impl),
424 4 * LowFrequencyAnimationInterval());
428 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
429 host_impl->BlockNotifyReadyToActivateForTesting(false);
432 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
433 active_tree_was_animated_ = false;
435 // Verify that commits are actually alternating with empty / non-empty
436 // trees.
437 int frame_number = host_impl->active_tree()->source_frame_number();
438 switch (frame_number) {
439 case 0:
440 case 2:
441 EXPECT_TRUE(host_impl->active_tree()->root_layer())
442 << "frame: " << frame_number;
443 break;
444 case 1:
445 case 3:
446 EXPECT_FALSE(host_impl->active_tree()->root_layer())
447 << "frame: " << frame_number;
448 break;
451 if (host_impl->active_tree()->source_frame_number() < 3) {
452 // Initiate the next commit after a delay to give us a chance to
453 // background tick if the active tree isn't empty.
454 base::MessageLoopProxy::current()->PostDelayedTask(
455 FROM_HERE,
456 base::Bind(
457 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
458 InitiateNextCommit,
459 base::Unretained(this),
460 host_impl),
461 4 * LowFrequencyAnimationInterval());
465 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
466 base::TimeTicks monotonic_time) OVERRIDE {
467 EXPECT_TRUE(host_impl->active_tree()->root_layer());
468 active_tree_was_animated_ = true;
471 void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
472 // Verify that we actually animated when we should have.
473 bool has_active_tree = host_impl->active_tree()->root_layer();
474 EXPECT_EQ(has_active_tree, active_tree_was_animated_);
476 // The next commit is blocked until we become visible again.
477 PostSetVisibleToMainThread(true);
480 virtual void AfterTest() OVERRIDE {}
482 bool active_tree_was_animated_;
485 SINGLE_AND_MULTI_THREAD_TEST_F(
486 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
488 // Ensure that an animation's timing function is respected.
489 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
490 : public LayerTreeHostAnimationTest {
491 public:
492 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
494 virtual void SetupTree() OVERRIDE {
495 LayerTreeHostAnimationTest::SetupTree();
496 content_ = FakeContentLayer::Create(&client_);
497 content_->SetBounds(gfx::Size(4, 4));
498 layer_tree_host()->root_layer()->AddChild(content_);
501 virtual void BeginTest() OVERRIDE {
502 PostAddAnimationToMainThread(content_.get());
505 virtual void AnimateLayers(
506 LayerTreeHostImpl* host_impl,
507 base::TimeTicks monotonic_time) OVERRIDE {
508 LayerAnimationController* controller_impl =
509 host_impl->active_tree()->root_layer()->children()[0]->
510 layer_animation_controller();
511 Animation* animation =
512 controller_impl->GetAnimation(Animation::Opacity);
513 if (!animation)
514 return;
516 const FloatAnimationCurve* curve =
517 animation->curve()->ToFloatAnimationCurve();
518 float start_opacity = curve->GetValue(0.0);
519 float end_opacity = curve->GetValue(curve->Duration());
520 float linearly_interpolated_opacity =
521 0.25f * end_opacity + 0.75f * start_opacity;
522 double time = curve->Duration() * 0.25;
523 // If the linear timing function associated with this animation was not
524 // picked up, then the linearly interpolated opacity would be different
525 // because of the default ease timing function.
526 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
528 EndTest();
531 virtual void AfterTest() OVERRIDE {}
533 FakeContentLayerClient client_;
534 scoped_refptr<FakeContentLayer> content_;
537 SINGLE_AND_MULTI_THREAD_TEST_F(
538 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
540 // Ensures that main thread animations have their start times synchronized with
541 // impl thread animations.
542 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
543 : public LayerTreeHostAnimationTest {
544 public:
545 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
546 : main_start_time_(-1.0),
547 impl_start_time_(-1.0) {}
549 virtual void SetupTree() OVERRIDE {
550 LayerTreeHostAnimationTest::SetupTree();
551 content_ = FakeContentLayer::Create(&client_);
552 content_->SetBounds(gfx::Size(4, 4));
553 content_->set_layer_animation_delegate(this);
554 layer_tree_host()->root_layer()->AddChild(content_);
557 virtual void BeginTest() OVERRIDE {
558 PostAddAnimationToMainThread(content_.get());
561 virtual void NotifyAnimationStarted(
562 base::TimeTicks monotonic_time,
563 Animation::TargetProperty target_property) OVERRIDE {
564 LayerAnimationController* controller =
565 layer_tree_host()->root_layer()->children()[0]->
566 layer_animation_controller();
567 Animation* animation =
568 controller->GetAnimation(Animation::Opacity);
569 main_start_time_ =
570 (animation->start_time() - base::TimeTicks()).InSecondsF();
571 controller->RemoveAnimation(animation->id());
573 if (impl_start_time_ > 0.0)
574 EndTest();
577 virtual void UpdateAnimationState(
578 LayerTreeHostImpl* impl_host,
579 bool has_unfinished_animation) OVERRIDE {
580 LayerAnimationController* controller =
581 impl_host->active_tree()->root_layer()->children()[0]->
582 layer_animation_controller();
583 Animation* animation =
584 controller->GetAnimation(Animation::Opacity);
585 if (!animation)
586 return;
588 impl_start_time_ =
589 (animation->start_time() - base::TimeTicks()).InSecondsF();
590 controller->RemoveAnimation(animation->id());
592 if (main_start_time_ > 0.0)
593 EndTest();
596 virtual void AfterTest() OVERRIDE {
597 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_);
600 private:
601 double main_start_time_;
602 double impl_start_time_;
603 FakeContentLayerClient client_;
604 scoped_refptr<FakeContentLayer> content_;
607 SINGLE_AND_MULTI_THREAD_TEST_F(
608 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
610 // Ensures that notify animation finished is called.
611 class LayerTreeHostAnimationTestAnimationFinishedEvents
612 : public LayerTreeHostAnimationTest {
613 public:
614 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
616 virtual void BeginTest() OVERRIDE {
617 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
620 virtual void NotifyAnimationFinished(
621 base::TimeTicks monotonic_time,
622 Animation::TargetProperty target_property) OVERRIDE {
623 LayerAnimationController* controller =
624 layer_tree_host()->root_layer()->layer_animation_controller();
625 Animation* animation =
626 controller->GetAnimation(Animation::Opacity);
627 if (animation)
628 controller->RemoveAnimation(animation->id());
629 EndTest();
632 virtual void AfterTest() OVERRIDE {}
635 SINGLE_AND_MULTI_THREAD_TEST_F(
636 LayerTreeHostAnimationTestAnimationFinishedEvents);
638 // Ensures that when opacity is being animated, this value does not cause the
639 // subtree to be skipped.
640 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
641 : public LayerTreeHostAnimationTest {
642 public:
643 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
644 : update_check_layer_(FakeContentLayer::Create(&client_)) {
647 virtual void SetupTree() OVERRIDE {
648 update_check_layer_->SetOpacity(0.f);
649 layer_tree_host()->SetRootLayer(update_check_layer_);
650 LayerTreeHostAnimationTest::SetupTree();
653 virtual void BeginTest() OVERRIDE {
654 PostAddAnimationToMainThread(update_check_layer_.get());
657 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
658 LayerAnimationController* controller_impl =
659 host_impl->active_tree()->root_layer()->layer_animation_controller();
660 Animation* animation_impl =
661 controller_impl->GetAnimation(Animation::Opacity);
662 controller_impl->RemoveAnimation(animation_impl->id());
663 EndTest();
666 virtual void AfterTest() OVERRIDE {
667 // Update() should have been called once, proving that the layer was not
668 // skipped.
669 EXPECT_EQ(1u, update_check_layer_->update_count());
671 // clear update_check_layer_ so LayerTreeHost dies.
672 update_check_layer_ = NULL;
675 private:
676 FakeContentLayerClient client_;
677 scoped_refptr<FakeContentLayer> update_check_layer_;
680 SINGLE_AND_MULTI_THREAD_TEST_F(
681 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
683 // Layers added to tree with existing active animations should have the
684 // animation correctly recognized.
685 class LayerTreeHostAnimationTestLayerAddedWithAnimation
686 : public LayerTreeHostAnimationTest {
687 public:
688 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
690 virtual void BeginTest() OVERRIDE {
691 PostSetNeedsCommitToMainThread();
694 virtual void DidCommit() OVERRIDE {
695 if (layer_tree_host()->source_frame_number() == 1) {
696 scoped_refptr<Layer> layer = Layer::Create();
697 layer->set_layer_animation_delegate(this);
699 // Any valid AnimationCurve will do here.
700 scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create());
701 scoped_ptr<Animation> animation(
702 Animation::Create(curve.Pass(), 1, 1,
703 Animation::Opacity));
704 layer->layer_animation_controller()->AddAnimation(animation.Pass());
706 // We add the animation *before* attaching the layer to the tree.
707 layer_tree_host()->root_layer()->AddChild(layer);
711 virtual void AnimateLayers(
712 LayerTreeHostImpl* impl_host,
713 base::TimeTicks monotonic_time) OVERRIDE {
714 EndTest();
717 virtual void AfterTest() OVERRIDE {}
720 SINGLE_AND_MULTI_THREAD_TEST_F(
721 LayerTreeHostAnimationTestLayerAddedWithAnimation);
723 class LayerTreeHostAnimationTestCancelAnimateCommit
724 : public LayerTreeHostAnimationTest {
725 public:
726 LayerTreeHostAnimationTestCancelAnimateCommit()
727 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
729 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
731 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
732 num_begin_frames_++;
733 // No-op animate will cancel the commit.
734 if (layer_tree_host()->source_frame_number() == 1) {
735 EndTest();
736 return;
738 layer_tree_host()->SetNeedsAnimate();
741 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
742 num_commit_calls_++;
743 if (impl->active_tree()->source_frame_number() > 1)
744 FAIL() << "Commit should have been canceled.";
747 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
748 num_draw_calls_++;
749 if (impl->active_tree()->source_frame_number() > 1)
750 FAIL() << "Draw should have been canceled.";
753 virtual void AfterTest() OVERRIDE {
754 EXPECT_EQ(2, num_begin_frames_);
755 EXPECT_EQ(1, num_commit_calls_);
756 EXPECT_EQ(1, num_draw_calls_);
759 private:
760 int num_begin_frames_;
761 int num_commit_calls_;
762 int num_draw_calls_;
763 FakeContentLayerClient client_;
764 scoped_refptr<FakeContentLayer> content_;
767 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
769 class LayerTreeHostAnimationTestForceRedraw
770 : public LayerTreeHostAnimationTest {
771 public:
772 LayerTreeHostAnimationTestForceRedraw()
773 : num_animate_(0), num_draw_layers_(0) {}
775 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
777 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
778 if (++num_animate_ < 2)
779 layer_tree_host()->SetNeedsAnimate();
782 virtual void Layout() OVERRIDE {
783 layer_tree_host()->SetNextCommitForcesRedraw();
786 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
787 if (++num_draw_layers_ == 2)
788 EndTest();
791 virtual void AfterTest() OVERRIDE {
792 // The first commit will always draw; make sure the second draw triggered
793 // by the animation was not cancelled.
794 EXPECT_EQ(2, num_draw_layers_);
795 EXPECT_EQ(2, num_animate_);
798 private:
799 int num_animate_;
800 int num_draw_layers_;
803 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
805 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
806 : public LayerTreeHostAnimationTest {
807 public:
808 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
809 : num_animate_(0), num_draw_layers_(0) {}
811 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
813 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
814 if (++num_animate_ <= 2) {
815 layer_tree_host()->SetNeedsCommit();
816 layer_tree_host()->SetNeedsAnimate();
820 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
821 if (++num_draw_layers_ == 2)
822 EndTest();
825 virtual void AfterTest() OVERRIDE {
826 // The first commit will always draw; make sure the second draw triggered
827 // by the SetNeedsCommit was not cancelled.
828 EXPECT_EQ(2, num_draw_layers_);
829 EXPECT_GE(num_animate_, 2);
832 private:
833 int num_animate_;
834 int num_draw_layers_;
837 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
839 // Make sure the main thread can still execute animations when CanDraw() is not
840 // true.
841 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
842 : public LayerTreeHostAnimationTest {
843 public:
844 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
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_);
854 virtual void BeginTest() OVERRIDE {
855 layer_tree_host()->SetViewportSize(gfx::Size());
856 PostAddAnimationToMainThread(content_.get());
859 virtual void NotifyAnimationStarted(
860 base::TimeTicks monotonic_time,
861 Animation::TargetProperty target_property) OVERRIDE {
862 started_times_++;
865 virtual void NotifyAnimationFinished(
866 base::TimeTicks monotonic_time,
867 Animation::TargetProperty target_property) OVERRIDE {
868 EndTest();
871 virtual void AfterTest() OVERRIDE {
872 EXPECT_EQ(1, started_times_);
875 private:
876 int started_times_;
877 FakeContentLayerClient client_;
878 scoped_refptr<FakeContentLayer> content_;
881 SINGLE_AND_MULTI_THREAD_TEST_F(
882 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
884 // Make sure the main thread can still execute animations when the renderer is
885 // backgrounded.
886 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
887 : public LayerTreeHostAnimationTest {
888 public:
889 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
891 virtual void SetupTree() OVERRIDE {
892 LayerTreeHostAnimationTest::SetupTree();
893 content_ = FakeContentLayer::Create(&client_);
894 content_->SetBounds(gfx::Size(4, 4));
895 content_->set_layer_animation_delegate(this);
896 layer_tree_host()->root_layer()->AddChild(content_);
899 virtual void BeginTest() OVERRIDE {
900 visible_ = true;
901 PostAddAnimationToMainThread(content_.get());
904 virtual void DidCommit() OVERRIDE {
905 visible_ = false;
906 layer_tree_host()->SetVisible(false);
909 virtual void NotifyAnimationStarted(
910 base::TimeTicks monotonic_time,
911 Animation::TargetProperty target_property) OVERRIDE {
912 EXPECT_FALSE(visible_);
913 started_times_++;
916 virtual void NotifyAnimationFinished(
917 base::TimeTicks monotonic_time,
918 Animation::TargetProperty target_property) OVERRIDE {
919 EXPECT_FALSE(visible_);
920 EXPECT_EQ(1, started_times_);
921 EndTest();
924 virtual void AfterTest() OVERRIDE {}
926 private:
927 bool visible_;
928 int started_times_;
929 FakeContentLayerClient client_;
930 scoped_refptr<FakeContentLayer> content_;
933 SINGLE_AND_MULTI_THREAD_TEST_F(
934 LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
936 // Animations should not be started when frames are being skipped due to
937 // checkerboard.
938 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
939 : public LayerTreeHostAnimationTest {
940 virtual void SetupTree() OVERRIDE {
941 LayerTreeHostAnimationTest::SetupTree();
942 content_ = FakeContentLayer::Create(&client_);
943 content_->SetBounds(gfx::Size(4, 4));
944 content_->set_layer_animation_delegate(this);
945 layer_tree_host()->root_layer()->AddChild(content_);
948 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
949 // Make sure that drawing many times doesn't cause a checkerboarded
950 // animation to start so we avoid flake in this test.
951 settings->timeout_and_draw_when_animation_checkerboards = false;
954 virtual void BeginTest() OVERRIDE {
955 prevented_draw_ = 0;
956 added_animations_ = 0;
957 started_times_ = 0;
959 PostSetNeedsCommitToMainThread();
962 virtual DrawResult PrepareToDrawOnThread(
963 LayerTreeHostImpl* host_impl,
964 LayerTreeHostImpl::FrameData* frame_data,
965 DrawResult draw_result) OVERRIDE {
966 if (added_animations_ < 2)
967 return draw_result;
968 if (TestEnded())
969 return draw_result;
970 // Act like there is checkerboard when the second animation wants to draw.
971 ++prevented_draw_;
972 if (prevented_draw_ > 2)
973 EndTest();
974 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
977 virtual void DidCommitAndDrawFrame() OVERRIDE {
978 switch (layer_tree_host()->source_frame_number()) {
979 case 1:
980 // The animation is longer than 1 BeginFrame interval.
981 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
982 added_animations_++;
983 break;
984 case 2:
985 // This second animation will not be drawn so it should not start.
986 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
987 added_animations_++;
988 break;
992 virtual void NotifyAnimationStarted(
993 base::TimeTicks monotonic_time,
994 Animation::TargetProperty target_property) OVERRIDE {
995 if (TestEnded())
996 return;
997 started_times_++;
1000 virtual void AfterTest() OVERRIDE {
1001 // Make sure we tried to draw the second animation but failed.
1002 EXPECT_LT(0, prevented_draw_);
1003 // The first animation should be started, but the second should not because
1004 // of checkerboard.
1005 EXPECT_EQ(1, started_times_);
1008 int prevented_draw_;
1009 int added_animations_;
1010 int started_times_;
1011 FakeContentLayerClient client_;
1012 scoped_refptr<FakeContentLayer> content_;
1015 MULTI_THREAD_TEST_F(
1016 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
1018 // Verifies that scroll offset animations are only accepted when impl-scrolling
1019 // is supported, and that when scroll offset animations are accepted,
1020 // scroll offset updates are sent back to the main thread.
1021 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
1022 : public LayerTreeHostAnimationTest {
1023 public:
1024 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
1026 virtual void SetupTree() OVERRIDE {
1027 LayerTreeHostAnimationTest::SetupTree();
1029 scroll_layer_ = FakeContentLayer::Create(&client_);
1030 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
1031 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
1032 scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20));
1033 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1036 virtual void BeginTest() OVERRIDE {
1037 PostSetNeedsCommitToMainThread();
1040 virtual void DidCommit() OVERRIDE {
1041 switch (layer_tree_host()->source_frame_number()) {
1042 case 1: {
1043 scoped_ptr<ScrollOffsetAnimationCurve> curve(
1044 ScrollOffsetAnimationCurve::Create(
1045 gfx::Vector2dF(500.f, 550.f),
1046 EaseInOutTimingFunction::Create()));
1047 scoped_ptr<Animation> animation(Animation::Create(
1048 curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset));
1049 animation->set_needs_synchronized_start_time(true);
1050 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
1051 bool impl_scrolling_supported =
1052 layer_tree_host()->proxy()->SupportsImplScrolling();
1053 EXPECT_EQ(impl_scrolling_supported, animation_added);
1054 if (!impl_scrolling_supported)
1055 EndTest();
1056 break;
1058 default:
1059 if (scroll_layer_->scroll_offset().x() > 10 &&
1060 scroll_layer_->scroll_offset().y() > 20)
1061 EndTest();
1065 virtual void AfterTest() OVERRIDE {}
1067 private:
1068 FakeContentLayerClient client_;
1069 scoped_refptr<FakeContentLayer> scroll_layer_;
1072 SINGLE_AND_MULTI_THREAD_TEST_F(
1073 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
1075 // Ensure that animation time is correctly updated when animations are frozen
1076 // because of checkerboarding.
1077 class LayerTreeHostAnimationTestFrozenAnimationTickTime
1078 : public LayerTreeHostAnimationTest {
1079 public:
1080 LayerTreeHostAnimationTestFrozenAnimationTickTime()
1081 : started_animating_(false), num_commits_(0), num_draw_attempts_(2) {}
1083 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1084 // Make sure that drawing many times doesn't cause a checkerboarded
1085 // animation to start so we avoid flake in this test.
1086 settings->timeout_and_draw_when_animation_checkerboards = false;
1089 virtual void BeginTest() OVERRIDE {
1090 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
1093 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE {
1094 last_main_thread_tick_time_ = args.frame_time;
1097 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
1098 base::TimeTicks monotonic_time) OVERRIDE {
1099 if (TestEnded())
1100 return;
1101 if (!started_animating_) {
1102 started_animating_ = true;
1103 expected_impl_tick_time_ = monotonic_time;
1104 } else {
1105 EXPECT_EQ(expected_impl_tick_time_, monotonic_time);
1106 if (num_commits_ > 2)
1107 EndTest();
1111 virtual DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1112 LayerTreeHostImpl::FrameData* frame,
1113 DrawResult draw_result) OVERRIDE {
1114 if (TestEnded())
1115 return draw_result;
1116 num_draw_attempts_++;
1117 if (num_draw_attempts_ > 2) {
1118 num_draw_attempts_ = 0;
1119 PostSetNeedsCommitToMainThread();
1121 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
1124 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1125 if (!started_animating_)
1126 return;
1127 expected_impl_tick_time_ =
1128 std::max(expected_impl_tick_time_, last_main_thread_tick_time_);
1129 num_commits_++;
1132 virtual void AfterTest() OVERRIDE {}
1134 private:
1135 bool started_animating_;
1136 int num_commits_;
1137 int num_draw_attempts_;
1138 base::TimeTicks last_main_thread_tick_time_;
1139 base::TimeTicks expected_impl_tick_time_;
1142 // Only the non-impl-paint multi-threaded compositor freezes animations.
1143 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime);
1145 // When animations are simultaneously added to an existing layer and to a new
1146 // layer, they should start at the same time, even when there's already a
1147 // running animation on the existing layer.
1148 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1149 : public LayerTreeHostAnimationTest {
1150 public:
1151 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1152 : frame_count_with_pending_tree_(0) {}
1154 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1156 virtual void DidCommit() OVERRIDE {
1157 if (layer_tree_host()->source_frame_number() == 1) {
1158 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1159 } else if (layer_tree_host()->source_frame_number() == 2) {
1160 AddOpacityTransitionToLayer(
1161 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
1163 scoped_refptr<Layer> layer = Layer::Create();
1164 layer_tree_host()->root_layer()->AddChild(layer);
1165 layer->set_layer_animation_delegate(this);
1166 layer->SetBounds(gfx::Size(4, 4));
1167 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
1171 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1172 host_impl->BlockNotifyReadyToActivateForTesting(true);
1175 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1176 // For the commit that added animations to new and existing layers, keep
1177 // blocking activation. We want to verify that even with activation blocked,
1178 // the animation on the layer that's already in the active tree won't get a
1179 // head start.
1180 if (!host_impl->settings().impl_side_painting ||
1181 host_impl->pending_tree()->source_frame_number() != 2)
1182 host_impl->BlockNotifyReadyToActivateForTesting(false);
1185 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1186 const BeginFrameArgs& args) OVERRIDE {
1187 if (!host_impl->pending_tree() ||
1188 host_impl->pending_tree()->source_frame_number() != 2)
1189 return;
1191 frame_count_with_pending_tree_++;
1192 if (frame_count_with_pending_tree_ == 2)
1193 host_impl->BlockNotifyReadyToActivateForTesting(false);
1196 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1197 bool has_unfinished_animation) OVERRIDE {
1198 LayerAnimationController* root_controller_impl =
1199 host_impl->active_tree()->root_layer()->layer_animation_controller();
1200 Animation* root_animation =
1201 root_controller_impl->GetAnimation(Animation::Opacity);
1202 if (!root_animation || root_animation->run_state() != Animation::Running)
1203 return;
1205 LayerAnimationController* child_controller_impl =
1206 host_impl->active_tree()->root_layer()->children()
1207 [0]->layer_animation_controller();
1208 Animation* child_animation =
1209 child_controller_impl->GetAnimation(Animation::Opacity);
1210 EXPECT_EQ(Animation::Running, child_animation->run_state());
1211 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
1212 root_controller_impl->AbortAnimations(Animation::Opacity);
1213 root_controller_impl->AbortAnimations(Animation::Transform);
1214 child_controller_impl->AbortAnimations(Animation::Opacity);
1215 EndTest();
1218 virtual void AfterTest() OVERRIDE {}
1220 private:
1221 int frame_count_with_pending_tree_;
1224 SINGLE_AND_MULTI_THREAD_TEST_F(
1225 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
1227 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1228 : public LayerTreeHostAnimationTest {
1229 public:
1230 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1231 : num_swap_buffers_(0) {}
1233 virtual void SetupTree() OVERRIDE {
1234 LayerTreeHostAnimationTest::SetupTree();
1235 content_ = Layer::Create();
1236 content_->SetBounds(gfx::Size(4, 4));
1237 layer_tree_host()->root_layer()->AddChild(content_);
1240 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1242 virtual void DidCommit() OVERRIDE {
1243 switch (layer_tree_host()->source_frame_number()) {
1244 case 1:
1245 // First frame: add an animation to the root layer.
1246 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1247 break;
1248 case 2:
1249 // Second frame: add an animation to the content layer. The root layer
1250 // animation has caused us to animate already during this frame.
1251 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
1252 break;
1256 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1257 bool result) OVERRIDE {
1258 // After both animations have started, verify that they have valid
1259 // start times.
1260 num_swap_buffers_++;
1261 AnimationRegistrar::AnimationControllerMap copy =
1262 host_impl->animation_registrar()->active_animation_controllers();
1263 if (copy.size() == 2u) {
1264 EndTest();
1265 EXPECT_GE(num_swap_buffers_, 3);
1266 for (AnimationRegistrar::AnimationControllerMap::iterator iter =
1267 copy.begin();
1268 iter != copy.end();
1269 ++iter) {
1270 int id = ((*iter).second->id());
1271 if (id == host_impl->RootLayer()->id()) {
1272 Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
1273 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1274 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1275 Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
1276 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1282 virtual void AfterTest() OVERRIDE {}
1284 private:
1285 scoped_refptr<Layer> content_;
1286 int num_swap_buffers_;
1289 SINGLE_AND_MULTI_THREAD_TEST_F(
1290 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1292 } // namespace
1293 } // namespace cc