Landing Recent QUIC changes until 8/19/2015 17:00 UTC.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation_timelines.cc
blob448b2f4a0f4b5a39a6dc0425fdf3b6d5f0aa9aba
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 // Animations should not be started when frames are being skipped due to
448 // checkerboard.
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 {
471 prevented_draw_ = 0;
472 added_animations_ = 0;
473 started_times_ = 0;
475 PostSetNeedsCommitToMainThread();
478 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
479 LayerTreeHostImpl::FrameData* frame_data,
480 DrawResult draw_result) override {
481 if (added_animations_ < 2)
482 return draw_result;
483 if (TestEnded())
484 return draw_result;
485 // Act like there is checkerboard when the second animation wants to draw.
486 ++prevented_draw_;
487 if (prevented_draw_ > 2)
488 EndTest();
489 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
492 void DidCommitAndDrawFrame() override {
493 switch (layer_tree_host()->source_frame_number()) {
494 case 1:
495 // The animation is longer than 1 BeginFrame interval.
496 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
497 false);
498 added_animations_++;
499 break;
500 case 2:
501 // This second animation will not be drawn so it should not start.
502 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
503 added_animations_++;
504 break;
508 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
509 Animation::TargetProperty target_property,
510 int group) override {
511 if (TestEnded())
512 return;
513 started_times_++;
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
520 // of checkerboard.
521 EXPECT_EQ(1, started_times_);
524 int prevented_draw_;
525 int added_animations_;
526 int started_times_;
527 FakeContentLayerClient client_;
528 scoped_refptr<FakePictureLayer> picture_;
531 MULTI_THREAD_TEST_F(
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 {
540 public:
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()) {
560 case 1: {
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());
572 else
573 EndTest();
574 break;
576 default:
577 if (scroll_layer_->scroll_offset().x() > 10 &&
578 scroll_layer_->scroll_offset().y() > 20)
579 EndTest();
583 void AfterTest() override {}
585 private:
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
596 // delta.
597 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
598 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
599 : public LayerTreeHostTimelinesTest {
600 public:
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()) {
629 case 0:
630 break;
631 case 1: {
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_);
637 break;
639 default:
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())
651 return;
653 if (!host_impl->active_tree()->root_layer()) {
654 host_impl->BlockNotifyReadyToActivateForTesting(false);
655 return;
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);
671 return;
674 // Block activation until the running animation has a chance to produce a
675 // scroll delta.
676 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
677 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
678 return;
680 host_impl->BlockNotifyReadyToActivateForTesting(false);
683 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
684 if (host_impl->pending_tree()->source_frame_number() != 1)
685 return;
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)
693 return;
694 LayerImpl* scroll_layer_impl =
695 host_impl->active_tree()->root_layer()->children()[0];
696 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
697 EndTest();
700 void AfterTest() override {
701 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
704 private:
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 {
718 public:
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
752 // head start.
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)
762 return;
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())
781 return;
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)
788 return;
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);
799 EndTest();
802 void AfterTest() override {}
804 private:
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 {
815 public:
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()) {
832 case 1:
833 // First frame: add an animation to the root layer.
834 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
835 break;
836 case 2:
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);
840 break;
844 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
845 // After both animations have started, verify that they have valid
846 // start times.
847 if (host_impl->active_tree()->source_frame_number() < 2)
848 return;
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) {
855 int id = it.first;
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);
863 EndTest();
867 void AfterTest() override {}
869 private:
870 scoped_refptr<Layer> content_;
873 SINGLE_AND_MULTI_THREAD_TEST_F(
874 LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
876 class LayerTreeHostTimelinesTestRemoveAnimation
877 : public LayerTreeHostTimelinesTest {
878 public:
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()) {
895 case 1:
896 AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
897 break;
898 case 2:
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()));
909 break;
913 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
914 if (host_impl->active_tree()->source_frame_number() < 2)
915 return;
916 gfx::Transform expected_transform;
917 expected_transform.Translate(10.f, 10.f);
918 EXPECT_EQ(expected_transform, host_impl->active_tree()
919 ->root_layer()
920 ->children()[0]
921 ->draw_transform());
922 EndTest();
925 void AfterTest() override {}
927 private:
928 scoped_refptr<Layer> layer_;
929 FakeContentLayerClient client_;
932 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation);
934 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
935 : public LayerTreeHostTimelinesTest {
936 public:
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.
963 completion_.Wait();
967 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
968 switch (host_impl->sync_tree()->source_frame_number()) {
969 case 1:
970 PostSetNeedsCommitToMainThread();
971 break;
972 case 2:
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());
978 EndTest();
979 break;
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 {}
994 private:
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);
1004 } // namespace
1005 } // namespace cc