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
{
472 added_animations_
= 0;
475 PostSetNeedsCommitToMainThread();
478 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
479 LayerTreeHostImpl::FrameData
* frame_data
,
480 DrawResult draw_result
) override
{
481 if (added_animations_
< 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
,
501 // This second animation will not be drawn so it should not start.
502 AddAnimatedTransformToPlayer(player_child_
.get(), 0.1, 5, 5);
508 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
509 Animation::TargetProperty target_property
,
510 int group
) override
{
516 void AfterTest() override
{
517 // Make sure we tried to draw the second animation but failed.
518 EXPECT_LT(0, prevented_draw_
);
519 // The first animation should be started, but the second should not because
521 EXPECT_EQ(1, started_times_
);
525 int added_animations_
;
527 FakeContentLayerClient client_
;
528 scoped_refptr
<FakePictureLayer
> picture_
;
532 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
);
534 // Verifies that scroll offset animations are only accepted when impl-scrolling
535 // is supported, and that when scroll offset animations are accepted,
536 // scroll offset updates are sent back to the main thread.
537 // Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
538 class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
539 : public LayerTreeHostTimelinesTest
{
541 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
543 void SetupTree() override
{
544 LayerTreeHostTimelinesTest::SetupTree();
546 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
547 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
548 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
549 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
550 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
552 AttachPlayersToTimeline();
553 player_child_
->AttachLayer(scroll_layer_
->id());
556 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
558 void DidCommit() override
{
559 switch (layer_tree_host()->source_frame_number()) {
561 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
562 ScrollOffsetAnimationCurve::Create(
563 gfx::ScrollOffset(500.f
, 550.f
),
564 EaseInOutTimingFunction::Create()));
565 scoped_ptr
<Animation
> animation(
566 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
567 animation
->set_needs_synchronized_start_time(true);
568 bool impl_scrolling_supported
=
569 layer_tree_host()->proxy()->SupportsImplScrolling();
570 if (impl_scrolling_supported
)
571 player_child_
->AddAnimation(animation
.Pass());
577 if (scroll_layer_
->scroll_offset().x() > 10 &&
578 scroll_layer_
->scroll_offset().y() > 20)
583 void AfterTest() override
{}
586 FakeContentLayerClient client_
;
587 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
590 SINGLE_AND_MULTI_THREAD_TEST_F(
591 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
);
593 // Verifies that when the main thread removes a scroll animation and sets a new
594 // scroll position, the active tree takes on exactly this new scroll position
595 // after activation, and the main thread doesn't receive a spurious scroll
597 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
598 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
599 : public LayerTreeHostTimelinesTest
{
601 LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
602 : final_postion_(50.0, 100.0) {}
604 void SetupTree() override
{
605 LayerTreeHostTimelinesTest::SetupTree();
607 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
608 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
609 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
610 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
611 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
613 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
614 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
615 EaseInOutTimingFunction::Create()));
616 scoped_ptr
<Animation
> animation(
617 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
618 animation
->set_needs_synchronized_start_time(true);
620 AttachPlayersToTimeline();
621 player_child_
->AttachLayer(scroll_layer_
->id());
622 player_child_
->AddAnimation(animation
.Pass());
625 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
627 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
628 switch (layer_tree_host()->source_frame_number()) {
632 Animation
* animation
= player_child_
->element_animations()
633 ->layer_animation_controller()
634 ->GetAnimation(Animation::SCROLL_OFFSET
);
635 player_child_
->RemoveAnimation(animation
->id());
636 scroll_layer_
->SetScrollOffset(final_postion_
);
640 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
644 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
645 host_impl
->BlockNotifyReadyToActivateForTesting(true);
648 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
649 const BeginFrameArgs
& args
) override
{
650 if (!host_impl
->pending_tree())
653 if (!host_impl
->active_tree()->root_layer()) {
654 host_impl
->BlockNotifyReadyToActivateForTesting(false);
658 scoped_refptr
<AnimationTimeline
> timeline_impl
=
659 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
660 scoped_refptr
<AnimationPlayer
> player_impl
=
661 timeline_impl
->GetPlayerById(player_child_id_
);
663 LayerImpl
* scroll_layer_impl
=
664 host_impl
->active_tree()->root_layer()->children()[0];
665 Animation
* animation
= player_impl
->element_animations()
666 ->layer_animation_controller()
667 ->GetAnimation(Animation::SCROLL_OFFSET
);
669 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
670 host_impl
->BlockNotifyReadyToActivateForTesting(false);
674 // Block activation until the running animation has a chance to produce a
676 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
677 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
680 host_impl
->BlockNotifyReadyToActivateForTesting(false);
683 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
684 if (host_impl
->pending_tree()->source_frame_number() != 1)
686 LayerImpl
* scroll_layer_impl
=
687 host_impl
->pending_tree()->root_layer()->children()[0];
688 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
691 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
692 if (host_impl
->active_tree()->source_frame_number() != 1)
694 LayerImpl
* scroll_layer_impl
=
695 host_impl
->active_tree()->root_layer()->children()[0];
696 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
700 void AfterTest() override
{
701 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
705 FakeContentLayerClient client_
;
706 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
707 const gfx::ScrollOffset final_postion_
;
710 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
);
712 // When animations are simultaneously added to an existing layer and to a new
713 // layer, they should start at the same time, even when there's already a
714 // running animation on the existing layer.
715 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
716 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
717 : public LayerTreeHostTimelinesTest
{
719 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
720 : frame_count_with_pending_tree_(0) {}
722 void BeginTest() override
{
723 AttachPlayersToTimeline();
724 PostSetNeedsCommitToMainThread();
727 void DidCommit() override
{
728 if (layer_tree_host()->source_frame_number() == 1) {
729 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
730 AddAnimatedTransformToPlayer(player_
.get(), 4, 1, 1);
731 } else if (layer_tree_host()->source_frame_number() == 2) {
732 AddOpacityTransitionToPlayer(player_
.get(), 1, 0.f
, 0.5f
, true);
734 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
735 layer_tree_host()->root_layer()->AddChild(layer
);
736 layer
->SetBounds(gfx::Size(4, 4));
738 player_child_
->AttachLayer(layer
->id());
739 player_child_
->set_layer_animation_delegate(this);
740 AddOpacityTransitionToPlayer(player_child_
.get(), 1, 0.f
, 0.5f
, true);
744 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
745 host_impl
->BlockNotifyReadyToActivateForTesting(true);
748 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
749 // For the commit that added animations to new and existing layers, keep
750 // blocking activation. We want to verify that even with activation blocked,
751 // the animation on the layer that's already in the active tree won't get a
753 if (host_impl
->pending_tree()->source_frame_number() != 2) {
754 host_impl
->BlockNotifyReadyToActivateForTesting(false);
758 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
759 const BeginFrameArgs
& args
) override
{
760 if (!host_impl
->pending_tree() ||
761 host_impl
->pending_tree()->source_frame_number() != 2)
764 frame_count_with_pending_tree_
++;
765 if (frame_count_with_pending_tree_
== 2) {
766 host_impl
->BlockNotifyReadyToActivateForTesting(false);
770 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
771 bool has_unfinished_animation
) override
{
772 scoped_refptr
<AnimationTimeline
> timeline_impl
=
773 host_impl
->animation_host()->GetTimelineById(timeline_id_
);
774 scoped_refptr
<AnimationPlayer
> player_impl
=
775 timeline_impl
->GetPlayerById(player_id_
);
776 scoped_refptr
<AnimationPlayer
> player_child_impl
=
777 timeline_impl
->GetPlayerById(player_child_id_
);
779 // wait for tree activation.
780 if (!player_impl
->element_animations())
783 LayerAnimationController
* root_controller_impl
=
784 player_impl
->element_animations()->layer_animation_controller();
785 Animation
* root_animation
=
786 root_controller_impl
->GetAnimation(Animation::OPACITY
);
787 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
790 LayerAnimationController
* child_controller_impl
=
791 player_child_impl
->element_animations()->layer_animation_controller();
792 Animation
* child_animation
=
793 child_controller_impl
->GetAnimation(Animation::OPACITY
);
794 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
795 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
796 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
797 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
798 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
802 void AfterTest() override
{}
805 int frame_count_with_pending_tree_
;
808 // This test blocks activation which is not supported for single thread mode.
809 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
810 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
);
812 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
813 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
814 : public LayerTreeHostTimelinesTest
{
816 void SetupTree() override
{
817 LayerTreeHostTimelinesTest::SetupTree();
818 content_
= Layer::Create(layer_settings());
819 content_
->SetBounds(gfx::Size(4, 4));
820 layer_tree_host()->root_layer()->AddChild(content_
);
822 AttachPlayersToTimeline();
824 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
825 player_child_
->AttachLayer(content_
->id());
828 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
830 void DidCommit() override
{
831 switch (layer_tree_host()->source_frame_number()) {
833 // First frame: add an animation to the root layer.
834 AddAnimatedTransformToPlayer(player_
.get(), 0.1, 5, 5);
837 // Second frame: add an animation to the content layer. The root layer
838 // animation has caused us to animate already during this frame.
839 AddOpacityTransitionToPlayer(player_child_
.get(), 0.1, 5, 5, false);
844 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
845 // After both animations have started, verify that they have valid
847 if (host_impl
->active_tree()->source_frame_number() < 2)
849 AnimationRegistrar::AnimationControllerMap controllers_copy
=
850 host_impl
->animation_host()
851 ->animation_registrar()
852 ->active_animation_controllers_for_testing();
853 EXPECT_EQ(2u, controllers_copy
.size());
854 for (auto& it
: controllers_copy
) {
856 if (id
== host_impl
->RootLayer()->id()) {
857 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
858 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
859 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
860 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
861 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
867 void AfterTest() override
{}
870 scoped_refptr
<Layer
> content_
;
873 SINGLE_AND_MULTI_THREAD_TEST_F(
874 LayerTreeHostTimelinesTestAddAnimationAfterAnimating
);
876 class LayerTreeHostTimelinesTestRemoveAnimation
877 : public LayerTreeHostTimelinesTest
{
879 void SetupTree() override
{
880 LayerTreeHostTimelinesTest::SetupTree();
881 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
882 layer_
->SetBounds(gfx::Size(4, 4));
883 layer_tree_host()->root_layer()->AddChild(layer_
);
885 AttachPlayersToTimeline();
887 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
888 player_child_
->AttachLayer(layer_
->id());
891 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
893 void DidCommit() override
{
894 switch (layer_tree_host()->source_frame_number()) {
896 AddAnimatedTransformToPlayer(player_child_
.get(), 1.0, 5, 5);
899 LayerAnimationController
* controller
=
900 player_child_
->element_animations()->layer_animation_controller();
901 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
902 player_child_
->RemoveAnimation(animation
->id());
903 gfx::Transform transform
;
904 transform
.Translate(10.f
, 10.f
);
905 layer_
->SetTransform(transform
);
907 // Do something that causes property trees to get rebuilt.
908 layer_
->AddChild(Layer::Create(layer_settings()));
913 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
914 if (host_impl
->active_tree()->source_frame_number() < 2)
916 gfx::Transform expected_transform
;
917 expected_transform
.Translate(10.f
, 10.f
);
918 EXPECT_EQ(expected_transform
, host_impl
->active_tree()
925 void AfterTest() override
{}
928 scoped_refptr
<Layer
> layer_
;
929 FakeContentLayerClient client_
;
932 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation
);
934 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
935 : public LayerTreeHostTimelinesTest
{
937 void SetupTree() override
{
938 LayerTreeHostTimelinesTest::SetupTree();
939 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
940 layer_
->SetBounds(gfx::Size(4, 4));
941 layer_tree_host()->root_layer()->AddChild(layer_
);
943 AttachPlayersToTimeline();
945 player_
->AttachLayer(layer_tree_host()->root_layer()->id());
946 player_child_
->AttachLayer(layer_
->id());
949 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
951 void DidCommit() override
{
952 if (layer_tree_host()->source_frame_number() == 1)
953 AddAnimatedTransformToPlayer(player_child_
.get(), 0.04, 5, 5);
956 void WillCommit() override
{
957 if (layer_tree_host()->source_frame_number() == 2) {
958 // Block until the animation finishes on the compositor thread. Since
959 // animations have already been ticked on the main thread, when the commit
960 // happens the state on the main thread will be consistent with having a
961 // running animation but the state on the compositor thread will be
962 // consistent with having only a finished animation.
967 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
968 switch (host_impl
->sync_tree()->source_frame_number()) {
970 PostSetNeedsCommitToMainThread();
973 gfx::Transform expected_transform
;
974 expected_transform
.Translate(5.f
, 5.f
);
975 LayerImpl
* layer_impl
=
976 host_impl
->sync_tree()->root_layer()->children()[0];
977 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
983 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
984 bool has_unfinished_animation
) override
{
985 if (host_impl
->active_tree()->source_frame_number() == 1 &&
986 !has_unfinished_animation
) {
987 // The animation has finished, so allow the main thread to commit.
988 completion_
.Signal();
992 void AfterTest() override
{}
995 scoped_refptr
<Layer
> layer_
;
996 FakeContentLayerClient client_
;
997 CompletionEvent completion_
;
1000 // An animation finishing during commit can only happen when we have a separate
1001 // compositor thread.
1002 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
);