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/animation/transform_operations.h"
12 #include "cc/base/completion_event.h"
13 #include "cc/base/time_util.h"
14 #include "cc/layers/layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_content_layer_client.h"
18 #include "cc/test/fake_picture_layer.h"
19 #include "cc/test/layer_tree_test.h"
20 #include "cc/trees/layer_tree_impl.h"
25 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
27 void SetupTree() override
{
28 LayerTreeTest::SetupTree();
29 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
33 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
35 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
36 : public LayerTreeHostAnimationTest
{
38 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
41 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
43 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
44 // We skip the first commit because its the commit that populates the
45 // impl thread with a tree. After the second commit, the test is done.
46 if (num_commits_
!= 1)
49 layer_tree_host()->SetNeedsAnimate();
50 // Right now, CommitRequested is going to be true, because during
51 // BeginFrame, we force CommitRequested to true to prevent requests from
52 // hitting the impl thread. But, when the next DidCommit happens, we should
53 // verify that CommitRequested has gone back to false.
56 void DidCommit() override
{
58 EXPECT_FALSE(layer_tree_host()->CommitRequested());
59 layer_tree_host()->SetNeedsAnimate();
60 EXPECT_FALSE(layer_tree_host()->CommitRequested());
63 // Verifies that the SetNeedsAnimate we made in ::Animate did not
64 // trigger CommitRequested.
65 EXPECT_FALSE(layer_tree_host()->CommitRequested());
70 void AfterTest() override
{}
77 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
79 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
80 // callback, request another frame using SetNeedsAnimate. End the test when
81 // animate gets called yet-again, indicating that the proxy is correctly
82 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
84 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
85 : public LayerTreeHostAnimationTest
{
87 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
88 : num_begin_frames_(0) {}
90 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
92 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
93 if (!num_begin_frames_
) {
94 layer_tree_host()->SetNeedsAnimate();
101 void AfterTest() override
{}
104 int num_begin_frames_
;
107 SINGLE_AND_MULTI_THREAD_TEST_F(
108 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
110 // Add a layer animation and confirm that
111 // LayerTreeHostImpl::UpdateAnimationState does get called.
112 class LayerTreeHostAnimationTestAddAnimation
113 : public LayerTreeHostAnimationTest
{
115 LayerTreeHostAnimationTestAddAnimation()
116 : update_animation_state_was_called_(false) {}
118 void BeginTest() override
{
119 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
122 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
123 bool has_unfinished_animation
) override
{
124 EXPECT_FALSE(has_unfinished_animation
);
125 update_animation_state_was_called_
= true;
128 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
129 Animation::TargetProperty target_property
,
130 int group
) override
{
131 EXPECT_LT(base::TimeTicks(), monotonic_time
);
133 LayerAnimationController
* controller
=
134 layer_tree_host()->root_layer()->layer_animation_controller();
135 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
137 controller
->RemoveAnimation(animation
->id());
142 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
145 bool update_animation_state_was_called_
;
148 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
150 // Add a layer animation to a layer, but continually fail to draw. Confirm that
151 // after a while, we do eventually force a draw.
152 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
153 : public LayerTreeHostAnimationTest
{
155 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
156 : started_animating_(false) {}
158 void BeginTest() override
{
159 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
162 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
163 base::TimeTicks monotonic_time
) override
{
164 started_animating_
= true;
167 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
168 if (started_animating_
)
172 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
173 LayerTreeHostImpl::FrameData
* frame
,
174 DrawResult draw_result
) override
{
175 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
178 void AfterTest() override
{}
181 bool started_animating_
;
184 // Starvation can only be an issue with the MT compositor.
185 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
187 // Ensures that animations eventually get deleted.
188 class LayerTreeHostAnimationTestAnimationsGetDeleted
189 : public LayerTreeHostAnimationTest
{
191 LayerTreeHostAnimationTestAnimationsGetDeleted()
192 : started_animating_(false) {}
194 void BeginTest() override
{
195 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
198 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
199 base::TimeTicks monotonic_time
) override
{
200 bool have_animations
= !host_impl
->animation_registrar()
201 ->active_animation_controllers_for_testing()
203 if (!started_animating_
&& have_animations
) {
204 started_animating_
= true;
208 if (started_animating_
&& !have_animations
)
212 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
213 Animation::TargetProperty target_property
,
214 int group
) override
{
215 // Animations on the impl-side controller only get deleted during a commit,
216 // so we need to schedule a commit.
217 layer_tree_host()->SetNeedsCommit();
220 void AfterTest() override
{}
223 bool started_animating_
;
226 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
228 // Ensure that an animation's timing function is respected.
229 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
230 : public LayerTreeHostAnimationTest
{
232 void SetupTree() override
{
233 LayerTreeHostAnimationTest::SetupTree();
234 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
235 picture_
->SetBounds(gfx::Size(4, 4));
236 layer_tree_host()->root_layer()->AddChild(picture_
);
239 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
241 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
242 base::TimeTicks monotonic_time
) override
{
243 // TODO(ajuma): This test only checks the active tree. Add checks for
245 if (!host_impl
->active_tree()->root_layer())
247 LayerAnimationController
* controller_impl
=
248 host_impl
->active_tree()->root_layer()->children()[0]->
249 layer_animation_controller();
250 Animation
* animation
= controller_impl
->GetAnimation(Animation::OPACITY
);
254 const FloatAnimationCurve
* curve
=
255 animation
->curve()->ToFloatAnimationCurve();
256 float start_opacity
= curve
->GetValue(base::TimeDelta());
257 float end_opacity
= curve
->GetValue(curve
->Duration());
258 float linearly_interpolated_opacity
=
259 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
260 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
261 // If the linear timing function associated with this animation was not
262 // picked up, then the linearly interpolated opacity would be different
263 // because of the default ease timing function.
264 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
269 void AfterTest() override
{}
271 FakeContentLayerClient client_
;
272 scoped_refptr
<FakePictureLayer
> picture_
;
275 SINGLE_AND_MULTI_THREAD_TEST_F(
276 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
278 // Ensures that main thread animations have their start times synchronized with
279 // impl thread animations.
280 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
281 : public LayerTreeHostAnimationTest
{
283 void SetupTree() override
{
284 LayerTreeHostAnimationTest::SetupTree();
285 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
286 picture_
->SetBounds(gfx::Size(4, 4));
287 picture_
->set_layer_animation_delegate(this);
288 layer_tree_host()->root_layer()->AddChild(picture_
);
291 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
293 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
294 Animation::TargetProperty target_property
,
295 int group
) override
{
296 LayerAnimationController
* controller
=
297 layer_tree_host()->root_layer()->children()[0]->
298 layer_animation_controller();
299 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
300 main_start_time_
= animation
->start_time();
301 controller
->RemoveAnimation(animation
->id());
305 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
306 bool has_unfinished_animation
) override
{
307 LayerAnimationController
* controller
=
308 impl_host
->active_tree()->root_layer()->children()[0]->
309 layer_animation_controller();
310 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
314 impl_start_time_
= animation
->start_time();
317 void AfterTest() override
{
318 EXPECT_EQ(impl_start_time_
, main_start_time_
);
319 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
323 base::TimeTicks main_start_time_
;
324 base::TimeTicks impl_start_time_
;
325 FakeContentLayerClient client_
;
326 scoped_refptr
<FakePictureLayer
> picture_
;
329 SINGLE_AND_MULTI_THREAD_TEST_F(
330 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
332 // Ensures that notify animation finished is called.
333 class LayerTreeHostAnimationTestAnimationFinishedEvents
334 : public LayerTreeHostAnimationTest
{
336 void BeginTest() override
{
337 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
340 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
341 Animation::TargetProperty target_property
,
342 int group
) override
{
343 LayerAnimationController
* controller
=
344 layer_tree_host()->root_layer()->layer_animation_controller();
345 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
347 controller
->RemoveAnimation(animation
->id());
351 void AfterTest() override
{}
354 SINGLE_AND_MULTI_THREAD_TEST_F(
355 LayerTreeHostAnimationTestAnimationFinishedEvents
);
357 // Ensures that when opacity is being animated, this value does not cause the
358 // subtree to be skipped.
359 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
360 : public LayerTreeHostAnimationTest
{
362 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
363 : update_check_layer_(
364 FakePictureLayer::Create(layer_settings(), &client_
)) {}
366 void SetupTree() override
{
367 update_check_layer_
->SetOpacity(0.f
);
368 layer_tree_host()->SetRootLayer(update_check_layer_
);
369 LayerTreeHostAnimationTest::SetupTree();
372 void BeginTest() override
{
373 PostAddAnimationToMainThread(update_check_layer_
.get());
376 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
377 LayerAnimationController
* controller_impl
=
378 host_impl
->active_tree()->root_layer()->layer_animation_controller();
379 Animation
* animation_impl
=
380 controller_impl
->GetAnimation(Animation::OPACITY
);
381 controller_impl
->RemoveAnimation(animation_impl
->id());
385 void AfterTest() override
{
386 // Update() should have been called once, proving that the layer was not
388 EXPECT_EQ(1, update_check_layer_
->update_count());
390 // clear update_check_layer_ so LayerTreeHost dies.
391 update_check_layer_
= NULL
;
395 FakeContentLayerClient client_
;
396 scoped_refptr
<FakePictureLayer
> update_check_layer_
;
399 SINGLE_AND_MULTI_THREAD_TEST_F(
400 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
402 // Layers added to tree with existing active animations should have the
403 // animation correctly recognized.
404 class LayerTreeHostAnimationTestLayerAddedWithAnimation
405 : public LayerTreeHostAnimationTest
{
407 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
409 void DidCommit() override
{
410 if (layer_tree_host()->source_frame_number() == 1) {
411 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
412 layer
->set_layer_animation_delegate(this);
414 // Any valid AnimationCurve will do here.
415 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
416 scoped_ptr
<Animation
> animation(
417 Animation::Create(curve
.Pass(), 1, 1, Animation::OPACITY
));
418 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
420 // We add the animation *before* attaching the layer to the tree.
421 layer_tree_host()->root_layer()->AddChild(layer
);
425 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
426 base::TimeTicks monotonic_time
) override
{
430 void AfterTest() override
{}
433 SINGLE_AND_MULTI_THREAD_TEST_F(
434 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
436 class LayerTreeHostAnimationTestCancelAnimateCommit
437 : public LayerTreeHostAnimationTest
{
439 LayerTreeHostAnimationTestCancelAnimateCommit()
440 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
442 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
444 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
446 // No-op animate will cancel the commit.
447 if (layer_tree_host()->source_frame_number() == 1) {
451 layer_tree_host()->SetNeedsAnimate();
454 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
456 if (impl
->active_tree()->source_frame_number() > 1)
457 FAIL() << "Commit should have been canceled.";
460 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
462 if (impl
->active_tree()->source_frame_number() > 1)
463 FAIL() << "Draw should have been canceled.";
466 void AfterTest() override
{
467 EXPECT_EQ(2, num_begin_frames_
);
468 EXPECT_EQ(1, num_commit_calls_
);
469 EXPECT_EQ(1, num_draw_calls_
);
473 int num_begin_frames_
;
474 int num_commit_calls_
;
478 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
480 class LayerTreeHostAnimationTestForceRedraw
481 : public LayerTreeHostAnimationTest
{
483 LayerTreeHostAnimationTestForceRedraw()
484 : num_animate_(0), num_draw_layers_(0) {}
486 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
488 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
489 if (++num_animate_
< 2)
490 layer_tree_host()->SetNeedsAnimate();
493 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
495 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
496 if (++num_draw_layers_
== 2)
500 void AfterTest() override
{
501 // The first commit will always draw; make sure the second draw triggered
502 // by the animation was not cancelled.
503 EXPECT_EQ(2, num_draw_layers_
);
504 EXPECT_EQ(2, num_animate_
);
509 int num_draw_layers_
;
512 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
514 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
515 : public LayerTreeHostAnimationTest
{
517 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
518 : num_animate_(0), num_draw_layers_(0) {}
520 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
522 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
523 if (++num_animate_
<= 2) {
524 layer_tree_host()->SetNeedsCommit();
525 layer_tree_host()->SetNeedsAnimate();
529 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
530 if (++num_draw_layers_
== 2)
534 void AfterTest() override
{
535 // The first commit will always draw; make sure the second draw triggered
536 // by the SetNeedsCommit was not cancelled.
537 EXPECT_EQ(2, num_draw_layers_
);
538 EXPECT_GE(num_animate_
, 2);
543 int num_draw_layers_
;
546 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
548 // Animations should not be started when frames are being skipped due to
550 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
551 : public LayerTreeHostAnimationTest
{
552 void SetupTree() override
{
553 LayerTreeHostAnimationTest::SetupTree();
554 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
555 picture_
->SetBounds(gfx::Size(4, 4));
556 picture_
->set_layer_animation_delegate(this);
557 layer_tree_host()->root_layer()->AddChild(picture_
);
560 void InitializeSettings(LayerTreeSettings
* settings
) override
{
561 // Make sure that drawing many times doesn't cause a checkerboarded
562 // animation to start so we avoid flake in this test.
563 settings
->timeout_and_draw_when_animation_checkerboards
= false;
566 void BeginTest() override
{
568 added_animations_
= 0;
571 PostSetNeedsCommitToMainThread();
574 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
575 LayerTreeHostImpl::FrameData
* frame_data
,
576 DrawResult draw_result
) override
{
577 if (added_animations_
< 2)
581 // Act like there is checkerboard when the second animation wants to draw.
583 if (prevented_draw_
> 2)
585 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
588 void DidCommitAndDrawFrame() override
{
589 switch (layer_tree_host()->source_frame_number()) {
591 // The animation is longer than 1 BeginFrame interval.
592 AddOpacityTransitionToLayer(picture_
.get(), 0.1, 0.2f
, 0.8f
, false);
596 // This second animation will not be drawn so it should not start.
597 AddAnimatedTransformToLayer(picture_
.get(), 0.1, 5, 5);
603 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
604 Animation::TargetProperty target_property
,
605 int group
) override
{
611 void AfterTest() override
{
612 // Make sure we tried to draw the second animation but failed.
613 EXPECT_LT(0, prevented_draw_
);
614 // The first animation should be started, but the second should not because
616 EXPECT_EQ(1, started_times_
);
620 int added_animations_
;
622 FakeContentLayerClient client_
;
623 scoped_refptr
<FakePictureLayer
> picture_
;
627 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
629 // Verifies that scroll offset animations are only accepted when impl-scrolling
630 // is supported, and that when scroll offset animations are accepted,
631 // scroll offset updates are sent back to the main thread.
632 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
633 : public LayerTreeHostAnimationTest
{
635 void SetupTree() override
{
636 LayerTreeHostAnimationTest::SetupTree();
638 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
639 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
640 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
641 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
642 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
645 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
647 void DidCommit() override
{
648 switch (layer_tree_host()->source_frame_number()) {
650 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
651 ScrollOffsetAnimationCurve::Create(
652 gfx::ScrollOffset(500.f
, 550.f
),
653 EaseInOutTimingFunction::Create()));
654 scoped_ptr
<Animation
> animation(
655 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
656 animation
->set_needs_synchronized_start_time(true);
657 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
658 bool impl_scrolling_supported
=
659 layer_tree_host()->proxy()->SupportsImplScrolling();
660 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
661 if (!impl_scrolling_supported
)
666 if (scroll_layer_
->scroll_offset().x() > 10 &&
667 scroll_layer_
->scroll_offset().y() > 20)
672 void AfterTest() override
{}
675 FakeContentLayerClient client_
;
676 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
679 SINGLE_AND_MULTI_THREAD_TEST_F(
680 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
682 // Verifies that when the main thread removes a scroll animation and sets a new
683 // scroll position, the active tree takes on exactly this new scroll position
684 // after activation, and the main thread doesn't receive a spurious scroll
686 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
687 : public LayerTreeHostAnimationTest
{
689 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
690 : final_postion_(50.0, 100.0) {}
692 void SetupTree() override
{
693 LayerTreeHostAnimationTest::SetupTree();
695 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
696 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
697 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
698 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
699 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
701 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
702 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
703 EaseInOutTimingFunction::Create()));
704 scoped_ptr
<Animation
> animation(
705 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
706 animation
->set_needs_synchronized_start_time(true);
707 scroll_layer_
->AddAnimation(animation
.Pass());
710 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
712 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
713 switch (layer_tree_host()->source_frame_number()) {
717 Animation
* animation
=
718 scroll_layer_
->layer_animation_controller()->GetAnimation(
719 Animation::SCROLL_OFFSET
);
720 scroll_layer_
->layer_animation_controller()->RemoveAnimation(
722 scroll_layer_
->SetScrollOffset(final_postion_
);
726 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
730 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
731 host_impl
->BlockNotifyReadyToActivateForTesting(true);
734 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
735 const BeginFrameArgs
& args
) override
{
736 if (!host_impl
->pending_tree())
739 if (!host_impl
->active_tree()->root_layer()) {
740 host_impl
->BlockNotifyReadyToActivateForTesting(false);
744 LayerImpl
* scroll_layer_impl
=
745 host_impl
->active_tree()->root_layer()->children()[0];
746 Animation
* animation
=
747 scroll_layer_impl
->layer_animation_controller()->GetAnimation(
748 Animation::SCROLL_OFFSET
);
750 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
751 host_impl
->BlockNotifyReadyToActivateForTesting(false);
755 // Block activation until the running animation has a chance to produce a
757 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
758 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
761 host_impl
->BlockNotifyReadyToActivateForTesting(false);
764 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
765 if (host_impl
->pending_tree()->source_frame_number() != 1)
767 LayerImpl
* scroll_layer_impl
=
768 host_impl
->pending_tree()->root_layer()->children()[0];
769 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
772 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
773 if (host_impl
->active_tree()->source_frame_number() != 1)
775 LayerImpl
* scroll_layer_impl
=
776 host_impl
->active_tree()->root_layer()->children()[0];
777 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
781 void AfterTest() override
{
782 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
786 FakeContentLayerClient client_
;
787 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
788 const gfx::ScrollOffset final_postion_
;
791 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
);
793 // When animations are simultaneously added to an existing layer and to a new
794 // layer, they should start at the same time, even when there's already a
795 // running animation on the existing layer.
796 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
797 : public LayerTreeHostAnimationTest
{
799 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
800 : frame_count_with_pending_tree_(0) {}
802 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
804 void DidCommit() override
{
805 if (layer_tree_host()->source_frame_number() == 1) {
806 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
807 } else if (layer_tree_host()->source_frame_number() == 2) {
808 AddOpacityTransitionToLayer(
809 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
811 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
812 layer_tree_host()->root_layer()->AddChild(layer
);
813 layer
->set_layer_animation_delegate(this);
814 layer
->SetBounds(gfx::Size(4, 4));
815 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
819 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
820 host_impl
->BlockNotifyReadyToActivateForTesting(true);
823 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
824 // For the commit that added animations to new and existing layers, keep
825 // blocking activation. We want to verify that even with activation blocked,
826 // the animation on the layer that's already in the active tree won't get a
828 if (host_impl
->pending_tree()->source_frame_number() != 2) {
829 host_impl
->BlockNotifyReadyToActivateForTesting(false);
833 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
834 const BeginFrameArgs
& args
) override
{
835 if (!host_impl
->pending_tree() ||
836 host_impl
->pending_tree()->source_frame_number() != 2)
839 frame_count_with_pending_tree_
++;
840 if (frame_count_with_pending_tree_
== 2) {
841 host_impl
->BlockNotifyReadyToActivateForTesting(false);
845 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
846 bool has_unfinished_animation
) override
{
847 LayerAnimationController
* root_controller_impl
=
848 host_impl
->active_tree()->root_layer()->layer_animation_controller();
849 Animation
* root_animation
=
850 root_controller_impl
->GetAnimation(Animation::OPACITY
);
851 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
854 LayerAnimationController
* child_controller_impl
=
855 host_impl
->active_tree()->root_layer()->children()
856 [0]->layer_animation_controller();
857 Animation
* child_animation
=
858 child_controller_impl
->GetAnimation(Animation::OPACITY
);
859 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
860 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
861 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
862 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
863 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
867 void AfterTest() override
{}
870 int frame_count_with_pending_tree_
;
873 // This test blocks activation which is not supported for single thread mode.
874 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
875 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
877 class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
878 : public LayerTreeHostAnimationTest
{
880 void SetupTree() override
{
881 LayerTreeHostAnimationTest::SetupTree();
883 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
884 layer_
->SetBounds(gfx::Size(2, 2));
885 // Transform the layer to 4,4 to start.
886 gfx::Transform start_transform
;
887 start_transform
.Translate(4.0, 4.0);
888 layer_
->SetTransform(start_transform
);
890 layer_tree_host()->root_layer()->AddChild(layer_
);
893 void BeginTest() override
{
894 // Add a translate from 6,7 to 8,9.
895 TransformOperations start
;
896 start
.AppendTranslate(6.f
, 7.f
, 0.f
);
897 TransformOperations end
;
898 end
.AppendTranslate(8.f
, 9.f
, 0.f
);
899 AddAnimatedTransformToLayer(layer_
.get(), 4.0, start
, end
);
901 PostSetNeedsCommitToMainThread();
904 void WillPrepareTiles(LayerTreeHostImpl
* host_impl
) override
{
905 if (host_impl
->sync_tree()->source_frame_number() != 0)
908 // After checking this on the sync tree, we will activate, which will cause
909 // PrepareTiles to happen again (which races with the test exiting).
913 LayerImpl
* root
= host_impl
->sync_tree()->root_layer();
914 LayerImpl
* child
= root
->children()[0];
915 LayerAnimationController
* controller_impl
=
916 child
->layer_animation_controller();
917 Animation
* animation
= controller_impl
->GetAnimation(Animation::TRANSFORM
);
919 // The animation should be starting for the first frame.
920 EXPECT_EQ(Animation::STARTING
, animation
->run_state());
922 // And the transform should be propogated to the sync tree layer, at its
923 // starting state which is 6,7.
924 gfx::Transform expected_transform
;
925 expected_transform
.Translate(6.0, 7.0);
926 EXPECT_EQ(expected_transform
, child
->draw_transform());
927 // And the sync tree layer should know it is animating.
928 EXPECT_TRUE(child
->screen_space_transform_is_animating());
930 controller_impl
->AbortAnimations(Animation::TRANSFORM
);
934 void AfterTest() override
{}
936 FakeContentLayerClient client_
;
937 scoped_refptr
<Layer
> layer_
;
940 SINGLE_AND_MULTI_THREAD_TEST_F(
941 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
);
943 // When a layer with an animation is removed from the tree and later re-added,
944 // the animation should resume.
945 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
946 : public LayerTreeHostAnimationTest
{
948 void SetupTree() override
{
949 LayerTreeHostAnimationTest::SetupTree();
950 layer_
= Layer::Create(layer_settings());
951 layer_
->SetBounds(gfx::Size(4, 4));
952 layer_tree_host()->root_layer()->AddChild(layer_
);
953 AddOpacityTransitionToLayer(layer_
.get(), 10000.0, 0.1f
, 0.9f
, true);
956 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
958 void DidCommit() override
{
959 switch (layer_tree_host()->source_frame_number()) {
961 layer_
->RemoveFromParent();
964 layer_tree_host()->root_layer()->AddChild(layer_
);
969 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
970 switch (host_impl
->active_tree()->source_frame_number()) {
972 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
975 EXPECT_FALSE(host_impl
->animation_registrar()->needs_animate_layers());
978 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
984 void AfterTest() override
{}
987 scoped_refptr
<Layer
> layer_
;
990 SINGLE_AND_MULTI_THREAD_TEST_F(
991 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
);
993 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
994 : public LayerTreeHostAnimationTest
{
996 void SetupTree() override
{
997 LayerTreeHostAnimationTest::SetupTree();
998 layer_
= Layer::Create(layer_settings());
999 layer_
->SetBounds(gfx::Size(4, 4));
1000 layer_tree_host()->root_layer()->AddChild(layer_
);
1003 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1005 void DidCommit() override
{
1006 switch (layer_tree_host()->source_frame_number()) {
1008 // First frame: add an animation to the root layer.
1009 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1012 // Second frame: add an animation to the content layer. The root layer
1013 // animation has caused us to animate already during this frame.
1014 AddOpacityTransitionToLayer(layer_
.get(), 0.1, 5, 5, false);
1019 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
1020 // After both animations have started, verify that they have valid
1022 if (host_impl
->active_tree()->source_frame_number() < 2)
1024 AnimationRegistrar::AnimationControllerMap controllers_copy
=
1025 host_impl
->animation_registrar()
1026 ->active_animation_controllers_for_testing();
1027 EXPECT_EQ(2u, controllers_copy
.size());
1028 for (auto& it
: controllers_copy
) {
1030 if (id
== host_impl
->RootLayer()->id()) {
1031 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
1032 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1033 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
1034 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
1035 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1041 void AfterTest() override
{}
1044 scoped_refptr
<Layer
> layer_
;
1047 SINGLE_AND_MULTI_THREAD_TEST_F(
1048 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);
1050 class LayerTreeHostAnimationTestRemoveAnimation
1051 : public LayerTreeHostAnimationTest
{
1053 void SetupTree() override
{
1054 LayerTreeHostAnimationTest::SetupTree();
1055 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1056 layer_
->SetBounds(gfx::Size(4, 4));
1057 layer_tree_host()->root_layer()->AddChild(layer_
);
1060 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1062 void DidCommit() override
{
1063 switch (layer_tree_host()->source_frame_number()) {
1065 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1068 LayerAnimationController
* controller
=
1069 layer_
->layer_animation_controller();
1070 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1071 layer_
->RemoveAnimation(animation
->id());
1072 gfx::Transform transform
;
1073 transform
.Translate(10.f
, 10.f
);
1074 layer_
->SetTransform(transform
);
1076 // Do something that causes property trees to get rebuilt. This is
1077 // intended to simulate the conditions that caused the bug whose fix
1078 // this is testing (the test will pass without it but won't test what
1079 // we want it to). We were updating the wrong transform node at the end
1080 // of an animation (we were assuming the layer with the finished
1081 // animation still had its own transform node). But nodes can only get
1082 // added/deleted when something triggers a rebuild. Adding a layer
1083 // triggers a rebuild, and since the layer that had an animation before
1084 // no longer has one, it doesn't get a transform node in the rebuild.
1085 layer_
->AddChild(Layer::Create(layer_settings()));
1090 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1091 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
1092 LayerImpl
* child
= root
->children()[0];
1093 switch (host_impl
->active_tree()->source_frame_number()) {
1095 // No animation yet.
1098 // Animation is started.
1099 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1102 // The animation is removed, the transform that was set afterward is
1104 gfx::Transform expected_transform
;
1105 expected_transform
.Translate(10.f
, 10.f
);
1106 EXPECT_EQ(expected_transform
, child
->draw_transform());
1107 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1116 void AfterTest() override
{}
1119 scoped_refptr
<Layer
> layer_
;
1120 FakeContentLayerClient client_
;
1123 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation
);
1125 class LayerTreeHostAnimationTestIsAnimating
1126 : public LayerTreeHostAnimationTest
{
1128 void SetupTree() override
{
1129 LayerTreeHostAnimationTest::SetupTree();
1130 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1131 layer_
->SetBounds(gfx::Size(4, 4));
1132 layer_tree_host()->root_layer()->AddChild(layer_
);
1135 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1137 void DidCommit() override
{
1138 switch (layer_tree_host()->source_frame_number()) {
1140 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1143 LayerAnimationController
* controller
=
1144 layer_
->layer_animation_controller();
1145 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1146 layer_
->RemoveAnimation(animation
->id());
1151 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1152 LayerImpl
* root
= host_impl
->sync_tree()->root_layer();
1153 LayerImpl
* child
= root
->children()[0];
1154 switch (host_impl
->sync_tree()->source_frame_number()) {
1156 // No animation yet.
1159 // Animation is started.
1160 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1163 // The animation is removed/stopped.
1164 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1172 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1173 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
1174 LayerImpl
* child
= root
->children()[0];
1175 switch (host_impl
->active_tree()->source_frame_number()) {
1177 // No animation yet.
1180 // Animation is started.
1181 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1184 // The animation is removed/stopped.
1185 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1193 void AfterTest() override
{}
1196 scoped_refptr
<Layer
> layer_
;
1197 FakeContentLayerClient client_
;
1200 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating
);
1202 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1203 : public LayerTreeHostAnimationTest
{
1205 void SetupTree() override
{
1206 LayerTreeHostAnimationTest::SetupTree();
1207 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1208 layer_
->SetBounds(gfx::Size(4, 4));
1209 layer_tree_host()->root_layer()->AddChild(layer_
);
1212 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1214 void DidCommit() override
{
1215 if (layer_tree_host()->source_frame_number() == 1)
1216 AddAnimatedTransformToLayer(layer_
.get(), 0.04, 5, 5);
1219 void WillCommit() override
{
1220 if (layer_tree_host()->source_frame_number() == 2) {
1221 // Block until the animation finishes on the compositor thread. Since
1222 // animations have already been ticked on the main thread, when the commit
1223 // happens the state on the main thread will be consistent with having a
1224 // running animation but the state on the compositor thread will be
1225 // consistent with having only a finished animation.
1230 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1231 switch (host_impl
->sync_tree()->source_frame_number()) {
1233 PostSetNeedsCommitToMainThread();
1236 gfx::Transform expected_transform
;
1237 expected_transform
.Translate(5.f
, 5.f
);
1238 LayerImpl
* layer_impl
=
1239 host_impl
->sync_tree()->root_layer()->children()[0];
1240 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
1246 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1247 bool has_unfinished_animation
) override
{
1248 if (host_impl
->active_tree()->source_frame_number() == 1 &&
1249 !has_unfinished_animation
) {
1250 // The animation has finished, so allow the main thread to commit.
1251 completion_
.Signal();
1255 void AfterTest() override
{}
1258 scoped_refptr
<Layer
> layer_
;
1259 FakeContentLayerClient client_
;
1260 CompletionEvent completion_
;
1263 // An animation finishing during commit can only happen when we have a separate
1264 // compositor thread.
1265 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit
);
1267 class LayerTreeHostAnimationTestNotifyAnimationFinished
1268 : public LayerTreeHostAnimationTest
{
1270 LayerTreeHostAnimationTestNotifyAnimationFinished()
1271 : called_animation_started_(false), called_animation_finished_(false) {}
1273 void SetupTree() override
{
1274 LayerTreeHostAnimationTest::SetupTree();
1275 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
1276 picture_
->SetBounds(gfx::Size(4, 4));
1277 picture_
->set_layer_animation_delegate(this);
1278 layer_tree_host()->root_layer()->AddChild(picture_
);
1281 void BeginTest() override
{
1282 PostAddLongAnimationToMainThread(picture_
.get());
1285 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
1286 Animation::TargetProperty target_property
,
1287 int group
) override
{
1288 called_animation_started_
= true;
1289 layer_tree_host()->AnimateLayers(
1290 base::TimeTicks::FromInternalValue(std::numeric_limits
<int64
>::max()));
1291 PostSetNeedsCommitToMainThread();
1294 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
1295 Animation::TargetProperty target_property
,
1296 int group
) override
{
1297 called_animation_finished_
= true;
1301 void AfterTest() override
{
1302 EXPECT_TRUE(called_animation_started_
);
1303 EXPECT_TRUE(called_animation_finished_
);
1307 bool called_animation_started_
;
1308 bool called_animation_finished_
;
1309 FakeContentLayerClient client_
;
1310 scoped_refptr
<FakePictureLayer
> picture_
;
1313 SINGLE_AND_MULTI_THREAD_TEST_F(
1314 LayerTreeHostAnimationTestNotifyAnimationFinished
);