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 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)
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()
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();
102 virtual void AfterTest() OVERRIDE
{}
105 int num_begin_frames_
;
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()
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
);
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
);
143 controller_impl
->RemoveAnimation(animation_impl
->id());
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
);
162 controller
->RemoveAnimation(animation
->id());
168 virtual void AfterTest() OVERRIDE
{}
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
{
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_
)
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
{ }
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
{
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;
238 if (started_animating_
&& !have_animations
)
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
{}
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
{
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
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);
289 virtual void AfterTest() OVERRIDE
{}
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
{
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_
)
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
{
339 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
342 virtual void AfterTest() OVERRIDE
{}
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
{
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
379 switch (layer_tree_host()->source_frame_number()) {
381 // Wait for NotifyAnimationFinished to commit an empty tree.
385 AddOpacityTransitionToLayer(
386 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
389 // Wait for NotifyAnimationFinished to commit an empty tree.
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
);
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(
420 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
422 base::Unretained(this),
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
437 int frame_number
= host_impl
->active_tree()->source_frame_number();
438 switch (frame_number
) {
441 EXPECT_TRUE(host_impl
->active_tree()->root_layer())
442 << "frame: " << frame_number
;
446 EXPECT_FALSE(host_impl
->active_tree()->root_layer())
447 << "frame: " << frame_number
;
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(
457 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
459 base::Unretained(this),
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
{
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
);
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
));
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
{
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
);
570 (animation
->start_time() - base::TimeTicks()).InSecondsF();
571 controller
->RemoveAnimation(animation
->id());
573 if (impl_start_time_
> 0.0)
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
);
589 (animation
->start_time() - base::TimeTicks()).InSecondsF();
590 controller
->RemoveAnimation(animation
->id());
592 if (main_start_time_
> 0.0)
596 virtual void AfterTest() OVERRIDE
{
597 EXPECT_FLOAT_EQ(impl_start_time_
, main_start_time_
);
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
{
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
);
628 controller
->RemoveAnimation(animation
->id());
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
{
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());
666 virtual void AfterTest() OVERRIDE
{
667 // Update() should have been called once, proving that the layer was not
669 EXPECT_EQ(1u, update_check_layer_
->update_count());
671 // clear update_check_layer_ so LayerTreeHost dies.
672 update_check_layer_
= NULL
;
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
{
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
{
717 virtual void AfterTest() OVERRIDE
{}
720 SINGLE_AND_MULTI_THREAD_TEST_F(
721 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
723 class LayerTreeHostAnimationTestCancelAnimateCommit
724 : public LayerTreeHostAnimationTest
{
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
{
733 // No-op animate will cancel the commit.
734 if (layer_tree_host()->source_frame_number() == 1) {
738 layer_tree_host()->SetNeedsAnimate();
741 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
743 if (impl
->active_tree()->source_frame_number() > 1)
744 FAIL() << "Commit should have been canceled.";
747 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
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_
);
760 int num_begin_frames_
;
761 int num_commit_calls_
;
763 FakeContentLayerClient client_
;
764 scoped_refptr
<FakeContentLayer
> content_
;
767 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
769 class LayerTreeHostAnimationTestForceRedraw
770 : public LayerTreeHostAnimationTest
{
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)
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_
);
800 int num_draw_layers_
;
803 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
805 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
806 : public LayerTreeHostAnimationTest
{
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)
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);
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
841 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
842 : public LayerTreeHostAnimationTest
{
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
{
865 virtual void NotifyAnimationFinished(
866 base::TimeTicks monotonic_time
,
867 Animation::TargetProperty target_property
) OVERRIDE
{
871 virtual void AfterTest() OVERRIDE
{
872 EXPECT_EQ(1, 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
886 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
887 : public LayerTreeHostAnimationTest
{
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
{
901 PostAddAnimationToMainThread(content_
.get());
904 virtual void DidCommit() OVERRIDE
{
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_
);
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_
);
924 virtual void AfterTest() OVERRIDE
{}
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
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
{
956 added_animations_
= 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)
970 // Act like there is checkerboard when the second animation wants to draw.
972 if (prevented_draw_
> 2)
974 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
977 virtual void DidCommitAndDrawFrame() OVERRIDE
{
978 switch (layer_tree_host()->source_frame_number()) {
980 // The animation is longer than 1 BeginFrame interval.
981 AddOpacityTransitionToLayer(content_
.get(), 0.1, 0.2f
, 0.8f
, false);
985 // This second animation will not be drawn so it should not start.
986 AddAnimatedTransformToLayer(content_
.get(), 0.1, 5, 5);
992 virtual void NotifyAnimationStarted(
993 base::TimeTicks monotonic_time
,
994 Animation::TargetProperty target_property
) OVERRIDE
{
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
1005 EXPECT_EQ(1, started_times_
);
1008 int prevented_draw_
;
1009 int added_animations_
;
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
{
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()) {
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
)
1059 if (scroll_layer_
->scroll_offset().x() > 10 &&
1060 scroll_layer_
->scroll_offset().y() > 20)
1065 virtual void AfterTest() OVERRIDE
{}
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
{
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
{
1101 if (!started_animating_
) {
1102 started_animating_
= true;
1103 expected_impl_tick_time_
= monotonic_time
;
1105 EXPECT_EQ(expected_impl_tick_time_
, monotonic_time
);
1106 if (num_commits_
> 2)
1111 virtual DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
1112 LayerTreeHostImpl::FrameData
* frame
,
1113 DrawResult draw_result
) OVERRIDE
{
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_
)
1127 expected_impl_tick_time_
=
1128 std::max(expected_impl_tick_time_
, last_main_thread_tick_time_
);
1132 virtual void AfterTest() OVERRIDE
{}
1135 bool started_animating_
;
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
{
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
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)
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
)
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
);
1218 virtual void AfterTest() OVERRIDE
{}
1221 int frame_count_with_pending_tree_
;
1224 SINGLE_AND_MULTI_THREAD_TEST_F(
1225 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
1227 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1228 : public LayerTreeHostAnimationTest
{
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()) {
1245 // First frame: add an animation to the root layer.
1246 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
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);
1256 virtual void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
,
1257 bool result
) OVERRIDE
{
1258 // After both animations have started, verify that they have valid
1260 num_swap_buffers_
++;
1261 AnimationRegistrar::AnimationControllerMap copy
=
1262 host_impl
->animation_registrar()->active_animation_controllers();
1263 if (copy
.size() == 2u) {
1265 EXPECT_GE(num_swap_buffers_
, 3);
1266 for (AnimationRegistrar::AnimationControllerMap::iterator 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
{}
1285 scoped_refptr
<Layer
> content_
;
1286 int num_swap_buffers_
;
1289 SINGLE_AND_MULTI_THREAD_TEST_F(
1290 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);