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/completion_event.h"
12 #include "cc/base/time_util.h"
13 #include "cc/layers/layer.h"
14 #include "cc/layers/layer_impl.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_content_layer_client.h"
17 #include "cc/test/fake_picture_layer.h"
18 #include "cc/test/layer_tree_test.h"
19 #include "cc/trees/layer_tree_impl.h"
24 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
26 void SetupTree() override
{
27 LayerTreeTest::SetupTree();
28 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
32 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
34 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
35 : public LayerTreeHostAnimationTest
{
37 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
40 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
42 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
43 // We skip the first commit because its the commit that populates the
44 // impl thread with a tree. After the second commit, the test is done.
45 if (num_commits_
!= 1)
48 layer_tree_host()->SetNeedsAnimate();
49 // Right now, CommitRequested is going to be true, because during
50 // BeginFrame, we force CommitRequested to true to prevent requests from
51 // hitting the impl thread. But, when the next DidCommit happens, we should
52 // verify that CommitRequested has gone back to false.
55 void DidCommit() override
{
57 EXPECT_FALSE(layer_tree_host()->CommitRequested());
58 layer_tree_host()->SetNeedsAnimate();
59 EXPECT_FALSE(layer_tree_host()->CommitRequested());
62 // Verifies that the SetNeedsAnimate we made in ::Animate did not
63 // trigger CommitRequested.
64 EXPECT_FALSE(layer_tree_host()->CommitRequested());
69 void AfterTest() override
{}
76 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
78 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
79 // callback, request another frame using SetNeedsAnimate. End the test when
80 // animate gets called yet-again, indicating that the proxy is correctly
81 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
83 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
84 : public LayerTreeHostAnimationTest
{
86 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
87 : num_begin_frames_(0) {}
89 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
91 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
92 if (!num_begin_frames_
) {
93 layer_tree_host()->SetNeedsAnimate();
100 void AfterTest() override
{}
103 int num_begin_frames_
;
106 SINGLE_AND_MULTI_THREAD_TEST_F(
107 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
109 // Add a layer animation and confirm that
110 // LayerTreeHostImpl::UpdateAnimationState does get called.
111 class LayerTreeHostAnimationTestAddAnimation
112 : public LayerTreeHostAnimationTest
{
114 LayerTreeHostAnimationTestAddAnimation()
115 : update_animation_state_was_called_(false) {}
117 void BeginTest() override
{
118 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
121 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
122 bool has_unfinished_animation
) override
{
123 EXPECT_FALSE(has_unfinished_animation
);
124 update_animation_state_was_called_
= true;
127 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
128 Animation::TargetProperty target_property
,
129 int group
) override
{
130 EXPECT_LT(base::TimeTicks(), monotonic_time
);
132 LayerAnimationController
* controller
=
133 layer_tree_host()->root_layer()->layer_animation_controller();
134 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
136 controller
->RemoveAnimation(animation
->id());
141 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
144 bool update_animation_state_was_called_
;
147 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
149 // Add a layer animation to a layer, but continually fail to draw. Confirm that
150 // after a while, we do eventually force a draw.
151 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
152 : public LayerTreeHostAnimationTest
{
154 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
155 : started_animating_(false) {}
157 void BeginTest() override
{
158 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
161 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
162 base::TimeTicks monotonic_time
) override
{
163 started_animating_
= true;
166 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
167 if (started_animating_
)
171 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
172 LayerTreeHostImpl::FrameData
* frame
,
173 DrawResult draw_result
) override
{
174 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
177 void AfterTest() override
{}
180 bool started_animating_
;
183 // Starvation can only be an issue with the MT compositor.
184 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
186 // Ensures that animations eventually get deleted.
187 class LayerTreeHostAnimationTestAnimationsGetDeleted
188 : public LayerTreeHostAnimationTest
{
190 LayerTreeHostAnimationTestAnimationsGetDeleted()
191 : started_animating_(false) {}
193 void BeginTest() override
{
194 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
197 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
198 base::TimeTicks monotonic_time
) override
{
199 bool have_animations
= !host_impl
->animation_registrar()
200 ->active_animation_controllers_for_testing()
202 if (!started_animating_
&& have_animations
) {
203 started_animating_
= true;
207 if (started_animating_
&& !have_animations
)
211 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
212 Animation::TargetProperty target_property
,
213 int group
) override
{
214 // Animations on the impl-side controller only get deleted during a commit,
215 // so we need to schedule a commit.
216 layer_tree_host()->SetNeedsCommit();
219 void AfterTest() override
{}
222 bool started_animating_
;
225 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
227 // Ensure that an animation's timing function is respected.
228 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
229 : public LayerTreeHostAnimationTest
{
231 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
233 void SetupTree() override
{
234 LayerTreeHostAnimationTest::SetupTree();
235 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
236 picture_
->SetBounds(gfx::Size(4, 4));
237 layer_tree_host()->root_layer()->AddChild(picture_
);
240 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
242 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
243 base::TimeTicks monotonic_time
) override
{
244 LayerAnimationController
* controller_impl
=
245 host_impl
->active_tree()->root_layer()->children()[0]->
246 layer_animation_controller();
247 Animation
* animation
= controller_impl
->GetAnimation(Animation::OPACITY
);
251 const FloatAnimationCurve
* curve
=
252 animation
->curve()->ToFloatAnimationCurve();
253 float start_opacity
= curve
->GetValue(base::TimeDelta());
254 float end_opacity
= curve
->GetValue(curve
->Duration());
255 float linearly_interpolated_opacity
=
256 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
257 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
258 // If the linear timing function associated with this animation was not
259 // picked up, then the linearly interpolated opacity would be different
260 // because of the default ease timing function.
261 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
266 void AfterTest() override
{}
268 FakeContentLayerClient client_
;
269 scoped_refptr
<FakePictureLayer
> picture_
;
272 SINGLE_AND_MULTI_THREAD_TEST_F(
273 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
275 // Ensures that main thread animations have their start times synchronized with
276 // impl thread animations.
277 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
278 : public LayerTreeHostAnimationTest
{
280 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
282 void SetupTree() override
{
283 LayerTreeHostAnimationTest::SetupTree();
284 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
285 picture_
->SetBounds(gfx::Size(4, 4));
286 picture_
->set_layer_animation_delegate(this);
287 layer_tree_host()->root_layer()->AddChild(picture_
);
290 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
292 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
293 Animation::TargetProperty target_property
,
294 int group
) override
{
295 LayerAnimationController
* controller
=
296 layer_tree_host()->root_layer()->children()[0]->
297 layer_animation_controller();
298 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
299 main_start_time_
= animation
->start_time();
300 controller
->RemoveAnimation(animation
->id());
304 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
305 bool has_unfinished_animation
) override
{
306 LayerAnimationController
* controller
=
307 impl_host
->active_tree()->root_layer()->children()[0]->
308 layer_animation_controller();
309 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
313 impl_start_time_
= animation
->start_time();
316 void AfterTest() override
{
317 EXPECT_EQ(impl_start_time_
, main_start_time_
);
318 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
322 base::TimeTicks main_start_time_
;
323 base::TimeTicks impl_start_time_
;
324 FakeContentLayerClient client_
;
325 scoped_refptr
<FakePictureLayer
> picture_
;
328 SINGLE_AND_MULTI_THREAD_TEST_F(
329 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
331 // Ensures that notify animation finished is called.
332 class LayerTreeHostAnimationTestAnimationFinishedEvents
333 : public LayerTreeHostAnimationTest
{
335 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
337 void BeginTest() override
{
338 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
341 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
342 Animation::TargetProperty target_property
,
343 int group
) override
{
344 LayerAnimationController
* controller
=
345 layer_tree_host()->root_layer()->layer_animation_controller();
346 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
348 controller
->RemoveAnimation(animation
->id());
352 void AfterTest() override
{}
355 SINGLE_AND_MULTI_THREAD_TEST_F(
356 LayerTreeHostAnimationTestAnimationFinishedEvents
);
358 // Ensures that when opacity is being animated, this value does not cause the
359 // subtree to be skipped.
360 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
361 : public LayerTreeHostAnimationTest
{
363 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
364 : update_check_layer_(
365 FakePictureLayer::Create(layer_settings(), &client_
)) {}
367 void SetupTree() override
{
368 update_check_layer_
->SetOpacity(0.f
);
369 layer_tree_host()->SetRootLayer(update_check_layer_
);
370 LayerTreeHostAnimationTest::SetupTree();
373 void BeginTest() override
{
374 PostAddAnimationToMainThread(update_check_layer_
.get());
377 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
378 LayerAnimationController
* controller_impl
=
379 host_impl
->active_tree()->root_layer()->layer_animation_controller();
380 Animation
* animation_impl
=
381 controller_impl
->GetAnimation(Animation::OPACITY
);
382 controller_impl
->RemoveAnimation(animation_impl
->id());
386 void AfterTest() override
{
387 // Update() should have been called once, proving that the layer was not
389 EXPECT_EQ(1, update_check_layer_
->update_count());
391 // clear update_check_layer_ so LayerTreeHost dies.
392 update_check_layer_
= NULL
;
396 FakeContentLayerClient client_
;
397 scoped_refptr
<FakePictureLayer
> update_check_layer_
;
400 SINGLE_AND_MULTI_THREAD_TEST_F(
401 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
403 // Layers added to tree with existing active animations should have the
404 // animation correctly recognized.
405 class LayerTreeHostAnimationTestLayerAddedWithAnimation
406 : public LayerTreeHostAnimationTest
{
408 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
410 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
412 void DidCommit() override
{
413 if (layer_tree_host()->source_frame_number() == 1) {
414 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
415 layer
->set_layer_animation_delegate(this);
417 // Any valid AnimationCurve will do here.
418 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
419 scoped_ptr
<Animation
> animation(
420 Animation::Create(curve
.Pass(), 1, 1, Animation::OPACITY
));
421 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
423 // We add the animation *before* attaching the layer to the tree.
424 layer_tree_host()->root_layer()->AddChild(layer
);
428 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
429 base::TimeTicks monotonic_time
) override
{
433 void AfterTest() override
{}
436 SINGLE_AND_MULTI_THREAD_TEST_F(
437 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
439 class LayerTreeHostAnimationTestCancelAnimateCommit
440 : public LayerTreeHostAnimationTest
{
442 LayerTreeHostAnimationTestCancelAnimateCommit()
443 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
445 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
447 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
449 // No-op animate will cancel the commit.
450 if (layer_tree_host()->source_frame_number() == 1) {
454 layer_tree_host()->SetNeedsAnimate();
457 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
459 if (impl
->active_tree()->source_frame_number() > 1)
460 FAIL() << "Commit should have been canceled.";
463 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
465 if (impl
->active_tree()->source_frame_number() > 1)
466 FAIL() << "Draw should have been canceled.";
469 void AfterTest() override
{
470 EXPECT_EQ(2, num_begin_frames_
);
471 EXPECT_EQ(1, num_commit_calls_
);
472 EXPECT_EQ(1, num_draw_calls_
);
476 int num_begin_frames_
;
477 int num_commit_calls_
;
481 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
483 class LayerTreeHostAnimationTestForceRedraw
484 : public LayerTreeHostAnimationTest
{
486 LayerTreeHostAnimationTestForceRedraw()
487 : num_animate_(0), num_draw_layers_(0) {}
489 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
491 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
492 if (++num_animate_
< 2)
493 layer_tree_host()->SetNeedsAnimate();
496 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
498 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
499 if (++num_draw_layers_
== 2)
503 void AfterTest() override
{
504 // The first commit will always draw; make sure the second draw triggered
505 // by the animation was not cancelled.
506 EXPECT_EQ(2, num_draw_layers_
);
507 EXPECT_EQ(2, num_animate_
);
512 int num_draw_layers_
;
515 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
517 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
518 : public LayerTreeHostAnimationTest
{
520 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
521 : num_animate_(0), num_draw_layers_(0) {}
523 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
525 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
526 if (++num_animate_
<= 2) {
527 layer_tree_host()->SetNeedsCommit();
528 layer_tree_host()->SetNeedsAnimate();
532 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
533 if (++num_draw_layers_
== 2)
537 void AfterTest() override
{
538 // The first commit will always draw; make sure the second draw triggered
539 // by the SetNeedsCommit was not cancelled.
540 EXPECT_EQ(2, num_draw_layers_
);
541 EXPECT_GE(num_animate_
, 2);
546 int num_draw_layers_
;
549 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
551 // Animations should not be started when frames are being skipped due to
553 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
554 : public LayerTreeHostAnimationTest
{
555 void SetupTree() override
{
556 LayerTreeHostAnimationTest::SetupTree();
557 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
558 picture_
->SetBounds(gfx::Size(4, 4));
559 picture_
->set_layer_animation_delegate(this);
560 layer_tree_host()->root_layer()->AddChild(picture_
);
563 void InitializeSettings(LayerTreeSettings
* settings
) override
{
564 // Make sure that drawing many times doesn't cause a checkerboarded
565 // animation to start so we avoid flake in this test.
566 settings
->timeout_and_draw_when_animation_checkerboards
= false;
569 void BeginTest() override
{
571 added_animations_
= 0;
574 PostSetNeedsCommitToMainThread();
577 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
578 LayerTreeHostImpl::FrameData
* frame_data
,
579 DrawResult draw_result
) override
{
580 if (added_animations_
< 2)
584 // Act like there is checkerboard when the second animation wants to draw.
586 if (prevented_draw_
> 2)
588 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
591 void DidCommitAndDrawFrame() override
{
592 switch (layer_tree_host()->source_frame_number()) {
594 // The animation is longer than 1 BeginFrame interval.
595 AddOpacityTransitionToLayer(picture_
.get(), 0.1, 0.2f
, 0.8f
, false);
599 // This second animation will not be drawn so it should not start.
600 AddAnimatedTransformToLayer(picture_
.get(), 0.1, 5, 5);
606 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
607 Animation::TargetProperty target_property
,
608 int group
) override
{
614 void AfterTest() override
{
615 // Make sure we tried to draw the second animation but failed.
616 EXPECT_LT(0, prevented_draw_
);
617 // The first animation should be started, but the second should not because
619 EXPECT_EQ(1, started_times_
);
623 int added_animations_
;
625 FakeContentLayerClient client_
;
626 scoped_refptr
<FakePictureLayer
> picture_
;
630 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
632 // Verifies that scroll offset animations are only accepted when impl-scrolling
633 // is supported, and that when scroll offset animations are accepted,
634 // scroll offset updates are sent back to the main thread.
635 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
636 : public LayerTreeHostAnimationTest
{
638 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
640 void SetupTree() override
{
641 LayerTreeHostAnimationTest::SetupTree();
643 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
644 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
645 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
646 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
647 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
650 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
652 void DidCommit() override
{
653 switch (layer_tree_host()->source_frame_number()) {
655 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
656 ScrollOffsetAnimationCurve::Create(
657 gfx::ScrollOffset(500.f
, 550.f
),
658 EaseInOutTimingFunction::Create()));
659 scoped_ptr
<Animation
> animation(
660 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
661 animation
->set_needs_synchronized_start_time(true);
662 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
663 bool impl_scrolling_supported
=
664 layer_tree_host()->proxy()->SupportsImplScrolling();
665 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
666 if (!impl_scrolling_supported
)
671 if (scroll_layer_
->scroll_offset().x() > 10 &&
672 scroll_layer_
->scroll_offset().y() > 20)
677 void AfterTest() override
{}
680 FakeContentLayerClient client_
;
681 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
684 SINGLE_AND_MULTI_THREAD_TEST_F(
685 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
687 // Verifies that when the main thread removes a scroll animation and sets a new
688 // scroll position, the active tree takes on exactly this new scroll position
689 // after activation, and the main thread doesn't receive a spurious scroll
691 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
692 : public LayerTreeHostAnimationTest
{
694 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
695 : final_postion_(50.0, 100.0) {}
697 void SetupTree() override
{
698 LayerTreeHostAnimationTest::SetupTree();
700 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
701 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
702 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
703 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
704 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
706 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
707 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
708 EaseInOutTimingFunction::Create()));
709 scoped_ptr
<Animation
> animation(
710 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
711 animation
->set_needs_synchronized_start_time(true);
712 scroll_layer_
->AddAnimation(animation
.Pass());
715 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
717 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
718 switch (layer_tree_host()->source_frame_number()) {
722 Animation
* animation
=
723 scroll_layer_
->layer_animation_controller()->GetAnimation(
724 Animation::SCROLL_OFFSET
);
725 scroll_layer_
->layer_animation_controller()->RemoveAnimation(
727 scroll_layer_
->SetScrollOffset(final_postion_
);
731 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
735 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
736 host_impl
->BlockNotifyReadyToActivateForTesting(true);
739 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
740 const BeginFrameArgs
& args
) override
{
741 if (!host_impl
->pending_tree())
744 if (!host_impl
->active_tree()->root_layer()) {
745 host_impl
->BlockNotifyReadyToActivateForTesting(false);
749 LayerImpl
* scroll_layer_impl
=
750 host_impl
->active_tree()->root_layer()->children()[0];
751 Animation
* animation
=
752 scroll_layer_impl
->layer_animation_controller()->GetAnimation(
753 Animation::SCROLL_OFFSET
);
755 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
756 host_impl
->BlockNotifyReadyToActivateForTesting(false);
760 // Block activation until the running animation has a chance to produce a
762 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
763 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
766 host_impl
->BlockNotifyReadyToActivateForTesting(false);
769 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
770 if (host_impl
->pending_tree()->source_frame_number() != 1)
772 LayerImpl
* scroll_layer_impl
=
773 host_impl
->pending_tree()->root_layer()->children()[0];
774 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
777 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
778 if (host_impl
->active_tree()->source_frame_number() != 1)
780 LayerImpl
* scroll_layer_impl
=
781 host_impl
->active_tree()->root_layer()->children()[0];
782 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
786 void AfterTest() override
{
787 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
791 FakeContentLayerClient client_
;
792 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
793 const gfx::ScrollOffset final_postion_
;
796 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
);
798 // When animations are simultaneously added to an existing layer and to a new
799 // layer, they should start at the same time, even when there's already a
800 // running animation on the existing layer.
801 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
802 : public LayerTreeHostAnimationTest
{
804 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
805 : frame_count_with_pending_tree_(0) {}
807 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
809 void DidCommit() override
{
810 if (layer_tree_host()->source_frame_number() == 1) {
811 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
812 } else if (layer_tree_host()->source_frame_number() == 2) {
813 AddOpacityTransitionToLayer(
814 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
816 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
817 layer_tree_host()->root_layer()->AddChild(layer
);
818 layer
->set_layer_animation_delegate(this);
819 layer
->SetBounds(gfx::Size(4, 4));
820 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
824 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
825 host_impl
->BlockNotifyReadyToActivateForTesting(true);
828 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
829 // For the commit that added animations to new and existing layers, keep
830 // blocking activation. We want to verify that even with activation blocked,
831 // the animation on the layer that's already in the active tree won't get a
833 if (host_impl
->pending_tree()->source_frame_number() != 2) {
834 host_impl
->BlockNotifyReadyToActivateForTesting(false);
838 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
839 const BeginFrameArgs
& args
) override
{
840 if (!host_impl
->pending_tree() ||
841 host_impl
->pending_tree()->source_frame_number() != 2)
844 frame_count_with_pending_tree_
++;
845 if (frame_count_with_pending_tree_
== 2) {
846 host_impl
->BlockNotifyReadyToActivateForTesting(false);
850 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
851 bool has_unfinished_animation
) override
{
852 LayerAnimationController
* root_controller_impl
=
853 host_impl
->active_tree()->root_layer()->layer_animation_controller();
854 Animation
* root_animation
=
855 root_controller_impl
->GetAnimation(Animation::OPACITY
);
856 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
859 LayerAnimationController
* child_controller_impl
=
860 host_impl
->active_tree()->root_layer()->children()
861 [0]->layer_animation_controller();
862 Animation
* child_animation
=
863 child_controller_impl
->GetAnimation(Animation::OPACITY
);
864 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
865 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
866 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
867 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
868 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
872 void AfterTest() override
{}
875 int frame_count_with_pending_tree_
;
878 // This test blocks activation which is not supported for single thread mode.
879 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
880 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
882 // When a layer with an animation is removed from the tree and later re-added,
883 // the animation should resume.
884 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
885 : public LayerTreeHostAnimationTest
{
887 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
889 void SetupTree() override
{
890 LayerTreeHostAnimationTest::SetupTree();
891 layer_
= Layer::Create(layer_settings());
892 layer_
->SetBounds(gfx::Size(4, 4));
893 layer_tree_host()->root_layer()->AddChild(layer_
);
894 AddOpacityTransitionToLayer(layer_
.get(), 10000.0, 0.1f
, 0.9f
, true);
897 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
899 void DidCommit() override
{
900 switch (layer_tree_host()->source_frame_number()) {
902 layer_
->RemoveFromParent();
905 layer_tree_host()->root_layer()->AddChild(layer_
);
910 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
911 switch (host_impl
->active_tree()->source_frame_number()) {
913 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
916 EXPECT_FALSE(host_impl
->animation_registrar()->needs_animate_layers());
919 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
925 void AfterTest() override
{}
928 scoped_refptr
<Layer
> layer_
;
931 SINGLE_AND_MULTI_THREAD_TEST_F(
932 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
);
934 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
935 : public LayerTreeHostAnimationTest
{
937 void SetupTree() override
{
938 LayerTreeHostAnimationTest::SetupTree();
939 layer_
= Layer::Create(layer_settings());
940 layer_
->SetBounds(gfx::Size(4, 4));
941 layer_tree_host()->root_layer()->AddChild(layer_
);
944 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
946 void DidCommit() override
{
947 switch (layer_tree_host()->source_frame_number()) {
949 // First frame: add an animation to the root layer.
950 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
953 // Second frame: add an animation to the content layer. The root layer
954 // animation has caused us to animate already during this frame.
955 AddOpacityTransitionToLayer(layer_
.get(), 0.1, 5, 5, false);
960 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
961 // After both animations have started, verify that they have valid
963 if (host_impl
->active_tree()->source_frame_number() < 2)
965 AnimationRegistrar::AnimationControllerMap controllers_copy
=
966 host_impl
->animation_registrar()
967 ->active_animation_controllers_for_testing();
968 EXPECT_EQ(2u, controllers_copy
.size());
969 for (auto& it
: controllers_copy
) {
971 if (id
== host_impl
->RootLayer()->id()) {
972 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
973 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
974 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
975 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
976 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
982 void AfterTest() override
{}
985 scoped_refptr
<Layer
> layer_
;
988 SINGLE_AND_MULTI_THREAD_TEST_F(
989 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);
991 class LayerTreeHostAnimationTestRemoveAnimation
992 : public LayerTreeHostAnimationTest
{
994 void SetupTree() override
{
995 LayerTreeHostAnimationTest::SetupTree();
996 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
997 layer_
->SetBounds(gfx::Size(4, 4));
998 layer_tree_host()->root_layer()->AddChild(layer_
);
1001 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1003 void DidCommit() override
{
1004 switch (layer_tree_host()->source_frame_number()) {
1006 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1009 LayerAnimationController
* controller
=
1010 layer_
->layer_animation_controller();
1011 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1012 controller
->RemoveAnimation(animation
->id());
1013 gfx::Transform transform
;
1014 transform
.Translate(10.f
, 10.f
);
1015 layer_
->SetTransform(transform
);
1017 // Do something that causes property trees to get rebuilt.
1018 layer_
->AddChild(Layer::Create(layer_settings()));
1023 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1024 if (host_impl
->active_tree()->source_frame_number() < 2)
1026 gfx::Transform expected_transform
;
1027 expected_transform
.Translate(10.f
, 10.f
);
1028 EXPECT_EQ(expected_transform
, host_impl
->active_tree()
1031 ->draw_transform());
1035 void AfterTest() override
{}
1038 scoped_refptr
<Layer
> layer_
;
1039 FakeContentLayerClient client_
;
1042 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation
);
1044 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1045 : public LayerTreeHostAnimationTest
{
1047 void SetupTree() override
{
1048 LayerTreeHostAnimationTest::SetupTree();
1049 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1050 layer_
->SetBounds(gfx::Size(4, 4));
1051 layer_tree_host()->root_layer()->AddChild(layer_
);
1054 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1056 void DidCommit() override
{
1057 if (layer_tree_host()->source_frame_number() == 1)
1058 AddAnimatedTransformToLayer(layer_
.get(), 0.04, 5, 5);
1061 void WillCommit() override
{
1062 if (layer_tree_host()->source_frame_number() == 2) {
1063 // Block until the animation finishes on the compositor thread. Since
1064 // animations have already been ticked on the main thread, when the commit
1065 // happens the state on the main thread will be consistent with having a
1066 // running animation but the state on the compositor thread will be
1067 // consistent with having only a finished animation.
1072 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1073 switch (host_impl
->sync_tree()->source_frame_number()) {
1075 PostSetNeedsCommitToMainThread();
1078 gfx::Transform expected_transform
;
1079 expected_transform
.Translate(5.f
, 5.f
);
1080 LayerImpl
* layer_impl
=
1081 host_impl
->sync_tree()->root_layer()->children()[0];
1082 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
1088 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1089 bool has_unfinished_animation
) override
{
1090 if (host_impl
->active_tree()->source_frame_number() == 1 &&
1091 !has_unfinished_animation
) {
1092 // The animation has finished, so allow the main thread to commit.
1093 completion_
.Signal();
1097 void AfterTest() override
{}
1100 scoped_refptr
<Layer
> layer_
;
1101 FakeContentLayerClient client_
;
1102 CompletionEvent completion_
;
1105 // An animation finishing during commit can only happen when we have a separate
1106 // compositor thread.
1107 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit
);
1109 class LayerTreeHostAnimationTestNotifyAnimationFinished
1110 : public LayerTreeHostAnimationTest
{
1112 LayerTreeHostAnimationTestNotifyAnimationFinished()
1113 : called_animation_started_(false), called_animation_finished_(false) {}
1115 void SetupTree() override
{
1116 LayerTreeHostAnimationTest::SetupTree();
1117 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
1118 picture_
->SetBounds(gfx::Size(4, 4));
1119 picture_
->set_layer_animation_delegate(this);
1120 layer_tree_host()->root_layer()->AddChild(picture_
);
1123 void BeginTest() override
{
1124 PostAddLongAnimationToMainThread(picture_
.get());
1127 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
1128 Animation::TargetProperty target_property
,
1129 int group
) override
{
1130 called_animation_started_
= true;
1131 layer_tree_host()->AnimateLayers(
1132 base::TimeTicks::FromInternalValue(std::numeric_limits
<int64
>::max()));
1133 PostSetNeedsCommitToMainThread();
1136 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
1137 Animation::TargetProperty target_property
,
1138 int group
) override
{
1139 called_animation_finished_
= true;
1143 void AfterTest() override
{
1144 EXPECT_TRUE(called_animation_started_
);
1145 EXPECT_TRUE(called_animation_finished_
);
1149 bool called_animation_started_
;
1150 bool called_animation_finished_
;
1151 FakeContentLayerClient client_
;
1152 scoped_refptr
<FakePictureLayer
> picture_
;
1155 SINGLE_AND_MULTI_THREAD_TEST_F(
1156 LayerTreeHostAnimationTestNotifyAnimationFinished
);