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 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;
158 EXPECT_LT(base::TimeTicks(), start_time_);
160 LayerAnimationController* controller =
161 layer_tree_host()->root_layer()->layer_animation_controller();
162 Animation* animation =
163 controller->GetAnimation(Animation::Opacity);
165 controller->RemoveAnimation(animation->id());
171 virtual void AfterTest() OVERRIDE {}
175 bool received_animation_started_notification_;
176 base::TimeTicks start_time_;
179 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
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 {
186 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
187 : started_animating_(false) {}
189 virtual void BeginTest() OVERRIDE {
190 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
193 virtual void AnimateLayers(
194 LayerTreeHostImpl* host_impl,
195 base::TimeTicks monotonic_time) OVERRIDE {
196 started_animating_ = true;
199 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
200 if (started_animating_)
204 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
205 LayerTreeHostImpl* host_impl,
206 LayerTreeHostImpl::FrameData* frame,
207 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
208 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
211 virtual void AfterTest() OVERRIDE { }
214 bool started_animating_;
217 // Starvation can only be an issue with the MT compositor.
218 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
220 // Ensures that animations eventually get deleted.
221 class LayerTreeHostAnimationTestAnimationsGetDeleted
222 : public LayerTreeHostAnimationTest {
224 LayerTreeHostAnimationTestAnimationsGetDeleted()
225 : started_animating_(false) {}
227 virtual void BeginTest() OVERRIDE {
228 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
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;
241 if (started_animating_ && !have_animations)
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();
254 virtual void AfterTest() OVERRIDE {}
257 bool started_animating_;
260 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
262 // Ensures that animations continue to be ticked when we are backgrounded.
263 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
264 : public LayerTreeHostAnimationTest {
266 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
267 : num_animates_(0) {}
269 virtual void BeginTest() OVERRIDE {
270 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
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
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);
293 virtual void AfterTest() OVERRIDE {}
299 SINGLE_AND_MULTI_THREAD_TEST_F(
300 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
302 // Ensures that animation time remains monotonic when we switch from foreground
303 // to background ticking and back, even if we're skipping draws due to
304 // checkerboarding when in the foreground.
305 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
306 : public LayerTreeHostAnimationTest {
308 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
309 : has_background_ticked_(false), num_foreground_animates_(0) {}
311 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
312 // Make sure that drawing many times doesn't cause a checkerboarded
313 // animation to start so we avoid flake in this test.
314 settings->timeout_and_draw_when_animation_checkerboards = false;
317 virtual void BeginTest() OVERRIDE {
318 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
321 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
322 base::TimeTicks monotonic_time) OVERRIDE {
323 EXPECT_GE(monotonic_time, last_tick_time_);
324 last_tick_time_ = monotonic_time;
325 if (host_impl->visible()) {
326 num_foreground_animates_++;
327 if (num_foreground_animates_ > 1 && !has_background_ticked_)
328 PostSetVisibleToMainThread(false);
329 else if (has_background_ticked_)
332 has_background_ticked_ = true;
333 PostSetVisibleToMainThread(true);
337 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
338 LayerTreeHostImpl* host_impl,
339 LayerTreeHostImpl::FrameData* frame,
340 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
343 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
346 virtual void AfterTest() OVERRIDE {}
349 bool has_background_ticked_;
350 int num_foreground_animates_;
351 base::TimeTicks last_tick_time_;
354 SINGLE_AND_MULTI_THREAD_TEST_F(
355 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic);
357 // Ensures that animations do not tick when we are backgrounded and
358 // and we have an empty active tree.
359 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
360 : public LayerTreeHostAnimationTest {
362 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
363 : active_tree_was_animated_(false) {}
365 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE {
366 return base::TimeDelta::FromMilliseconds(4);
369 virtual void BeginTest() OVERRIDE {
370 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
373 virtual void NotifyAnimationFinished(
374 double wall_clock_time,
375 base::TimeTicks monotonic_time,
376 Animation::TargetProperty target_property) OVERRIDE {
377 // Replace animated commits with an empty tree.
378 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
381 virtual void DidCommit() OVERRIDE {
382 // This alternates setting an empty tree and a non-empty tree with an
384 switch (layer_tree_host()->source_frame_number()) {
386 // Wait for NotifyAnimationFinished to commit an empty tree.
390 AddOpacityTransitionToLayer(
391 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
394 // Wait for NotifyAnimationFinished to commit an empty tree.
402 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
403 // At the start of every commit, block activations and make sure
404 // we are backgrounded.
405 host_impl->BlockNotifyReadyToActivateForTesting(true);
406 PostSetVisibleToMainThread(false);
409 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
410 if (!host_impl->settings().impl_side_painting) {
411 // There are no activations to block if we're not impl-side-painting,
412 // so just advance the test immediately.
413 if (host_impl->active_tree()->source_frame_number() < 3)
414 UnblockActivations(host_impl);
418 // We block activation for several ticks to make sure that, even though
419 // there is a pending tree with animations, we still do not background
420 // tick if the active tree is empty.
421 if (host_impl->pending_tree()->source_frame_number() < 3) {
422 base::MessageLoopProxy::current()->PostDelayedTask(
425 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
427 base::Unretained(this),
429 4 * LowFrequencyAnimationInterval());
433 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
434 host_impl->BlockNotifyReadyToActivateForTesting(false);
437 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
438 active_tree_was_animated_ = false;
440 // Verify that commits are actually alternating with empty / non-empty
442 int frame_number = host_impl->active_tree()->source_frame_number();
443 switch (frame_number) {
446 EXPECT_TRUE(host_impl->active_tree()->root_layer())
447 << "frame: " << frame_number;
451 EXPECT_FALSE(host_impl->active_tree()->root_layer())
452 << "frame: " << frame_number;
456 if (host_impl->active_tree()->source_frame_number() < 3) {
457 // Initiate the next commit after a delay to give us a chance to
458 // background tick if the active tree isn't empty.
459 base::MessageLoopProxy::current()->PostDelayedTask(
462 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
464 base::Unretained(this),
466 4 * LowFrequencyAnimationInterval());
470 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl,
471 base::TimeTicks monotonic_time) OVERRIDE {
472 EXPECT_TRUE(host_impl->active_tree()->root_layer());
473 active_tree_was_animated_ = true;
476 void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
477 // Verify that we actually animated when we should have.
478 bool has_active_tree = host_impl->active_tree()->root_layer();
479 EXPECT_EQ(has_active_tree, active_tree_was_animated_);
481 // The next commit is blocked until we become visible again.
482 PostSetVisibleToMainThread(true);
485 virtual void AfterTest() OVERRIDE {}
487 bool active_tree_was_animated_;
490 SINGLE_AND_MULTI_THREAD_TEST_F(
491 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
493 // Ensure that an animation's timing function is respected.
494 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
495 : public LayerTreeHostAnimationTest {
497 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
499 virtual void SetupTree() OVERRIDE {
500 LayerTreeHostAnimationTest::SetupTree();
501 content_ = FakeContentLayer::Create(&client_);
502 content_->SetBounds(gfx::Size(4, 4));
503 layer_tree_host()->root_layer()->AddChild(content_);
506 virtual void BeginTest() OVERRIDE {
507 PostAddAnimationToMainThread(content_.get());
510 virtual void AnimateLayers(
511 LayerTreeHostImpl* host_impl,
512 base::TimeTicks monotonic_time) OVERRIDE {
513 LayerAnimationController* controller_impl =
514 host_impl->active_tree()->root_layer()->children()[0]->
515 layer_animation_controller();
516 Animation* animation =
517 controller_impl->GetAnimation(Animation::Opacity);
521 const FloatAnimationCurve* curve =
522 animation->curve()->ToFloatAnimationCurve();
523 float start_opacity = curve->GetValue(0.0);
524 float end_opacity = curve->GetValue(curve->Duration());
525 float linearly_interpolated_opacity =
526 0.25f * end_opacity + 0.75f * start_opacity;
527 double time = curve->Duration() * 0.25;
528 // If the linear timing function associated with this animation was not
529 // picked up, then the linearly interpolated opacity would be different
530 // because of the default ease timing function.
531 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
536 virtual void AfterTest() OVERRIDE {}
538 FakeContentLayerClient client_;
539 scoped_refptr<FakeContentLayer> content_;
542 SINGLE_AND_MULTI_THREAD_TEST_F(
543 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
545 // Ensures that main thread animations have their start times synchronized with
546 // impl thread animations.
547 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
548 : public LayerTreeHostAnimationTest {
550 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
551 : main_start_time_(-1.0),
552 impl_start_time_(-1.0) {}
554 virtual void SetupTree() OVERRIDE {
555 LayerTreeHostAnimationTest::SetupTree();
556 content_ = FakeContentLayer::Create(&client_);
557 content_->SetBounds(gfx::Size(4, 4));
558 content_->set_layer_animation_delegate(this);
559 layer_tree_host()->root_layer()->AddChild(content_);
562 virtual void BeginTest() OVERRIDE {
563 PostAddAnimationToMainThread(content_.get());
566 virtual void NotifyAnimationStarted(
567 double wall_clock_time,
568 base::TimeTicks monotonic_time,
569 Animation::TargetProperty target_property) OVERRIDE {
570 LayerAnimationController* controller =
571 layer_tree_host()->root_layer()->children()[0]->
572 layer_animation_controller();
573 Animation* animation =
574 controller->GetAnimation(Animation::Opacity);
575 main_start_time_ = animation->start_time();
576 controller->RemoveAnimation(animation->id());
578 if (impl_start_time_ > 0.0)
582 virtual void UpdateAnimationState(
583 LayerTreeHostImpl* impl_host,
584 bool has_unfinished_animation) OVERRIDE {
585 LayerAnimationController* controller =
586 impl_host->active_tree()->root_layer()->children()[0]->
587 layer_animation_controller();
588 Animation* animation =
589 controller->GetAnimation(Animation::Opacity);
593 impl_start_time_ = animation->start_time();
594 controller->RemoveAnimation(animation->id());
596 if (main_start_time_ > 0.0)
600 virtual void AfterTest() OVERRIDE {
601 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_);
605 double main_start_time_;
606 double impl_start_time_;
607 FakeContentLayerClient client_;
608 scoped_refptr<FakeContentLayer> content_;
611 SINGLE_AND_MULTI_THREAD_TEST_F(
612 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
614 // Ensures that notify animation finished is called.
615 class LayerTreeHostAnimationTestAnimationFinishedEvents
616 : public LayerTreeHostAnimationTest {
618 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
620 virtual void BeginTest() OVERRIDE {
621 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
624 virtual void NotifyAnimationFinished(
625 double wall_clock_time,
626 base::TimeTicks monotonic_time,
627 Animation::TargetProperty target_property) OVERRIDE {
628 LayerAnimationController* controller =
629 layer_tree_host()->root_layer()->layer_animation_controller();
630 Animation* animation =
631 controller->GetAnimation(Animation::Opacity);
633 controller->RemoveAnimation(animation->id());
637 virtual void AfterTest() OVERRIDE {}
640 SINGLE_AND_MULTI_THREAD_TEST_F(
641 LayerTreeHostAnimationTestAnimationFinishedEvents);
643 // Ensures that when opacity is being animated, this value does not cause the
644 // subtree to be skipped.
645 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
646 : public LayerTreeHostAnimationTest {
648 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
649 : update_check_layer_(FakeContentLayer::Create(&client_)) {
652 virtual void SetupTree() OVERRIDE {
653 update_check_layer_->SetOpacity(0.f);
654 layer_tree_host()->SetRootLayer(update_check_layer_);
655 LayerTreeHostAnimationTest::SetupTree();
658 virtual void BeginTest() OVERRIDE {
659 PostAddAnimationToMainThread(update_check_layer_.get());
662 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
663 LayerAnimationController* controller_impl =
664 host_impl->active_tree()->root_layer()->layer_animation_controller();
665 Animation* animation_impl =
666 controller_impl->GetAnimation(Animation::Opacity);
667 controller_impl->RemoveAnimation(animation_impl->id());
671 virtual void AfterTest() OVERRIDE {
672 // Update() should have been called once, proving that the layer was not
674 EXPECT_EQ(1u, update_check_layer_->update_count());
676 // clear update_check_layer_ so LayerTreeHost dies.
677 update_check_layer_ = NULL;
681 FakeContentLayerClient client_;
682 scoped_refptr<FakeContentLayer> update_check_layer_;
685 SINGLE_AND_MULTI_THREAD_TEST_F(
686 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
688 // Layers added to tree with existing active animations should have the
689 // animation correctly recognized.
690 class LayerTreeHostAnimationTestLayerAddedWithAnimation
691 : public LayerTreeHostAnimationTest {
693 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
695 virtual void BeginTest() OVERRIDE {
696 PostSetNeedsCommitToMainThread();
699 virtual void DidCommit() OVERRIDE {
700 if (layer_tree_host()->source_frame_number() == 1) {
701 scoped_refptr<Layer> layer = Layer::Create();
702 layer->set_layer_animation_delegate(this);
704 // Any valid AnimationCurve will do here.
705 scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create());
706 scoped_ptr<Animation> animation(
707 Animation::Create(curve.Pass(), 1, 1,
708 Animation::Opacity));
709 layer->layer_animation_controller()->AddAnimation(animation.Pass());
711 // We add the animation *before* attaching the layer to the tree.
712 layer_tree_host()->root_layer()->AddChild(layer);
716 virtual void AnimateLayers(
717 LayerTreeHostImpl* impl_host,
718 base::TimeTicks monotonic_time) OVERRIDE {
722 virtual void AfterTest() OVERRIDE {}
725 SINGLE_AND_MULTI_THREAD_TEST_F(
726 LayerTreeHostAnimationTestLayerAddedWithAnimation);
728 class LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount
729 : public LayerTreeHostAnimationTest {
731 LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount()
732 : animated_commit_(-1) {
735 virtual void Animate(base::TimeTicks) OVERRIDE {
736 // We shouldn't animate on the CompositeAndReadback-forced commit, but we
737 // should for the SetNeedsCommit-triggered commit.
738 animated_commit_ = layer_tree_host()->source_frame_number();
739 EXPECT_NE(2, animated_commit_);
742 virtual void BeginTest() OVERRIDE {
743 PostSetNeedsCommitToMainThread();
746 virtual void DidCommit() OVERRIDE {
747 switch (layer_tree_host()->source_frame_number()) {
749 layer_tree_host()->SetNeedsCommit();
753 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1));
757 // This is finishing the readback's commit.
760 // This is finishing the followup commit.
768 virtual void AfterTest() OVERRIDE {
769 EXPECT_EQ(3, animated_commit_);
773 int animated_commit_;
776 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount);
778 class LayerTreeHostAnimationTestContinuousAnimate
779 : public LayerTreeHostAnimationTest {
781 LayerTreeHostAnimationTestContinuousAnimate()
782 : num_commit_complete_(0),
783 num_draw_layers_(0) {
786 virtual void BeginTest() OVERRIDE {
787 PostSetNeedsCommitToMainThread();
790 virtual void Animate(base::TimeTicks) OVERRIDE {
791 if (num_draw_layers_ == 2)
793 layer_tree_host()->SetNeedsAnimate();
796 virtual void Layout() OVERRIDE {
797 layer_tree_host()->root_layer()->SetNeedsDisplay();
800 virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE {
801 if (num_draw_layers_ == 1)
802 num_commit_complete_++;
805 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE {
807 if (num_draw_layers_ == 2)
811 virtual void AfterTest() OVERRIDE {
812 // Check that we didn't commit twice between first and second draw.
813 EXPECT_EQ(1, num_commit_complete_);
817 int num_commit_complete_;
818 int num_draw_layers_;
821 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate);
823 // Make sure the main thread can still execute animations when CanDraw() is not
825 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
826 : public LayerTreeHostAnimationTest {
828 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
830 virtual void SetupTree() OVERRIDE {
831 LayerTreeHostAnimationTest::SetupTree();
832 content_ = FakeContentLayer::Create(&client_);
833 content_->SetBounds(gfx::Size(4, 4));
834 content_->set_layer_animation_delegate(this);
835 layer_tree_host()->root_layer()->AddChild(content_);
838 virtual void BeginTest() OVERRIDE {
839 layer_tree_host()->SetViewportSize(gfx::Size());
840 PostAddAnimationToMainThread(content_.get());
843 virtual void NotifyAnimationStarted(
844 double wall_clock_time,
845 base::TimeTicks monotonic_time,
846 Animation::TargetProperty target_property) OVERRIDE {
850 virtual void NotifyAnimationFinished(
851 double wall_clock_time,
852 base::TimeTicks monotonic_time,
853 Animation::TargetProperty target_property) OVERRIDE {
857 virtual void AfterTest() OVERRIDE {
858 EXPECT_EQ(1, started_times_);
863 FakeContentLayerClient client_;
864 scoped_refptr<FakeContentLayer> content_;
867 SINGLE_AND_MULTI_THREAD_TEST_F(
868 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
870 // Make sure the main thread can still execute animations when the renderer is
872 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
873 : public LayerTreeHostAnimationTest {
875 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
877 virtual void SetupTree() OVERRIDE {
878 LayerTreeHostAnimationTest::SetupTree();
879 content_ = FakeContentLayer::Create(&client_);
880 content_->SetBounds(gfx::Size(4, 4));
881 content_->set_layer_animation_delegate(this);
882 layer_tree_host()->root_layer()->AddChild(content_);
885 virtual void BeginTest() OVERRIDE {
887 PostAddAnimationToMainThread(content_.get());
890 virtual void DidCommit() OVERRIDE {
892 layer_tree_host()->SetVisible(false);
895 virtual void NotifyAnimationStarted(
896 double wall_clock_time,
897 base::TimeTicks monotonic_time,
898 Animation::TargetProperty target_property) OVERRIDE {
899 EXPECT_FALSE(visible_);
903 virtual void NotifyAnimationFinished(
904 double wall_clock_time,
905 base::TimeTicks monotonic_time,
906 Animation::TargetProperty target_property) OVERRIDE {
907 EXPECT_FALSE(visible_);
908 EXPECT_EQ(1, started_times_);
912 virtual void AfterTest() OVERRIDE {}
917 FakeContentLayerClient client_;
918 scoped_refptr<FakeContentLayer> content_;
921 SINGLE_AND_MULTI_THREAD_TEST_F(
922 LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
924 // Animations should not be started when frames are being skipped due to
926 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
927 : public LayerTreeHostAnimationTest {
928 virtual void SetupTree() OVERRIDE {
929 LayerTreeHostAnimationTest::SetupTree();
930 content_ = FakeContentLayer::Create(&client_);
931 content_->SetBounds(gfx::Size(4, 4));
932 content_->set_layer_animation_delegate(this);
933 layer_tree_host()->root_layer()->AddChild(content_);
936 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
937 // Make sure that drawing many times doesn't cause a checkerboarded
938 // animation to start so we avoid flake in this test.
939 settings->timeout_and_draw_when_animation_checkerboards = false;
942 virtual void BeginTest() OVERRIDE {
944 added_animations_ = 0;
947 PostSetNeedsCommitToMainThread();
950 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
951 LayerTreeHostImpl* host_impl,
952 LayerTreeHostImpl::FrameData* frame_data,
953 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
954 if (added_animations_ < 2)
958 // Act like there is checkerboard when the second animation wants to draw.
960 if (prevented_draw_ > 2)
962 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
965 virtual void DidCommitAndDrawFrame() OVERRIDE {
966 switch (layer_tree_host()->source_frame_number()) {
968 // The animation is longer than 1 BeginFrame interval.
969 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
973 // This second animation will not be drawn so it should not start.
974 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
980 virtual void NotifyAnimationStarted(
981 double wall_clock_time,
982 base::TimeTicks monotonic_time,
983 Animation::TargetProperty target_property) OVERRIDE {
989 virtual void AfterTest() OVERRIDE {
990 // Make sure we tried to draw the second animation but failed.
991 EXPECT_LT(0, prevented_draw_);
992 // The first animation should be started, but the second should not because
994 EXPECT_EQ(1, started_times_);
998 int added_animations_;
1000 FakeContentLayerClient client_;
1001 scoped_refptr<FakeContentLayer> content_;
1004 MULTI_THREAD_TEST_F(
1005 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
1007 // Verifies that when scroll offset is animated on the impl thread, updates
1008 // are sent back to the main thread.
1009 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
1010 : public LayerTreeHostAnimationTest {
1012 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
1014 virtual void SetupTree() OVERRIDE {
1015 LayerTreeHostAnimationTest::SetupTree();
1017 scroll_layer_ = FakeContentLayer::Create(&client_);
1018 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
1019 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
1020 scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20));
1021 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1024 virtual void BeginTest() OVERRIDE {
1025 PostSetNeedsCommitToMainThread();
1028 virtual void DidCommit() OVERRIDE {
1029 switch (layer_tree_host()->source_frame_number()) {
1031 scoped_ptr<ScrollOffsetAnimationCurve> curve(
1032 ScrollOffsetAnimationCurve::Create(
1033 gfx::Vector2dF(500.f, 550.f),
1034 EaseInOutTimingFunction::Create()));
1035 scoped_ptr<Animation> animation(Animation::Create(
1036 curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset));
1037 animation->set_needs_synchronized_start_time(true);
1038 scroll_layer_->AddAnimation(animation.Pass());
1042 if (scroll_layer_->scroll_offset().x() > 10 &&
1043 scroll_layer_->scroll_offset().y() > 20)
1048 virtual void AfterTest() OVERRIDE {}
1051 FakeContentLayerClient client_;
1052 scoped_refptr<FakeContentLayer> scroll_layer_;
1055 // SingleThreadProxy doesn't send scroll updates from LayerTreeHostImpl to
1057 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
1059 // Ensure that animation time is correctly updated when animations are frozen
1060 // because of checkerboarding.
1061 class LayerTreeHostAnimationTestFrozenAnimationTickTime
1062 : public LayerTreeHostAnimationTest {
1064 LayerTreeHostAnimationTestFrozenAnimationTickTime()
1065 : started_animating_(false), num_commits_(0), num_draw_attempts_(2) {}
1067 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
1068 // Make sure that drawing many times doesn't cause a checkerboarded
1069 // animation to start so we avoid flake in this test.
1070 settings->timeout_and_draw_when_animation_checkerboards = false;
1073 virtual void BeginTest() OVERRIDE {
1074 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
1077 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE {
1078 last_main_thread_tick_time_ = monotonic_time;
1081 virtual void AnimateLayers(LayerTreeHostImpl* host_impl,
1082 base::TimeTicks monotonic_time) OVERRIDE {
1085 if (!started_animating_) {
1086 started_animating_ = true;
1087 expected_impl_tick_time_ = monotonic_time;
1089 EXPECT_EQ(expected_impl_tick_time_, monotonic_time);
1090 if (num_commits_ > 2)
1095 virtual DrawSwapReadbackResult::DrawResult PrepareToDrawOnThread(
1096 LayerTreeHostImpl* host_impl,
1097 LayerTreeHostImpl::FrameData* frame,
1098 DrawSwapReadbackResult::DrawResult draw_result) OVERRIDE {
1101 num_draw_attempts_++;
1102 if (num_draw_attempts_ > 2) {
1103 num_draw_attempts_ = 0;
1104 PostSetNeedsCommitToMainThread();
1106 return DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
1109 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
1110 if (!started_animating_)
1112 expected_impl_tick_time_ =
1113 std::max(expected_impl_tick_time_, last_main_thread_tick_time_);
1117 virtual void AfterTest() OVERRIDE {}
1120 bool started_animating_;
1122 int num_draw_attempts_;
1123 base::TimeTicks last_main_thread_tick_time_;
1124 base::TimeTicks expected_impl_tick_time_;
1127 // Only the non-impl-paint multi-threaded compositor freezes animations.
1128 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime);