Roll src/third_party/WebKit 3e22810:3ab7adc (svn 198865:198873)
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation_timelines.cc
blob472aa9823b235ce324e1bca23fc0c074e462c749
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"
26 namespace cc {
27 namespace {
29 class LayerTreeHostTimelinesTest : public LayerTreeTest {
30 public:
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());
58 protected:
59 scoped_refptr<AnimationTimeline> timeline_;
60 scoped_refptr<AnimationPlayer> player_;
61 scoped_refptr<AnimationPlayer> player_child_;
63 const int timeline_id_;
64 const int player_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 {
73 public:
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,
91 int group) override {
92 EXPECT_LT(base::TimeTicks(), monotonic_time);
94 LayerAnimationController* controller =
95 player_->element_animations()->layer_animation_controller();
96 Animation* animation = controller->GetAnimation(Animation::OPACITY);
97 if (animation)
98 player_->RemoveAnimation(animation->id());
100 EndTest();
103 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
105 private:
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 {
116 public:
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_)
133 EndTest();
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 {}
144 private:
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 {
155 public:
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()
170 .empty();
171 if (!started_animating_ && have_animations) {
172 started_animating_ = true;
173 return;
176 if (started_animating_ && !have_animations)
177 EndTest();
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 {}
190 private:
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 {
200 public:
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)
227 return;
229 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
230 if (!animation)
231 return;
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));
245 EndTest();
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 {
262 public:
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());
289 EndTest();
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);
302 if (!animation)
303 return;
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_);
313 private:
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 {
327 public:
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);
342 if (animation)
343 controller->RemoveAnimation(animation->id());
344 EndTest();
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 {
358 public:
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());
387 EndTest();
390 void AfterTest() override {
391 // Update() should have been called once, proving that the layer was not
392 // skipped.
393 EXPECT_EQ(1, update_check_layer_->update_count());
395 // clear update_check_layer_ so LayerTreeHost dies.
396 update_check_layer_ = NULL;
399 private:
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 {
412 public:
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 {
438 EndTest();
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
448 // true.
449 // Evolved from LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
450 class LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
451 : public LayerTreeHostTimelinesTest {
452 public:
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 {
474 started_times_++;
477 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
478 Animation::TargetProperty target_property,
479 int group) override {
480 EndTest();
483 void AfterTest() override { EXPECT_EQ(1, started_times_); }
485 private:
486 int 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
495 // checkerboard.
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 {
518 prevented_draw_ = 0;
519 added_animations_ = 0;
520 started_times_ = 0;
522 PostSetNeedsCommitToMainThread();
525 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
526 LayerTreeHostImpl::FrameData* frame_data,
527 DrawResult draw_result) override {
528 if (added_animations_ < 2)
529 return draw_result;
530 if (TestEnded())
531 return draw_result;
532 // Act like there is checkerboard when the second animation wants to draw.
533 ++prevented_draw_;
534 if (prevented_draw_ > 2)
535 EndTest();
536 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
539 void DidCommitAndDrawFrame() override {
540 switch (layer_tree_host()->source_frame_number()) {
541 case 1:
542 // The animation is longer than 1 BeginFrame interval.
543 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
544 false);
545 added_animations_++;
546 break;
547 case 2:
548 // This second animation will not be drawn so it should not start.
549 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
550 added_animations_++;
551 break;
555 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
556 Animation::TargetProperty target_property,
557 int group) override {
558 if (TestEnded())
559 return;
560 started_times_++;
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
567 // of checkerboard.
568 EXPECT_EQ(1, started_times_);
571 int prevented_draw_;
572 int added_animations_;
573 int started_times_;
574 FakeContentLayerClient client_;
575 scoped_refptr<FakePictureLayer> picture_;
578 MULTI_THREAD_TEST_F(
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 {
587 public:
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()) {
607 case 1: {
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());
619 else
620 EndTest();
621 break;
623 default:
624 if (scroll_layer_->scroll_offset().x() > 10 &&
625 scroll_layer_->scroll_offset().y() > 20)
626 EndTest();
630 void AfterTest() override {}
632 private:
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
643 // delta.
644 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
645 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
646 : public LayerTreeHostTimelinesTest {
647 public:
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()) {
676 case 0:
677 break;
678 case 1: {
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_);
684 break;
686 default:
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())
698 return;
700 if (!host_impl->active_tree()->root_layer()) {
701 host_impl->BlockNotifyReadyToActivateForTesting(false);
702 return;
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);
718 return;
721 // Block activation until the running animation has a chance to produce a
722 // scroll delta.
723 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
724 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
725 return;
727 host_impl->BlockNotifyReadyToActivateForTesting(false);
730 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
731 if (host_impl->pending_tree()->source_frame_number() != 1)
732 return;
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)
740 return;
741 LayerImpl* scroll_layer_impl =
742 host_impl->active_tree()->root_layer()->children()[0];
743 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
744 EndTest();
747 void AfterTest() override {
748 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
751 private:
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 {
765 public:
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
799 // head start.
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)
809 return;
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())
828 return;
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)
835 return;
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);
846 EndTest();
849 void AfterTest() override {}
851 private:
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 {
862 public:
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()) {
879 case 1:
880 // First frame: add an animation to the root layer.
881 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
882 break;
883 case 2:
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);
887 break;
891 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
892 // After both animations have started, verify that they have valid
893 // start times.
894 if (host_impl->active_tree()->source_frame_number() < 2)
895 return;
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) {
902 int id = it.first;
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);
910 EndTest();
914 void AfterTest() override {}
916 private:
917 scoped_refptr<Layer> content_;
920 SINGLE_AND_MULTI_THREAD_TEST_F(
921 LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
923 class LayerTreeHostTimelinesTestRemoveAnimation
924 : public LayerTreeHostTimelinesTest {
925 public:
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()) {
942 case 1:
943 AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
944 break;
945 case 2:
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()));
956 break;
960 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
961 if (host_impl->active_tree()->source_frame_number() < 2)
962 return;
963 gfx::Transform expected_transform;
964 expected_transform.Translate(10.f, 10.f);
965 EXPECT_EQ(expected_transform, host_impl->active_tree()
966 ->root_layer()
967 ->children()[0]
968 ->draw_transform());
969 EndTest();
972 void AfterTest() override {}
974 private:
975 scoped_refptr<Layer> layer_;
976 FakeContentLayerClient client_;
979 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation);
981 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
982 : public LayerTreeHostTimelinesTest {
983 public:
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.
1010 completion_.Wait();
1014 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1015 switch (host_impl->sync_tree()->source_frame_number()) {
1016 case 1:
1017 PostSetNeedsCommitToMainThread();
1018 break;
1019 case 2:
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());
1025 EndTest();
1026 break;
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 {}
1041 private:
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);
1051 } // namespace
1052 } // namespace cc