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/base/time_util.h"
12 #include "cc/layers/layer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_content_layer.h"
16 #include "cc/test/fake_content_layer_client.h"
17 #include "cc/test/layer_tree_test.h"
18 #include "cc/trees/layer_tree_impl.h"
23 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
25 void SetupTree() override
{
26 LayerTreeTest::SetupTree();
27 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
31 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
33 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
34 : public LayerTreeHostAnimationTest
{
36 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
39 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
41 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
42 // We skip the first commit because its the commit that populates the
43 // impl thread with a tree. After the second commit, the test is done.
44 if (num_commits_
!= 1)
47 layer_tree_host()->SetNeedsAnimate();
48 // Right now, CommitRequested is going to be true, because during
49 // BeginFrame, we force CommitRequested to true to prevent requests from
50 // hitting the impl thread. But, when the next DidCommit happens, we should
51 // verify that CommitRequested has gone back to false.
54 void DidCommit() override
{
56 EXPECT_FALSE(layer_tree_host()->CommitRequested());
57 layer_tree_host()->SetNeedsAnimate();
58 EXPECT_FALSE(layer_tree_host()->CommitRequested());
61 // Verifies that the SetNeedsAnimate we made in ::Animate did not
62 // trigger CommitRequested.
63 EXPECT_FALSE(layer_tree_host()->CommitRequested());
68 void AfterTest() override
{}
75 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
77 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
78 // callback, request another frame using SetNeedsAnimate. End the test when
79 // animate gets called yet-again, indicating that the proxy is correctly
80 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
83 : public LayerTreeHostAnimationTest
{
85 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
86 : num_begin_frames_(0) {}
88 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
90 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
91 if (!num_begin_frames_
) {
92 layer_tree_host()->SetNeedsAnimate();
99 void AfterTest() override
{}
102 int num_begin_frames_
;
106 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
108 // Add a layer animation and confirm that
109 // LayerTreeHostImpl::UpdateAnimationState does get called.
110 class LayerTreeHostAnimationTestAddAnimation
111 : public LayerTreeHostAnimationTest
{
113 LayerTreeHostAnimationTestAddAnimation()
114 : update_animation_state_was_called_(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 EXPECT_FALSE(has_unfinished_animation
);
123 update_animation_state_was_called_
= true;
126 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
127 Animation::TargetProperty target_property
,
128 int group
) override
{
129 EXPECT_LT(base::TimeTicks(), monotonic_time
);
131 LayerAnimationController
* controller
=
132 layer_tree_host()->root_layer()->layer_animation_controller();
133 Animation
* animation
= controller
->GetAnimation(Animation::Opacity
);
135 controller
->RemoveAnimation(animation
->id());
140 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
143 bool update_animation_state_was_called_
;
146 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
148 // Add a layer animation to a layer, but continually fail to draw. Confirm that
149 // after a while, we do eventually force a draw.
150 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
151 : public LayerTreeHostAnimationTest
{
153 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
154 : started_animating_(false) {}
156 void BeginTest() override
{
157 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
160 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
161 base::TimeTicks monotonic_time
) override
{
162 started_animating_
= true;
165 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
166 if (started_animating_
)
170 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
171 LayerTreeHostImpl::FrameData
* frame
,
172 DrawResult draw_result
) override
{
173 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
176 void AfterTest() override
{}
179 bool started_animating_
;
182 // Starvation can only be an issue with the MT compositor.
183 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
185 // Ensures that animations eventually get deleted.
186 class LayerTreeHostAnimationTestAnimationsGetDeleted
187 : public LayerTreeHostAnimationTest
{
189 LayerTreeHostAnimationTestAnimationsGetDeleted()
190 : started_animating_(false) {}
192 void BeginTest() override
{
193 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
196 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
197 base::TimeTicks monotonic_time
) override
{
198 bool have_animations
= !host_impl
->animation_registrar()->
199 active_animation_controllers().empty();
200 if (!started_animating_
&& have_animations
) {
201 started_animating_
= true;
205 if (started_animating_
&& !have_animations
)
209 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
210 Animation::TargetProperty target_property
,
211 int group
) override
{
212 // Animations on the impl-side controller only get deleted during a commit,
213 // so we need to schedule a commit.
214 layer_tree_host()->SetNeedsCommit();
217 void AfterTest() override
{}
220 bool started_animating_
;
223 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
225 // Ensures that animations continue to be ticked when we are backgrounded.
226 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
227 : public LayerTreeHostAnimationTest
{
229 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
230 : num_begin_frames_(0) {}
232 void BeginTest() override
{
233 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
236 // Use WillAnimateLayers to set visible false before the animation runs and
237 // causes a commit, so we block the second visible animate in single-thread
239 void WillAnimateLayers(LayerTreeHostImpl
* host_impl
,
240 base::TimeTicks monotonic_time
) override
{
241 // Verify that the host can draw, it's just not visible.
242 EXPECT_TRUE(host_impl
->CanDraw());
243 if (num_begin_frames_
< 2) {
244 if (!num_begin_frames_
) {
245 // We have a long animation running. It should continue to tick even
246 // if we are not visible.
247 PostSetVisibleToMainThread(false);
255 void AfterTest() override
{}
258 int num_begin_frames_
;
261 SINGLE_AND_MULTI_THREAD_TEST_F(
262 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
);
264 // Ensures that animation time remains monotonic when we switch from foreground
265 // to background ticking and back, even if we're skipping draws due to
266 // checkerboarding when in the foreground.
267 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
268 : public LayerTreeHostAnimationTest
{
270 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
271 : has_background_ticked_(false), num_foreground_animates_(0) {}
273 void InitializeSettings(LayerTreeSettings
* settings
) override
{
274 // Make sure that drawing many times doesn't cause a checkerboarded
275 // animation to start so we avoid flake in this test.
276 settings
->timeout_and_draw_when_animation_checkerboards
= false;
279 void BeginTest() override
{
280 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
283 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
284 base::TimeTicks monotonic_time
) override
{
285 EXPECT_GE(monotonic_time
, last_tick_time_
);
286 last_tick_time_
= monotonic_time
;
287 if (host_impl
->visible()) {
288 num_foreground_animates_
++;
289 if (num_foreground_animates_
> 1 && !has_background_ticked_
)
290 PostSetVisibleToMainThread(false);
291 else if (has_background_ticked_
)
294 has_background_ticked_
= true;
295 PostSetVisibleToMainThread(true);
299 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
300 LayerTreeHostImpl::FrameData
* frame
,
301 DrawResult draw_result
) override
{
304 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
307 void AfterTest() override
{}
310 bool has_background_ticked_
;
311 int num_foreground_animates_
;
312 base::TimeTicks last_tick_time_
;
315 SINGLE_AND_MULTI_THREAD_TEST_F(
316 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
);
318 // Ensures that animations do not tick when we are backgrounded and
319 // and we have an empty active tree.
320 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
321 : public LayerTreeHostAnimationTest
{
323 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
324 : active_tree_was_animated_(false) {}
326 base::TimeDelta
BackgroundAnimationInterval(LayerTreeHostImpl
* host_impl
) {
327 return base::TimeDelta::FromSecondsD(
328 1.0 / host_impl
->settings().background_animation_rate
);
331 void BeginTest() override
{
332 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
335 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
336 Animation::TargetProperty target_property
,
337 int group
) override
{
338 // Replace animated commits with an empty tree.
339 layer_tree_host()->SetRootLayer(make_scoped_refptr
<Layer
>(NULL
));
342 void DidCommit() override
{
343 // This alternates setting an empty tree and a non-empty tree with an
345 switch (layer_tree_host()->source_frame_number()) {
347 // Wait for NotifyAnimationFinished to commit an empty tree.
351 AddOpacityTransitionToLayer(
352 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
355 // Wait for NotifyAnimationFinished to commit an empty tree.
363 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
364 // At the start of every commit, block activations and make sure
365 // we are backgrounded.
366 if (host_impl
->settings().impl_side_painting
)
367 host_impl
->BlockNotifyReadyToActivateForTesting(true);
368 PostSetVisibleToMainThread(false);
371 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
372 if (!host_impl
->settings().impl_side_painting
) {
373 // There are no activations to block if we're not impl-side-painting,
374 // so just advance the test immediately.
375 if (host_impl
->active_tree()->source_frame_number() < 3)
376 UnblockActivations(host_impl
);
380 // We block activation for several ticks to make sure that, even though
381 // there is a pending tree with animations, we still do not background
382 // tick if the active tree is empty.
383 if (host_impl
->pending_tree()->source_frame_number() < 3) {
384 base::MessageLoopProxy::current()->PostDelayedTask(
387 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
389 base::Unretained(this), host_impl
),
390 4 * BackgroundAnimationInterval(host_impl
));
394 virtual void UnblockActivations(LayerTreeHostImpl
* host_impl
) {
395 if (host_impl
->settings().impl_side_painting
)
396 host_impl
->BlockNotifyReadyToActivateForTesting(false);
399 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
400 active_tree_was_animated_
= false;
402 // Verify that commits are actually alternating with empty / non-empty
404 int frame_number
= host_impl
->active_tree()->source_frame_number();
405 switch (frame_number
) {
408 EXPECT_TRUE(host_impl
->active_tree()->root_layer())
409 << "frame: " << frame_number
;
413 EXPECT_FALSE(host_impl
->active_tree()->root_layer())
414 << "frame: " << frame_number
;
418 if (host_impl
->active_tree()->source_frame_number() < 3) {
419 // Initiate the next commit after a delay to give us a chance to
420 // background tick if the active tree isn't empty.
421 base::MessageLoopProxy::current()->PostDelayedTask(
424 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
426 base::Unretained(this), host_impl
),
427 4 * BackgroundAnimationInterval(host_impl
));
431 void WillAnimateLayers(LayerTreeHostImpl
* host_impl
,
432 base::TimeTicks monotonic_time
) override
{
433 EXPECT_TRUE(host_impl
->active_tree()->root_layer());
434 active_tree_was_animated_
= true;
437 void InitiateNextCommit(LayerTreeHostImpl
* host_impl
) {
438 // Verify that we actually animated when we should have.
439 bool has_active_tree
= host_impl
->active_tree()->root_layer();
440 EXPECT_EQ(has_active_tree
, active_tree_was_animated_
);
442 // The next commit is blocked until we become visible again.
443 PostSetVisibleToMainThread(true);
446 void AfterTest() override
{}
448 bool active_tree_was_animated_
;
451 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
452 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
);
454 // Ensure that an animation's timing function is respected.
455 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
456 : public LayerTreeHostAnimationTest
{
458 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
460 void SetupTree() override
{
461 LayerTreeHostAnimationTest::SetupTree();
462 content_
= FakeContentLayer::Create(&client_
);
463 content_
->SetBounds(gfx::Size(4, 4));
464 layer_tree_host()->root_layer()->AddChild(content_
);
467 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
469 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
470 base::TimeTicks monotonic_time
) override
{
471 LayerAnimationController
* controller_impl
=
472 host_impl
->active_tree()->root_layer()->children()[0]->
473 layer_animation_controller();
474 Animation
* animation
=
475 controller_impl
->GetAnimation(Animation::Opacity
);
479 const FloatAnimationCurve
* curve
=
480 animation
->curve()->ToFloatAnimationCurve();
481 float start_opacity
= curve
->GetValue(base::TimeDelta());
482 float end_opacity
= curve
->GetValue(curve
->Duration());
483 float linearly_interpolated_opacity
=
484 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
485 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
486 // If the linear timing function associated with this animation was not
487 // picked up, then the linearly interpolated opacity would be different
488 // because of the default ease timing function.
489 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
494 void AfterTest() override
{}
496 FakeContentLayerClient client_
;
497 scoped_refptr
<FakeContentLayer
> content_
;
500 SINGLE_AND_MULTI_THREAD_TEST_F(
501 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
503 // Ensures that main thread animations have their start times synchronized with
504 // impl thread animations.
505 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
506 : public LayerTreeHostAnimationTest
{
508 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
510 void SetupTree() override
{
511 LayerTreeHostAnimationTest::SetupTree();
512 content_
= FakeContentLayer::Create(&client_
);
513 content_
->SetBounds(gfx::Size(4, 4));
514 content_
->set_layer_animation_delegate(this);
515 layer_tree_host()->root_layer()->AddChild(content_
);
518 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
520 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
521 Animation::TargetProperty target_property
,
522 int group
) override
{
523 LayerAnimationController
* controller
=
524 layer_tree_host()->root_layer()->children()[0]->
525 layer_animation_controller();
526 Animation
* animation
=
527 controller
->GetAnimation(Animation::Opacity
);
528 main_start_time_
= animation
->start_time();
529 controller
->RemoveAnimation(animation
->id());
533 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
534 bool has_unfinished_animation
) override
{
535 LayerAnimationController
* controller
=
536 impl_host
->active_tree()->root_layer()->children()[0]->
537 layer_animation_controller();
538 Animation
* animation
=
539 controller
->GetAnimation(Animation::Opacity
);
543 impl_start_time_
= animation
->start_time();
546 void AfterTest() override
{
547 EXPECT_EQ(impl_start_time_
, main_start_time_
);
548 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
552 base::TimeTicks main_start_time_
;
553 base::TimeTicks impl_start_time_
;
554 FakeContentLayerClient client_
;
555 scoped_refptr
<FakeContentLayer
> content_
;
558 SINGLE_AND_MULTI_THREAD_TEST_F(
559 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
561 // Ensures that notify animation finished is called.
562 class LayerTreeHostAnimationTestAnimationFinishedEvents
563 : public LayerTreeHostAnimationTest
{
565 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
567 void BeginTest() override
{
568 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
571 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
572 Animation::TargetProperty target_property
,
573 int group
) override
{
574 LayerAnimationController
* controller
=
575 layer_tree_host()->root_layer()->layer_animation_controller();
576 Animation
* animation
=
577 controller
->GetAnimation(Animation::Opacity
);
579 controller
->RemoveAnimation(animation
->id());
583 void AfterTest() override
{}
586 SINGLE_AND_MULTI_THREAD_TEST_F(
587 LayerTreeHostAnimationTestAnimationFinishedEvents
);
589 // Ensures that when opacity is being animated, this value does not cause the
590 // subtree to be skipped.
591 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
592 : public LayerTreeHostAnimationTest
{
594 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
595 : update_check_layer_(FakeContentLayer::Create(&client_
)) {
598 void SetupTree() override
{
599 update_check_layer_
->SetOpacity(0.f
);
600 layer_tree_host()->SetRootLayer(update_check_layer_
);
601 LayerTreeHostAnimationTest::SetupTree();
604 void BeginTest() override
{
605 PostAddAnimationToMainThread(update_check_layer_
.get());
608 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
609 LayerAnimationController
* controller_impl
=
610 host_impl
->active_tree()->root_layer()->layer_animation_controller();
611 Animation
* animation_impl
=
612 controller_impl
->GetAnimation(Animation::Opacity
);
613 controller_impl
->RemoveAnimation(animation_impl
->id());
617 void AfterTest() override
{
618 // Update() should have been called once, proving that the layer was not
620 EXPECT_EQ(1u, update_check_layer_
->update_count());
622 // clear update_check_layer_ so LayerTreeHost dies.
623 update_check_layer_
= NULL
;
627 FakeContentLayerClient client_
;
628 scoped_refptr
<FakeContentLayer
> update_check_layer_
;
631 SINGLE_AND_MULTI_THREAD_TEST_F(
632 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
634 // Layers added to tree with existing active animations should have the
635 // animation correctly recognized.
636 class LayerTreeHostAnimationTestLayerAddedWithAnimation
637 : public LayerTreeHostAnimationTest
{
639 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
641 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
643 void DidCommit() override
{
644 if (layer_tree_host()->source_frame_number() == 1) {
645 scoped_refptr
<Layer
> layer
= Layer::Create();
646 layer
->set_layer_animation_delegate(this);
648 // Any valid AnimationCurve will do here.
649 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
650 scoped_ptr
<Animation
> animation(
651 Animation::Create(curve
.Pass(), 1, 1,
652 Animation::Opacity
));
653 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
655 // We add the animation *before* attaching the layer to the tree.
656 layer_tree_host()->root_layer()->AddChild(layer
);
660 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
661 base::TimeTicks monotonic_time
) override
{
665 void AfterTest() override
{}
668 SINGLE_AND_MULTI_THREAD_TEST_F(
669 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
671 class LayerTreeHostAnimationTestCancelAnimateCommit
672 : public LayerTreeHostAnimationTest
{
674 LayerTreeHostAnimationTestCancelAnimateCommit()
675 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
677 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
679 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
681 // No-op animate will cancel the commit.
682 if (layer_tree_host()->source_frame_number() == 1) {
686 layer_tree_host()->SetNeedsAnimate();
689 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
691 if (impl
->active_tree()->source_frame_number() > 1)
692 FAIL() << "Commit should have been canceled.";
695 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
697 if (impl
->active_tree()->source_frame_number() > 1)
698 FAIL() << "Draw should have been canceled.";
701 void AfterTest() override
{
702 EXPECT_EQ(2, num_begin_frames_
);
703 EXPECT_EQ(1, num_commit_calls_
);
704 EXPECT_EQ(1, num_draw_calls_
);
708 int num_begin_frames_
;
709 int num_commit_calls_
;
711 FakeContentLayerClient client_
;
712 scoped_refptr
<FakeContentLayer
> content_
;
715 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
717 class LayerTreeHostAnimationTestForceRedraw
718 : public LayerTreeHostAnimationTest
{
720 LayerTreeHostAnimationTestForceRedraw()
721 : num_animate_(0), num_draw_layers_(0) {}
723 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
725 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
726 if (++num_animate_
< 2)
727 layer_tree_host()->SetNeedsAnimate();
730 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
732 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
733 if (++num_draw_layers_
== 2)
737 void AfterTest() override
{
738 // The first commit will always draw; make sure the second draw triggered
739 // by the animation was not cancelled.
740 EXPECT_EQ(2, num_draw_layers_
);
741 EXPECT_EQ(2, num_animate_
);
746 int num_draw_layers_
;
749 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
751 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
752 : public LayerTreeHostAnimationTest
{
754 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
755 : num_animate_(0), num_draw_layers_(0) {}
757 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
759 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
760 if (++num_animate_
<= 2) {
761 layer_tree_host()->SetNeedsCommit();
762 layer_tree_host()->SetNeedsAnimate();
766 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
767 if (++num_draw_layers_
== 2)
771 void AfterTest() override
{
772 // The first commit will always draw; make sure the second draw triggered
773 // by the SetNeedsCommit was not cancelled.
774 EXPECT_EQ(2, num_draw_layers_
);
775 EXPECT_GE(num_animate_
, 2);
780 int num_draw_layers_
;
783 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
785 // Make sure the main thread can still execute animations when CanDraw() is not
787 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
788 : public LayerTreeHostAnimationTest
{
790 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
792 void SetupTree() override
{
793 LayerTreeHostAnimationTest::SetupTree();
794 content_
= FakeContentLayer::Create(&client_
);
795 content_
->SetBounds(gfx::Size(4, 4));
796 content_
->set_layer_animation_delegate(this);
797 layer_tree_host()->root_layer()->AddChild(content_
);
800 void BeginTest() override
{
801 layer_tree_host()->SetViewportSize(gfx::Size());
802 PostAddAnimationToMainThread(content_
.get());
805 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
806 Animation::TargetProperty target_property
,
807 int group
) override
{
811 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
812 Animation::TargetProperty target_property
,
813 int group
) override
{
817 void AfterTest() override
{ EXPECT_EQ(1, started_times_
); }
821 FakeContentLayerClient client_
;
822 scoped_refptr
<FakeContentLayer
> content_
;
825 SINGLE_AND_MULTI_THREAD_TEST_F(
826 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
);
828 // Make sure the main thread can still execute animations when the renderer is
830 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
831 : public LayerTreeHostAnimationTest
{
833 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
835 void SetupTree() override
{
836 LayerTreeHostAnimationTest::SetupTree();
837 content_
= FakeContentLayer::Create(&client_
);
838 content_
->SetBounds(gfx::Size(4, 4));
839 content_
->set_layer_animation_delegate(this);
840 layer_tree_host()->root_layer()->AddChild(content_
);
843 void BeginTest() override
{
845 PostAddAnimationToMainThread(content_
.get());
848 void DidCommit() override
{
850 layer_tree_host()->SetVisible(false);
853 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
854 Animation::TargetProperty target_property
,
855 int group
) override
{
856 EXPECT_FALSE(visible_
);
860 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
861 Animation::TargetProperty target_property
,
862 int group
) override
{
863 EXPECT_FALSE(visible_
);
864 EXPECT_EQ(1, started_times_
);
868 void AfterTest() override
{}
873 FakeContentLayerClient client_
;
874 scoped_refptr
<FakeContentLayer
> content_
;
877 SINGLE_AND_MULTI_THREAD_TEST_F(
878 LayerTreeHostAnimationTestRunAnimationWhenNotVisible
);
880 // Animations should not be started when frames are being skipped due to
882 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
883 : public LayerTreeHostAnimationTest
{
884 void SetupTree() override
{
885 LayerTreeHostAnimationTest::SetupTree();
886 content_
= FakeContentLayer::Create(&client_
);
887 content_
->SetBounds(gfx::Size(4, 4));
888 content_
->set_layer_animation_delegate(this);
889 layer_tree_host()->root_layer()->AddChild(content_
);
892 void InitializeSettings(LayerTreeSettings
* settings
) override
{
893 // Make sure that drawing many times doesn't cause a checkerboarded
894 // animation to start so we avoid flake in this test.
895 settings
->timeout_and_draw_when_animation_checkerboards
= false;
898 void BeginTest() override
{
900 added_animations_
= 0;
903 PostSetNeedsCommitToMainThread();
906 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
907 LayerTreeHostImpl::FrameData
* frame_data
,
908 DrawResult draw_result
) override
{
909 if (added_animations_
< 2)
913 // Act like there is checkerboard when the second animation wants to draw.
915 if (prevented_draw_
> 2)
917 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
920 void DidCommitAndDrawFrame() override
{
921 switch (layer_tree_host()->source_frame_number()) {
923 // The animation is longer than 1 BeginFrame interval.
924 AddOpacityTransitionToLayer(content_
.get(), 0.1, 0.2f
, 0.8f
, false);
928 // This second animation will not be drawn so it should not start.
929 AddAnimatedTransformToLayer(content_
.get(), 0.1, 5, 5);
935 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
936 Animation::TargetProperty target_property
,
937 int group
) override
{
943 void AfterTest() override
{
944 // Make sure we tried to draw the second animation but failed.
945 EXPECT_LT(0, prevented_draw_
);
946 // The first animation should be started, but the second should not because
948 EXPECT_EQ(1, started_times_
);
952 int added_animations_
;
954 FakeContentLayerClient client_
;
955 scoped_refptr
<FakeContentLayer
> content_
;
959 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
961 // Verifies that scroll offset animations are only accepted when impl-scrolling
962 // is supported, and that when scroll offset animations are accepted,
963 // scroll offset updates are sent back to the main thread.
964 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
965 : public LayerTreeHostAnimationTest
{
967 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
969 void SetupTree() override
{
970 LayerTreeHostAnimationTest::SetupTree();
972 scroll_layer_
= FakeContentLayer::Create(&client_
);
973 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
974 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
975 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
976 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
979 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
981 void DidCommit() override
{
982 switch (layer_tree_host()->source_frame_number()) {
984 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
985 ScrollOffsetAnimationCurve::Create(
986 gfx::ScrollOffset(500.f
, 550.f
),
987 EaseInOutTimingFunction::Create()));
988 scoped_ptr
<Animation
> animation(
989 Animation::Create(curve
.Pass(), 1, 0, Animation::ScrollOffset
));
990 animation
->set_needs_synchronized_start_time(true);
991 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
992 bool impl_scrolling_supported
=
993 layer_tree_host()->proxy()->SupportsImplScrolling();
994 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
995 if (!impl_scrolling_supported
)
1000 if (scroll_layer_
->scroll_offset().x() > 10 &&
1001 scroll_layer_
->scroll_offset().y() > 20)
1006 void AfterTest() override
{}
1009 FakeContentLayerClient client_
;
1010 scoped_refptr
<FakeContentLayer
> scroll_layer_
;
1013 SINGLE_AND_MULTI_THREAD_TEST_F(
1014 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
1016 // When animations are simultaneously added to an existing layer and to a new
1017 // layer, they should start at the same time, even when there's already a
1018 // running animation on the existing layer.
1019 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1020 : public LayerTreeHostAnimationTest
{
1022 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1023 : frame_count_with_pending_tree_(0) {}
1025 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1027 void DidCommit() override
{
1028 if (layer_tree_host()->source_frame_number() == 1) {
1029 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1030 } else if (layer_tree_host()->source_frame_number() == 2) {
1031 AddOpacityTransitionToLayer(
1032 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
1034 scoped_refptr
<Layer
> layer
= Layer::Create();
1035 layer_tree_host()->root_layer()->AddChild(layer
);
1036 layer
->set_layer_animation_delegate(this);
1037 layer
->SetBounds(gfx::Size(4, 4));
1038 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
1042 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
1043 if (host_impl
->settings().impl_side_painting
)
1044 host_impl
->BlockNotifyReadyToActivateForTesting(true);
1047 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1048 // For the commit that added animations to new and existing layers, keep
1049 // blocking activation. We want to verify that even with activation blocked,
1050 // the animation on the layer that's already in the active tree won't get a
1052 if (host_impl
->settings().impl_side_painting
&&
1053 host_impl
->pending_tree()->source_frame_number() != 2) {
1054 host_impl
->BlockNotifyReadyToActivateForTesting(false);
1058 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
1059 const BeginFrameArgs
& args
) override
{
1060 if (!host_impl
->pending_tree() ||
1061 host_impl
->pending_tree()->source_frame_number() != 2)
1064 frame_count_with_pending_tree_
++;
1065 if (frame_count_with_pending_tree_
== 2 &&
1066 host_impl
->settings().impl_side_painting
) {
1067 host_impl
->BlockNotifyReadyToActivateForTesting(false);
1071 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1072 bool has_unfinished_animation
) override
{
1073 LayerAnimationController
* root_controller_impl
=
1074 host_impl
->active_tree()->root_layer()->layer_animation_controller();
1075 Animation
* root_animation
=
1076 root_controller_impl
->GetAnimation(Animation::Opacity
);
1077 if (!root_animation
|| root_animation
->run_state() != Animation::Running
)
1080 LayerAnimationController
* child_controller_impl
=
1081 host_impl
->active_tree()->root_layer()->children()
1082 [0]->layer_animation_controller();
1083 Animation
* child_animation
=
1084 child_controller_impl
->GetAnimation(Animation::Opacity
);
1085 EXPECT_EQ(Animation::Running
, child_animation
->run_state());
1086 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
1087 root_controller_impl
->AbortAnimations(Animation::Opacity
);
1088 root_controller_impl
->AbortAnimations(Animation::Transform
);
1089 child_controller_impl
->AbortAnimations(Animation::Opacity
);
1093 void AfterTest() override
{}
1096 int frame_count_with_pending_tree_
;
1099 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1100 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
1102 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1103 : public LayerTreeHostAnimationTest
{
1105 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1106 : num_swap_buffers_(0) {}
1108 void SetupTree() override
{
1109 LayerTreeHostAnimationTest::SetupTree();
1110 content_
= Layer::Create();
1111 content_
->SetBounds(gfx::Size(4, 4));
1112 layer_tree_host()->root_layer()->AddChild(content_
);
1115 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1117 void DidCommit() override
{
1118 switch (layer_tree_host()->source_frame_number()) {
1120 // First frame: add an animation to the root layer.
1121 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1124 // Second frame: add an animation to the content layer. The root layer
1125 // animation has caused us to animate already during this frame.
1126 AddOpacityTransitionToLayer(content_
.get(), 0.1, 5, 5, false);
1131 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
1132 // After both animations have started, verify that they have valid
1134 num_swap_buffers_
++;
1135 AnimationRegistrar::AnimationControllerMap copy
=
1136 host_impl
->animation_registrar()->active_animation_controllers();
1137 if (copy
.size() == 2u) {
1139 EXPECT_GE(num_swap_buffers_
, 3);
1140 for (AnimationRegistrar::AnimationControllerMap::iterator iter
=
1144 int id
= ((*iter
).second
->id());
1145 if (id
== host_impl
->RootLayer()->id()) {
1146 Animation
* anim
= (*iter
).second
->GetAnimation(Animation::Transform
);
1147 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1148 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
1149 Animation
* anim
= (*iter
).second
->GetAnimation(Animation::Opacity
);
1150 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1156 void AfterTest() override
{}
1159 scoped_refptr
<Layer
> content_
;
1160 int num_swap_buffers_
;
1163 SINGLE_AND_MULTI_THREAD_TEST_F(
1164 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);