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 // Animations should not be started when frames are being skipped due to
449 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
450 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
451 : public LayerTreeHostTimelinesTest
{
452 void SetupTree() override
{
453 LayerTreeHostTimelinesTest::SetupTree();
454 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
455 picture_
->SetBounds(gfx::Size(4, 4));
456 layer_tree_host()->root_layer()->AddChild(picture_
);
458 AttachPlayersToTimeline();
459 player_child_
->AttachLayer(picture_
->id());
460 player_child_
->set_layer_animation_delegate(this);
463 void InitializeSettings(LayerTreeSettings
* settings
) override
{
464 // Make sure that drawing many times doesn't cause a checkerboarded
465 // animation to start so we avoid flake in this test.
466 settings
->timeout_and_draw_when_animation_checkerboards
= false;
467 LayerTreeHostTimelinesTest::InitializeSettings(settings
);
470 void BeginTest() override
{
474 PostSetNeedsCommitToMainThread();
477 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
478 LayerTreeHostImpl::FrameData
* frame_data
,
479 DrawResult draw_result
) override
{
480 // Don't checkerboard when the first animation wants to start.
481 if (host_impl
->active_tree()->source_frame_number() < 2)
485 // Act like there is checkerboard when the second animation wants to draw.
487 if (prevented_draw_
> 2)
489 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
492 void DidCommitAndDrawFrame() override
{
493 switch (layer_tree_host()->source_frame_number()) {
495 // The animation is longer than 1 BeginFrame interval.
496 AddOpacityTransitionToPlayer(player_child_
.get(), 0.1, 0.2f
, 0.8f
,
500 // This second animation will not be drawn so it should not start.
501 AddAnimatedTransformToPlayer(player_child_
.get(), 0.1, 5, 5);
506 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
507 Animation::TargetProperty target_property
,
508 int group
) override
{
514 void AfterTest() override
{
515 // Make sure we tried to draw the second animation but failed.
516 EXPECT_LT(0, prevented_draw_
);
517 // The first animation should be started, but the second should not because
519 EXPECT_EQ(1, started_times_
);
524 FakeContentLayerClient client_
;
525 scoped_refptr
<FakePictureLayer
> picture_
;
529 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
);
531 // Verifies that scroll offset animations are only accepted when impl-scrolling
532 // is supported, and that when scroll offset animations are accepted,
533 // scroll offset updates are sent back to the main thread.
534 // Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
535 class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
536 : public LayerTreeHostTimelinesTest
{
538 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
540 void SetupTree() override
{
541 LayerTreeHostTimelinesTest::SetupTree();
543 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
544 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
545 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
546 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
547 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
549 AttachPlayersToTimeline();
550 player_child_
->AttachLayer(scroll_layer_
->id());
553 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
555 void DidCommit() override
{
556 switch (layer_tree_host()->source_frame_number()) {
558 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
559 ScrollOffsetAnimationCurve::Create(
560 gfx::ScrollOffset(500.f
, 550.f
),
561 EaseInOutTimingFunction::Create()));
562 scoped_ptr
<Animation
> animation(
563 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
564 animation
->set_needs_synchronized_start_time(true);
565 bool impl_scrolling_supported
=
566 layer_tree_host()->proxy()->SupportsImplScrolling();
567 if (impl_scrolling_supported
)
568 player_child_
->AddAnimation(animation
.Pass());
574 if (scroll_layer_
->scroll_offset().x() > 10 &&
575 scroll_layer_
->scroll_offset().y() > 20)
580 void AfterTest() override
{}
583 FakeContentLayerClient client_
;
584 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
587 SINGLE_AND_MULTI_THREAD_TEST_F(
588 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
);
590 // Verifies that when the main thread removes a scroll animation and sets a new
591 // scroll position, the active tree takes on exactly this new scroll position
592 // after activation, and the main thread doesn't receive a spurious scroll
594 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
595 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
596 : public LayerTreeHostTimelinesTest
{
598 LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
599 : final_postion_(50.0, 100.0) {}
601 void SetupTree() override
{
602 LayerTreeHostTimelinesTest::SetupTree();
604 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
605 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
606 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
607 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
608 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
610 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
611 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
612 EaseInOutTimingFunction::Create()));
613 scoped_ptr
<Animation
> animation(
614 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
615 animation
->set_needs_synchronized_start_time(true);
617 AttachPlayersToTimeline();
618 player_child_
->AttachLayer(scroll_layer_
->id());
619 player_child_
->AddAnimation(animation
.Pass());
622 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
624 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
625 switch (layer_tree_host()->source_frame_number()) {
629 Animation
* animation
= player_child_
->element_animations()
630 ->layer_animation_controller()
631 ->GetAnimation(Animation::SCROLL_OFFSET
);
632 player_child_
->RemoveAnimation(animation
->id());
633 scroll_layer_
->SetScrollOffset(final_postion_
);
637 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
641 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
642 host_impl
->BlockNotifyReadyToActivateForTesting(true);
645 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
646 const BeginFrameArgs
& args
) override
{
647 if (!host_impl
->pending_tree())
650 if (!host_impl
->active_tree()->root_layer()) {
651 host_impl
->BlockNotifyReadyToActivateForTesting(false);
655 scoped_refptr
<AnimationTimeline
> timeline_impl
=
656 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
657 scoped_refptr
<AnimationPlayer
> player_impl
=
658 timeline_impl
->GetPlayerById(player_child_id_
);
660 LayerImpl
* scroll_layer_impl
=
661 host_impl
->active_tree()->root_layer()->children()[0];
662 Animation
* animation
= player_impl
->element_animations()
663 ->layer_animation_controller()
664 ->GetAnimation(Animation::SCROLL_OFFSET
);
666 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
667 host_impl
->BlockNotifyReadyToActivateForTesting(false);
671 // Block activation until the running animation has a chance to produce a
673 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
674 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
677 host_impl
->BlockNotifyReadyToActivateForTesting(false);
680 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
681 if (host_impl
->pending_tree()->source_frame_number() != 1)
683 LayerImpl
* scroll_layer_impl
=
684 host_impl
->pending_tree()->root_layer()->children()[0];
685 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
688 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
689 if (host_impl
->active_tree()->source_frame_number() != 1)
691 LayerImpl
* scroll_layer_impl
=
692 host_impl
->active_tree()->root_layer()->children()[0];
693 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
697 void AfterTest() override
{
698 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
702 FakeContentLayerClient client_
;
703 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
704 const gfx::ScrollOffset final_postion_
;
707 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
);
709 // When animations are simultaneously added to an existing layer and to a new
710 // layer, they should start at the same time, even when there's already a
711 // running animation on the existing layer.
712 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
713 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
714 : public LayerTreeHostTimelinesTest
{
716 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
717 : frame_count_with_pending_tree_(0) {}
719 void BeginTest() override
{
720 AttachPlayersToTimeline();
721 PostSetNeedsCommitToMainThread();
724 void DidCommit() override
{
725 if (layer_tree_host()->source_frame_number() == 1) {
726 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
727 AddAnimatedTransformToPlayer(player_
.get(), 4, 1, 1);
728 } else if (layer_tree_host()->source_frame_number() == 2) {
729 AddOpacityTransitionToPlayer(player_
.get(), 1, 0.f
, 0.5f
, true);
731 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
732 layer_tree_host()->root_layer()->AddChild(layer
);
733 layer
->SetBounds(gfx::Size(4, 4));
735 player_child_
->AttachLayer(layer
->id());
736 player_child_
->set_layer_animation_delegate(this);
737 AddOpacityTransitionToPlayer(player_child_
.get(), 1, 0.f
, 0.5f
, true);
741 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
742 host_impl
->BlockNotifyReadyToActivateForTesting(true);
745 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
746 // For the commit that added animations to new and existing layers, keep
747 // blocking activation. We want to verify that even with activation blocked,
748 // the animation on the layer that's already in the active tree won't get a
750 if (host_impl
->pending_tree()->source_frame_number() != 2) {
751 host_impl
->BlockNotifyReadyToActivateForTesting(false);
755 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
756 const BeginFrameArgs
& args
) override
{
757 if (!host_impl
->pending_tree() ||
758 host_impl
->pending_tree()->source_frame_number() != 2)
761 frame_count_with_pending_tree_
++;
762 if (frame_count_with_pending_tree_
== 2) {
763 host_impl
->BlockNotifyReadyToActivateForTesting(false);
767 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
768 bool has_unfinished_animation
) override
{
769 scoped_refptr
<AnimationTimeline
> timeline_impl
=
770 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
771 scoped_refptr
<AnimationPlayer
> player_impl
=
772 timeline_impl
->GetPlayerById(player_id_
);
773 scoped_refptr
<AnimationPlayer
> player_child_impl
=
774 timeline_impl
->GetPlayerById(player_child_id_
);
776 // wait for tree activation.
777 if (!player_impl
->element_animations())
780 LayerAnimationController
* root_controller_impl
=
781 player_impl
->element_animations()->layer_animation_controller();
782 Animation
* root_animation
=
783 root_controller_impl
->GetAnimation(Animation::OPACITY
);
784 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
787 LayerAnimationController
* child_controller_impl
=
788 player_child_impl
->element_animations()->layer_animation_controller();
789 Animation
* child_animation
=
790 child_controller_impl
->GetAnimation(Animation::OPACITY
);
791 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
792 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
793 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
794 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
795 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
799 void AfterTest() override
{}
802 int frame_count_with_pending_tree_
;
805 // This test blocks activation which is not supported for single thread mode.
806 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
807 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
);
809 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
810 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
811 : public LayerTreeHostTimelinesTest
{
813 void SetupTree() override
{
814 LayerTreeHostTimelinesTest::SetupTree();
815 content_
= Layer::Create(layer_settings());
816 content_
->SetBounds(gfx::Size(4, 4));
817 layer_tree_host()->root_layer()->AddChild(content_
);
819 AttachPlayersToTimeline();
821 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
822 player_child_
->AttachLayer(content_
->id());
825 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
827 void DidCommit() override
{
828 switch (layer_tree_host()->source_frame_number()) {
830 // First frame: add an animation to the root layer.
831 AddAnimatedTransformToPlayer(player_
.get(), 0.1, 5, 5);
834 // Second frame: add an animation to the content layer. The root layer
835 // animation has caused us to animate already during this frame.
836 AddOpacityTransitionToPlayer(player_child_
.get(), 0.1, 5, 5, false);
841 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
842 // After both animations have started, verify that they have valid
844 if (host_impl
->active_tree()->source_frame_number() < 2)
846 AnimationRegistrar::AnimationControllerMap controllers_copy
=
847 host_impl
->animation_host()
848 ->animation_registrar()
849 ->active_animation_controllers_for_testing();
850 EXPECT_EQ(2u, controllers_copy
.size());
851 for (auto& it
: controllers_copy
) {
853 if (id
== host_impl
->RootLayer()->id()) {
854 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
855 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
856 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
857 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
858 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
864 void AfterTest() override
{}
867 scoped_refptr
<Layer
> content_
;
870 SINGLE_AND_MULTI_THREAD_TEST_F(
871 LayerTreeHostTimelinesTestAddAnimationAfterAnimating
);
873 class LayerTreeHostTimelinesTestRemoveAnimation
874 : public LayerTreeHostTimelinesTest
{
876 void SetupTree() override
{
877 LayerTreeHostTimelinesTest::SetupTree();
878 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
879 layer_
->SetBounds(gfx::Size(4, 4));
880 layer_tree_host()->root_layer()->AddChild(layer_
);
882 AttachPlayersToTimeline();
884 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
885 player_child_
->AttachLayer(layer_
->id());
888 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
890 void DidCommit() override
{
891 switch (layer_tree_host()->source_frame_number()) {
893 AddAnimatedTransformToPlayer(player_child_
.get(), 1.0, 5, 5);
896 LayerAnimationController
* controller
=
897 player_child_
->element_animations()->layer_animation_controller();
898 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
899 player_child_
->RemoveAnimation(animation
->id());
900 gfx::Transform transform
;
901 transform
.Translate(10.f
, 10.f
);
902 layer_
->SetTransform(transform
);
904 // Do something that causes property trees to get rebuilt.
905 layer_
->AddChild(Layer::Create(layer_settings()));
910 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
911 if (host_impl
->active_tree()->source_frame_number() < 2)
913 gfx::Transform expected_transform
;
914 expected_transform
.Translate(10.f
, 10.f
);
915 EXPECT_EQ(expected_transform
, host_impl
->active_tree()
922 void AfterTest() override
{}
925 scoped_refptr
<Layer
> layer_
;
926 FakeContentLayerClient client_
;
929 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation
);
931 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
932 : public LayerTreeHostTimelinesTest
{
934 void SetupTree() override
{
935 LayerTreeHostTimelinesTest::SetupTree();
936 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
937 layer_
->SetBounds(gfx::Size(4, 4));
938 layer_tree_host()->root_layer()->AddChild(layer_
);
940 AttachPlayersToTimeline();
942 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
943 player_child_
->AttachLayer(layer_
->id());
946 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
948 void DidCommit() override
{
949 if (layer_tree_host()->source_frame_number() == 1)
950 AddAnimatedTransformToPlayer(player_child_
.get(), 0.04, 5, 5);
953 void WillCommit() override
{
954 if (layer_tree_host()->source_frame_number() == 2) {
955 // Block until the animation finishes on the compositor thread. Since
956 // animations have already been ticked on the main thread, when the commit
957 // happens the state on the main thread will be consistent with having a
958 // running animation but the state on the compositor thread will be
959 // consistent with having only a finished animation.
964 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
965 switch (host_impl
->sync_tree()->source_frame_number()) {
967 PostSetNeedsCommitToMainThread();
970 gfx::Transform expected_transform
;
971 expected_transform
.Translate(5.f
, 5.f
);
972 LayerImpl
* layer_impl
=
973 host_impl
->sync_tree()->root_layer()->children()[0];
974 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
980 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
981 bool has_unfinished_animation
) override
{
982 if (host_impl
->active_tree()->source_frame_number() == 1 &&
983 !has_unfinished_animation
) {
984 // The animation has finished, so allow the main thread to commit.
985 completion_
.Signal();
989 void AfterTest() override
{}
992 scoped_refptr
<Layer
> layer_
;
993 FakeContentLayerClient client_
;
994 CompletionEvent completion_
;
997 // An animation finishing during commit can only happen when we have a separate
998 // compositor thread.
999 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
);