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"
22 class LayerTreeHostAnimationTest : public LayerTreeTest {
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
32 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
33 : public LayerTreeHostAnimationTest {
35 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
38 virtual void BeginTest() OVERRIDE {
39 PostSetNeedsCommitToMainThread();
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)
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 {
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());
69 virtual void AfterTest() OVERRIDE {}
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
83 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
84 : public LayerTreeHostAnimationTest {
86 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
89 virtual void BeginTest() OVERRIDE {
90 PostSetNeedsCommitToMainThread();
93 virtual void Animate(base::TimeTicks) OVERRIDE {
95 layer_tree_host()->SetNeedsAnimate();
102 virtual void AfterTest() OVERRIDE {}
109 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
111 // Add a layer animation and confirm that
112 // LayerTreeHostImpl::updateAnimationState does get called and continues to
114 class LayerTreeHostAnimationTestAddAnimation
115 : public LayerTreeHostAnimationTest {
117 LayerTreeHostAnimationTestAddAnimation()
119 received_animation_started_notification_(false) {
122 virtual void BeginTest() OVERRIDE {
123 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
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);
137 if (received_animation_started_notification_) {
138 EXPECT_LT(base::TimeTicks(), start_time_);
140 LayerAnimationController* controller_impl =
141 host_impl->active_tree()->root_layer()->layer_animation_controller();
142 Animation* animation_impl =
143 controller_impl->GetAnimation(Animation::Opacity);
145 controller_impl->RemoveAnimation(animation_impl->id());
151 virtual void NotifyAnimationStarted(
152 base::TimeTicks monotonic_time,
153 Animation::TargetProperty target_property) OVERRIDE {
154 received_animation_started_notification_ = true;
155 start_time_ = monotonic_time;
157 EXPECT_LT(base::TimeTicks(), start_time_);
159 LayerAnimationController* controller =
160 layer_tree_host()->root_layer()->layer_animation_controller();
161 Animation* animation =
162 controller->GetAnimation(Animation::Opacity);
164 controller->RemoveAnimation(animation->id());
170 virtual void AfterTest() OVERRIDE {}
174 bool received_animation_started_notification_;
175 base::TimeTicks start_time_;
178 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
180 // Add a layer animation to a layer, but continually fail to draw. Confirm that
181 // after a while, we do eventually force a draw.
182 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
183 : public LayerTreeHostAnimationTest {
185 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
186 : started_animating_(false) {}
188 virtual void BeginTest() OVERRIDE {
189 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
192 virtual void AnimateLayers(
193 LayerTreeHostImpl* host_impl,
194 base::TimeTicks monotonic_time) OVERRIDE {
195 started_animating_ = true;
198 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
199 if (started_animating_)
203 virtual DrawResult PrepareToDrawOnThread(
204 LayerTreeHostImpl* host_impl,
205 LayerTreeHostImpl::FrameData* frame,
206 DrawResult draw_result) OVERRIDE {
207 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
210 virtual void AfterTest() OVERRIDE { }
213 bool started_animating_;
216 // Starvation can only be an issue with the MT compositor.
217 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
219 // Ensures that animations eventually get deleted.
220 class LayerTreeHostAnimationTestAnimationsGetDeleted
221 : public LayerTreeHostAnimationTest {
223 LayerTreeHostAnimationTestAnimationsGetDeleted()
224 : started_animating_(false) {}
226 virtual void BeginTest() OVERRIDE {
227 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
230 virtual void AnimateLayers(
231 LayerTreeHostImpl* host_impl,
232 base::TimeTicks monotonic_time) OVERRIDE {
233 bool have_animations = !host_impl->animation_registrar()->
234 active_animation_controllers().empty();
235 if (!started_animating_ && have_animations) {
236 started_animating_ = true;
240 if (started_animating_ && !have_animations)
244 virtual void NotifyAnimationFinished(
245 base::TimeTicks monotonic_time,
246 Animation::TargetProperty target_property) OVERRIDE {
247 // Animations on the impl-side controller only get deleted during a commit,
248 // so we need to schedule a commit.
249 layer_tree_host()->SetNeedsCommit();
252 virtual void AfterTest() OVERRIDE {}
255 bool started_animating_;
258 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
260 // Ensures that animations continue to be ticked when we are backgrounded.
261 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
262 : public LayerTreeHostAnimationTest {
264 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
265 : num_animates_(0) {}
267 virtual void BeginTest() OVERRIDE {
268 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
271 // Use WillAnimateLayers to set visible false before the animation runs and
272 // causes a commit, so we block the second visible animate in single-thread
274 virtual void WillAnimateLayers(
275 LayerTreeHostImpl* host_impl,
276 base::TimeTicks monotonic_time) OVERRIDE {
277 // Verify that the host can draw, it's just not visible.
278 EXPECT_TRUE(host_impl->CanDraw());
279 if (num_animates_ < 2) {
280 if (!num_animates_) {
281 // We have a long animation running. It should continue to tick even
282 // if we are not visible.
283 PostSetVisibleToMainThread(false);
291 virtual void AfterTest() OVERRIDE {}
297 SINGLE_AND_MULTI_THREAD_TEST_F(
298 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
300 // Ensures that animation time remains monotonic when we switch from foreground
301 // to background ticking and back, even if we're skipping draws due to
302 // checkerboarding when in the foreground.
303 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
304 : public LayerTreeHostAnimationTest {
306 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
307 : has_background_ticked_(false), num_foreground_animates_(0) {}
309 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
310 // Make sure that drawing many times doesn't cause a checkerboarded
311 // animation to start so we avoid flake in this test.
312 settings->timeout_and_draw_when_animation_checkerboards = false;
315 virtual void BeginTest() OVERRIDE {
316 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
319 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
320 base::TimeTicks monotonic_time) OVERRIDE {
321 EXPECT_GE(monotonic_time, last_tick_time_);
322 last_tick_time_ = monotonic_time;
323 if (host_impl->visible()) {
324 num_foreground_animates_++;
325 if (num_foreground_animates_ > 1 && !has_background_ticked_)
326 PostSetVisibleToMainThread(false);
327 else if (has_background_ticked_)
330 has_background_ticked_ = true;
331 PostSetVisibleToMainThread(true);
335 virtual DrawResult PrepareToDrawOnThread(
336 LayerTreeHostImpl* host_impl,
337 LayerTreeHostImpl::FrameData* frame,
338 DrawResult draw_result) OVERRIDE {
341 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
344 virtual void AfterTest() OVERRIDE {}
347 bool has_background_ticked_;
348 int num_foreground_animates_;
349 base::TimeTicks last_tick_time_;
352 SINGLE_AND_MULTI_THREAD_TEST_F(
353 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic);
355 // Ensures that animations do not tick when we are backgrounded and
356 // and we have an empty active tree.
357 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
358 : public LayerTreeHostAnimationTest {
360 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
361 : active_tree_was_animated_(false) {}
363 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
364 return base::TimeDelta::FromMilliseconds(4);
367 virtual void BeginTest() OVERRIDE {
368 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
371 virtual void NotifyAnimationFinished(
372 base::TimeTicks monotonic_time,
373 Animation::TargetProperty target_property) OVERRIDE {
374 // Replace animated commits with an empty tree.
375 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
378 virtual void DidCommit() OVERRIDE {
379 // This alternates setting an empty tree and a non-empty tree with an
381 switch (layer_tree_host()->source_frame_number()) {
383 // Wait for NotifyAnimationFinished to commit an empty tree.
387 AddOpacityTransitionToLayer(
388 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
391 // Wait for NotifyAnimationFinished to commit an empty tree.
399 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
400 // At the start of every commit, block activations and make sure
401 // we are backgrounded.
402 host_impl->BlockNotifyReadyToActivateForTesting(true);
403 PostSetVisibleToMainThread(false);
406 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
407 if (!host_impl->settings().impl_side_painting) {
408 // There are no activations to block if we're not impl-side-painting,
409 // so just advance the test immediately.
410 if (host_impl->active_tree()->source_frame_number() < 3)
411 UnblockActivations(host_impl);
415 // We block activation for several ticks to make sure that, even though
416 // there is a pending tree with animations, we still do not background
417 // tick if the active tree is empty.
418 if (host_impl->pending_tree()->source_frame_number() < 3) {
419 base::MessageLoopProxy::current()->PostDelayedTask(
422 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
424 base::Unretained(this),
426 4 * LowFrequencyAnimationInterval());
430 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
431 host_impl->BlockNotifyReadyToActivateForTesting(false);
434 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
435 active_tree_was_animated_ = false;
437 // Verify that commits are actually alternating with empty / non-empty
439 int frame_number = host_impl->active_tree()->source_frame_number();
440 switch (frame_number) {
443 EXPECT_TRUE(host_impl->active_tree()->root_layer())
444 << "frame: " << frame_number;
448 EXPECT_FALSE(host_impl->active_tree()->root_layer())
449 << "frame: " << frame_number;
453 if (host_impl->active_tree()->source_frame_number() < 3) {
454 // Initiate the next commit after a delay to give us a chance to
455 // background tick if the active tree isn't empty.
456 base::MessageLoopProxy::current()->PostDelayedTask(
459 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
461 base::Unretained(this),
463 4 * LowFrequencyAnimationInterval());
467 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
468 base::TimeTicks monotonic_time) OVERRIDE {
469 EXPECT_TRUE(host_impl->active_tree()->root_layer());
470 active_tree_was_animated_ = true;
473 void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
474 // Verify that we actually animated when we should have.
475 bool has_active_tree = host_impl->active_tree()->root_layer();
476 EXPECT_EQ(has_active_tree, active_tree_was_animated_);
478 // The next commit is blocked until we become visible again.
479 PostSetVisibleToMainThread(true);
482 virtual void AfterTest() OVERRIDE {}
484 bool active_tree_was_animated_;
487 SINGLE_AND_MULTI_THREAD_TEST_F(
488 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
490 // Ensure that an animation's timing function is respected.
491 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
492 : public LayerTreeHostAnimationTest {
494 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
496 virtual void SetupTree() OVERRIDE {
497 LayerTreeHostAnimationTest::SetupTree();
498 content_ = FakeContentLayer::Create(&client_);
499 content_->SetBounds(gfx::Size(4, 4));
500 layer_tree_host()->root_layer()->AddChild(content_);
503 virtual void BeginTest() OVERRIDE {
504 PostAddAnimationToMainThread(content_.get());
507 virtual void AnimateLayers(
508 LayerTreeHostImpl* host_impl,
509 base::TimeTicks monotonic_time) OVERRIDE {
510 LayerAnimationController* controller_impl =
511 host_impl->active_tree()->root_layer()->children()[0]->
512 layer_animation_controller();
513 Animation* animation =
514 controller_impl->GetAnimation(Animation::Opacity);
518 const FloatAnimationCurve* curve =
519 animation->curve()->ToFloatAnimationCurve();
520 float start_opacity = curve->GetValue(0.0);
521 float end_opacity = curve->GetValue(curve->Duration());
522 float linearly_interpolated_opacity =
523 0.25f * end_opacity + 0.75f * start_opacity;
524 double time = curve->Duration() * 0.25;
525 // If the linear timing function associated with this animation was not
526 // picked up, then the linearly interpolated opacity would be different
527 // because of the default ease timing function.
528 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
533 virtual void AfterTest() OVERRIDE {}
535 FakeContentLayerClient client_;
536 scoped_refptr<FakeContentLayer> content_;
539 SINGLE_AND_MULTI_THREAD_TEST_F(
540 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
542 // Ensures that main thread animations have their start times synchronized with
543 // impl thread animations.
544 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
545 : public LayerTreeHostAnimationTest {
547 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
548 : main_start_time_(-1.0),
549 impl_start_time_(-1.0) {}
551 virtual void SetupTree() OVERRIDE {
552 LayerTreeHostAnimationTest::SetupTree();
553 content_ = FakeContentLayer::Create(&client_);
554 content_->SetBounds(gfx::Size(4, 4));
555 content_->set_layer_animation_delegate(this);
556 layer_tree_host()->root_layer()->AddChild(content_);
559 virtual void BeginTest() OVERRIDE {
560 PostAddAnimationToMainThread(content_.get());
563 virtual void NotifyAnimationStarted(
564 base::TimeTicks monotonic_time,
565 Animation::TargetProperty target_property) OVERRIDE {
566 LayerAnimationController* controller =
567 layer_tree_host()->root_layer()->children()[0]->
568 layer_animation_controller();
569 Animation* animation =
570 controller->GetAnimation(Animation::Opacity);
572 (animation->start_time() - base::TimeTicks()).InSecondsF();
573 controller->RemoveAnimation(animation->id());
575 if (impl_start_time_ > 0.0)
579 virtual void UpdateAnimationState(
580 LayerTreeHostImpl* impl_host,
581 bool has_unfinished_animation) OVERRIDE {
582 LayerAnimationController* controller =
583 impl_host->active_tree()->root_layer()->children()[0]->
584 layer_animation_controller();
585 Animation* animation =
586 controller->GetAnimation(Animation::Opacity);
591 (animation->start_time() - base::TimeTicks()).InSecondsF();
592 controller->RemoveAnimation(animation->id());
594 if (main_start_time_ > 0.0)
598 virtual void AfterTest() OVERRIDE {
599 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_);
603 double main_start_time_;
604 double impl_start_time_;
605 FakeContentLayerClient client_;
606 scoped_refptr<FakeContentLayer> content_;
609 SINGLE_AND_MULTI_THREAD_TEST_F(
610 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
612 // Ensures that notify animation finished is called.
613 class LayerTreeHostAnimationTestAnimationFinishedEvents
614 : public LayerTreeHostAnimationTest {
616 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
618 virtual void BeginTest() OVERRIDE {
619 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
622 virtual void NotifyAnimationFinished(
623 base::TimeTicks monotonic_time,
624 Animation::TargetProperty target_property) OVERRIDE {
625 LayerAnimationController* controller =
626 layer_tree_host()->root_layer()->layer_animation_controller();
627 Animation* animation =
628 controller->GetAnimation(Animation::Opacity);
630 controller->RemoveAnimation(animation->id());
634 virtual void AfterTest() OVERRIDE {}
637 SINGLE_AND_MULTI_THREAD_TEST_F(
638 LayerTreeHostAnimationTestAnimationFinishedEvents);
640 // Ensures that when opacity is being animated, this value does not cause the
641 // subtree to be skipped.
642 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
643 : public LayerTreeHostAnimationTest {
645 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
646 : update_check_layer_(FakeContentLayer::Create(&client_)) {
649 virtual void SetupTree() OVERRIDE {
650 update_check_layer_->SetOpacity(0.f);
651 layer_tree_host()->SetRootLayer(update_check_layer_);
652 LayerTreeHostAnimationTest::SetupTree();
655 virtual void BeginTest() OVERRIDE {
656 PostAddAnimationToMainThread(update_check_layer_.get());
659 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
660 LayerAnimationController* controller_impl =
661 host_impl->active_tree()->root_layer()->layer_animation_controller();
662 Animation* animation_impl =
663 controller_impl->GetAnimation(Animation::Opacity);
664 controller_impl->RemoveAnimation(animation_impl->id());
668 virtual void AfterTest() OVERRIDE {
669 // Update() should have been called once, proving that the layer was not
671 EXPECT_EQ(1u, update_check_layer_->update_count());
673 // clear update_check_layer_ so LayerTreeHost dies.
674 update_check_layer_ = NULL;
678 FakeContentLayerClient client_;
679 scoped_refptr<FakeContentLayer> update_check_layer_;
682 SINGLE_AND_MULTI_THREAD_TEST_F(
683 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
685 // Layers added to tree with existing active animations should have the
686 // animation correctly recognized.
687 class LayerTreeHostAnimationTestLayerAddedWithAnimation
688 : public LayerTreeHostAnimationTest {
690 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
692 virtual void BeginTest() OVERRIDE {
693 PostSetNeedsCommitToMainThread();
696 virtual void DidCommit() OVERRIDE {
697 if (layer_tree_host()->source_frame_number() == 1) {
698 scoped_refptr<Layer> layer = Layer::Create();
699 layer->set_layer_animation_delegate(this);
701 // Any valid AnimationCurve will do here.
702 scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create());
703 scoped_ptr<Animation> animation(
704 Animation::Create(curve.Pass(), 1, 1,
705 Animation::Opacity));
706 layer->layer_animation_controller()->AddAnimation(animation.Pass());
708 // We add the animation *before* attaching the layer to the tree.
709 layer_tree_host()->root_layer()->AddChild(layer);
713 virtual void AnimateLayers(
714 LayerTreeHostImpl* impl_host,
715 base::TimeTicks monotonic_time) OVERRIDE {
719 virtual void AfterTest() OVERRIDE {}
722 SINGLE_AND_MULTI_THREAD_TEST_F(
723 LayerTreeHostAnimationTestLayerAddedWithAnimation);
725 class LayerTreeHostAnimationTestCancelAnimateCommit
726 : public LayerTreeHostAnimationTest {
728 LayerTreeHostAnimationTestCancelAnimateCommit()
729 : num_animate_calls_(0), num_commit_calls_(0), num_draw_calls_(0) {}
731 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
733 virtual void Animate(base::TimeTicks) OVERRIDE {
734 num_animate_calls_++;
735 // No-op animate will cancel the commit.
736 if (layer_tree_host()->source_frame_number() == 1) {
740 layer_tree_host()->SetNeedsAnimate();
743 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE {
745 if (impl->active_tree()->source_frame_number() > 1)
746 FAIL() << "Commit should have been canceled.";
749 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
751 if (impl->active_tree()->source_frame_number() > 1)
752 FAIL() << "Draw should have been canceled.";
755 virtual void AfterTest() OVERRIDE {
756 EXPECT_EQ(2, num_animate_calls_);
757 EXPECT_EQ(1, num_commit_calls_);
758 EXPECT_EQ(1, num_draw_calls_);
762 int num_animate_calls_;
763 int num_commit_calls_;
765 FakeContentLayerClient client_;
766 scoped_refptr<FakeContentLayer> content_;
769 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
771 class LayerTreeHostAnimationTestForceRedraw
772 : public LayerTreeHostAnimationTest {
774 LayerTreeHostAnimationTestForceRedraw()
775 : num_animate_(0), num_draw_layers_(0) {}
777 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
779 virtual void Animate(base::TimeTicks) OVERRIDE {
780 if (++num_animate_ < 2)
781 layer_tree_host()->SetNeedsAnimate();
784 virtual void Layout() OVERRIDE {
785 layer_tree_host()->SetNextCommitForcesRedraw();
788 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
789 if (++num_draw_layers_ == 2)
793 virtual void AfterTest() OVERRIDE {
794 // The first commit will always draw; make sure the second draw triggered
795 // by the animation was not cancelled.
796 EXPECT_EQ(2, num_draw_layers_);
797 EXPECT_EQ(2, num_animate_);
802 int num_draw_layers_;
805 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
807 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
808 : public LayerTreeHostAnimationTest {
810 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
811 : num_animate_(0), num_draw_layers_(0) {}
813 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
815 virtual void Animate(base::TimeTicks) OVERRIDE {
816 if (++num_animate_ <= 2) {
817 layer_tree_host()->SetNeedsCommit();
818 layer_tree_host()->SetNeedsAnimate();
822 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
823 if (++num_draw_layers_ == 2)
827 virtual void AfterTest() OVERRIDE {
828 // The first commit will always draw; make sure the second draw triggered
829 // by the SetNeedsCommit was not cancelled.
830 EXPECT_EQ(2, num_draw_layers_);
831 EXPECT_GE(num_animate_, 2);
836 int num_draw_layers_;
839 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
841 // Make sure the main thread can still execute animations when CanDraw() is not
843 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
844 : public LayerTreeHostAnimationTest {
846 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
848 virtual void SetupTree() OVERRIDE {
849 LayerTreeHostAnimationTest::SetupTree();
850 content_ = FakeContentLayer::Create(&client_);
851 content_->SetBounds(gfx::Size(4, 4));
852 content_->set_layer_animation_delegate(this);
853 layer_tree_host()->root_layer()->AddChild(content_);
856 virtual void BeginTest() OVERRIDE {
857 layer_tree_host()->SetViewportSize(gfx::Size());
858 PostAddAnimationToMainThread(content_.get());
861 virtual void NotifyAnimationStarted(
862 base::TimeTicks monotonic_time,
863 Animation::TargetProperty target_property) OVERRIDE {
867 virtual void NotifyAnimationFinished(
868 base::TimeTicks monotonic_time,
869 Animation::TargetProperty target_property) OVERRIDE {
873 virtual void AfterTest() OVERRIDE {
874 EXPECT_EQ(1, started_times_);
879 FakeContentLayerClient client_;
880 scoped_refptr<FakeContentLayer> content_;
883 SINGLE_AND_MULTI_THREAD_TEST_F(
884 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
886 // Make sure the main thread can still execute animations when the renderer is
888 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
889 : public LayerTreeHostAnimationTest {
891 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
893 virtual void SetupTree() OVERRIDE {
894 LayerTreeHostAnimationTest::SetupTree();
895 content_ = FakeContentLayer::Create(&client_);
896 content_->SetBounds(gfx::Size(4, 4));
897 content_->set_layer_animation_delegate(this);
898 layer_tree_host()->root_layer()->AddChild(content_);
901 virtual void BeginTest() OVERRIDE {
903 PostAddAnimationToMainThread(content_.get());
906 virtual void DidCommit() OVERRIDE {
908 layer_tree_host()->SetVisible(false);
911 virtual void NotifyAnimationStarted(
912 base::TimeTicks monotonic_time,
913 Animation::TargetProperty target_property) OVERRIDE {
914 EXPECT_FALSE(visible_);
918 virtual void NotifyAnimationFinished(
919 base::TimeTicks monotonic_time,
920 Animation::TargetProperty target_property) OVERRIDE {
921 EXPECT_FALSE(visible_);
922 EXPECT_EQ(1, started_times_);
926 virtual void AfterTest() OVERRIDE {}
931 FakeContentLayerClient client_;
932 scoped_refptr<FakeContentLayer> content_;
935 SINGLE_AND_MULTI_THREAD_TEST_F(
936 LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
938 // Animations should not be started when frames are being skipped due to
940 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
941 : public LayerTreeHostAnimationTest {
942 virtual void SetupTree() OVERRIDE {
943 LayerTreeHostAnimationTest::SetupTree();
944 content_ = FakeContentLayer::Create(&client_);
945 content_->SetBounds(gfx::Size(4, 4));
946 content_->set_layer_animation_delegate(this);
947 layer_tree_host()->root_layer()->AddChild(content_);
950 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
951 // Make sure that drawing many times doesn't cause a checkerboarded
952 // animation to start so we avoid flake in this test.
953 settings->timeout_and_draw_when_animation_checkerboards = false;
956 virtual void BeginTest() OVERRIDE {
958 added_animations_ = 0;
961 PostSetNeedsCommitToMainThread();
964 virtual DrawResult PrepareToDrawOnThread(
965 LayerTreeHostImpl* host_impl,
966 LayerTreeHostImpl::FrameData* frame_data,
967 DrawResult draw_result) OVERRIDE {
968 if (added_animations_ < 2)
972 // Act like there is checkerboard when the second animation wants to draw.
974 if (prevented_draw_ > 2)
976 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
979 virtual void DidCommitAndDrawFrame() OVERRIDE {
980 switch (layer_tree_host()->source_frame_number()) {
982 // The animation is longer than 1 BeginFrame interval.
983 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
987 // This second animation will not be drawn so it should not start.
988 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
994 virtual void NotifyAnimationStarted(
995 base::TimeTicks monotonic_time,
996 Animation::TargetProperty target_property) OVERRIDE {
1002 virtual void AfterTest() OVERRIDE {
1003 // Make sure we tried to draw the second animation but failed.
1004 EXPECT_LT(0, prevented_draw_);
1005 // The first animation should be started, but the second should not because
1007 EXPECT_EQ(1, started_times_);
1010 int prevented_draw_;
1011 int added_animations_;
1013 FakeContentLayerClient client_;
1014 scoped_refptr<FakeContentLayer> content_;
1017 MULTI_THREAD_TEST_F(
1018 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
1020 // Verifies that scroll offset animations are only accepted when impl-scrolling
1021 // is supported, and that when scroll offset animations are accepted,
1022 // scroll offset updates are sent back to the main thread.
1023 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
1024 : public LayerTreeHostAnimationTest {
1026 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
1028 virtual void SetupTree() OVERRIDE {
1029 LayerTreeHostAnimationTest::SetupTree();
1031 scroll_layer_ = FakeContentLayer::Create(&client_);
1032 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
1033 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
1034 scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20));
1035 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1038 virtual void BeginTest() OVERRIDE {
1039 PostSetNeedsCommitToMainThread();
1042 virtual void DidCommit() OVERRIDE {
1043 switch (layer_tree_host()->source_frame_number()) {
1045 scoped_ptr<ScrollOffsetAnimationCurve> curve(
1046 ScrollOffsetAnimationCurve::Create(
1047 gfx::Vector2dF(500.f, 550.f),
1048 EaseInOutTimingFunction::Create()));
1049 scoped_ptr<Animation> animation(Animation::Create(
1050 curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset));
1051 animation->set_needs_synchronized_start_time(true);
1052 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
1053 bool impl_scrolling_supported =
1054 layer_tree_host()->proxy()->SupportsImplScrolling();
1055 EXPECT_EQ(impl_scrolling_supported, animation_added);
1056 if (!impl_scrolling_supported)
1061 if (scroll_layer_->scroll_offset().x() > 10 &&
1062 scroll_layer_->scroll_offset().y() > 20)
1067 virtual void AfterTest() OVERRIDE {}
1070 FakeContentLayerClient client_;
1071 scoped_refptr<FakeContentLayer> scroll_layer_;
1074 SINGLE_AND_MULTI_THREAD_TEST_F(
1075 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
1077 // Ensure that animation time is correctly updated when animations are frozen
1078 // because of checkerboarding.
1079 class LayerTreeHostAnimationTestFrozenAnimationTickTime
1080 : public LayerTreeHostAnimationTest {
1082 LayerTreeHostAnimationTestFrozenAnimationTickTime()
1083 : started_animating_(false), num_commits_(0), num_draw_attempts_(2) {}
1085 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1086 // Make sure that drawing many times doesn't cause a checkerboarded
1087 // animation to start so we avoid flake in this test.
1088 settings->timeout_and_draw_when_animation_checkerboards = false;
1091 virtual void BeginTest() OVERRIDE {
1092 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
1095 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
1096 last_main_thread_tick_time_ = monotonic_time;
1099 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
1100 base::TimeTicks monotonic_time) OVERRIDE {
1103 if (!started_animating_) {
1104 started_animating_ = true;
1105 expected_impl_tick_time_ = monotonic_time;
1107 EXPECT_EQ(expected_impl_tick_time_, monotonic_time);
1108 if (num_commits_ > 2)
1113 virtual DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
1114 LayerTreeHostImpl::FrameData* frame,
1115 DrawResult draw_result) OVERRIDE {
1118 num_draw_attempts_++;
1119 if (num_draw_attempts_ > 2) {
1120 num_draw_attempts_ = 0;
1121 PostSetNeedsCommitToMainThread();
1123 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
1126 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1127 if (!started_animating_)
1129 expected_impl_tick_time_ =
1130 std::max(expected_impl_tick_time_, last_main_thread_tick_time_);
1134 virtual void AfterTest() OVERRIDE {}
1137 bool started_animating_;
1139 int num_draw_attempts_;
1140 base::TimeTicks last_main_thread_tick_time_;
1141 base::TimeTicks expected_impl_tick_time_;
1144 // Only the non-impl-paint multi-threaded compositor freezes animations.
1145 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime);
1147 // When animations are simultaneously added to an existing layer and to a new
1148 // layer, they should start at the same time, even when there's already a
1149 // running animation on the existing layer.
1150 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1151 : public LayerTreeHostAnimationTest {
1153 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1154 : frame_count_with_pending_tree_(0) {}
1156 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1158 virtual void DidCommit() OVERRIDE {
1159 if (layer_tree_host()->source_frame_number() == 1) {
1160 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1161 } else if (layer_tree_host()->source_frame_number() == 2) {
1162 AddOpacityTransitionToLayer(
1163 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
1165 scoped_refptr<Layer> layer = Layer::Create();
1166 layer_tree_host()->root_layer()->AddChild(layer);
1167 layer->set_layer_animation_delegate(this);
1168 layer->SetBounds(gfx::Size(4, 4));
1169 AddOpacityTransitionToLayer(layer, 1, 0.f, 0.5f, true);
1173 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1174 host_impl->BlockNotifyReadyToActivateForTesting(true);
1177 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1178 // For the commit that added animations to new and existing layers, keep
1179 // blocking activation. We want to verify that even with activation blocked,
1180 // the animation on the layer that's already in the active tree won't get a
1182 if (!host_impl->settings().impl_side_painting ||
1183 host_impl->pending_tree()->source_frame_number() != 2)
1184 host_impl->BlockNotifyReadyToActivateForTesting(false);
1187 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1188 const BeginFrameArgs& args) OVERRIDE {
1189 if (!host_impl->pending_tree() ||
1190 host_impl->pending_tree()->source_frame_number() != 2)
1193 frame_count_with_pending_tree_++;
1194 if (frame_count_with_pending_tree_ == 2)
1195 host_impl->BlockNotifyReadyToActivateForTesting(false);
1198 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1199 bool has_unfinished_animation) OVERRIDE {
1200 LayerAnimationController* root_controller_impl =
1201 host_impl->active_tree()->root_layer()->layer_animation_controller();
1202 Animation* root_animation =
1203 root_controller_impl->GetAnimation(Animation::Opacity);
1204 if (!root_animation || root_animation->run_state() != Animation::Running)
1207 LayerAnimationController* child_controller_impl =
1208 host_impl->active_tree()->root_layer()->children()
1209 [0]->layer_animation_controller();
1210 Animation* child_animation =
1211 child_controller_impl->GetAnimation(Animation::Opacity);
1212 EXPECT_EQ(Animation::Running, child_animation->run_state());
1213 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
1214 root_controller_impl->AbortAnimations(Animation::Opacity);
1215 root_controller_impl->AbortAnimations(Animation::Transform);
1216 child_controller_impl->AbortAnimations(Animation::Opacity);
1220 virtual void AfterTest() OVERRIDE {}
1223 int frame_count_with_pending_tree_;
1226 SINGLE_AND_MULTI_THREAD_TEST_F(
1227 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
1229 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1230 : public LayerTreeHostAnimationTest {
1232 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1233 : num_swap_buffers_(0) {}
1235 virtual void SetupTree() OVERRIDE {
1236 LayerTreeHostAnimationTest::SetupTree();
1237 content_ = Layer::Create();
1238 content_->SetBounds(gfx::Size(4, 4));
1239 layer_tree_host()->root_layer()->AddChild(content_);
1242 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
1244 virtual void DidCommit() OVERRIDE {
1245 switch (layer_tree_host()->source_frame_number()) {
1247 // First frame: add an animation to the root layer.
1248 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1251 // Second frame: add an animation to the content layer. The root layer
1252 // animation has caused us to animate already during this frame.
1253 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
1258 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
1259 bool result) OVERRIDE {
1260 // After both animations have started, verify that they have valid
1262 num_swap_buffers_++;
1263 AnimationRegistrar::AnimationControllerMap copy =
1264 host_impl->animation_registrar()->active_animation_controllers();
1265 if (copy.size() == 2u) {
1267 EXPECT_GE(num_swap_buffers_, 3);
1268 for (AnimationRegistrar::AnimationControllerMap::iterator iter =
1272 int id = ((*iter).second->id());
1273 if (id == host_impl->RootLayer()->id()) {
1274 Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
1275 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1276 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1277 Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
1278 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1284 virtual void AfterTest() OVERRIDE {}
1287 scoped_refptr<Layer> content_;
1288 int num_swap_buffers_;
1291 SINGLE_AND_MULTI_THREAD_TEST_F(
1292 LayerTreeHostAnimationTestAddAnimationAfterAnimating);