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 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 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
40 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
41 // We skip the first commit because its the commit that populates the
42 // impl thread with a tree. After the second commit, the test is done.
43 if (num_commits_
!= 1)
46 layer_tree_host()->SetNeedsAnimate();
47 // Right now, CommitRequested is going to be true, because during
48 // BeginFrame, we force CommitRequested to true to prevent requests from
49 // hitting the impl thread. But, when the next DidCommit happens, we should
50 // verify that CommitRequested has gone back to false.
53 void DidCommit() override
{
55 EXPECT_FALSE(layer_tree_host()->CommitRequested());
56 layer_tree_host()->SetNeedsAnimate();
57 EXPECT_FALSE(layer_tree_host()->CommitRequested());
60 // Verifies that the SetNeedsAnimate we made in ::Animate did not
61 // trigger CommitRequested.
62 EXPECT_FALSE(layer_tree_host()->CommitRequested());
67 void AfterTest() override
{}
74 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
76 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
77 // callback, request another frame using SetNeedsAnimate. End the test when
78 // animate gets called yet-again, indicating that the proxy is correctly
79 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
81 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
82 : public LayerTreeHostAnimationTest
{
84 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
85 : num_begin_frames_(0) {}
87 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
89 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
90 if (!num_begin_frames_
) {
91 layer_tree_host()->SetNeedsAnimate();
98 void AfterTest() override
{}
101 int num_begin_frames_
;
105 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
107 // Add a layer animation and confirm that
108 // LayerTreeHostImpl::updateAnimationState does get called and continues to
110 class LayerTreeHostAnimationTestAddAnimation
111 : public LayerTreeHostAnimationTest
{
113 LayerTreeHostAnimationTestAddAnimation()
114 : num_begin_frames_(0), received_animation_started_notification_(false) {}
116 void BeginTest() override
{
117 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
120 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
121 bool has_unfinished_animation
) override
{
122 if (!num_begin_frames_
) {
123 // The animation had zero duration so LayerTreeHostImpl should no
124 // longer need to animate its layers.
125 EXPECT_FALSE(has_unfinished_animation
);
130 if (received_animation_started_notification_
) {
131 EXPECT_LT(base::TimeTicks(), start_time_
);
133 LayerAnimationController
* controller_impl
=
134 host_impl
->active_tree()->root_layer()->layer_animation_controller();
135 Animation
* animation_impl
=
136 controller_impl
->GetAnimation(Animation::Opacity
);
138 controller_impl
->RemoveAnimation(animation_impl
->id());
144 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
145 Animation::TargetProperty target_property
,
146 int group
) override
{
147 received_animation_started_notification_
= true;
148 start_time_
= monotonic_time
;
149 if (num_begin_frames_
) {
150 EXPECT_LT(base::TimeTicks(), start_time_
);
152 LayerAnimationController
* controller
=
153 layer_tree_host()->root_layer()->layer_animation_controller();
154 Animation
* animation
=
155 controller
->GetAnimation(Animation::Opacity
);
157 controller
->RemoveAnimation(animation
->id());
163 void AfterTest() override
{}
166 int num_begin_frames_
;
167 bool received_animation_started_notification_
;
168 base::TimeTicks start_time_
;
171 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
173 // Add a layer animation to a layer, but continually fail to draw. Confirm that
174 // after a while, we do eventually force a draw.
175 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
176 : public LayerTreeHostAnimationTest
{
178 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
179 : started_animating_(false) {}
181 void BeginTest() override
{
182 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
185 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
186 base::TimeTicks monotonic_time
) override
{
187 started_animating_
= true;
190 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
191 if (started_animating_
)
195 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
196 LayerTreeHostImpl::FrameData
* frame
,
197 DrawResult draw_result
) override
{
198 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
201 void AfterTest() override
{}
204 bool started_animating_
;
207 // Starvation can only be an issue with the MT compositor.
208 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
210 // Ensures that animations eventually get deleted.
211 class LayerTreeHostAnimationTestAnimationsGetDeleted
212 : public LayerTreeHostAnimationTest
{
214 LayerTreeHostAnimationTestAnimationsGetDeleted()
215 : started_animating_(false) {}
217 void BeginTest() override
{
218 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
221 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
222 base::TimeTicks monotonic_time
) override
{
223 bool have_animations
= !host_impl
->animation_registrar()->
224 active_animation_controllers().empty();
225 if (!started_animating_
&& have_animations
) {
226 started_animating_
= true;
230 if (started_animating_
&& !have_animations
)
234 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
235 Animation::TargetProperty target_property
,
236 int group
) override
{
237 // Animations on the impl-side controller only get deleted during a commit,
238 // so we need to schedule a commit.
239 layer_tree_host()->SetNeedsCommit();
242 void AfterTest() override
{}
245 bool started_animating_
;
248 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
250 // Ensures that animations continue to be ticked when we are backgrounded.
251 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
252 : public LayerTreeHostAnimationTest
{
254 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
255 : num_begin_frames_(0) {}
257 void BeginTest() override
{
258 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
261 // Use WillAnimateLayers to set visible false before the animation runs and
262 // causes a commit, so we block the second visible animate in single-thread
264 void WillAnimateLayers(LayerTreeHostImpl
* host_impl
,
265 base::TimeTicks monotonic_time
) override
{
266 // Verify that the host can draw, it's just not visible.
267 EXPECT_TRUE(host_impl
->CanDraw());
268 if (num_begin_frames_
< 2) {
269 if (!num_begin_frames_
) {
270 // We have a long animation running. It should continue to tick even
271 // if we are not visible.
272 PostSetVisibleToMainThread(false);
280 void AfterTest() override
{}
283 int num_begin_frames_
;
286 SINGLE_AND_MULTI_THREAD_TEST_F(
287 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
);
289 // Ensures that animation time remains monotonic when we switch from foreground
290 // to background ticking and back, even if we're skipping draws due to
291 // checkerboarding when in the foreground.
292 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
293 : public LayerTreeHostAnimationTest
{
295 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
296 : has_background_ticked_(false), num_foreground_animates_(0) {}
298 void InitializeSettings(LayerTreeSettings
* settings
) override
{
299 // Make sure that drawing many times doesn't cause a checkerboarded
300 // animation to start so we avoid flake in this test.
301 settings
->timeout_and_draw_when_animation_checkerboards
= false;
304 void BeginTest() override
{
305 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
308 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
309 base::TimeTicks monotonic_time
) override
{
310 EXPECT_GE(monotonic_time
, last_tick_time_
);
311 last_tick_time_
= monotonic_time
;
312 if (host_impl
->visible()) {
313 num_foreground_animates_
++;
314 if (num_foreground_animates_
> 1 && !has_background_ticked_
)
315 PostSetVisibleToMainThread(false);
316 else if (has_background_ticked_
)
319 has_background_ticked_
= true;
320 PostSetVisibleToMainThread(true);
324 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
325 LayerTreeHostImpl::FrameData
* frame
,
326 DrawResult draw_result
) override
{
329 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
332 void AfterTest() override
{}
335 bool has_background_ticked_
;
336 int num_foreground_animates_
;
337 base::TimeTicks last_tick_time_
;
340 SINGLE_AND_MULTI_THREAD_TEST_F(
341 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
);
343 // Ensures that animations do not tick when we are backgrounded and
344 // and we have an empty active tree.
345 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
346 : public LayerTreeHostAnimationTest
{
348 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
349 : active_tree_was_animated_(false) {}
351 base::TimeDelta
LowFrequencyAnimationInterval() const override
{
352 return base::TimeDelta::FromMilliseconds(4);
355 void BeginTest() override
{
356 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
359 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
360 Animation::TargetProperty target_property
,
361 int group
) override
{
362 // Replace animated commits with an empty tree.
363 layer_tree_host()->SetRootLayer(make_scoped_refptr
<Layer
>(NULL
));
366 void DidCommit() override
{
367 // This alternates setting an empty tree and a non-empty tree with an
369 switch (layer_tree_host()->source_frame_number()) {
371 // Wait for NotifyAnimationFinished to commit an empty tree.
375 AddOpacityTransitionToLayer(
376 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
379 // Wait for NotifyAnimationFinished to commit an empty tree.
387 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
388 // At the start of every commit, block activations and make sure
389 // we are backgrounded.
390 if (host_impl
->settings().impl_side_painting
)
391 host_impl
->BlockNotifyReadyToActivateForTesting(true);
392 PostSetVisibleToMainThread(false);
395 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
396 if (!host_impl
->settings().impl_side_painting
) {
397 // There are no activations to block if we're not impl-side-painting,
398 // so just advance the test immediately.
399 if (host_impl
->active_tree()->source_frame_number() < 3)
400 UnblockActivations(host_impl
);
404 // We block activation for several ticks to make sure that, even though
405 // there is a pending tree with animations, we still do not background
406 // tick if the active tree is empty.
407 if (host_impl
->pending_tree()->source_frame_number() < 3) {
408 base::MessageLoopProxy::current()->PostDelayedTask(
411 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
413 base::Unretained(this),
415 4 * LowFrequencyAnimationInterval());
419 virtual void UnblockActivations(LayerTreeHostImpl
* host_impl
) {
420 if (host_impl
->settings().impl_side_painting
)
421 host_impl
->BlockNotifyReadyToActivateForTesting(false);
424 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
425 active_tree_was_animated_
= false;
427 // Verify that commits are actually alternating with empty / non-empty
429 int frame_number
= host_impl
->active_tree()->source_frame_number();
430 switch (frame_number
) {
433 EXPECT_TRUE(host_impl
->active_tree()->root_layer())
434 << "frame: " << frame_number
;
438 EXPECT_FALSE(host_impl
->active_tree()->root_layer())
439 << "frame: " << frame_number
;
443 if (host_impl
->active_tree()->source_frame_number() < 3) {
444 // Initiate the next commit after a delay to give us a chance to
445 // background tick if the active tree isn't empty.
446 base::MessageLoopProxy::current()->PostDelayedTask(
449 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
451 base::Unretained(this),
453 4 * LowFrequencyAnimationInterval());
457 void WillAnimateLayers(LayerTreeHostImpl
* host_impl
,
458 base::TimeTicks monotonic_time
) override
{
459 EXPECT_TRUE(host_impl
->active_tree()->root_layer());
460 active_tree_was_animated_
= true;
463 void InitiateNextCommit(LayerTreeHostImpl
* host_impl
) {
464 // Verify that we actually animated when we should have.
465 bool has_active_tree
= host_impl
->active_tree()->root_layer();
466 EXPECT_EQ(has_active_tree
, active_tree_was_animated_
);
468 // The next commit is blocked until we become visible again.
469 PostSetVisibleToMainThread(true);
472 void AfterTest() override
{}
474 bool active_tree_was_animated_
;
477 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
478 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
);
480 // Ensure that an animation's timing function is respected.
481 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
482 : public LayerTreeHostAnimationTest
{
484 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
486 void SetupTree() override
{
487 LayerTreeHostAnimationTest::SetupTree();
488 content_
= FakeContentLayer::Create(&client_
);
489 content_
->SetBounds(gfx::Size(4, 4));
490 layer_tree_host()->root_layer()->AddChild(content_
);
493 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
495 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
496 base::TimeTicks monotonic_time
) override
{
497 LayerAnimationController
* controller_impl
=
498 host_impl
->active_tree()->root_layer()->children()[0]->
499 layer_animation_controller();
500 Animation
* animation
=
501 controller_impl
->GetAnimation(Animation::Opacity
);
505 const FloatAnimationCurve
* curve
=
506 animation
->curve()->ToFloatAnimationCurve();
507 float start_opacity
= curve
->GetValue(0.0);
508 float end_opacity
= curve
->GetValue(curve
->Duration());
509 float linearly_interpolated_opacity
=
510 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
511 double time
= curve
->Duration() * 0.25;
512 // If the linear timing function associated with this animation was not
513 // picked up, then the linearly interpolated opacity would be different
514 // because of the default ease timing function.
515 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
520 void AfterTest() override
{}
522 FakeContentLayerClient client_
;
523 scoped_refptr
<FakeContentLayer
> content_
;
526 SINGLE_AND_MULTI_THREAD_TEST_F(
527 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
529 // Ensures that main thread animations have their start times synchronized with
530 // impl thread animations.
531 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
532 : public LayerTreeHostAnimationTest
{
534 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
535 : main_start_time_(-1.0),
536 impl_start_time_(-1.0) {}
538 void SetupTree() override
{
539 LayerTreeHostAnimationTest::SetupTree();
540 content_
= FakeContentLayer::Create(&client_
);
541 content_
->SetBounds(gfx::Size(4, 4));
542 content_
->set_layer_animation_delegate(this);
543 layer_tree_host()->root_layer()->AddChild(content_
);
546 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
548 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
549 Animation::TargetProperty target_property
,
550 int group
) override
{
551 LayerAnimationController
* controller
=
552 layer_tree_host()->root_layer()->children()[0]->
553 layer_animation_controller();
554 Animation
* animation
=
555 controller
->GetAnimation(Animation::Opacity
);
557 (animation
->start_time() - base::TimeTicks()).InSecondsF();
558 controller
->RemoveAnimation(animation
->id());
560 if (impl_start_time_
> 0.0)
564 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
565 bool has_unfinished_animation
) override
{
566 LayerAnimationController
* controller
=
567 impl_host
->active_tree()->root_layer()->children()[0]->
568 layer_animation_controller();
569 Animation
* animation
=
570 controller
->GetAnimation(Animation::Opacity
);
575 (animation
->start_time() - base::TimeTicks()).InSecondsF();
576 controller
->RemoveAnimation(animation
->id());
578 if (main_start_time_
> 0.0)
582 void AfterTest() override
{
583 EXPECT_FLOAT_EQ(impl_start_time_
, main_start_time_
);
587 double main_start_time_
;
588 double impl_start_time_
;
589 FakeContentLayerClient client_
;
590 scoped_refptr
<FakeContentLayer
> content_
;
593 SINGLE_AND_MULTI_THREAD_TEST_F(
594 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
596 // Ensures that notify animation finished is called.
597 class LayerTreeHostAnimationTestAnimationFinishedEvents
598 : public LayerTreeHostAnimationTest
{
600 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
602 void BeginTest() override
{
603 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
606 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
607 Animation::TargetProperty target_property
,
608 int group
) override
{
609 LayerAnimationController
* controller
=
610 layer_tree_host()->root_layer()->layer_animation_controller();
611 Animation
* animation
=
612 controller
->GetAnimation(Animation::Opacity
);
614 controller
->RemoveAnimation(animation
->id());
618 void AfterTest() override
{}
621 SINGLE_AND_MULTI_THREAD_TEST_F(
622 LayerTreeHostAnimationTestAnimationFinishedEvents
);
624 // Ensures that when opacity is being animated, this value does not cause the
625 // subtree to be skipped.
626 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
627 : public LayerTreeHostAnimationTest
{
629 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
630 : update_check_layer_(FakeContentLayer::Create(&client_
)) {
633 void SetupTree() override
{
634 update_check_layer_
->SetOpacity(0.f
);
635 layer_tree_host()->SetRootLayer(update_check_layer_
);
636 LayerTreeHostAnimationTest::SetupTree();
639 void BeginTest() override
{
640 PostAddAnimationToMainThread(update_check_layer_
.get());
643 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
644 LayerAnimationController
* controller_impl
=
645 host_impl
->active_tree()->root_layer()->layer_animation_controller();
646 Animation
* animation_impl
=
647 controller_impl
->GetAnimation(Animation::Opacity
);
648 controller_impl
->RemoveAnimation(animation_impl
->id());
652 void AfterTest() override
{
653 // Update() should have been called once, proving that the layer was not
655 EXPECT_EQ(1u, update_check_layer_
->update_count());
657 // clear update_check_layer_ so LayerTreeHost dies.
658 update_check_layer_
= NULL
;
662 FakeContentLayerClient client_
;
663 scoped_refptr
<FakeContentLayer
> update_check_layer_
;
666 SINGLE_AND_MULTI_THREAD_TEST_F(
667 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
669 // Layers added to tree with existing active animations should have the
670 // animation correctly recognized.
671 class LayerTreeHostAnimationTestLayerAddedWithAnimation
672 : public LayerTreeHostAnimationTest
{
674 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
676 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
678 void DidCommit() override
{
679 if (layer_tree_host()->source_frame_number() == 1) {
680 scoped_refptr
<Layer
> layer
= Layer::Create();
681 layer
->set_layer_animation_delegate(this);
683 // Any valid AnimationCurve will do here.
684 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
685 scoped_ptr
<Animation
> animation(
686 Animation::Create(curve
.Pass(), 1, 1,
687 Animation::Opacity
));
688 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
690 // We add the animation *before* attaching the layer to the tree.
691 layer_tree_host()->root_layer()->AddChild(layer
);
695 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
696 base::TimeTicks monotonic_time
) override
{
700 void AfterTest() override
{}
703 SINGLE_AND_MULTI_THREAD_TEST_F(
704 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
706 class LayerTreeHostAnimationTestCancelAnimateCommit
707 : public LayerTreeHostAnimationTest
{
709 LayerTreeHostAnimationTestCancelAnimateCommit()
710 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
712 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
714 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
716 // No-op animate will cancel the commit.
717 if (layer_tree_host()->source_frame_number() == 1) {
721 layer_tree_host()->SetNeedsAnimate();
724 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
726 if (impl
->active_tree()->source_frame_number() > 1)
727 FAIL() << "Commit should have been canceled.";
730 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
732 if (impl
->active_tree()->source_frame_number() > 1)
733 FAIL() << "Draw should have been canceled.";
736 void AfterTest() override
{
737 EXPECT_EQ(2, num_begin_frames_
);
738 EXPECT_EQ(1, num_commit_calls_
);
739 EXPECT_EQ(1, num_draw_calls_
);
743 int num_begin_frames_
;
744 int num_commit_calls_
;
746 FakeContentLayerClient client_
;
747 scoped_refptr
<FakeContentLayer
> content_
;
750 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
752 class LayerTreeHostAnimationTestForceRedraw
753 : public LayerTreeHostAnimationTest
{
755 LayerTreeHostAnimationTestForceRedraw()
756 : num_animate_(0), num_draw_layers_(0) {}
758 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
760 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
761 if (++num_animate_
< 2)
762 layer_tree_host()->SetNeedsAnimate();
765 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
767 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
768 if (++num_draw_layers_
== 2)
772 void AfterTest() override
{
773 // The first commit will always draw; make sure the second draw triggered
774 // by the animation was not cancelled.
775 EXPECT_EQ(2, num_draw_layers_
);
776 EXPECT_EQ(2, num_animate_
);
781 int num_draw_layers_
;
784 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
786 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
787 : public LayerTreeHostAnimationTest
{
789 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
790 : num_animate_(0), num_draw_layers_(0) {}
792 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
794 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
795 if (++num_animate_
<= 2) {
796 layer_tree_host()->SetNeedsCommit();
797 layer_tree_host()->SetNeedsAnimate();
801 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
802 if (++num_draw_layers_
== 2)
806 void AfterTest() override
{
807 // The first commit will always draw; make sure the second draw triggered
808 // by the SetNeedsCommit was not cancelled.
809 EXPECT_EQ(2, num_draw_layers_
);
810 EXPECT_GE(num_animate_
, 2);
815 int num_draw_layers_
;
818 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
820 // Make sure the main thread can still execute animations when CanDraw() is not
822 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
823 : public LayerTreeHostAnimationTest
{
825 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
827 void SetupTree() override
{
828 LayerTreeHostAnimationTest::SetupTree();
829 content_
= FakeContentLayer::Create(&client_
);
830 content_
->SetBounds(gfx::Size(4, 4));
831 content_
->set_layer_animation_delegate(this);
832 layer_tree_host()->root_layer()->AddChild(content_
);
835 void BeginTest() override
{
836 layer_tree_host()->SetViewportSize(gfx::Size());
837 PostAddAnimationToMainThread(content_
.get());
840 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
841 Animation::TargetProperty target_property
,
842 int group
) override
{
846 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
847 Animation::TargetProperty target_property
,
848 int group
) override
{
852 void AfterTest() override
{ EXPECT_EQ(1, started_times_
); }
856 FakeContentLayerClient client_
;
857 scoped_refptr
<FakeContentLayer
> content_
;
860 SINGLE_AND_MULTI_THREAD_TEST_F(
861 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
);
863 // Make sure the main thread can still execute animations when the renderer is
865 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
866 : public LayerTreeHostAnimationTest
{
868 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
870 void SetupTree() override
{
871 LayerTreeHostAnimationTest::SetupTree();
872 content_
= FakeContentLayer::Create(&client_
);
873 content_
->SetBounds(gfx::Size(4, 4));
874 content_
->set_layer_animation_delegate(this);
875 layer_tree_host()->root_layer()->AddChild(content_
);
878 void BeginTest() override
{
880 PostAddAnimationToMainThread(content_
.get());
883 void DidCommit() override
{
885 layer_tree_host()->SetVisible(false);
888 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
889 Animation::TargetProperty target_property
,
890 int group
) override
{
891 EXPECT_FALSE(visible_
);
895 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
896 Animation::TargetProperty target_property
,
897 int group
) override
{
898 EXPECT_FALSE(visible_
);
899 EXPECT_EQ(1, started_times_
);
903 void AfterTest() override
{}
908 FakeContentLayerClient client_
;
909 scoped_refptr
<FakeContentLayer
> content_
;
912 SINGLE_AND_MULTI_THREAD_TEST_F(
913 LayerTreeHostAnimationTestRunAnimationWhenNotVisible
);
915 // Animations should not be started when frames are being skipped due to
917 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
918 : public LayerTreeHostAnimationTest
{
919 void SetupTree() override
{
920 LayerTreeHostAnimationTest::SetupTree();
921 content_
= FakeContentLayer::Create(&client_
);
922 content_
->SetBounds(gfx::Size(4, 4));
923 content_
->set_layer_animation_delegate(this);
924 layer_tree_host()->root_layer()->AddChild(content_
);
927 void InitializeSettings(LayerTreeSettings
* settings
) override
{
928 // Make sure that drawing many times doesn't cause a checkerboarded
929 // animation to start so we avoid flake in this test.
930 settings
->timeout_and_draw_when_animation_checkerboards
= false;
933 void BeginTest() override
{
935 added_animations_
= 0;
938 PostSetNeedsCommitToMainThread();
941 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
942 LayerTreeHostImpl::FrameData
* frame_data
,
943 DrawResult draw_result
) override
{
944 if (added_animations_
< 2)
948 // Act like there is checkerboard when the second animation wants to draw.
950 if (prevented_draw_
> 2)
952 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
955 void DidCommitAndDrawFrame() override
{
956 switch (layer_tree_host()->source_frame_number()) {
958 // The animation is longer than 1 BeginFrame interval.
959 AddOpacityTransitionToLayer(content_
.get(), 0.1, 0.2f
, 0.8f
, false);
963 // This second animation will not be drawn so it should not start.
964 AddAnimatedTransformToLayer(content_
.get(), 0.1, 5, 5);
970 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
971 Animation::TargetProperty target_property
,
972 int group
) override
{
978 void AfterTest() override
{
979 // Make sure we tried to draw the second animation but failed.
980 EXPECT_LT(0, prevented_draw_
);
981 // The first animation should be started, but the second should not because
983 EXPECT_EQ(1, started_times_
);
987 int added_animations_
;
989 FakeContentLayerClient client_
;
990 scoped_refptr
<FakeContentLayer
> content_
;
994 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
996 // Verifies that scroll offset animations are only accepted when impl-scrolling
997 // is supported, and that when scroll offset animations are accepted,
998 // scroll offset updates are sent back to the main thread.
999 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
1000 : public LayerTreeHostAnimationTest
{
1002 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
1004 void SetupTree() override
{
1005 LayerTreeHostAnimationTest::SetupTree();
1007 scroll_layer_
= FakeContentLayer::Create(&client_
);
1008 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
1009 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
1010 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
1011 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
1014 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1016 void DidCommit() override
{
1017 switch (layer_tree_host()->source_frame_number()) {
1019 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
1020 ScrollOffsetAnimationCurve::Create(
1021 gfx::ScrollOffset(500.f
, 550.f
),
1022 EaseInOutTimingFunction::Create()));
1023 scoped_ptr
<Animation
> animation(
1024 Animation::Create(curve
.Pass(), 1, 0, Animation::ScrollOffset
));
1025 animation
->set_needs_synchronized_start_time(true);
1026 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
1027 bool impl_scrolling_supported
=
1028 layer_tree_host()->proxy()->SupportsImplScrolling();
1029 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
1030 if (!impl_scrolling_supported
)
1035 if (scroll_layer_
->scroll_offset().x() > 10 &&
1036 scroll_layer_
->scroll_offset().y() > 20)
1041 void AfterTest() override
{}
1044 FakeContentLayerClient client_
;
1045 scoped_refptr
<FakeContentLayer
> scroll_layer_
;
1048 SINGLE_AND_MULTI_THREAD_TEST_F(
1049 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
1051 // When animations are simultaneously added to an existing layer and to a new
1052 // layer, they should start at the same time, even when there's already a
1053 // running animation on the existing layer.
1054 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1055 : public LayerTreeHostAnimationTest
{
1057 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1058 : frame_count_with_pending_tree_(0) {}
1060 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1062 void DidCommit() override
{
1063 if (layer_tree_host()->source_frame_number() == 1) {
1064 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1065 } else if (layer_tree_host()->source_frame_number() == 2) {
1066 AddOpacityTransitionToLayer(
1067 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
1069 scoped_refptr
<Layer
> layer
= Layer::Create();
1070 layer_tree_host()->root_layer()->AddChild(layer
);
1071 layer
->set_layer_animation_delegate(this);
1072 layer
->SetBounds(gfx::Size(4, 4));
1073 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
1077 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
1078 if (host_impl
->settings().impl_side_painting
)
1079 host_impl
->BlockNotifyReadyToActivateForTesting(true);
1082 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1083 // For the commit that added animations to new and existing layers, keep
1084 // blocking activation. We want to verify that even with activation blocked,
1085 // the animation on the layer that's already in the active tree won't get a
1087 if (host_impl
->settings().impl_side_painting
&&
1088 host_impl
->pending_tree()->source_frame_number() != 2) {
1089 host_impl
->BlockNotifyReadyToActivateForTesting(false);
1093 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
1094 const BeginFrameArgs
& args
) override
{
1095 if (!host_impl
->pending_tree() ||
1096 host_impl
->pending_tree()->source_frame_number() != 2)
1099 frame_count_with_pending_tree_
++;
1100 if (frame_count_with_pending_tree_
== 2 &&
1101 host_impl
->settings().impl_side_painting
) {
1102 host_impl
->BlockNotifyReadyToActivateForTesting(false);
1106 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1107 bool has_unfinished_animation
) override
{
1108 LayerAnimationController
* root_controller_impl
=
1109 host_impl
->active_tree()->root_layer()->layer_animation_controller();
1110 Animation
* root_animation
=
1111 root_controller_impl
->GetAnimation(Animation::Opacity
);
1112 if (!root_animation
|| root_animation
->run_state() != Animation::Running
)
1115 LayerAnimationController
* child_controller_impl
=
1116 host_impl
->active_tree()->root_layer()->children()
1117 [0]->layer_animation_controller();
1118 Animation
* child_animation
=
1119 child_controller_impl
->GetAnimation(Animation::Opacity
);
1120 EXPECT_EQ(Animation::Running
, child_animation
->run_state());
1121 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
1122 root_controller_impl
->AbortAnimations(Animation::Opacity
);
1123 root_controller_impl
->AbortAnimations(Animation::Transform
);
1124 child_controller_impl
->AbortAnimations(Animation::Opacity
);
1128 void AfterTest() override
{}
1131 int frame_count_with_pending_tree_
;
1134 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1135 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
1137 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1138 : public LayerTreeHostAnimationTest
{
1140 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1141 : num_swap_buffers_(0) {}
1143 void SetupTree() override
{
1144 LayerTreeHostAnimationTest::SetupTree();
1145 content_
= Layer::Create();
1146 content_
->SetBounds(gfx::Size(4, 4));
1147 layer_tree_host()->root_layer()->AddChild(content_
);
1150 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1152 void DidCommit() override
{
1153 switch (layer_tree_host()->source_frame_number()) {
1155 // First frame: add an animation to the root layer.
1156 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1159 // Second frame: add an animation to the content layer. The root layer
1160 // animation has caused us to animate already during this frame.
1161 AddOpacityTransitionToLayer(content_
.get(), 0.1, 5, 5, false);
1166 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
1167 // After both animations have started, verify that they have valid
1169 num_swap_buffers_
++;
1170 AnimationRegistrar::AnimationControllerMap copy
=
1171 host_impl
->animation_registrar()->active_animation_controllers();
1172 if (copy
.size() == 2u) {
1174 EXPECT_GE(num_swap_buffers_
, 3);
1175 for (AnimationRegistrar::AnimationControllerMap::iterator iter
=
1179 int id
= ((*iter
).second
->id());
1180 if (id
== host_impl
->RootLayer()->id()) {
1181 Animation
* anim
= (*iter
).second
->GetAnimation(Animation::Transform
);
1182 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1183 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
1184 Animation
* anim
= (*iter
).second
->GetAnimation(Animation::Opacity
);
1185 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1191 void AfterTest() override
{}
1194 scoped_refptr
<Layer
> content_
;
1195 int num_swap_buffers_
;
1198 SINGLE_AND_MULTI_THREAD_TEST_F(
1199 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);