Roll src/third_party/skia d32087a:1052f51
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobc9f922020b21f65f3da0355b5b44e5841710c3f2
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 started_times_ = 0;
570 PostSetNeedsCommitToMainThread();
573 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
574 LayerTreeHostImpl::FrameData* frame_data,
575 DrawResult draw_result) override {
576 // Don't checkerboard when the first animation wants to start.
577 if (host_impl->active_tree()->source_frame_number() < 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 break;
594 case 2:
595 // This second animation will not be drawn so it should not start.
596 AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
597 break;
601 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
602 Animation::TargetProperty target_property,
603 int group) override {
604 if (TestEnded())
605 return;
606 started_times_++;
609 void AfterTest() override {
610 // Make sure we tried to draw the second animation but failed.
611 EXPECT_LT(0, prevented_draw_);
612 // The first animation should be started, but the second should not because
613 // of checkerboard.
614 EXPECT_EQ(1, started_times_);
617 int prevented_draw_;
618 int started_times_;
619 FakeContentLayerClient client_;
620 scoped_refptr<FakePictureLayer> picture_;
623 MULTI_THREAD_TEST_F(
624 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
626 // Verifies that scroll offset animations are only accepted when impl-scrolling
627 // is supported, and that when scroll offset animations are accepted,
628 // scroll offset updates are sent back to the main thread.
629 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
630 : public LayerTreeHostAnimationTest {
631 public:
632 void SetupTree() override {
633 LayerTreeHostAnimationTest::SetupTree();
635 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
636 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
637 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
638 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
639 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
642 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
644 void DidCommit() override {
645 switch (layer_tree_host()->source_frame_number()) {
646 case 1: {
647 scoped_ptr<ScrollOffsetAnimationCurve> curve(
648 ScrollOffsetAnimationCurve::Create(
649 gfx::ScrollOffset(500.f, 550.f),
650 EaseInOutTimingFunction::Create()));
651 scoped_ptr<Animation> animation(
652 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
653 animation->set_needs_synchronized_start_time(true);
654 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
655 bool impl_scrolling_supported =
656 layer_tree_host()->proxy()->SupportsImplScrolling();
657 EXPECT_EQ(impl_scrolling_supported, animation_added);
658 if (!impl_scrolling_supported)
659 EndTest();
660 break;
662 default:
663 if (scroll_layer_->scroll_offset().x() > 10 &&
664 scroll_layer_->scroll_offset().y() > 20)
665 EndTest();
669 void AfterTest() override {}
671 private:
672 FakeContentLayerClient client_;
673 scoped_refptr<FakePictureLayer> scroll_layer_;
676 SINGLE_AND_MULTI_THREAD_TEST_F(
677 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
679 // Verifies that when the main thread removes a scroll animation and sets a new
680 // scroll position, the active tree takes on exactly this new scroll position
681 // after activation, and the main thread doesn't receive a spurious scroll
682 // delta.
683 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
684 : public LayerTreeHostAnimationTest {
685 public:
686 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
687 : final_postion_(50.0, 100.0) {}
689 void SetupTree() override {
690 LayerTreeHostAnimationTest::SetupTree();
692 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
693 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
694 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
695 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
696 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
698 scoped_ptr<ScrollOffsetAnimationCurve> curve(
699 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
700 EaseInOutTimingFunction::Create()));
701 scoped_ptr<Animation> animation(
702 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
703 animation->set_needs_synchronized_start_time(true);
704 scroll_layer_->AddAnimation(animation.Pass());
707 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
709 void BeginMainFrame(const BeginFrameArgs& args) override {
710 switch (layer_tree_host()->source_frame_number()) {
711 case 0:
712 break;
713 case 1: {
714 Animation* animation =
715 scroll_layer_->layer_animation_controller()->GetAnimation(
716 Animation::SCROLL_OFFSET);
717 scroll_layer_->layer_animation_controller()->RemoveAnimation(
718 animation->id());
719 scroll_layer_->SetScrollOffset(final_postion_);
720 break;
722 default:
723 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
727 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
728 host_impl->BlockNotifyReadyToActivateForTesting(true);
731 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
732 const BeginFrameArgs& args) override {
733 if (!host_impl->pending_tree())
734 return;
736 if (!host_impl->active_tree()->root_layer()) {
737 host_impl->BlockNotifyReadyToActivateForTesting(false);
738 return;
741 LayerImpl* scroll_layer_impl =
742 host_impl->active_tree()->root_layer()->children()[0];
743 Animation* animation =
744 scroll_layer_impl->layer_animation_controller()->GetAnimation(
745 Animation::SCROLL_OFFSET);
747 if (!animation || animation->run_state() != Animation::RUNNING) {
748 host_impl->BlockNotifyReadyToActivateForTesting(false);
749 return;
752 // Block activation until the running animation has a chance to produce a
753 // scroll delta.
754 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
755 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
756 return;
758 host_impl->BlockNotifyReadyToActivateForTesting(false);
761 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
762 if (host_impl->pending_tree()->source_frame_number() != 1)
763 return;
764 LayerImpl* scroll_layer_impl =
765 host_impl->pending_tree()->root_layer()->children()[0];
766 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
769 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
770 if (host_impl->active_tree()->source_frame_number() != 1)
771 return;
772 LayerImpl* scroll_layer_impl =
773 host_impl->active_tree()->root_layer()->children()[0];
774 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
775 EndTest();
778 void AfterTest() override {
779 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
782 private:
783 FakeContentLayerClient client_;
784 scoped_refptr<FakePictureLayer> scroll_layer_;
785 const gfx::ScrollOffset final_postion_;
788 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
790 // When animations are simultaneously added to an existing layer and to a new
791 // layer, they should start at the same time, even when there's already a
792 // running animation on the existing layer.
793 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
794 : public LayerTreeHostAnimationTest {
795 public:
796 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
797 : frame_count_with_pending_tree_(0) {}
799 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
801 void DidCommit() override {
802 if (layer_tree_host()->source_frame_number() == 1) {
803 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
804 } else if (layer_tree_host()->source_frame_number() == 2) {
805 AddOpacityTransitionToLayer(
806 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
808 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
809 layer_tree_host()->root_layer()->AddChild(layer);
810 layer->set_layer_animation_delegate(this);
811 layer->SetBounds(gfx::Size(4, 4));
812 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
816 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
817 host_impl->BlockNotifyReadyToActivateForTesting(true);
820 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
821 // For the commit that added animations to new and existing layers, keep
822 // blocking activation. We want to verify that even with activation blocked,
823 // the animation on the layer that's already in the active tree won't get a
824 // head start.
825 if (host_impl->pending_tree()->source_frame_number() != 2) {
826 host_impl->BlockNotifyReadyToActivateForTesting(false);
830 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
831 const BeginFrameArgs& args) override {
832 if (!host_impl->pending_tree() ||
833 host_impl->pending_tree()->source_frame_number() != 2)
834 return;
836 frame_count_with_pending_tree_++;
837 if (frame_count_with_pending_tree_ == 2) {
838 host_impl->BlockNotifyReadyToActivateForTesting(false);
842 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
843 bool has_unfinished_animation) override {
844 LayerAnimationController* root_controller_impl =
845 host_impl->active_tree()->root_layer()->layer_animation_controller();
846 Animation* root_animation =
847 root_controller_impl->GetAnimation(Animation::OPACITY);
848 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
849 return;
851 LayerAnimationController* child_controller_impl =
852 host_impl->active_tree()->root_layer()->children()
853 [0]->layer_animation_controller();
854 Animation* child_animation =
855 child_controller_impl->GetAnimation(Animation::OPACITY);
856 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
857 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
858 root_controller_impl->AbortAnimations(Animation::OPACITY);
859 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
860 child_controller_impl->AbortAnimations(Animation::OPACITY);
861 EndTest();
864 void AfterTest() override {}
866 private:
867 int frame_count_with_pending_tree_;
870 // This test blocks activation which is not supported for single thread mode.
871 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
872 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
874 class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit
875 : public LayerTreeHostAnimationTest {
876 public:
877 void SetupTree() override {
878 LayerTreeHostAnimationTest::SetupTree();
880 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
881 layer_->SetBounds(gfx::Size(2, 2));
882 // Transform the layer to 4,4 to start.
883 gfx::Transform start_transform;
884 start_transform.Translate(4.0, 4.0);
885 layer_->SetTransform(start_transform);
887 layer_tree_host()->root_layer()->AddChild(layer_);
890 void BeginTest() override {
891 // Add a translate from 6,7 to 8,9.
892 TransformOperations start;
893 start.AppendTranslate(6.f, 7.f, 0.f);
894 TransformOperations end;
895 end.AppendTranslate(8.f, 9.f, 0.f);
896 AddAnimatedTransformToLayer(layer_.get(), 4.0, start, end);
898 PostSetNeedsCommitToMainThread();
901 void WillPrepareTiles(LayerTreeHostImpl* host_impl) override {
902 if (host_impl->sync_tree()->source_frame_number() != 0)
903 return;
905 // After checking this on the sync tree, we will activate, which will cause
906 // PrepareTiles to happen again (which races with the test exiting).
907 if (TestEnded())
908 return;
910 LayerImpl* root = host_impl->sync_tree()->root_layer();
911 LayerImpl* child = root->children()[0];
912 LayerAnimationController* controller_impl =
913 child->layer_animation_controller();
914 Animation* animation = controller_impl->GetAnimation(Animation::TRANSFORM);
916 // The animation should be starting for the first frame.
917 EXPECT_EQ(Animation::STARTING, animation->run_state());
919 // And the transform should be propogated to the sync tree layer, at its
920 // starting state which is 6,7.
921 gfx::Transform expected_transform;
922 expected_transform.Translate(6.0, 7.0);
923 EXPECT_EQ(expected_transform, child->draw_transform());
924 // And the sync tree layer should know it is animating.
925 EXPECT_TRUE(child->screen_space_transform_is_animating());
927 controller_impl->AbortAnimations(Animation::TRANSFORM);
928 EndTest();
931 void AfterTest() override {}
933 FakeContentLayerClient client_;
934 scoped_refptr<Layer> layer_;
937 SINGLE_AND_MULTI_THREAD_TEST_F(
938 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit);
940 // When a layer with an animation is removed from the tree and later re-added,
941 // the animation should resume.
942 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
943 : public LayerTreeHostAnimationTest {
944 public:
945 void SetupTree() override {
946 LayerTreeHostAnimationTest::SetupTree();
947 layer_ = Layer::Create(layer_settings());
948 layer_->SetBounds(gfx::Size(4, 4));
949 layer_tree_host()->root_layer()->AddChild(layer_);
950 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
953 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
955 void DidCommit() override {
956 switch (layer_tree_host()->source_frame_number()) {
957 case 1:
958 layer_->RemoveFromParent();
959 break;
960 case 2:
961 layer_tree_host()->root_layer()->AddChild(layer_);
962 break;
966 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
967 switch (host_impl->active_tree()->source_frame_number()) {
968 case 0:
969 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
970 break;
971 case 1:
972 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
973 break;
974 case 2:
975 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
976 EndTest();
977 break;
981 void AfterTest() override {}
983 private:
984 scoped_refptr<Layer> layer_;
987 SINGLE_AND_MULTI_THREAD_TEST_F(
988 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
990 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
991 : public LayerTreeHostAnimationTest {
992 public:
993 void SetupTree() override {
994 LayerTreeHostAnimationTest::SetupTree();
995 layer_ = Layer::Create(layer_settings());
996 layer_->SetBounds(gfx::Size(4, 4));
997 layer_tree_host()->root_layer()->AddChild(layer_);
1000 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1002 void DidCommit() override {
1003 switch (layer_tree_host()->source_frame_number()) {
1004 case 1:
1005 // First frame: add an animation to the root layer.
1006 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1007 break;
1008 case 2:
1009 // Second frame: add an animation to the content layer. The root layer
1010 // animation has caused us to animate already during this frame.
1011 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
1012 break;
1016 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1017 // After both animations have started, verify that they have valid
1018 // start times.
1019 if (host_impl->active_tree()->source_frame_number() < 2)
1020 return;
1021 AnimationRegistrar::AnimationControllerMap controllers_copy =
1022 host_impl->animation_registrar()
1023 ->active_animation_controllers_for_testing();
1024 EXPECT_EQ(2u, controllers_copy.size());
1025 for (auto& it : controllers_copy) {
1026 int id = it.first;
1027 if (id == host_impl->RootLayer()->id()) {
1028 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
1029 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1030 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1031 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
1032 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1034 EndTest();
1038 void AfterTest() override {}
1040 private:
1041 scoped_refptr<Layer> layer_;
1044 SINGLE_AND_MULTI_THREAD_TEST_F(
1045 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1047 class LayerTreeHostAnimationTestRemoveAnimation
1048 : public LayerTreeHostAnimationTest {
1049 public:
1050 void SetupTree() override {
1051 LayerTreeHostAnimationTest::SetupTree();
1052 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1053 layer_->SetBounds(gfx::Size(4, 4));
1054 layer_tree_host()->root_layer()->AddChild(layer_);
1057 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1059 void DidCommit() override {
1060 switch (layer_tree_host()->source_frame_number()) {
1061 case 1:
1062 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1063 break;
1064 case 2:
1065 LayerAnimationController* controller =
1066 layer_->layer_animation_controller();
1067 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1068 layer_->RemoveAnimation(animation->id());
1069 gfx::Transform transform;
1070 transform.Translate(10.f, 10.f);
1071 layer_->SetTransform(transform);
1073 // Do something that causes property trees to get rebuilt. This is
1074 // intended to simulate the conditions that caused the bug whose fix
1075 // this is testing (the test will pass without it but won't test what
1076 // we want it to). We were updating the wrong transform node at the end
1077 // of an animation (we were assuming the layer with the finished
1078 // animation still had its own transform node). But nodes can only get
1079 // added/deleted when something triggers a rebuild. Adding a layer
1080 // triggers a rebuild, and since the layer that had an animation before
1081 // no longer has one, it doesn't get a transform node in the rebuild.
1082 layer_->AddChild(Layer::Create(layer_settings()));
1083 break;
1087 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1088 LayerImpl* root = host_impl->active_tree()->root_layer();
1089 LayerImpl* child = root->children()[0];
1090 switch (host_impl->active_tree()->source_frame_number()) {
1091 case 0:
1092 // No animation yet.
1093 break;
1094 case 1:
1095 // Animation is started.
1096 EXPECT_TRUE(child->screen_space_transform_is_animating());
1097 break;
1098 case 2: {
1099 // The animation is removed, the transform that was set afterward is
1100 // applied.
1101 gfx::Transform expected_transform;
1102 expected_transform.Translate(10.f, 10.f);
1103 EXPECT_EQ(expected_transform, child->draw_transform());
1104 EXPECT_FALSE(child->screen_space_transform_is_animating());
1105 EndTest();
1106 break;
1108 default:
1109 NOTREACHED();
1113 void AfterTest() override {}
1115 private:
1116 scoped_refptr<Layer> layer_;
1117 FakeContentLayerClient client_;
1120 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation);
1122 class LayerTreeHostAnimationTestIsAnimating
1123 : public LayerTreeHostAnimationTest {
1124 public:
1125 void SetupTree() override {
1126 LayerTreeHostAnimationTest::SetupTree();
1127 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1128 layer_->SetBounds(gfx::Size(4, 4));
1129 layer_tree_host()->root_layer()->AddChild(layer_);
1132 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1134 void DidCommit() override {
1135 switch (layer_tree_host()->source_frame_number()) {
1136 case 1:
1137 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1138 break;
1139 case 2:
1140 LayerAnimationController* controller =
1141 layer_->layer_animation_controller();
1142 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1143 layer_->RemoveAnimation(animation->id());
1144 break;
1148 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1149 LayerImpl* root = host_impl->sync_tree()->root_layer();
1150 LayerImpl* child = root->children()[0];
1151 switch (host_impl->sync_tree()->source_frame_number()) {
1152 case 0:
1153 // No animation yet.
1154 break;
1155 case 1:
1156 // Animation is started.
1157 EXPECT_TRUE(child->screen_space_transform_is_animating());
1158 break;
1159 case 2:
1160 // The animation is removed/stopped.
1161 EXPECT_FALSE(child->screen_space_transform_is_animating());
1162 EndTest();
1163 break;
1164 default:
1165 NOTREACHED();
1169 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1170 LayerImpl* root = host_impl->active_tree()->root_layer();
1171 LayerImpl* child = root->children()[0];
1172 switch (host_impl->active_tree()->source_frame_number()) {
1173 case 0:
1174 // No animation yet.
1175 break;
1176 case 1:
1177 // Animation is started.
1178 EXPECT_TRUE(child->screen_space_transform_is_animating());
1179 break;
1180 case 2:
1181 // The animation is removed/stopped.
1182 EXPECT_FALSE(child->screen_space_transform_is_animating());
1183 EndTest();
1184 break;
1185 default:
1186 NOTREACHED();
1190 void AfterTest() override {}
1192 private:
1193 scoped_refptr<Layer> layer_;
1194 FakeContentLayerClient client_;
1197 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating);
1199 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1200 : public LayerTreeHostAnimationTest {
1201 public:
1202 LayerTreeHostAnimationTestAnimationFinishesDuringCommit()
1203 : signalled_(false) {}
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 && !signalled_) {
1250 // The animation has finished, so allow the main thread to commit.
1251 completion_.Signal();
1252 signalled_ = true;
1256 void AfterTest() override {}
1258 private:
1259 scoped_refptr<Layer> layer_;
1260 FakeContentLayerClient client_;
1261 CompletionEvent completion_;
1262 bool signalled_;
1265 // An animation finishing during commit can only happen when we have a separate
1266 // compositor thread.
1267 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit);
1269 class LayerTreeHostAnimationTestNotifyAnimationFinished
1270 : public LayerTreeHostAnimationTest {
1271 public:
1272 LayerTreeHostAnimationTestNotifyAnimationFinished()
1273 : called_animation_started_(false), called_animation_finished_(false) {}
1275 void SetupTree() override {
1276 LayerTreeHostAnimationTest::SetupTree();
1277 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1278 picture_->SetBounds(gfx::Size(4, 4));
1279 picture_->set_layer_animation_delegate(this);
1280 layer_tree_host()->root_layer()->AddChild(picture_);
1283 void BeginTest() override {
1284 PostAddLongAnimationToMainThread(picture_.get());
1287 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1288 Animation::TargetProperty target_property,
1289 int group) override {
1290 called_animation_started_ = true;
1291 layer_tree_host()->AnimateLayers(
1292 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1293 PostSetNeedsCommitToMainThread();
1296 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1297 Animation::TargetProperty target_property,
1298 int group) override {
1299 called_animation_finished_ = true;
1300 EndTest();
1303 void AfterTest() override {
1304 EXPECT_TRUE(called_animation_started_);
1305 EXPECT_TRUE(called_animation_finished_);
1308 private:
1309 bool called_animation_started_;
1310 bool called_animation_finished_;
1311 FakeContentLayerClient client_;
1312 scoped_refptr<FakePictureLayer> picture_;
1315 SINGLE_AND_MULTI_THREAD_TEST_F(
1316 LayerTreeHostAnimationTestNotifyAnimationFinished);
1318 } // namespace
1319 } // namespace cc