Vectorize website settings icons in omnibox
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobb41005a464932f10456c74a3270c2e15285d568b
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;
907 LayerImpl* root = host_impl->sync_tree()->root_layer();
908 LayerImpl* child = root->children()[0];
909 LayerAnimationController* controller_impl =
910 child->layer_animation_controller();
911 Animation* animation = controller_impl->GetAnimation(Animation::TRANSFORM);
913 // The animation should be starting for the first frame.
914 EXPECT_EQ(Animation::STARTING, animation->run_state());
916 // And the transform should be propogated to the sync tree layer, at its
917 // starting state which is 6,7.
918 gfx::Transform expected_transform;
919 expected_transform.Translate(6.0, 7.0);
920 EXPECT_EQ(expected_transform, child->draw_transform());
921 // And the sync tree layer should know it is animating.
922 EXPECT_TRUE(child->screen_space_transform_is_animating());
924 controller_impl->AbortAnimations(Animation::TRANSFORM);
925 EndTest();
928 void AfterTest() override {}
930 FakeContentLayerClient client_;
931 scoped_refptr<Layer> layer_;
934 SINGLE_AND_MULTI_THREAD_TEST_F(
935 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit);
937 // When a layer with an animation is removed from the tree and later re-added,
938 // the animation should resume.
939 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
940 : public LayerTreeHostAnimationTest {
941 public:
942 void SetupTree() override {
943 LayerTreeHostAnimationTest::SetupTree();
944 layer_ = Layer::Create(layer_settings());
945 layer_->SetBounds(gfx::Size(4, 4));
946 layer_tree_host()->root_layer()->AddChild(layer_);
947 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
950 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
952 void DidCommit() override {
953 switch (layer_tree_host()->source_frame_number()) {
954 case 1:
955 layer_->RemoveFromParent();
956 break;
957 case 2:
958 layer_tree_host()->root_layer()->AddChild(layer_);
959 break;
963 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
964 switch (host_impl->active_tree()->source_frame_number()) {
965 case 0:
966 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
967 break;
968 case 1:
969 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
970 break;
971 case 2:
972 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
973 EndTest();
974 break;
978 void AfterTest() override {}
980 private:
981 scoped_refptr<Layer> layer_;
984 SINGLE_AND_MULTI_THREAD_TEST_F(
985 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
987 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
988 : public LayerTreeHostAnimationTest {
989 public:
990 void SetupTree() override {
991 LayerTreeHostAnimationTest::SetupTree();
992 layer_ = Layer::Create(layer_settings());
993 layer_->SetBounds(gfx::Size(4, 4));
994 layer_tree_host()->root_layer()->AddChild(layer_);
997 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
999 void DidCommit() override {
1000 switch (layer_tree_host()->source_frame_number()) {
1001 case 1:
1002 // First frame: add an animation to the root layer.
1003 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1004 break;
1005 case 2:
1006 // Second frame: add an animation to the content layer. The root layer
1007 // animation has caused us to animate already during this frame.
1008 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
1009 break;
1013 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1014 // After both animations have started, verify that they have valid
1015 // start times.
1016 if (host_impl->active_tree()->source_frame_number() < 2)
1017 return;
1018 AnimationRegistrar::AnimationControllerMap controllers_copy =
1019 host_impl->animation_registrar()
1020 ->active_animation_controllers_for_testing();
1021 EXPECT_EQ(2u, controllers_copy.size());
1022 for (auto& it : controllers_copy) {
1023 int id = it.first;
1024 if (id == host_impl->RootLayer()->id()) {
1025 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
1026 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1027 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1028 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
1029 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1031 EndTest();
1035 void AfterTest() override {}
1037 private:
1038 scoped_refptr<Layer> layer_;
1041 SINGLE_AND_MULTI_THREAD_TEST_F(
1042 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1044 class LayerTreeHostAnimationTestRemoveAnimation
1045 : public LayerTreeHostAnimationTest {
1046 public:
1047 void SetupTree() override {
1048 LayerTreeHostAnimationTest::SetupTree();
1049 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1050 layer_->SetBounds(gfx::Size(4, 4));
1051 layer_tree_host()->root_layer()->AddChild(layer_);
1054 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1056 void DidCommit() override {
1057 switch (layer_tree_host()->source_frame_number()) {
1058 case 1:
1059 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1060 break;
1061 case 2:
1062 LayerAnimationController* controller =
1063 layer_->layer_animation_controller();
1064 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1065 layer_->RemoveAnimation(animation->id());
1066 gfx::Transform transform;
1067 transform.Translate(10.f, 10.f);
1068 layer_->SetTransform(transform);
1070 // Do something that causes property trees to get rebuilt. This is
1071 // intended to simulate the conditions that caused the bug whose fix
1072 // this is testing (the test will pass without it but won't test what
1073 // we want it to). We were updating the wrong transform node at the end
1074 // of an animation (we were assuming the layer with the finished
1075 // animation still had its own transform node). But nodes can only get
1076 // added/deleted when something triggers a rebuild. Adding a layer
1077 // triggers a rebuild, and since the layer that had an animation before
1078 // no longer has one, it doesn't get a transform node in the rebuild.
1079 layer_->AddChild(Layer::Create(layer_settings()));
1080 break;
1084 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1085 LayerImpl* root = host_impl->active_tree()->root_layer();
1086 LayerImpl* child = root->children()[0];
1087 switch (host_impl->active_tree()->source_frame_number()) {
1088 case 0:
1089 // No animation yet.
1090 break;
1091 case 1:
1092 // Animation is started.
1093 EXPECT_TRUE(child->screen_space_transform_is_animating());
1094 break;
1095 case 2: {
1096 // The animation is removed, the transform that was set afterward is
1097 // applied.
1098 gfx::Transform expected_transform;
1099 expected_transform.Translate(10.f, 10.f);
1100 EXPECT_EQ(expected_transform, child->draw_transform());
1101 EXPECT_FALSE(child->screen_space_transform_is_animating());
1102 EndTest();
1103 break;
1105 default:
1106 NOTREACHED();
1110 void AfterTest() override {}
1112 private:
1113 scoped_refptr<Layer> layer_;
1114 FakeContentLayerClient client_;
1117 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation);
1119 class LayerTreeHostAnimationTestIsAnimating
1120 : public LayerTreeHostAnimationTest {
1121 public:
1122 void SetupTree() override {
1123 LayerTreeHostAnimationTest::SetupTree();
1124 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1125 layer_->SetBounds(gfx::Size(4, 4));
1126 layer_tree_host()->root_layer()->AddChild(layer_);
1129 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1131 void DidCommit() override {
1132 switch (layer_tree_host()->source_frame_number()) {
1133 case 1:
1134 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1135 break;
1136 case 2:
1137 LayerAnimationController* controller =
1138 layer_->layer_animation_controller();
1139 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1140 layer_->RemoveAnimation(animation->id());
1141 break;
1145 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1146 LayerImpl* root = host_impl->sync_tree()->root_layer();
1147 LayerImpl* child = root->children()[0];
1148 switch (host_impl->sync_tree()->source_frame_number()) {
1149 case 0:
1150 // No animation yet.
1151 break;
1152 case 1:
1153 // Animation is started.
1154 EXPECT_TRUE(child->screen_space_transform_is_animating());
1155 break;
1156 case 2:
1157 // The animation is removed/stopped.
1158 EXPECT_FALSE(child->screen_space_transform_is_animating());
1159 EndTest();
1160 break;
1161 default:
1162 NOTREACHED();
1166 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1167 LayerImpl* root = host_impl->active_tree()->root_layer();
1168 LayerImpl* child = root->children()[0];
1169 switch (host_impl->active_tree()->source_frame_number()) {
1170 case 0:
1171 // No animation yet.
1172 break;
1173 case 1:
1174 // Animation is started.
1175 EXPECT_TRUE(child->screen_space_transform_is_animating());
1176 break;
1177 case 2:
1178 // The animation is removed/stopped.
1179 EXPECT_FALSE(child->screen_space_transform_is_animating());
1180 EndTest();
1181 break;
1182 default:
1183 NOTREACHED();
1187 void AfterTest() override {}
1189 private:
1190 scoped_refptr<Layer> layer_;
1191 FakeContentLayerClient client_;
1194 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating);
1196 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1197 : public LayerTreeHostAnimationTest {
1198 public:
1199 void SetupTree() override {
1200 LayerTreeHostAnimationTest::SetupTree();
1201 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1202 layer_->SetBounds(gfx::Size(4, 4));
1203 layer_tree_host()->root_layer()->AddChild(layer_);
1206 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1208 void DidCommit() override {
1209 if (layer_tree_host()->source_frame_number() == 1)
1210 AddAnimatedTransformToLayer(layer_.get(), 0.04, 5, 5);
1213 void WillCommit() override {
1214 if (layer_tree_host()->source_frame_number() == 2) {
1215 // Block until the animation finishes on the compositor thread. Since
1216 // animations have already been ticked on the main thread, when the commit
1217 // happens the state on the main thread will be consistent with having a
1218 // running animation but the state on the compositor thread will be
1219 // consistent with having only a finished animation.
1220 completion_.Wait();
1224 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1225 switch (host_impl->sync_tree()->source_frame_number()) {
1226 case 1:
1227 PostSetNeedsCommitToMainThread();
1228 break;
1229 case 2:
1230 gfx::Transform expected_transform;
1231 expected_transform.Translate(5.f, 5.f);
1232 LayerImpl* layer_impl =
1233 host_impl->sync_tree()->root_layer()->children()[0];
1234 EXPECT_EQ(expected_transform, layer_impl->draw_transform());
1235 EndTest();
1236 break;
1240 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1241 bool has_unfinished_animation) override {
1242 if (host_impl->active_tree()->source_frame_number() == 1 &&
1243 !has_unfinished_animation) {
1244 // The animation has finished, so allow the main thread to commit.
1245 completion_.Signal();
1249 void AfterTest() override {}
1251 private:
1252 scoped_refptr<Layer> layer_;
1253 FakeContentLayerClient client_;
1254 CompletionEvent completion_;
1257 // An animation finishing during commit can only happen when we have a separate
1258 // compositor thread.
1259 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit);
1261 class LayerTreeHostAnimationTestNotifyAnimationFinished
1262 : public LayerTreeHostAnimationTest {
1263 public:
1264 LayerTreeHostAnimationTestNotifyAnimationFinished()
1265 : called_animation_started_(false), called_animation_finished_(false) {}
1267 void SetupTree() override {
1268 LayerTreeHostAnimationTest::SetupTree();
1269 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1270 picture_->SetBounds(gfx::Size(4, 4));
1271 picture_->set_layer_animation_delegate(this);
1272 layer_tree_host()->root_layer()->AddChild(picture_);
1275 void BeginTest() override {
1276 PostAddLongAnimationToMainThread(picture_.get());
1279 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1280 Animation::TargetProperty target_property,
1281 int group) override {
1282 called_animation_started_ = true;
1283 layer_tree_host()->AnimateLayers(
1284 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1285 PostSetNeedsCommitToMainThread();
1288 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1289 Animation::TargetProperty target_property,
1290 int group) override {
1291 called_animation_finished_ = true;
1292 EndTest();
1295 void AfterTest() override {
1296 EXPECT_TRUE(called_animation_started_);
1297 EXPECT_TRUE(called_animation_finished_);
1300 private:
1301 bool called_animation_started_;
1302 bool called_animation_finished_;
1303 FakeContentLayerClient client_;
1304 scoped_refptr<FakePictureLayer> picture_;
1307 SINGLE_AND_MULTI_THREAD_TEST_F(
1308 LayerTreeHostAnimationTestNotifyAnimationFinished);
1310 } // namespace
1311 } // namespace cc