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
{
570 PostSetNeedsCommitToMainThread();
573 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
574 LayerTreeHostImpl::FrameData
* frame_data
,
575 DrawResult draw_result
) override
{
576 // Don't checkerboard when the first animation wants to start.
577 if (host_impl
->active_tree()->source_frame_number() < 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);
595 // This second animation will not be drawn so it should not start.
596 AddAnimatedTransformToLayer(picture_
.get(), 0.1, 5, 5);
601 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
602 Animation::TargetProperty target_property
,
603 int group
) override
{
609 void AfterTest() override
{
610 // Make sure we tried to draw the second animation but failed.
611 EXPECT_LT(0, prevented_draw_
);
612 // The first animation should be started, but the second should not because
614 EXPECT_EQ(1, started_times_
);
619 FakeContentLayerClient client_
;
620 scoped_refptr
<FakePictureLayer
> picture_
;
624 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
626 // Verifies that scroll offset animations are only accepted when impl-scrolling
627 // is supported, and that when scroll offset animations are accepted,
628 // scroll offset updates are sent back to the main thread.
629 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
630 : public LayerTreeHostAnimationTest
{
632 void SetupTree() override
{
633 LayerTreeHostAnimationTest::SetupTree();
635 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
636 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
637 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
638 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
639 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
642 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
644 void DidCommit() override
{
645 switch (layer_tree_host()->source_frame_number()) {
647 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
648 ScrollOffsetAnimationCurve::Create(
649 gfx::ScrollOffset(500.f
, 550.f
),
650 EaseInOutTimingFunction::Create()));
651 scoped_ptr
<Animation
> animation(
652 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
653 animation
->set_needs_synchronized_start_time(true);
654 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
655 bool impl_scrolling_supported
=
656 layer_tree_host()->proxy()->SupportsImplScrolling();
657 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
658 if (!impl_scrolling_supported
)
663 if (scroll_layer_
->scroll_offset().x() > 10 &&
664 scroll_layer_
->scroll_offset().y() > 20)
669 void AfterTest() override
{}
672 FakeContentLayerClient client_
;
673 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
676 SINGLE_AND_MULTI_THREAD_TEST_F(
677 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
679 // Verifies that when the main thread removes a scroll animation and sets a new
680 // scroll position, the active tree takes on exactly this new scroll position
681 // after activation, and the main thread doesn't receive a spurious scroll
683 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
684 : public LayerTreeHostAnimationTest
{
686 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
687 : final_postion_(50.0, 100.0) {}
689 void SetupTree() override
{
690 LayerTreeHostAnimationTest::SetupTree();
692 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
693 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
694 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
695 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
696 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
698 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
699 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
700 EaseInOutTimingFunction::Create()));
701 scoped_ptr
<Animation
> animation(
702 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
703 animation
->set_needs_synchronized_start_time(true);
704 scroll_layer_
->AddAnimation(animation
.Pass());
707 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
709 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
710 switch (layer_tree_host()->source_frame_number()) {
714 Animation
* animation
=
715 scroll_layer_
->layer_animation_controller()->GetAnimation(
716 Animation::SCROLL_OFFSET
);
717 scroll_layer_
->layer_animation_controller()->RemoveAnimation(
719 scroll_layer_
->SetScrollOffset(final_postion_
);
723 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
727 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
728 host_impl
->BlockNotifyReadyToActivateForTesting(true);
731 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
732 const BeginFrameArgs
& args
) override
{
733 if (!host_impl
->pending_tree())
736 if (!host_impl
->active_tree()->root_layer()) {
737 host_impl
->BlockNotifyReadyToActivateForTesting(false);
741 LayerImpl
* scroll_layer_impl
=
742 host_impl
->active_tree()->root_layer()->children()[0];
743 Animation
* animation
=
744 scroll_layer_impl
->layer_animation_controller()->GetAnimation(
745 Animation::SCROLL_OFFSET
);
747 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
748 host_impl
->BlockNotifyReadyToActivateForTesting(false);
752 // Block activation until the running animation has a chance to produce a
754 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
755 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
758 host_impl
->BlockNotifyReadyToActivateForTesting(false);
761 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
762 if (host_impl
->pending_tree()->source_frame_number() != 1)
764 LayerImpl
* scroll_layer_impl
=
765 host_impl
->pending_tree()->root_layer()->children()[0];
766 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
769 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
770 if (host_impl
->active_tree()->source_frame_number() != 1)
772 LayerImpl
* scroll_layer_impl
=
773 host_impl
->active_tree()->root_layer()->children()[0];
774 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
778 void AfterTest() override
{
779 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
783 FakeContentLayerClient client_
;
784 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
785 const gfx::ScrollOffset final_postion_
;
788 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
);
790 // When animations are simultaneously added to an existing layer and to a new
791 // layer, they should start at the same time, even when there's already a
792 // running animation on the existing layer.
793 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
794 : public LayerTreeHostAnimationTest
{
796 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
797 : frame_count_with_pending_tree_(0) {}
799 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
801 void DidCommit() override
{
802 if (layer_tree_host()->source_frame_number() == 1) {
803 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
804 } else if (layer_tree_host()->source_frame_number() == 2) {
805 AddOpacityTransitionToLayer(
806 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
808 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
809 layer_tree_host()->root_layer()->AddChild(layer
);
810 layer
->set_layer_animation_delegate(this);
811 layer
->SetBounds(gfx::Size(4, 4));
812 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
816 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
817 host_impl
->BlockNotifyReadyToActivateForTesting(true);
820 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
821 // For the commit that added animations to new and existing layers, keep
822 // blocking activation. We want to verify that even with activation blocked,
823 // the animation on the layer that's already in the active tree won't get a
825 if (host_impl
->pending_tree()->source_frame_number() != 2) {
826 host_impl
->BlockNotifyReadyToActivateForTesting(false);
830 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
831 const BeginFrameArgs
& args
) override
{
832 if (!host_impl
->pending_tree() ||
833 host_impl
->pending_tree()->source_frame_number() != 2)
836 frame_count_with_pending_tree_
++;
837 if (frame_count_with_pending_tree_
== 2) {
838 host_impl
->BlockNotifyReadyToActivateForTesting(false);
842 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
843 bool has_unfinished_animation
) override
{
844 LayerAnimationController
* root_controller_impl
=
845 host_impl
->active_tree()->root_layer()->layer_animation_controller();
846 Animation
* root_animation
=
847 root_controller_impl
->GetAnimation(Animation::OPACITY
);
848 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
851 LayerAnimationController
* child_controller_impl
=
852 host_impl
->active_tree()->root_layer()->children()
853 [0]->layer_animation_controller();
854 Animation
* child_animation
=
855 child_controller_impl
->GetAnimation(Animation::OPACITY
);
856 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
857 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
858 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
859 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
860 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
864 void AfterTest() override
{}
867 int frame_count_with_pending_tree_
;
870 // This test blocks activation which is not supported for single thread mode.
871 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
872 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
874 class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
875 : public LayerTreeHostAnimationTest
{
877 void SetupTree() override
{
878 LayerTreeHostAnimationTest::SetupTree();
880 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
881 layer_
->SetBounds(gfx::Size(2, 2));
882 // Transform the layer to 4,4 to start.
883 gfx::Transform start_transform
;
884 start_transform
.Translate(4.0, 4.0);
885 layer_
->SetTransform(start_transform
);
887 layer_tree_host()->root_layer()->AddChild(layer_
);
890 void BeginTest() override
{
891 // Add a translate from 6,7 to 8,9.
892 TransformOperations start
;
893 start
.AppendTranslate(6.f
, 7.f
, 0.f
);
894 TransformOperations end
;
895 end
.AppendTranslate(8.f
, 9.f
, 0.f
);
896 AddAnimatedTransformToLayer(layer_
.get(), 4.0, start
, end
);
898 PostSetNeedsCommitToMainThread();
901 void WillPrepareTiles(LayerTreeHostImpl
* host_impl
) override
{
902 if (host_impl
->sync_tree()->source_frame_number() != 0)
905 // After checking this on the sync tree, we will activate, which will cause
906 // PrepareTiles to happen again (which races with the test exiting).
910 LayerImpl
* root
= host_impl
->sync_tree()->root_layer();
911 LayerImpl
* child
= root
->children()[0];
912 LayerAnimationController
* controller_impl
=
913 child
->layer_animation_controller();
914 Animation
* animation
= controller_impl
->GetAnimation(Animation::TRANSFORM
);
916 // The animation should be starting for the first frame.
917 EXPECT_EQ(Animation::STARTING
, animation
->run_state());
919 // And the transform should be propogated to the sync tree layer, at its
920 // starting state which is 6,7.
921 gfx::Transform expected_transform
;
922 expected_transform
.Translate(6.0, 7.0);
923 EXPECT_EQ(expected_transform
, child
->draw_transform());
924 // And the sync tree layer should know it is animating.
925 EXPECT_TRUE(child
->screen_space_transform_is_animating());
927 controller_impl
->AbortAnimations(Animation::TRANSFORM
);
931 void AfterTest() override
{}
933 FakeContentLayerClient client_
;
934 scoped_refptr
<Layer
> layer_
;
937 SINGLE_AND_MULTI_THREAD_TEST_F(
938 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
);
940 // When a layer with an animation is removed from the tree and later re-added,
941 // the animation should resume.
942 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
943 : public LayerTreeHostAnimationTest
{
945 void SetupTree() override
{
946 LayerTreeHostAnimationTest::SetupTree();
947 layer_
= Layer::Create(layer_settings());
948 layer_
->SetBounds(gfx::Size(4, 4));
949 layer_tree_host()->root_layer()->AddChild(layer_
);
950 AddOpacityTransitionToLayer(layer_
.get(), 10000.0, 0.1f
, 0.9f
, true);
953 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
955 void DidCommit() override
{
956 switch (layer_tree_host()->source_frame_number()) {
958 layer_
->RemoveFromParent();
961 layer_tree_host()->root_layer()->AddChild(layer_
);
966 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
967 switch (host_impl
->active_tree()->source_frame_number()) {
969 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
972 EXPECT_FALSE(host_impl
->animation_registrar()->needs_animate_layers());
975 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
981 void AfterTest() override
{}
984 scoped_refptr
<Layer
> layer_
;
987 SINGLE_AND_MULTI_THREAD_TEST_F(
988 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
);
990 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
991 : public LayerTreeHostAnimationTest
{
993 void SetupTree() override
{
994 LayerTreeHostAnimationTest::SetupTree();
995 layer_
= Layer::Create(layer_settings());
996 layer_
->SetBounds(gfx::Size(4, 4));
997 layer_tree_host()->root_layer()->AddChild(layer_
);
1000 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1002 void DidCommit() override
{
1003 switch (layer_tree_host()->source_frame_number()) {
1005 // First frame: add an animation to the root layer.
1006 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1009 // Second frame: add an animation to the content layer. The root layer
1010 // animation has caused us to animate already during this frame.
1011 AddOpacityTransitionToLayer(layer_
.get(), 0.1, 5, 5, false);
1016 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
1017 // After both animations have started, verify that they have valid
1019 if (host_impl
->active_tree()->source_frame_number() < 2)
1021 AnimationRegistrar::AnimationControllerMap controllers_copy
=
1022 host_impl
->animation_registrar()
1023 ->active_animation_controllers_for_testing();
1024 EXPECT_EQ(2u, controllers_copy
.size());
1025 for (auto& it
: controllers_copy
) {
1027 if (id
== host_impl
->RootLayer()->id()) {
1028 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
1029 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1030 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
1031 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
1032 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1038 void AfterTest() override
{}
1041 scoped_refptr
<Layer
> layer_
;
1044 SINGLE_AND_MULTI_THREAD_TEST_F(
1045 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);
1047 class LayerTreeHostAnimationTestRemoveAnimation
1048 : public LayerTreeHostAnimationTest
{
1050 void SetupTree() override
{
1051 LayerTreeHostAnimationTest::SetupTree();
1052 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1053 layer_
->SetBounds(gfx::Size(4, 4));
1054 layer_tree_host()->root_layer()->AddChild(layer_
);
1057 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1059 void DidCommit() override
{
1060 switch (layer_tree_host()->source_frame_number()) {
1062 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1065 LayerAnimationController
* controller
=
1066 layer_
->layer_animation_controller();
1067 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1068 layer_
->RemoveAnimation(animation
->id());
1069 gfx::Transform transform
;
1070 transform
.Translate(10.f
, 10.f
);
1071 layer_
->SetTransform(transform
);
1073 // Do something that causes property trees to get rebuilt. This is
1074 // intended to simulate the conditions that caused the bug whose fix
1075 // this is testing (the test will pass without it but won't test what
1076 // we want it to). We were updating the wrong transform node at the end
1077 // of an animation (we were assuming the layer with the finished
1078 // animation still had its own transform node). But nodes can only get
1079 // added/deleted when something triggers a rebuild. Adding a layer
1080 // triggers a rebuild, and since the layer that had an animation before
1081 // no longer has one, it doesn't get a transform node in the rebuild.
1082 layer_
->AddChild(Layer::Create(layer_settings()));
1087 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1088 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
1089 LayerImpl
* child
= root
->children()[0];
1090 switch (host_impl
->active_tree()->source_frame_number()) {
1092 // No animation yet.
1095 // Animation is started.
1096 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1099 // The animation is removed, the transform that was set afterward is
1101 gfx::Transform expected_transform
;
1102 expected_transform
.Translate(10.f
, 10.f
);
1103 EXPECT_EQ(expected_transform
, child
->draw_transform());
1104 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1113 void AfterTest() override
{}
1116 scoped_refptr
<Layer
> layer_
;
1117 FakeContentLayerClient client_
;
1120 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation
);
1122 class LayerTreeHostAnimationTestIsAnimating
1123 : public LayerTreeHostAnimationTest
{
1125 void SetupTree() override
{
1126 LayerTreeHostAnimationTest::SetupTree();
1127 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1128 layer_
->SetBounds(gfx::Size(4, 4));
1129 layer_tree_host()->root_layer()->AddChild(layer_
);
1132 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1134 void DidCommit() override
{
1135 switch (layer_tree_host()->source_frame_number()) {
1137 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1140 LayerAnimationController
* controller
=
1141 layer_
->layer_animation_controller();
1142 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1143 layer_
->RemoveAnimation(animation
->id());
1148 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1149 LayerImpl
* root
= host_impl
->sync_tree()->root_layer();
1150 LayerImpl
* child
= root
->children()[0];
1151 switch (host_impl
->sync_tree()->source_frame_number()) {
1153 // No animation yet.
1156 // Animation is started.
1157 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1160 // The animation is removed/stopped.
1161 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1169 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1170 LayerImpl
* root
= host_impl
->active_tree()->root_layer();
1171 LayerImpl
* child
= root
->children()[0];
1172 switch (host_impl
->active_tree()->source_frame_number()) {
1174 // No animation yet.
1177 // Animation is started.
1178 EXPECT_TRUE(child
->screen_space_transform_is_animating());
1181 // The animation is removed/stopped.
1182 EXPECT_FALSE(child
->screen_space_transform_is_animating());
1190 void AfterTest() override
{}
1193 scoped_refptr
<Layer
> layer_
;
1194 FakeContentLayerClient client_
;
1197 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating
);
1199 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1200 : public LayerTreeHostAnimationTest
{
1202 LayerTreeHostAnimationTestAnimationFinishesDuringCommit()
1203 : signalled_(false) {}
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
&& !signalled_
) {
1250 // The animation has finished, so allow the main thread to commit.
1251 completion_
.Signal();
1256 void AfterTest() override
{}
1259 scoped_refptr
<Layer
> layer_
;
1260 FakeContentLayerClient client_
;
1261 CompletionEvent completion_
;
1265 // An animation finishing during commit can only happen when we have a separate
1266 // compositor thread.
1267 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit
);
1269 class LayerTreeHostAnimationTestNotifyAnimationFinished
1270 : public LayerTreeHostAnimationTest
{
1272 LayerTreeHostAnimationTestNotifyAnimationFinished()
1273 : called_animation_started_(false), called_animation_finished_(false) {}
1275 void SetupTree() override
{
1276 LayerTreeHostAnimationTest::SetupTree();
1277 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
1278 picture_
->SetBounds(gfx::Size(4, 4));
1279 picture_
->set_layer_animation_delegate(this);
1280 layer_tree_host()->root_layer()->AddChild(picture_
);
1283 void BeginTest() override
{
1284 PostAddLongAnimationToMainThread(picture_
.get());
1287 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
1288 Animation::TargetProperty target_property
,
1289 int group
) override
{
1290 called_animation_started_
= true;
1291 layer_tree_host()->AnimateLayers(
1292 base::TimeTicks::FromInternalValue(std::numeric_limits
<int64
>::max()));
1293 PostSetNeedsCommitToMainThread();
1296 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
1297 Animation::TargetProperty target_property
,
1298 int group
) override
{
1299 called_animation_finished_
= true;
1303 void AfterTest() override
{
1304 EXPECT_TRUE(called_animation_started_
);
1305 EXPECT_TRUE(called_animation_finished_
);
1309 bool called_animation_started_
;
1310 bool called_animation_finished_
;
1311 FakeContentLayerClient client_
;
1312 scoped_refptr
<FakePictureLayer
> picture_
;
1315 SINGLE_AND_MULTI_THREAD_TEST_F(
1316 LayerTreeHostAnimationTestNotifyAnimationFinished
);