1 // Copyright 2015 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/animation_host.h"
9 #include "cc/animation/animation_id_provider.h"
10 #include "cc/animation/animation_player.h"
11 #include "cc/animation/animation_timeline.h"
12 #include "cc/animation/element_animations.h"
13 #include "cc/animation/layer_animation_controller.h"
14 #include "cc/animation/scroll_offset_animation_curve.h"
15 #include "cc/animation/timing_function.h"
16 #include "cc/base/completion_event.h"
17 #include "cc/base/time_util.h"
18 #include "cc/layers/layer.h"
19 #include "cc/layers/layer_impl.h"
20 #include "cc/test/animation_test_common.h"
21 #include "cc/test/fake_content_layer_client.h"
22 #include "cc/test/fake_picture_layer.h"
23 #include "cc/test/layer_tree_test.h"
24 #include "cc/trees/layer_tree_impl.h"
29 class LayerTreeHostTimelinesTest
: public LayerTreeTest
{
31 LayerTreeHostTimelinesTest()
32 : timeline_id_(AnimationIdProvider::NextTimelineId()),
33 player_id_(AnimationIdProvider::NextPlayerId()),
34 player_child_id_(AnimationIdProvider::NextPlayerId()) {
35 timeline_
= AnimationTimeline::Create(timeline_id_
);
36 player_
= AnimationPlayer::Create(player_id_
);
37 player_child_
= AnimationPlayer::Create(player_child_id_
);
39 player_
->set_layer_animation_delegate(this);
42 void InitializeSettings(LayerTreeSettings
* settings
) override
{
43 settings
->use_compositor_animation_timelines
= true;
46 void InitializeLayerSettings(LayerSettings
* layer_settings
) override
{
47 layer_settings
->use_compositor_animation_timelines
= true;
50 void SetupTree() override
{ LayerTreeTest::SetupTree(); }
52 void AttachPlayersToTimeline() {
53 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_
.get());
54 timeline_
->AttachPlayer(player_
.get());
55 timeline_
->AttachPlayer(player_child_
.get());
59 scoped_refptr
<AnimationTimeline
> timeline_
;
60 scoped_refptr
<AnimationPlayer
> player_
;
61 scoped_refptr
<AnimationPlayer
> player_child_
;
63 const int timeline_id_
;
65 const int player_child_id_
;
68 // Add a layer animation and confirm that
69 // LayerTreeHostImpl::UpdateAnimationState does get called.
70 // Evolved frome LayerTreeHostAnimationTestAddAnimation
71 class LayerTreeHostTimelinesTestAddAnimation
72 : public LayerTreeHostTimelinesTest
{
74 LayerTreeHostTimelinesTestAddAnimation()
75 : update_animation_state_was_called_(false) {}
77 void BeginTest() override
{
78 AttachPlayersToTimeline();
79 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
80 PostAddInstantAnimationToMainThreadPlayer(player_
.get());
83 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
84 bool has_unfinished_animation
) override
{
85 EXPECT_FALSE(has_unfinished_animation
);
86 update_animation_state_was_called_
= true;
89 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
90 Animation::TargetProperty target_property
,
92 EXPECT_LT(base::TimeTicks(), monotonic_time
);
94 LayerAnimationController
* controller
=
95 player_
->element_animations()->layer_animation_controller();
96 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
98 player_
->RemoveAnimation(animation
->id());
103 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
106 bool update_animation_state_was_called_
;
109 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation
);
111 // Add a layer animation to a layer, but continually fail to draw. Confirm that
112 // after a while, we do eventually force a draw.
113 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
114 class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
115 : public LayerTreeHostTimelinesTest
{
117 LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
118 : started_animating_(false) {}
120 void BeginTest() override
{
121 AttachPlayersToTimeline();
122 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
123 PostAddAnimationToMainThreadPlayer(player_
.get());
126 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
127 base::TimeTicks monotonic_time
) override
{
128 started_animating_
= true;
131 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
132 if (started_animating_
)
136 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
137 LayerTreeHostImpl::FrameData
* frame
,
138 DrawResult draw_result
) override
{
139 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
142 void AfterTest() override
{}
145 bool started_animating_
;
148 // Starvation can only be an issue with the MT compositor.
149 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
);
151 // Ensures that animations eventually get deleted.
152 // Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
153 class LayerTreeHostTimelinesTestAnimationsGetDeleted
154 : public LayerTreeHostTimelinesTest
{
156 LayerTreeHostTimelinesTestAnimationsGetDeleted()
157 : started_animating_(false) {}
159 void BeginTest() override
{
160 AttachPlayersToTimeline();
161 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
162 PostAddAnimationToMainThreadPlayer(player_
.get());
165 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
166 base::TimeTicks monotonic_time
) override
{
167 bool have_animations
= !host_impl
->animation_host()
168 ->animation_registrar()
169 ->active_animation_controllers_for_testing()
171 if (!started_animating_
&& have_animations
) {
172 started_animating_
= true;
176 if (started_animating_
&& !have_animations
)
180 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
181 Animation::TargetProperty target_property
,
182 int group
) override
{
183 // Animations on the impl-side controller only get deleted during a commit,
184 // so we need to schedule a commit.
185 layer_tree_host()->SetNeedsCommit();
188 void AfterTest() override
{}
191 bool started_animating_
;
194 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted
);
196 // Ensure that an animation's timing function is respected.
197 // Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
198 class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
199 : public LayerTreeHostTimelinesTest
{
201 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
203 void SetupTree() override
{
204 LayerTreeHostTimelinesTest::SetupTree();
205 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
206 picture_
->SetBounds(gfx::Size(4, 4));
207 layer_tree_host()->root_layer()->AddChild(picture_
);
209 AttachPlayersToTimeline();
210 player_child_
->AttachLayer(picture_
->id());
213 void BeginTest() override
{
214 PostAddAnimationToMainThreadPlayer(player_child_
.get());
217 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
218 base::TimeTicks monotonic_time
) override
{
219 scoped_refptr
<AnimationTimeline
> timeline_impl
=
220 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
221 scoped_refptr
<AnimationPlayer
> player_child_impl
=
222 timeline_impl
->GetPlayerById(player_child_id_
);
224 LayerAnimationController
* controller_impl
=
225 player_child_impl
->element_animations()->layer_animation_controller();
226 if (!controller_impl
)
229 Animation
* animation
= controller_impl
->GetAnimation(Animation::OPACITY
);
233 const FloatAnimationCurve
* curve
=
234 animation
->curve()->ToFloatAnimationCurve();
235 float start_opacity
= curve
->GetValue(base::TimeDelta());
236 float end_opacity
= curve
->GetValue(curve
->Duration());
237 float linearly_interpolated_opacity
=
238 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
239 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
240 // If the linear timing function associated with this animation was not
241 // picked up, then the linearly interpolated opacity would be different
242 // because of the default ease timing function.
243 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
248 void AfterTest() override
{}
250 FakeContentLayerClient client_
;
251 scoped_refptr
<FakePictureLayer
> picture_
;
254 SINGLE_AND_MULTI_THREAD_TEST_F(
255 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
);
257 // Ensures that main thread animations have their start times synchronized with
258 // impl thread animations.
259 // Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
260 class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
261 : public LayerTreeHostTimelinesTest
{
263 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
265 void SetupTree() override
{
266 LayerTreeHostTimelinesTest::SetupTree();
267 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
268 picture_
->SetBounds(gfx::Size(4, 4));
270 layer_tree_host()->root_layer()->AddChild(picture_
);
272 AttachPlayersToTimeline();
273 player_child_
->set_layer_animation_delegate(this);
274 player_child_
->AttachLayer(picture_
->id());
277 void BeginTest() override
{
278 PostAddAnimationToMainThreadPlayer(player_child_
.get());
281 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
282 Animation::TargetProperty target_property
,
283 int group
) override
{
284 LayerAnimationController
* controller
=
285 player_child_
->element_animations()->layer_animation_controller();
286 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
287 main_start_time_
= animation
->start_time();
288 controller
->RemoveAnimation(animation
->id());
292 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
293 bool has_unfinished_animation
) override
{
294 scoped_refptr
<AnimationTimeline
> timeline_impl
=
295 impl_host
->animation_host()->GetTimelineById(timeline_id_
);
296 scoped_refptr
<AnimationPlayer
> player_child_impl
=
297 timeline_impl
->GetPlayerById(player_child_id_
);
299 LayerAnimationController
* controller
=
300 player_child_impl
->element_animations()->layer_animation_controller();
301 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
305 impl_start_time_
= animation
->start_time();
308 void AfterTest() override
{
309 EXPECT_EQ(impl_start_time_
, main_start_time_
);
310 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
314 base::TimeTicks main_start_time_
;
315 base::TimeTicks impl_start_time_
;
316 FakeContentLayerClient client_
;
317 scoped_refptr
<FakePictureLayer
> picture_
;
320 SINGLE_AND_MULTI_THREAD_TEST_F(
321 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
);
323 // Ensures that notify animation finished is called.
324 // Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
325 class LayerTreeHostTimelinesTestAnimationFinishedEvents
326 : public LayerTreeHostTimelinesTest
{
328 LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
330 void BeginTest() override
{
331 AttachPlayersToTimeline();
332 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
333 PostAddInstantAnimationToMainThreadPlayer(player_
.get());
336 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
337 Animation::TargetProperty target_property
,
338 int group
) override
{
339 LayerAnimationController
* controller
=
340 player_
->element_animations()->layer_animation_controller();
341 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
343 controller
->RemoveAnimation(animation
->id());
347 void AfterTest() override
{}
350 SINGLE_AND_MULTI_THREAD_TEST_F(
351 LayerTreeHostTimelinesTestAnimationFinishedEvents
);
353 // Ensures that when opacity is being animated, this value does not cause the
354 // subtree to be skipped.
355 // Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
356 class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
357 : public LayerTreeHostTimelinesTest
{
359 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
360 : update_check_layer_(
361 FakePictureLayer::Create(layer_settings(), &client_
)) {}
363 void SetupTree() override
{
364 update_check_layer_
->SetOpacity(0.f
);
365 layer_tree_host()->SetRootLayer(update_check_layer_
);
366 LayerTreeHostTimelinesTest::SetupTree();
368 AttachPlayersToTimeline();
369 player_
->AttachLayer(update_check_layer_
->id());
372 void BeginTest() override
{
373 PostAddAnimationToMainThreadPlayer(player_
.get());
376 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
377 scoped_refptr
<AnimationTimeline
> timeline_impl
=
378 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
379 scoped_refptr
<AnimationPlayer
> player_impl
=
380 timeline_impl
->GetPlayerById(player_id_
);
382 LayerAnimationController
* controller_impl
=
383 player_impl
->element_animations()->layer_animation_controller();
384 Animation
* animation_impl
=
385 controller_impl
->GetAnimation(Animation::OPACITY
);
386 controller_impl
->RemoveAnimation(animation_impl
->id());
390 void AfterTest() override
{
391 // Update() should have been called once, proving that the layer was not
393 EXPECT_EQ(1, update_check_layer_
->update_count());
395 // clear update_check_layer_ so LayerTreeHost dies.
396 update_check_layer_
= NULL
;
400 FakeContentLayerClient client_
;
401 scoped_refptr
<FakePictureLayer
> update_check_layer_
;
404 SINGLE_AND_MULTI_THREAD_TEST_F(
405 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
);
407 // Layers added to tree with existing active animations should have the
408 // animation correctly recognized.
409 // Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
410 class LayerTreeHostTimelinesTestLayerAddedWithAnimation
411 : public LayerTreeHostTimelinesTest
{
413 LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
415 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
417 void DidCommit() override
{
418 if (layer_tree_host()->source_frame_number() == 1) {
419 AttachPlayersToTimeline();
421 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
422 player_
->AttachLayer(layer
->id());
423 player_
->set_layer_animation_delegate(this);
425 // Any valid AnimationCurve will do here.
426 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
427 scoped_ptr
<Animation
> animation(
428 Animation::Create(curve
.Pass(), 1, 1, Animation::OPACITY
));
429 player_
->AddAnimation(animation
.Pass());
431 // We add the animation *before* attaching the layer to the tree.
432 layer_tree_host()->root_layer()->AddChild(layer
);
436 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
437 base::TimeTicks monotonic_time
) override
{
441 void AfterTest() override
{}
444 SINGLE_AND_MULTI_THREAD_TEST_F(
445 LayerTreeHostTimelinesTestLayerAddedWithAnimation
);
447 // Make sure the main thread can still execute animations when CanDraw() is not
449 // Evolved from LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
450 class LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
451 : public LayerTreeHostTimelinesTest
{
453 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
455 void SetupTree() override
{
456 LayerTreeHostTimelinesTest::SetupTree();
457 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
458 picture_
->SetBounds(gfx::Size(4, 4));
459 layer_tree_host()->root_layer()->AddChild(picture_
);
461 AttachPlayersToTimeline();
462 player_child_
->AttachLayer(picture_
->id());
463 player_child_
->set_layer_animation_delegate(this);
466 void BeginTest() override
{
467 layer_tree_host()->SetViewportSize(gfx::Size());
468 PostAddAnimationToMainThreadPlayer(player_child_
.get());
471 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
472 Animation::TargetProperty target_property
,
473 int group
) override
{
477 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
478 Animation::TargetProperty target_property
,
479 int group
) override
{
483 void AfterTest() override
{ EXPECT_EQ(1, started_times_
); }
487 FakeContentLayerClient client_
;
488 scoped_refptr
<FakePictureLayer
> picture_
;
491 SINGLE_AND_MULTI_THREAD_TEST_F(
492 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
);
494 // Animations should not be started when frames are being skipped due to
496 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
497 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
498 : public LayerTreeHostTimelinesTest
{
499 void SetupTree() override
{
500 LayerTreeHostTimelinesTest::SetupTree();
501 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
502 picture_
->SetBounds(gfx::Size(4, 4));
503 layer_tree_host()->root_layer()->AddChild(picture_
);
505 AttachPlayersToTimeline();
506 player_child_
->AttachLayer(picture_
->id());
507 player_child_
->set_layer_animation_delegate(this);
510 void InitializeSettings(LayerTreeSettings
* settings
) override
{
511 // Make sure that drawing many times doesn't cause a checkerboarded
512 // animation to start so we avoid flake in this test.
513 settings
->timeout_and_draw_when_animation_checkerboards
= false;
514 LayerTreeHostTimelinesTest::InitializeSettings(settings
);
517 void BeginTest() override
{
519 added_animations_
= 0;
522 PostSetNeedsCommitToMainThread();
525 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
526 LayerTreeHostImpl::FrameData
* frame_data
,
527 DrawResult draw_result
) override
{
528 if (added_animations_
< 2)
532 // Act like there is checkerboard when the second animation wants to draw.
534 if (prevented_draw_
> 2)
536 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
539 void DidCommitAndDrawFrame() override
{
540 switch (layer_tree_host()->source_frame_number()) {
542 // The animation is longer than 1 BeginFrame interval.
543 AddOpacityTransitionToPlayer(player_child_
.get(), 0.1, 0.2f
, 0.8f
,
548 // This second animation will not be drawn so it should not start.
549 AddAnimatedTransformToPlayer(player_child_
.get(), 0.1, 5, 5);
555 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
556 Animation::TargetProperty target_property
,
557 int group
) override
{
563 void AfterTest() override
{
564 // Make sure we tried to draw the second animation but failed.
565 EXPECT_LT(0, prevented_draw_
);
566 // The first animation should be started, but the second should not because
568 EXPECT_EQ(1, started_times_
);
572 int added_animations_
;
574 FakeContentLayerClient client_
;
575 scoped_refptr
<FakePictureLayer
> picture_
;
579 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
);
581 // Verifies that scroll offset animations are only accepted when impl-scrolling
582 // is supported, and that when scroll offset animations are accepted,
583 // scroll offset updates are sent back to the main thread.
584 // Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
585 class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
586 : public LayerTreeHostTimelinesTest
{
588 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
590 void SetupTree() override
{
591 LayerTreeHostTimelinesTest::SetupTree();
593 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
594 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
595 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
596 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
597 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
599 AttachPlayersToTimeline();
600 player_child_
->AttachLayer(scroll_layer_
->id());
603 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
605 void DidCommit() override
{
606 switch (layer_tree_host()->source_frame_number()) {
608 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
609 ScrollOffsetAnimationCurve::Create(
610 gfx::ScrollOffset(500.f
, 550.f
),
611 EaseInOutTimingFunction::Create()));
612 scoped_ptr
<Animation
> animation(
613 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
614 animation
->set_needs_synchronized_start_time(true);
615 bool impl_scrolling_supported
=
616 layer_tree_host()->proxy()->SupportsImplScrolling();
617 if (impl_scrolling_supported
)
618 player_child_
->AddAnimation(animation
.Pass());
624 if (scroll_layer_
->scroll_offset().x() > 10 &&
625 scroll_layer_
->scroll_offset().y() > 20)
630 void AfterTest() override
{}
633 FakeContentLayerClient client_
;
634 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
637 SINGLE_AND_MULTI_THREAD_TEST_F(
638 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
);
640 // Verifies that when the main thread removes a scroll animation and sets a new
641 // scroll position, the active tree takes on exactly this new scroll position
642 // after activation, and the main thread doesn't receive a spurious scroll
644 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
645 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
646 : public LayerTreeHostTimelinesTest
{
648 LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
649 : final_postion_(50.0, 100.0) {}
651 void SetupTree() override
{
652 LayerTreeHostTimelinesTest::SetupTree();
654 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
655 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
656 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
657 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
658 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
660 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
661 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
662 EaseInOutTimingFunction::Create()));
663 scoped_ptr
<Animation
> animation(
664 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
665 animation
->set_needs_synchronized_start_time(true);
667 AttachPlayersToTimeline();
668 player_child_
->AttachLayer(scroll_layer_
->id());
669 player_child_
->AddAnimation(animation
.Pass());
672 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
674 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
675 switch (layer_tree_host()->source_frame_number()) {
679 Animation
* animation
= player_child_
->element_animations()
680 ->layer_animation_controller()
681 ->GetAnimation(Animation::SCROLL_OFFSET
);
682 player_child_
->RemoveAnimation(animation
->id());
683 scroll_layer_
->SetScrollOffset(final_postion_
);
687 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
691 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
692 host_impl
->BlockNotifyReadyToActivateForTesting(true);
695 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
696 const BeginFrameArgs
& args
) override
{
697 if (!host_impl
->pending_tree())
700 if (!host_impl
->active_tree()->root_layer()) {
701 host_impl
->BlockNotifyReadyToActivateForTesting(false);
705 scoped_refptr
<AnimationTimeline
> timeline_impl
=
706 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
707 scoped_refptr
<AnimationPlayer
> player_impl
=
708 timeline_impl
->GetPlayerById(player_child_id_
);
710 LayerImpl
* scroll_layer_impl
=
711 host_impl
->active_tree()->root_layer()->children()[0];
712 Animation
* animation
= player_impl
->element_animations()
713 ->layer_animation_controller()
714 ->GetAnimation(Animation::SCROLL_OFFSET
);
716 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
717 host_impl
->BlockNotifyReadyToActivateForTesting(false);
721 // Block activation until the running animation has a chance to produce a
723 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
724 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
727 host_impl
->BlockNotifyReadyToActivateForTesting(false);
730 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
731 if (host_impl
->pending_tree()->source_frame_number() != 1)
733 LayerImpl
* scroll_layer_impl
=
734 host_impl
->pending_tree()->root_layer()->children()[0];
735 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
738 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
739 if (host_impl
->active_tree()->source_frame_number() != 1)
741 LayerImpl
* scroll_layer_impl
=
742 host_impl
->active_tree()->root_layer()->children()[0];
743 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
747 void AfterTest() override
{
748 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
752 FakeContentLayerClient client_
;
753 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
754 const gfx::ScrollOffset final_postion_
;
757 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
);
759 // When animations are simultaneously added to an existing layer and to a new
760 // layer, they should start at the same time, even when there's already a
761 // running animation on the existing layer.
762 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
763 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
764 : public LayerTreeHostTimelinesTest
{
766 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
767 : frame_count_with_pending_tree_(0) {}
769 void BeginTest() override
{
770 AttachPlayersToTimeline();
771 PostSetNeedsCommitToMainThread();
774 void DidCommit() override
{
775 if (layer_tree_host()->source_frame_number() == 1) {
776 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
777 AddAnimatedTransformToPlayer(player_
.get(), 4, 1, 1);
778 } else if (layer_tree_host()->source_frame_number() == 2) {
779 AddOpacityTransitionToPlayer(player_
.get(), 1, 0.f
, 0.5f
, true);
781 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
782 layer_tree_host()->root_layer()->AddChild(layer
);
783 layer
->SetBounds(gfx::Size(4, 4));
785 player_child_
->AttachLayer(layer
->id());
786 player_child_
->set_layer_animation_delegate(this);
787 AddOpacityTransitionToPlayer(player_child_
.get(), 1, 0.f
, 0.5f
, true);
791 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
792 host_impl
->BlockNotifyReadyToActivateForTesting(true);
795 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
796 // For the commit that added animations to new and existing layers, keep
797 // blocking activation. We want to verify that even with activation blocked,
798 // the animation on the layer that's already in the active tree won't get a
800 if (host_impl
->pending_tree()->source_frame_number() != 2) {
801 host_impl
->BlockNotifyReadyToActivateForTesting(false);
805 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
806 const BeginFrameArgs
& args
) override
{
807 if (!host_impl
->pending_tree() ||
808 host_impl
->pending_tree()->source_frame_number() != 2)
811 frame_count_with_pending_tree_
++;
812 if (frame_count_with_pending_tree_
== 2) {
813 host_impl
->BlockNotifyReadyToActivateForTesting(false);
817 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
818 bool has_unfinished_animation
) override
{
819 scoped_refptr
<AnimationTimeline
> timeline_impl
=
820 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
821 scoped_refptr
<AnimationPlayer
> player_impl
=
822 timeline_impl
->GetPlayerById(player_id_
);
823 scoped_refptr
<AnimationPlayer
> player_child_impl
=
824 timeline_impl
->GetPlayerById(player_child_id_
);
826 // wait for tree activation.
827 if (!player_impl
->element_animations())
830 LayerAnimationController
* root_controller_impl
=
831 player_impl
->element_animations()->layer_animation_controller();
832 Animation
* root_animation
=
833 root_controller_impl
->GetAnimation(Animation::OPACITY
);
834 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
837 LayerAnimationController
* child_controller_impl
=
838 player_child_impl
->element_animations()->layer_animation_controller();
839 Animation
* child_animation
=
840 child_controller_impl
->GetAnimation(Animation::OPACITY
);
841 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
842 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
843 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
844 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
845 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
849 void AfterTest() override
{}
852 int frame_count_with_pending_tree_
;
855 // This test blocks activation which is not supported for single thread mode.
856 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
857 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
);
859 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
860 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
861 : public LayerTreeHostTimelinesTest
{
863 void SetupTree() override
{
864 LayerTreeHostTimelinesTest::SetupTree();
865 content_
= Layer::Create(layer_settings());
866 content_
->SetBounds(gfx::Size(4, 4));
867 layer_tree_host()->root_layer()->AddChild(content_
);
869 AttachPlayersToTimeline();
871 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
872 player_child_
->AttachLayer(content_
->id());
875 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
877 void DidCommit() override
{
878 switch (layer_tree_host()->source_frame_number()) {
880 // First frame: add an animation to the root layer.
881 AddAnimatedTransformToPlayer(player_
.get(), 0.1, 5, 5);
884 // Second frame: add an animation to the content layer. The root layer
885 // animation has caused us to animate already during this frame.
886 AddOpacityTransitionToPlayer(player_child_
.get(), 0.1, 5, 5, false);
891 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
892 // After both animations have started, verify that they have valid
894 if (host_impl
->active_tree()->source_frame_number() < 2)
896 AnimationRegistrar::AnimationControllerMap controllers_copy
=
897 host_impl
->animation_host()
898 ->animation_registrar()
899 ->active_animation_controllers_for_testing();
900 EXPECT_EQ(2u, controllers_copy
.size());
901 for (auto& it
: controllers_copy
) {
903 if (id
== host_impl
->RootLayer()->id()) {
904 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
905 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
906 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
907 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
908 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
914 void AfterTest() override
{}
917 scoped_refptr
<Layer
> content_
;
920 SINGLE_AND_MULTI_THREAD_TEST_F(
921 LayerTreeHostTimelinesTestAddAnimationAfterAnimating
);
923 class LayerTreeHostTimelinesTestRemoveAnimation
924 : public LayerTreeHostTimelinesTest
{
926 void SetupTree() override
{
927 LayerTreeHostTimelinesTest::SetupTree();
928 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
929 layer_
->SetBounds(gfx::Size(4, 4));
930 layer_tree_host()->root_layer()->AddChild(layer_
);
932 AttachPlayersToTimeline();
934 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
935 player_child_
->AttachLayer(layer_
->id());
938 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
940 void DidCommit() override
{
941 switch (layer_tree_host()->source_frame_number()) {
943 AddAnimatedTransformToPlayer(player_child_
.get(), 1.0, 5, 5);
946 LayerAnimationController
* controller
=
947 player_child_
->element_animations()->layer_animation_controller();
948 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
949 player_child_
->RemoveAnimation(animation
->id());
950 gfx::Transform transform
;
951 transform
.Translate(10.f
, 10.f
);
952 layer_
->SetTransform(transform
);
954 // Do something that causes property trees to get rebuilt.
955 layer_
->AddChild(Layer::Create(layer_settings()));
960 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
961 if (host_impl
->active_tree()->source_frame_number() < 2)
963 gfx::Transform expected_transform
;
964 expected_transform
.Translate(10.f
, 10.f
);
965 EXPECT_EQ(expected_transform
, host_impl
->active_tree()
972 void AfterTest() override
{}
975 scoped_refptr
<Layer
> layer_
;
976 FakeContentLayerClient client_
;
979 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation
);
981 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
982 : public LayerTreeHostTimelinesTest
{
984 void SetupTree() override
{
985 LayerTreeHostTimelinesTest::SetupTree();
986 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
987 layer_
->SetBounds(gfx::Size(4, 4));
988 layer_tree_host()->root_layer()->AddChild(layer_
);
990 AttachPlayersToTimeline();
992 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
993 player_child_
->AttachLayer(layer_
->id());
996 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
998 void DidCommit() override
{
999 if (layer_tree_host()->source_frame_number() == 1)
1000 AddAnimatedTransformToPlayer(player_child_
.get(), 0.04, 5, 5);
1003 void WillCommit() override
{
1004 if (layer_tree_host()->source_frame_number() == 2) {
1005 // Block until the animation finishes on the compositor thread. Since
1006 // animations have already been ticked on the main thread, when the commit
1007 // happens the state on the main thread will be consistent with having a
1008 // running animation but the state on the compositor thread will be
1009 // consistent with having only a finished animation.
1014 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1015 switch (host_impl
->sync_tree()->source_frame_number()) {
1017 PostSetNeedsCommitToMainThread();
1020 gfx::Transform expected_transform
;
1021 expected_transform
.Translate(5.f
, 5.f
);
1022 LayerImpl
* layer_impl
=
1023 host_impl
->sync_tree()->root_layer()->children()[0];
1024 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
1030 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1031 bool has_unfinished_animation
) override
{
1032 if (host_impl
->active_tree()->source_frame_number() == 1 &&
1033 !has_unfinished_animation
) {
1034 // The animation has finished, so allow the main thread to commit.
1035 completion_
.Signal();
1039 void AfterTest() override
{}
1042 scoped_refptr
<Layer
> layer_
;
1043 FakeContentLayerClient client_
;
1044 CompletionEvent completion_
;
1047 // An animation finishing during commit can only happen when we have a separate
1048 // compositor thread.
1049 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
);