Update V8 to version 4.7.42.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blob9e220c01551690546bab722a4ba7ec14005081a2
1 // Copyright 2012 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/layer_animation_controller.h"
9 #include "cc/animation/scroll_offset_animation_curve.h"
10 #include "cc/animation/timing_function.h"
11 #include "cc/animation/transform_operations.h"
12 #include "cc/base/completion_event.h"
13 #include "cc/base/time_util.h"
14 #include "cc/layers/layer.h"
15 #include "cc/layers/layer_impl.h"
16 #include "cc/test/animation_test_common.h"
17 #include "cc/test/fake_content_layer_client.h"
18 #include "cc/test/fake_picture_layer.h"
19 #include "cc/test/layer_tree_test.h"
20 #include "cc/trees/layer_tree_impl.h"
22 namespace cc {
23 namespace {
25 class LayerTreeHostAnimationTest : public LayerTreeTest {
26 public:
27 void SetupTree() override {
28 LayerTreeTest::SetupTree();
29 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
33 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
34 // be set.
35 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
36 : public LayerTreeHostAnimationTest {
37 public:
38 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
39 : num_commits_(0) {}
41 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
43 void BeginMainFrame(const BeginFrameArgs& args) override {
44 // We skip the first commit because its the commit that populates the
45 // impl thread with a tree. After the second commit, the test is done.
46 if (num_commits_ != 1)
47 return;
49 layer_tree_host()->SetNeedsAnimate();
50 // Right now, CommitRequested is going to be true, because during
51 // BeginFrame, we force CommitRequested to true to prevent requests from
52 // hitting the impl thread. But, when the next DidCommit happens, we should
53 // verify that CommitRequested has gone back to false.
56 void DidCommit() override {
57 if (!num_commits_) {
58 EXPECT_FALSE(layer_tree_host()->CommitRequested());
59 layer_tree_host()->SetNeedsAnimate();
60 EXPECT_FALSE(layer_tree_host()->CommitRequested());
63 // Verifies that the SetNeedsAnimate we made in ::Animate did not
64 // trigger CommitRequested.
65 EXPECT_FALSE(layer_tree_host()->CommitRequested());
66 EndTest();
67 num_commits_++;
70 void AfterTest() override {}
72 private:
73 int num_commits_;
76 MULTI_THREAD_TEST_F(
77 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
79 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
80 // callback, request another frame using SetNeedsAnimate. End the test when
81 // animate gets called yet-again, indicating that the proxy is correctly
82 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
83 // flow.
84 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
85 : public LayerTreeHostAnimationTest {
86 public:
87 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
88 : num_begin_frames_(0) {}
90 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
92 void BeginMainFrame(const BeginFrameArgs& args) override {
93 if (!num_begin_frames_) {
94 layer_tree_host()->SetNeedsAnimate();
95 num_begin_frames_++;
96 return;
98 EndTest();
101 void AfterTest() override {}
103 private:
104 int num_begin_frames_;
107 SINGLE_AND_MULTI_THREAD_TEST_F(
108 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
110 // Add a layer animation and confirm that
111 // LayerTreeHostImpl::UpdateAnimationState does get called.
112 class LayerTreeHostAnimationTestAddAnimation
113 : public LayerTreeHostAnimationTest {
114 public:
115 LayerTreeHostAnimationTestAddAnimation()
116 : update_animation_state_was_called_(false) {}
118 void BeginTest() override {
119 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
122 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
123 bool has_unfinished_animation) override {
124 EXPECT_FALSE(has_unfinished_animation);
125 update_animation_state_was_called_ = true;
128 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
129 Animation::TargetProperty target_property,
130 int group) override {
131 EXPECT_LT(base::TimeTicks(), monotonic_time);
133 LayerAnimationController* controller =
134 layer_tree_host()->root_layer()->layer_animation_controller();
135 Animation* animation = controller->GetAnimation(Animation::OPACITY);
136 if (animation)
137 controller->RemoveAnimation(animation->id());
139 EndTest();
142 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
144 private:
145 bool update_animation_state_was_called_;
148 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
150 // Add a layer animation to a layer, but continually fail to draw. Confirm that
151 // after a while, we do eventually force a draw.
152 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
153 : public LayerTreeHostAnimationTest {
154 public:
155 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
156 : started_animating_(false) {}
158 void BeginTest() override {
159 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
162 void AnimateLayers(LayerTreeHostImpl* host_impl,
163 base::TimeTicks monotonic_time) override {
164 started_animating_ = true;
167 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
168 if (started_animating_)
169 EndTest();
172 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
173 LayerTreeHostImpl::FrameData* frame,
174 DrawResult draw_result) override {
175 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
178 void AfterTest() override {}
180 private:
181 bool started_animating_;
184 // Starvation can only be an issue with the MT compositor.
185 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
187 // Ensures that animations eventually get deleted.
188 class LayerTreeHostAnimationTestAnimationsGetDeleted
189 : public LayerTreeHostAnimationTest {
190 public:
191 LayerTreeHostAnimationTestAnimationsGetDeleted()
192 : started_animating_(false) {}
194 void BeginTest() override {
195 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
198 void AnimateLayers(LayerTreeHostImpl* host_impl,
199 base::TimeTicks monotonic_time) override {
200 bool have_animations = !host_impl->animation_registrar()
201 ->active_animation_controllers_for_testing()
202 .empty();
203 if (!started_animating_ && have_animations) {
204 started_animating_ = true;
205 return;
208 if (started_animating_ && !have_animations)
209 EndTest();
212 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
213 Animation::TargetProperty target_property,
214 int group) override {
215 // Animations on the impl-side controller only get deleted during a commit,
216 // so we need to schedule a commit.
217 layer_tree_host()->SetNeedsCommit();
220 void AfterTest() override {}
222 private:
223 bool started_animating_;
226 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
228 // Ensure that an animation's timing function is respected.
229 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
230 : public LayerTreeHostAnimationTest {
231 public:
232 void SetupTree() override {
233 LayerTreeHostAnimationTest::SetupTree();
234 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
235 picture_->SetBounds(gfx::Size(4, 4));
236 layer_tree_host()->root_layer()->AddChild(picture_);
239 void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
241 void AnimateLayers(LayerTreeHostImpl* host_impl,
242 base::TimeTicks monotonic_time) override {
243 // TODO(ajuma): This test only checks the active tree. Add checks for
244 // pending tree too.
245 if (!host_impl->active_tree()->root_layer())
246 return;
247 LayerAnimationController* controller_impl =
248 host_impl->active_tree()->root_layer()->children()[0]->
249 layer_animation_controller();
250 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
251 if (!animation)
252 return;
254 const FloatAnimationCurve* curve =
255 animation->curve()->ToFloatAnimationCurve();
256 float start_opacity = curve->GetValue(base::TimeDelta());
257 float end_opacity = curve->GetValue(curve->Duration());
258 float linearly_interpolated_opacity =
259 0.25f * end_opacity + 0.75f * start_opacity;
260 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
261 // If the linear timing function associated with this animation was not
262 // picked up, then the linearly interpolated opacity would be different
263 // because of the default ease timing function.
264 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
266 EndTest();
269 void AfterTest() override {}
271 FakeContentLayerClient client_;
272 scoped_refptr<FakePictureLayer> picture_;
275 SINGLE_AND_MULTI_THREAD_TEST_F(
276 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
278 // Ensures that main thread animations have their start times synchronized with
279 // impl thread animations.
280 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
281 : public LayerTreeHostAnimationTest {
282 public:
283 void SetupTree() override {
284 LayerTreeHostAnimationTest::SetupTree();
285 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
286 picture_->SetBounds(gfx::Size(4, 4));
287 picture_->set_layer_animation_delegate(this);
288 layer_tree_host()->root_layer()->AddChild(picture_);
291 void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
293 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
294 Animation::TargetProperty target_property,
295 int group) override {
296 LayerAnimationController* controller =
297 layer_tree_host()->root_layer()->children()[0]->
298 layer_animation_controller();
299 Animation* animation = controller->GetAnimation(Animation::OPACITY);
300 main_start_time_ = animation->start_time();
301 controller->RemoveAnimation(animation->id());
302 EndTest();
305 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
306 bool has_unfinished_animation) override {
307 LayerAnimationController* controller =
308 impl_host->active_tree()->root_layer()->children()[0]->
309 layer_animation_controller();
310 Animation* animation = controller->GetAnimation(Animation::OPACITY);
311 if (!animation)
312 return;
314 impl_start_time_ = animation->start_time();
317 void AfterTest() override {
318 EXPECT_EQ(impl_start_time_, main_start_time_);
319 EXPECT_LT(base::TimeTicks(), impl_start_time_);
322 private:
323 base::TimeTicks main_start_time_;
324 base::TimeTicks impl_start_time_;
325 FakeContentLayerClient client_;
326 scoped_refptr<FakePictureLayer> picture_;
329 SINGLE_AND_MULTI_THREAD_TEST_F(
330 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
332 // Ensures that notify animation finished is called.
333 class LayerTreeHostAnimationTestAnimationFinishedEvents
334 : public LayerTreeHostAnimationTest {
335 public:
336 void BeginTest() override {
337 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
340 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
341 Animation::TargetProperty target_property,
342 int group) override {
343 LayerAnimationController* controller =
344 layer_tree_host()->root_layer()->layer_animation_controller();
345 Animation* animation = controller->GetAnimation(Animation::OPACITY);
346 if (animation)
347 controller->RemoveAnimation(animation->id());
348 EndTest();
351 void AfterTest() override {}
354 SINGLE_AND_MULTI_THREAD_TEST_F(
355 LayerTreeHostAnimationTestAnimationFinishedEvents);
357 // Ensures that when opacity is being animated, this value does not cause the
358 // subtree to be skipped.
359 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
360 : public LayerTreeHostAnimationTest {
361 public:
362 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
363 : update_check_layer_(
364 FakePictureLayer::Create(layer_settings(), &client_)) {}
366 void SetupTree() override {
367 update_check_layer_->SetOpacity(0.f);
368 layer_tree_host()->SetRootLayer(update_check_layer_);
369 LayerTreeHostAnimationTest::SetupTree();
372 void BeginTest() override {
373 PostAddAnimationToMainThread(update_check_layer_.get());
376 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
377 LayerAnimationController* controller_impl =
378 host_impl->active_tree()->root_layer()->layer_animation_controller();
379 Animation* animation_impl =
380 controller_impl->GetAnimation(Animation::OPACITY);
381 controller_impl->RemoveAnimation(animation_impl->id());
382 EndTest();
385 void AfterTest() override {
386 // Update() should have been called once, proving that the layer was not
387 // skipped.
388 EXPECT_EQ(1, update_check_layer_->update_count());
390 // clear update_check_layer_ so LayerTreeHost dies.
391 update_check_layer_ = NULL;
394 private:
395 FakeContentLayerClient client_;
396 scoped_refptr<FakePictureLayer> update_check_layer_;
399 SINGLE_AND_MULTI_THREAD_TEST_F(
400 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
402 // Layers added to tree with existing active animations should have the
403 // animation correctly recognized.
404 class LayerTreeHostAnimationTestLayerAddedWithAnimation
405 : public LayerTreeHostAnimationTest {
406 public:
407 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
409 void DidCommit() override {
410 if (layer_tree_host()->source_frame_number() == 1) {
411 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
412 layer->set_layer_animation_delegate(this);
414 // Any valid AnimationCurve will do here.
415 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
416 scoped_ptr<Animation> animation(
417 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
418 layer->layer_animation_controller()->AddAnimation(animation.Pass());
420 // We add the animation *before* attaching the layer to the tree.
421 layer_tree_host()->root_layer()->AddChild(layer);
425 void AnimateLayers(LayerTreeHostImpl* impl_host,
426 base::TimeTicks monotonic_time) override {
427 EndTest();
430 void AfterTest() override {}
433 SINGLE_AND_MULTI_THREAD_TEST_F(
434 LayerTreeHostAnimationTestLayerAddedWithAnimation);
436 class LayerTreeHostAnimationTestCancelAnimateCommit
437 : public LayerTreeHostAnimationTest {
438 public:
439 LayerTreeHostAnimationTestCancelAnimateCommit()
440 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
442 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
444 void BeginMainFrame(const BeginFrameArgs& args) override {
445 num_begin_frames_++;
446 // No-op animate will cancel the commit.
447 if (layer_tree_host()->source_frame_number() == 1) {
448 EndTest();
449 return;
451 layer_tree_host()->SetNeedsAnimate();
454 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
455 num_commit_calls_++;
456 if (impl->active_tree()->source_frame_number() > 1)
457 FAIL() << "Commit should have been canceled.";
460 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
461 num_draw_calls_++;
462 if (impl->active_tree()->source_frame_number() > 1)
463 FAIL() << "Draw should have been canceled.";
466 void AfterTest() override {
467 EXPECT_EQ(2, num_begin_frames_);
468 EXPECT_EQ(1, num_commit_calls_);
469 EXPECT_EQ(1, num_draw_calls_);
472 private:
473 int num_begin_frames_;
474 int num_commit_calls_;
475 int num_draw_calls_;
478 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
480 class LayerTreeHostAnimationTestForceRedraw
481 : public LayerTreeHostAnimationTest {
482 public:
483 LayerTreeHostAnimationTestForceRedraw()
484 : num_animate_(0), num_draw_layers_(0) {}
486 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
488 void BeginMainFrame(const BeginFrameArgs& args) override {
489 if (++num_animate_ < 2)
490 layer_tree_host()->SetNeedsAnimate();
493 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); }
495 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
496 if (++num_draw_layers_ == 2)
497 EndTest();
500 void AfterTest() override {
501 // The first commit will always draw; make sure the second draw triggered
502 // by the animation was not cancelled.
503 EXPECT_EQ(2, num_draw_layers_);
504 EXPECT_EQ(2, num_animate_);
507 private:
508 int num_animate_;
509 int num_draw_layers_;
512 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
514 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
515 : public LayerTreeHostAnimationTest {
516 public:
517 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
518 : num_animate_(0), num_draw_layers_(0) {}
520 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
522 void BeginMainFrame(const BeginFrameArgs& args) override {
523 if (++num_animate_ <= 2) {
524 layer_tree_host()->SetNeedsCommit();
525 layer_tree_host()->SetNeedsAnimate();
529 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
530 if (++num_draw_layers_ == 2)
531 EndTest();
534 void AfterTest() override {
535 // The first commit will always draw; make sure the second draw triggered
536 // by the SetNeedsCommit was not cancelled.
537 EXPECT_EQ(2, num_draw_layers_);
538 EXPECT_GE(num_animate_, 2);
541 private:
542 int num_animate_;
543 int num_draw_layers_;
546 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
548 // Animations should not be started when frames are being skipped due to
549 // checkerboard.
550 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
551 : public LayerTreeHostAnimationTest {
552 void SetupTree() override {
553 LayerTreeHostAnimationTest::SetupTree();
554 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
555 picture_->SetBounds(gfx::Size(4, 4));
556 picture_->set_layer_animation_delegate(this);
557 layer_tree_host()->root_layer()->AddChild(picture_);
560 void InitializeSettings(LayerTreeSettings* settings) override {
561 // Make sure that drawing many times doesn't cause a checkerboarded
562 // animation to start so we avoid flake in this test.
563 settings->timeout_and_draw_when_animation_checkerboards = false;
566 void BeginTest() override {
567 prevented_draw_ = 0;
568 added_animations_ = 0;
569 started_times_ = 0;
571 PostSetNeedsCommitToMainThread();
574 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
575 LayerTreeHostImpl::FrameData* frame_data,
576 DrawResult draw_result) override {
577 if (added_animations_ < 2)
578 return draw_result;
579 if (TestEnded())
580 return draw_result;
581 // Act like there is checkerboard when the second animation wants to draw.
582 ++prevented_draw_;
583 if (prevented_draw_ > 2)
584 EndTest();
585 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
588 void DidCommitAndDrawFrame() override {
589 switch (layer_tree_host()->source_frame_number()) {
590 case 1:
591 // The animation is longer than 1 BeginFrame interval.
592 AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
593 added_animations_++;
594 break;
595 case 2:
596 // This second animation will not be drawn so it should not start.
597 AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
598 added_animations_++;
599 break;
603 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
604 Animation::TargetProperty target_property,
605 int group) override {
606 if (TestEnded())
607 return;
608 started_times_++;
611 void AfterTest() override {
612 // Make sure we tried to draw the second animation but failed.
613 EXPECT_LT(0, prevented_draw_);
614 // The first animation should be started, but the second should not because
615 // of checkerboard.
616 EXPECT_EQ(1, started_times_);
619 int prevented_draw_;
620 int added_animations_;
621 int started_times_;
622 FakeContentLayerClient client_;
623 scoped_refptr<FakePictureLayer> picture_;
626 MULTI_THREAD_TEST_F(
627 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
629 // Verifies that scroll offset animations are only accepted when impl-scrolling
630 // is supported, and that when scroll offset animations are accepted,
631 // scroll offset updates are sent back to the main thread.
632 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
633 : public LayerTreeHostAnimationTest {
634 public:
635 void SetupTree() override {
636 LayerTreeHostAnimationTest::SetupTree();
638 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
639 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
640 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
641 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
642 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
645 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
647 void DidCommit() override {
648 switch (layer_tree_host()->source_frame_number()) {
649 case 1: {
650 scoped_ptr<ScrollOffsetAnimationCurve> curve(
651 ScrollOffsetAnimationCurve::Create(
652 gfx::ScrollOffset(500.f, 550.f),
653 EaseInOutTimingFunction::Create()));
654 scoped_ptr<Animation> animation(
655 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
656 animation->set_needs_synchronized_start_time(true);
657 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
658 bool impl_scrolling_supported =
659 layer_tree_host()->proxy()->SupportsImplScrolling();
660 EXPECT_EQ(impl_scrolling_supported, animation_added);
661 if (!impl_scrolling_supported)
662 EndTest();
663 break;
665 default:
666 if (scroll_layer_->scroll_offset().x() > 10 &&
667 scroll_layer_->scroll_offset().y() > 20)
668 EndTest();
672 void AfterTest() override {}
674 private:
675 FakeContentLayerClient client_;
676 scoped_refptr<FakePictureLayer> scroll_layer_;
679 SINGLE_AND_MULTI_THREAD_TEST_F(
680 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
682 // Verifies that when the main thread removes a scroll animation and sets a new
683 // scroll position, the active tree takes on exactly this new scroll position
684 // after activation, and the main thread doesn't receive a spurious scroll
685 // delta.
686 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
687 : public LayerTreeHostAnimationTest {
688 public:
689 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
690 : final_postion_(50.0, 100.0) {}
692 void SetupTree() override {
693 LayerTreeHostAnimationTest::SetupTree();
695 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
696 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
697 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
698 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
699 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
701 scoped_ptr<ScrollOffsetAnimationCurve> curve(
702 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
703 EaseInOutTimingFunction::Create()));
704 scoped_ptr<Animation> animation(
705 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
706 animation->set_needs_synchronized_start_time(true);
707 scroll_layer_->AddAnimation(animation.Pass());
710 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
712 void BeginMainFrame(const BeginFrameArgs& args) override {
713 switch (layer_tree_host()->source_frame_number()) {
714 case 0:
715 break;
716 case 1: {
717 Animation* animation =
718 scroll_layer_->layer_animation_controller()->GetAnimation(
719 Animation::SCROLL_OFFSET);
720 scroll_layer_->layer_animation_controller()->RemoveAnimation(
721 animation->id());
722 scroll_layer_->SetScrollOffset(final_postion_);
723 break;
725 default:
726 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
730 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
731 host_impl->BlockNotifyReadyToActivateForTesting(true);
734 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
735 const BeginFrameArgs& args) override {
736 if (!host_impl->pending_tree())
737 return;
739 if (!host_impl->active_tree()->root_layer()) {
740 host_impl->BlockNotifyReadyToActivateForTesting(false);
741 return;
744 LayerImpl* scroll_layer_impl =
745 host_impl->active_tree()->root_layer()->children()[0];
746 Animation* animation =
747 scroll_layer_impl->layer_animation_controller()->GetAnimation(
748 Animation::SCROLL_OFFSET);
750 if (!animation || animation->run_state() != Animation::RUNNING) {
751 host_impl->BlockNotifyReadyToActivateForTesting(false);
752 return;
755 // Block activation until the running animation has a chance to produce a
756 // scroll delta.
757 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
758 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
759 return;
761 host_impl->BlockNotifyReadyToActivateForTesting(false);
764 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
765 if (host_impl->pending_tree()->source_frame_number() != 1)
766 return;
767 LayerImpl* scroll_layer_impl =
768 host_impl->pending_tree()->root_layer()->children()[0];
769 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
772 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
773 if (host_impl->active_tree()->source_frame_number() != 1)
774 return;
775 LayerImpl* scroll_layer_impl =
776 host_impl->active_tree()->root_layer()->children()[0];
777 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
778 EndTest();
781 void AfterTest() override {
782 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
785 private:
786 FakeContentLayerClient client_;
787 scoped_refptr<FakePictureLayer> scroll_layer_;
788 const gfx::ScrollOffset final_postion_;
791 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
793 // When animations are simultaneously added to an existing layer and to a new
794 // layer, they should start at the same time, even when there's already a
795 // running animation on the existing layer.
796 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
797 : public LayerTreeHostAnimationTest {
798 public:
799 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
800 : frame_count_with_pending_tree_(0) {}
802 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
804 void DidCommit() override {
805 if (layer_tree_host()->source_frame_number() == 1) {
806 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
807 } else if (layer_tree_host()->source_frame_number() == 2) {
808 AddOpacityTransitionToLayer(
809 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
811 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
812 layer_tree_host()->root_layer()->AddChild(layer);
813 layer->set_layer_animation_delegate(this);
814 layer->SetBounds(gfx::Size(4, 4));
815 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
819 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
820 host_impl->BlockNotifyReadyToActivateForTesting(true);
823 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
824 // For the commit that added animations to new and existing layers, keep
825 // blocking activation. We want to verify that even with activation blocked,
826 // the animation on the layer that's already in the active tree won't get a
827 // head start.
828 if (host_impl->pending_tree()->source_frame_number() != 2) {
829 host_impl->BlockNotifyReadyToActivateForTesting(false);
833 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
834 const BeginFrameArgs& args) override {
835 if (!host_impl->pending_tree() ||
836 host_impl->pending_tree()->source_frame_number() != 2)
837 return;
839 frame_count_with_pending_tree_++;
840 if (frame_count_with_pending_tree_ == 2) {
841 host_impl->BlockNotifyReadyToActivateForTesting(false);
845 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
846 bool has_unfinished_animation) override {
847 LayerAnimationController* root_controller_impl =
848 host_impl->active_tree()->root_layer()->layer_animation_controller();
849 Animation* root_animation =
850 root_controller_impl->GetAnimation(Animation::OPACITY);
851 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
852 return;
854 LayerAnimationController* child_controller_impl =
855 host_impl->active_tree()->root_layer()->children()
856 [0]->layer_animation_controller();
857 Animation* child_animation =
858 child_controller_impl->GetAnimation(Animation::OPACITY);
859 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
860 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
861 root_controller_impl->AbortAnimations(Animation::OPACITY);
862 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
863 child_controller_impl->AbortAnimations(Animation::OPACITY);
864 EndTest();
867 void AfterTest() override {}
869 private:
870 int frame_count_with_pending_tree_;
873 // This test blocks activation which is not supported for single thread mode.
874 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
875 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
877 class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
878 : public LayerTreeHostAnimationTest {
879 public:
880 void SetupTree() override {
881 LayerTreeHostAnimationTest::SetupTree();
883 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
884 layer_->SetBounds(gfx::Size(2, 2));
885 // Transform the layer to 4,4 to start.
886 gfx::Transform start_transform;
887 start_transform.Translate(4.0, 4.0);
888 layer_->SetTransform(start_transform);
890 layer_tree_host()->root_layer()->AddChild(layer_);
893 void BeginTest() override {
894 // Add a translate from 6,7 to 8,9.
895 TransformOperations start;
896 start.AppendTranslate(6.f, 7.f, 0.f);
897 TransformOperations end;
898 end.AppendTranslate(8.f, 9.f, 0.f);
899 AddAnimatedTransformToLayer(layer_.get(), 4.0, start, end);
901 PostSetNeedsCommitToMainThread();
904 void WillPrepareTiles(LayerTreeHostImpl* host_impl) override {
905 if (host_impl->sync_tree()->source_frame_number() != 0)
906 return;
908 // After checking this on the sync tree, we will activate, which will cause
909 // PrepareTiles to happen again (which races with the test exiting).
910 if (TestEnded())
911 return;
913 LayerImpl* root = host_impl->sync_tree()->root_layer();
914 LayerImpl* child = root->children()[0];
915 LayerAnimationController* controller_impl =
916 child->layer_animation_controller();
917 Animation* animation = controller_impl->GetAnimation(Animation::TRANSFORM);
919 // The animation should be starting for the first frame.
920 EXPECT_EQ(Animation::STARTING, animation->run_state());
922 // And the transform should be propogated to the sync tree layer, at its
923 // starting state which is 6,7.
924 gfx::Transform expected_transform;
925 expected_transform.Translate(6.0, 7.0);
926 EXPECT_EQ(expected_transform, child->draw_transform());
927 // And the sync tree layer should know it is animating.
928 EXPECT_TRUE(child->screen_space_transform_is_animating());
930 controller_impl->AbortAnimations(Animation::TRANSFORM);
931 EndTest();
934 void AfterTest() override {}
936 FakeContentLayerClient client_;
937 scoped_refptr<Layer> layer_;
940 SINGLE_AND_MULTI_THREAD_TEST_F(
941 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit);
943 // When a layer with an animation is removed from the tree and later re-added,
944 // the animation should resume.
945 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
946 : public LayerTreeHostAnimationTest {
947 public:
948 void SetupTree() override {
949 LayerTreeHostAnimationTest::SetupTree();
950 layer_ = Layer::Create(layer_settings());
951 layer_->SetBounds(gfx::Size(4, 4));
952 layer_tree_host()->root_layer()->AddChild(layer_);
953 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
956 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
958 void DidCommit() override {
959 switch (layer_tree_host()->source_frame_number()) {
960 case 1:
961 layer_->RemoveFromParent();
962 break;
963 case 2:
964 layer_tree_host()->root_layer()->AddChild(layer_);
965 break;
969 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
970 switch (host_impl->active_tree()->source_frame_number()) {
971 case 0:
972 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
973 break;
974 case 1:
975 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
976 break;
977 case 2:
978 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
979 EndTest();
980 break;
984 void AfterTest() override {}
986 private:
987 scoped_refptr<Layer> layer_;
990 SINGLE_AND_MULTI_THREAD_TEST_F(
991 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
993 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
994 : public LayerTreeHostAnimationTest {
995 public:
996 void SetupTree() override {
997 LayerTreeHostAnimationTest::SetupTree();
998 layer_ = Layer::Create(layer_settings());
999 layer_->SetBounds(gfx::Size(4, 4));
1000 layer_tree_host()->root_layer()->AddChild(layer_);
1003 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1005 void DidCommit() override {
1006 switch (layer_tree_host()->source_frame_number()) {
1007 case 1:
1008 // First frame: add an animation to the root layer.
1009 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1010 break;
1011 case 2:
1012 // Second frame: add an animation to the content layer. The root layer
1013 // animation has caused us to animate already during this frame.
1014 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
1015 break;
1019 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1020 // After both animations have started, verify that they have valid
1021 // start times.
1022 if (host_impl->active_tree()->source_frame_number() < 2)
1023 return;
1024 AnimationRegistrar::AnimationControllerMap controllers_copy =
1025 host_impl->animation_registrar()
1026 ->active_animation_controllers_for_testing();
1027 EXPECT_EQ(2u, controllers_copy.size());
1028 for (auto& it : controllers_copy) {
1029 int id = it.first;
1030 if (id == host_impl->RootLayer()->id()) {
1031 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
1032 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1033 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1034 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
1035 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1037 EndTest();
1041 void AfterTest() override {}
1043 private:
1044 scoped_refptr<Layer> layer_;
1047 SINGLE_AND_MULTI_THREAD_TEST_F(
1048 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1050 class LayerTreeHostAnimationTestRemoveAnimation
1051 : public LayerTreeHostAnimationTest {
1052 public:
1053 void SetupTree() override {
1054 LayerTreeHostAnimationTest::SetupTree();
1055 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1056 layer_->SetBounds(gfx::Size(4, 4));
1057 layer_tree_host()->root_layer()->AddChild(layer_);
1060 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1062 void DidCommit() override {
1063 switch (layer_tree_host()->source_frame_number()) {
1064 case 1:
1065 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1066 break;
1067 case 2:
1068 LayerAnimationController* controller =
1069 layer_->layer_animation_controller();
1070 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1071 layer_->RemoveAnimation(animation->id());
1072 gfx::Transform transform;
1073 transform.Translate(10.f, 10.f);
1074 layer_->SetTransform(transform);
1076 // Do something that causes property trees to get rebuilt. This is
1077 // intended to simulate the conditions that caused the bug whose fix
1078 // this is testing (the test will pass without it but won't test what
1079 // we want it to). We were updating the wrong transform node at the end
1080 // of an animation (we were assuming the layer with the finished
1081 // animation still had its own transform node). But nodes can only get
1082 // added/deleted when something triggers a rebuild. Adding a layer
1083 // triggers a rebuild, and since the layer that had an animation before
1084 // no longer has one, it doesn't get a transform node in the rebuild.
1085 layer_->AddChild(Layer::Create(layer_settings()));
1086 break;
1090 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1091 LayerImpl* root = host_impl->active_tree()->root_layer();
1092 LayerImpl* child = root->children()[0];
1093 switch (host_impl->active_tree()->source_frame_number()) {
1094 case 0:
1095 // No animation yet.
1096 break;
1097 case 1:
1098 // Animation is started.
1099 EXPECT_TRUE(child->screen_space_transform_is_animating());
1100 break;
1101 case 2: {
1102 // The animation is removed, the transform that was set afterward is
1103 // applied.
1104 gfx::Transform expected_transform;
1105 expected_transform.Translate(10.f, 10.f);
1106 EXPECT_EQ(expected_transform, child->draw_transform());
1107 EXPECT_FALSE(child->screen_space_transform_is_animating());
1108 EndTest();
1109 break;
1111 default:
1112 NOTREACHED();
1116 void AfterTest() override {}
1118 private:
1119 scoped_refptr<Layer> layer_;
1120 FakeContentLayerClient client_;
1123 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation);
1125 class LayerTreeHostAnimationTestIsAnimating
1126 : public LayerTreeHostAnimationTest {
1127 public:
1128 void SetupTree() override {
1129 LayerTreeHostAnimationTest::SetupTree();
1130 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1131 layer_->SetBounds(gfx::Size(4, 4));
1132 layer_tree_host()->root_layer()->AddChild(layer_);
1135 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1137 void DidCommit() override {
1138 switch (layer_tree_host()->source_frame_number()) {
1139 case 1:
1140 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1141 break;
1142 case 2:
1143 LayerAnimationController* controller =
1144 layer_->layer_animation_controller();
1145 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1146 layer_->RemoveAnimation(animation->id());
1147 break;
1151 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1152 LayerImpl* root = host_impl->sync_tree()->root_layer();
1153 LayerImpl* child = root->children()[0];
1154 switch (host_impl->sync_tree()->source_frame_number()) {
1155 case 0:
1156 // No animation yet.
1157 break;
1158 case 1:
1159 // Animation is started.
1160 EXPECT_TRUE(child->screen_space_transform_is_animating());
1161 break;
1162 case 2:
1163 // The animation is removed/stopped.
1164 EXPECT_FALSE(child->screen_space_transform_is_animating());
1165 EndTest();
1166 break;
1167 default:
1168 NOTREACHED();
1172 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1173 LayerImpl* root = host_impl->active_tree()->root_layer();
1174 LayerImpl* child = root->children()[0];
1175 switch (host_impl->active_tree()->source_frame_number()) {
1176 case 0:
1177 // No animation yet.
1178 break;
1179 case 1:
1180 // Animation is started.
1181 EXPECT_TRUE(child->screen_space_transform_is_animating());
1182 break;
1183 case 2:
1184 // The animation is removed/stopped.
1185 EXPECT_FALSE(child->screen_space_transform_is_animating());
1186 EndTest();
1187 break;
1188 default:
1189 NOTREACHED();
1193 void AfterTest() override {}
1195 private:
1196 scoped_refptr<Layer> layer_;
1197 FakeContentLayerClient client_;
1200 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating);
1202 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1203 : public LayerTreeHostAnimationTest {
1204 public:
1205 void SetupTree() override {
1206 LayerTreeHostAnimationTest::SetupTree();
1207 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1208 layer_->SetBounds(gfx::Size(4, 4));
1209 layer_tree_host()->root_layer()->AddChild(layer_);
1212 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1214 void DidCommit() override {
1215 if (layer_tree_host()->source_frame_number() == 1)
1216 AddAnimatedTransformToLayer(layer_.get(), 0.04, 5, 5);
1219 void WillCommit() override {
1220 if (layer_tree_host()->source_frame_number() == 2) {
1221 // Block until the animation finishes on the compositor thread. Since
1222 // animations have already been ticked on the main thread, when the commit
1223 // happens the state on the main thread will be consistent with having a
1224 // running animation but the state on the compositor thread will be
1225 // consistent with having only a finished animation.
1226 completion_.Wait();
1230 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1231 switch (host_impl->sync_tree()->source_frame_number()) {
1232 case 1:
1233 PostSetNeedsCommitToMainThread();
1234 break;
1235 case 2:
1236 gfx::Transform expected_transform;
1237 expected_transform.Translate(5.f, 5.f);
1238 LayerImpl* layer_impl =
1239 host_impl->sync_tree()->root_layer()->children()[0];
1240 EXPECT_EQ(expected_transform, layer_impl->draw_transform());
1241 EndTest();
1242 break;
1246 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1247 bool has_unfinished_animation) override {
1248 if (host_impl->active_tree()->source_frame_number() == 1 &&
1249 !has_unfinished_animation) {
1250 // The animation has finished, so allow the main thread to commit.
1251 completion_.Signal();
1255 void AfterTest() override {}
1257 private:
1258 scoped_refptr<Layer> layer_;
1259 FakeContentLayerClient client_;
1260 CompletionEvent completion_;
1263 // An animation finishing during commit can only happen when we have a separate
1264 // compositor thread.
1265 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit);
1267 class LayerTreeHostAnimationTestNotifyAnimationFinished
1268 : public LayerTreeHostAnimationTest {
1269 public:
1270 LayerTreeHostAnimationTestNotifyAnimationFinished()
1271 : called_animation_started_(false), called_animation_finished_(false) {}
1273 void SetupTree() override {
1274 LayerTreeHostAnimationTest::SetupTree();
1275 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1276 picture_->SetBounds(gfx::Size(4, 4));
1277 picture_->set_layer_animation_delegate(this);
1278 layer_tree_host()->root_layer()->AddChild(picture_);
1281 void BeginTest() override {
1282 PostAddLongAnimationToMainThread(picture_.get());
1285 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1286 Animation::TargetProperty target_property,
1287 int group) override {
1288 called_animation_started_ = true;
1289 layer_tree_host()->AnimateLayers(
1290 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1291 PostSetNeedsCommitToMainThread();
1294 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1295 Animation::TargetProperty target_property,
1296 int group) override {
1297 called_animation_finished_ = true;
1298 EndTest();
1301 void AfterTest() override {
1302 EXPECT_TRUE(called_animation_started_);
1303 EXPECT_TRUE(called_animation_finished_);
1306 private:
1307 bool called_animation_started_;
1308 bool called_animation_finished_;
1309 FakeContentLayerClient client_;
1310 scoped_refptr<FakePictureLayer> picture_;
1313 SINGLE_AND_MULTI_THREAD_TEST_F(
1314 LayerTreeHostAnimationTestNotifyAnimationFinished);
1316 } // namespace
1317 } // namespace cc