Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobef27f16653ea24340991816b797242135b2970fc
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/base/completion_event.h"
12 #include "cc/base/time_util.h"
13 #include "cc/layers/layer.h"
14 #include "cc/layers/layer_impl.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_content_layer_client.h"
17 #include "cc/test/fake_picture_layer.h"
18 #include "cc/test/layer_tree_test.h"
19 #include "cc/trees/layer_tree_impl.h"
21 namespace cc {
22 namespace {
24 class LayerTreeHostAnimationTest : public LayerTreeTest {
25 public:
26 void SetupTree() override {
27 LayerTreeTest::SetupTree();
28 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
32 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
33 // be set.
34 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
35 : public LayerTreeHostAnimationTest {
36 public:
37 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
38 : num_commits_(0) {}
40 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
42 void BeginMainFrame(const BeginFrameArgs& args) override {
43 // We skip the first commit because its the commit that populates the
44 // impl thread with a tree. After the second commit, the test is done.
45 if (num_commits_ != 1)
46 return;
48 layer_tree_host()->SetNeedsAnimate();
49 // Right now, CommitRequested is going to be true, because during
50 // BeginFrame, we force CommitRequested to true to prevent requests from
51 // hitting the impl thread. But, when the next DidCommit happens, we should
52 // verify that CommitRequested has gone back to false.
55 void DidCommit() override {
56 if (!num_commits_) {
57 EXPECT_FALSE(layer_tree_host()->CommitRequested());
58 layer_tree_host()->SetNeedsAnimate();
59 EXPECT_FALSE(layer_tree_host()->CommitRequested());
62 // Verifies that the SetNeedsAnimate we made in ::Animate did not
63 // trigger CommitRequested.
64 EXPECT_FALSE(layer_tree_host()->CommitRequested());
65 EndTest();
66 num_commits_++;
69 void AfterTest() override {}
71 private:
72 int num_commits_;
75 MULTI_THREAD_TEST_F(
76 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
78 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
79 // callback, request another frame using SetNeedsAnimate. End the test when
80 // animate gets called yet-again, indicating that the proxy is correctly
81 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
82 // flow.
83 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
84 : public LayerTreeHostAnimationTest {
85 public:
86 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
87 : num_begin_frames_(0) {}
89 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
91 void BeginMainFrame(const BeginFrameArgs& args) override {
92 if (!num_begin_frames_) {
93 layer_tree_host()->SetNeedsAnimate();
94 num_begin_frames_++;
95 return;
97 EndTest();
100 void AfterTest() override {}
102 private:
103 int num_begin_frames_;
106 SINGLE_AND_MULTI_THREAD_TEST_F(
107 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
109 // Add a layer animation and confirm that
110 // LayerTreeHostImpl::UpdateAnimationState does get called.
111 class LayerTreeHostAnimationTestAddAnimation
112 : public LayerTreeHostAnimationTest {
113 public:
114 LayerTreeHostAnimationTestAddAnimation()
115 : update_animation_state_was_called_(false) {}
117 void BeginTest() override {
118 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
121 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
122 bool has_unfinished_animation) override {
123 EXPECT_FALSE(has_unfinished_animation);
124 update_animation_state_was_called_ = true;
127 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
128 Animation::TargetProperty target_property,
129 int group) override {
130 EXPECT_LT(base::TimeTicks(), monotonic_time);
132 LayerAnimationController* controller =
133 layer_tree_host()->root_layer()->layer_animation_controller();
134 Animation* animation = controller->GetAnimation(Animation::OPACITY);
135 if (animation)
136 controller->RemoveAnimation(animation->id());
138 EndTest();
141 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
143 private:
144 bool update_animation_state_was_called_;
147 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
149 // Add a layer animation to a layer, but continually fail to draw. Confirm that
150 // after a while, we do eventually force a draw.
151 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
152 : public LayerTreeHostAnimationTest {
153 public:
154 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
155 : started_animating_(false) {}
157 void BeginTest() override {
158 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
161 void AnimateLayers(LayerTreeHostImpl* host_impl,
162 base::TimeTicks monotonic_time) override {
163 started_animating_ = true;
166 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
167 if (started_animating_)
168 EndTest();
171 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
172 LayerTreeHostImpl::FrameData* frame,
173 DrawResult draw_result) override {
174 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
177 void AfterTest() override {}
179 private:
180 bool started_animating_;
183 // Starvation can only be an issue with the MT compositor.
184 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
186 // Ensures that animations eventually get deleted.
187 class LayerTreeHostAnimationTestAnimationsGetDeleted
188 : public LayerTreeHostAnimationTest {
189 public:
190 LayerTreeHostAnimationTestAnimationsGetDeleted()
191 : started_animating_(false) {}
193 void BeginTest() override {
194 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
197 void AnimateLayers(LayerTreeHostImpl* host_impl,
198 base::TimeTicks monotonic_time) override {
199 bool have_animations = !host_impl->animation_registrar()
200 ->active_animation_controllers_for_testing()
201 .empty();
202 if (!started_animating_ && have_animations) {
203 started_animating_ = true;
204 return;
207 if (started_animating_ && !have_animations)
208 EndTest();
211 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
212 Animation::TargetProperty target_property,
213 int group) override {
214 // Animations on the impl-side controller only get deleted during a commit,
215 // so we need to schedule a commit.
216 layer_tree_host()->SetNeedsCommit();
219 void AfterTest() override {}
221 private:
222 bool started_animating_;
225 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
227 // Ensure that an animation's timing function is respected.
228 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
229 : public LayerTreeHostAnimationTest {
230 public:
231 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
233 void SetupTree() override {
234 LayerTreeHostAnimationTest::SetupTree();
235 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
236 picture_->SetBounds(gfx::Size(4, 4));
237 layer_tree_host()->root_layer()->AddChild(picture_);
240 void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
242 void AnimateLayers(LayerTreeHostImpl* host_impl,
243 base::TimeTicks monotonic_time) override {
244 LayerAnimationController* controller_impl =
245 host_impl->active_tree()->root_layer()->children()[0]->
246 layer_animation_controller();
247 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
248 if (!animation)
249 return;
251 const FloatAnimationCurve* curve =
252 animation->curve()->ToFloatAnimationCurve();
253 float start_opacity = curve->GetValue(base::TimeDelta());
254 float end_opacity = curve->GetValue(curve->Duration());
255 float linearly_interpolated_opacity =
256 0.25f * end_opacity + 0.75f * start_opacity;
257 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
258 // If the linear timing function associated with this animation was not
259 // picked up, then the linearly interpolated opacity would be different
260 // because of the default ease timing function.
261 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
263 EndTest();
266 void AfterTest() override {}
268 FakeContentLayerClient client_;
269 scoped_refptr<FakePictureLayer> picture_;
272 SINGLE_AND_MULTI_THREAD_TEST_F(
273 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
275 // Ensures that main thread animations have their start times synchronized with
276 // impl thread animations.
277 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
278 : public LayerTreeHostAnimationTest {
279 public:
280 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
282 void SetupTree() override {
283 LayerTreeHostAnimationTest::SetupTree();
284 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
285 picture_->SetBounds(gfx::Size(4, 4));
286 picture_->set_layer_animation_delegate(this);
287 layer_tree_host()->root_layer()->AddChild(picture_);
290 void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
292 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
293 Animation::TargetProperty target_property,
294 int group) override {
295 LayerAnimationController* controller =
296 layer_tree_host()->root_layer()->children()[0]->
297 layer_animation_controller();
298 Animation* animation = controller->GetAnimation(Animation::OPACITY);
299 main_start_time_ = animation->start_time();
300 controller->RemoveAnimation(animation->id());
301 EndTest();
304 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
305 bool has_unfinished_animation) override {
306 LayerAnimationController* controller =
307 impl_host->active_tree()->root_layer()->children()[0]->
308 layer_animation_controller();
309 Animation* animation = controller->GetAnimation(Animation::OPACITY);
310 if (!animation)
311 return;
313 impl_start_time_ = animation->start_time();
316 void AfterTest() override {
317 EXPECT_EQ(impl_start_time_, main_start_time_);
318 EXPECT_LT(base::TimeTicks(), impl_start_time_);
321 private:
322 base::TimeTicks main_start_time_;
323 base::TimeTicks impl_start_time_;
324 FakeContentLayerClient client_;
325 scoped_refptr<FakePictureLayer> picture_;
328 SINGLE_AND_MULTI_THREAD_TEST_F(
329 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
331 // Ensures that notify animation finished is called.
332 class LayerTreeHostAnimationTestAnimationFinishedEvents
333 : public LayerTreeHostAnimationTest {
334 public:
335 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
337 void BeginTest() override {
338 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
341 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
342 Animation::TargetProperty target_property,
343 int group) override {
344 LayerAnimationController* controller =
345 layer_tree_host()->root_layer()->layer_animation_controller();
346 Animation* animation = controller->GetAnimation(Animation::OPACITY);
347 if (animation)
348 controller->RemoveAnimation(animation->id());
349 EndTest();
352 void AfterTest() override {}
355 SINGLE_AND_MULTI_THREAD_TEST_F(
356 LayerTreeHostAnimationTestAnimationFinishedEvents);
358 // Ensures that when opacity is being animated, this value does not cause the
359 // subtree to be skipped.
360 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
361 : public LayerTreeHostAnimationTest {
362 public:
363 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
364 : update_check_layer_(
365 FakePictureLayer::Create(layer_settings(), &client_)) {}
367 void SetupTree() override {
368 update_check_layer_->SetOpacity(0.f);
369 layer_tree_host()->SetRootLayer(update_check_layer_);
370 LayerTreeHostAnimationTest::SetupTree();
373 void BeginTest() override {
374 PostAddAnimationToMainThread(update_check_layer_.get());
377 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
378 LayerAnimationController* controller_impl =
379 host_impl->active_tree()->root_layer()->layer_animation_controller();
380 Animation* animation_impl =
381 controller_impl->GetAnimation(Animation::OPACITY);
382 controller_impl->RemoveAnimation(animation_impl->id());
383 EndTest();
386 void AfterTest() override {
387 // Update() should have been called once, proving that the layer was not
388 // skipped.
389 EXPECT_EQ(1, update_check_layer_->update_count());
391 // clear update_check_layer_ so LayerTreeHost dies.
392 update_check_layer_ = NULL;
395 private:
396 FakeContentLayerClient client_;
397 scoped_refptr<FakePictureLayer> update_check_layer_;
400 SINGLE_AND_MULTI_THREAD_TEST_F(
401 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
403 // Layers added to tree with existing active animations should have the
404 // animation correctly recognized.
405 class LayerTreeHostAnimationTestLayerAddedWithAnimation
406 : public LayerTreeHostAnimationTest {
407 public:
408 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
410 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
412 void DidCommit() override {
413 if (layer_tree_host()->source_frame_number() == 1) {
414 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
415 layer->set_layer_animation_delegate(this);
417 // Any valid AnimationCurve will do here.
418 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
419 scoped_ptr<Animation> animation(
420 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
421 layer->layer_animation_controller()->AddAnimation(animation.Pass());
423 // We add the animation *before* attaching the layer to the tree.
424 layer_tree_host()->root_layer()->AddChild(layer);
428 void AnimateLayers(LayerTreeHostImpl* impl_host,
429 base::TimeTicks monotonic_time) override {
430 EndTest();
433 void AfterTest() override {}
436 SINGLE_AND_MULTI_THREAD_TEST_F(
437 LayerTreeHostAnimationTestLayerAddedWithAnimation);
439 class LayerTreeHostAnimationTestCancelAnimateCommit
440 : public LayerTreeHostAnimationTest {
441 public:
442 LayerTreeHostAnimationTestCancelAnimateCommit()
443 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
445 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
447 void BeginMainFrame(const BeginFrameArgs& args) override {
448 num_begin_frames_++;
449 // No-op animate will cancel the commit.
450 if (layer_tree_host()->source_frame_number() == 1) {
451 EndTest();
452 return;
454 layer_tree_host()->SetNeedsAnimate();
457 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
458 num_commit_calls_++;
459 if (impl->active_tree()->source_frame_number() > 1)
460 FAIL() << "Commit should have been canceled.";
463 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
464 num_draw_calls_++;
465 if (impl->active_tree()->source_frame_number() > 1)
466 FAIL() << "Draw should have been canceled.";
469 void AfterTest() override {
470 EXPECT_EQ(2, num_begin_frames_);
471 EXPECT_EQ(1, num_commit_calls_);
472 EXPECT_EQ(1, num_draw_calls_);
475 private:
476 int num_begin_frames_;
477 int num_commit_calls_;
478 int num_draw_calls_;
481 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
483 class LayerTreeHostAnimationTestForceRedraw
484 : public LayerTreeHostAnimationTest {
485 public:
486 LayerTreeHostAnimationTestForceRedraw()
487 : num_animate_(0), num_draw_layers_(0) {}
489 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
491 void BeginMainFrame(const BeginFrameArgs& args) override {
492 if (++num_animate_ < 2)
493 layer_tree_host()->SetNeedsAnimate();
496 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); }
498 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
499 if (++num_draw_layers_ == 2)
500 EndTest();
503 void AfterTest() override {
504 // The first commit will always draw; make sure the second draw triggered
505 // by the animation was not cancelled.
506 EXPECT_EQ(2, num_draw_layers_);
507 EXPECT_EQ(2, num_animate_);
510 private:
511 int num_animate_;
512 int num_draw_layers_;
515 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
517 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
518 : public LayerTreeHostAnimationTest {
519 public:
520 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
521 : num_animate_(0), num_draw_layers_(0) {}
523 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
525 void BeginMainFrame(const BeginFrameArgs& args) override {
526 if (++num_animate_ <= 2) {
527 layer_tree_host()->SetNeedsCommit();
528 layer_tree_host()->SetNeedsAnimate();
532 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
533 if (++num_draw_layers_ == 2)
534 EndTest();
537 void AfterTest() override {
538 // The first commit will always draw; make sure the second draw triggered
539 // by the SetNeedsCommit was not cancelled.
540 EXPECT_EQ(2, num_draw_layers_);
541 EXPECT_GE(num_animate_, 2);
544 private:
545 int num_animate_;
546 int num_draw_layers_;
549 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
551 // Animations should not be started when frames are being skipped due to
552 // checkerboard.
553 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
554 : public LayerTreeHostAnimationTest {
555 void SetupTree() override {
556 LayerTreeHostAnimationTest::SetupTree();
557 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
558 picture_->SetBounds(gfx::Size(4, 4));
559 picture_->set_layer_animation_delegate(this);
560 layer_tree_host()->root_layer()->AddChild(picture_);
563 void InitializeSettings(LayerTreeSettings* settings) override {
564 // Make sure that drawing many times doesn't cause a checkerboarded
565 // animation to start so we avoid flake in this test.
566 settings->timeout_and_draw_when_animation_checkerboards = false;
569 void BeginTest() override {
570 prevented_draw_ = 0;
571 added_animations_ = 0;
572 started_times_ = 0;
574 PostSetNeedsCommitToMainThread();
577 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
578 LayerTreeHostImpl::FrameData* frame_data,
579 DrawResult draw_result) override {
580 if (added_animations_ < 2)
581 return draw_result;
582 if (TestEnded())
583 return draw_result;
584 // Act like there is checkerboard when the second animation wants to draw.
585 ++prevented_draw_;
586 if (prevented_draw_ > 2)
587 EndTest();
588 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
591 void DidCommitAndDrawFrame() override {
592 switch (layer_tree_host()->source_frame_number()) {
593 case 1:
594 // The animation is longer than 1 BeginFrame interval.
595 AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
596 added_animations_++;
597 break;
598 case 2:
599 // This second animation will not be drawn so it should not start.
600 AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
601 added_animations_++;
602 break;
606 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
607 Animation::TargetProperty target_property,
608 int group) override {
609 if (TestEnded())
610 return;
611 started_times_++;
614 void AfterTest() override {
615 // Make sure we tried to draw the second animation but failed.
616 EXPECT_LT(0, prevented_draw_);
617 // The first animation should be started, but the second should not because
618 // of checkerboard.
619 EXPECT_EQ(1, started_times_);
622 int prevented_draw_;
623 int added_animations_;
624 int started_times_;
625 FakeContentLayerClient client_;
626 scoped_refptr<FakePictureLayer> picture_;
629 MULTI_THREAD_TEST_F(
630 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
632 // Verifies that scroll offset animations are only accepted when impl-scrolling
633 // is supported, and that when scroll offset animations are accepted,
634 // scroll offset updates are sent back to the main thread.
635 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
636 : public LayerTreeHostAnimationTest {
637 public:
638 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
640 void SetupTree() override {
641 LayerTreeHostAnimationTest::SetupTree();
643 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
644 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
645 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
646 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
647 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
650 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
652 void DidCommit() override {
653 switch (layer_tree_host()->source_frame_number()) {
654 case 1: {
655 scoped_ptr<ScrollOffsetAnimationCurve> curve(
656 ScrollOffsetAnimationCurve::Create(
657 gfx::ScrollOffset(500.f, 550.f),
658 EaseInOutTimingFunction::Create()));
659 scoped_ptr<Animation> animation(
660 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
661 animation->set_needs_synchronized_start_time(true);
662 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
663 bool impl_scrolling_supported =
664 layer_tree_host()->proxy()->SupportsImplScrolling();
665 EXPECT_EQ(impl_scrolling_supported, animation_added);
666 if (!impl_scrolling_supported)
667 EndTest();
668 break;
670 default:
671 if (scroll_layer_->scroll_offset().x() > 10 &&
672 scroll_layer_->scroll_offset().y() > 20)
673 EndTest();
677 void AfterTest() override {}
679 private:
680 FakeContentLayerClient client_;
681 scoped_refptr<FakePictureLayer> scroll_layer_;
684 SINGLE_AND_MULTI_THREAD_TEST_F(
685 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
687 // Verifies that when the main thread removes a scroll animation and sets a new
688 // scroll position, the active tree takes on exactly this new scroll position
689 // after activation, and the main thread doesn't receive a spurious scroll
690 // delta.
691 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
692 : public LayerTreeHostAnimationTest {
693 public:
694 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
695 : final_postion_(50.0, 100.0) {}
697 void SetupTree() override {
698 LayerTreeHostAnimationTest::SetupTree();
700 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
701 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
702 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
703 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
704 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
706 scoped_ptr<ScrollOffsetAnimationCurve> curve(
707 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
708 EaseInOutTimingFunction::Create()));
709 scoped_ptr<Animation> animation(
710 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
711 animation->set_needs_synchronized_start_time(true);
712 scroll_layer_->AddAnimation(animation.Pass());
715 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
717 void BeginMainFrame(const BeginFrameArgs& args) override {
718 switch (layer_tree_host()->source_frame_number()) {
719 case 0:
720 break;
721 case 1: {
722 Animation* animation =
723 scroll_layer_->layer_animation_controller()->GetAnimation(
724 Animation::SCROLL_OFFSET);
725 scroll_layer_->layer_animation_controller()->RemoveAnimation(
726 animation->id());
727 scroll_layer_->SetScrollOffset(final_postion_);
728 break;
730 default:
731 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
735 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
736 host_impl->BlockNotifyReadyToActivateForTesting(true);
739 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
740 const BeginFrameArgs& args) override {
741 if (!host_impl->pending_tree())
742 return;
744 if (!host_impl->active_tree()->root_layer()) {
745 host_impl->BlockNotifyReadyToActivateForTesting(false);
746 return;
749 LayerImpl* scroll_layer_impl =
750 host_impl->active_tree()->root_layer()->children()[0];
751 Animation* animation =
752 scroll_layer_impl->layer_animation_controller()->GetAnimation(
753 Animation::SCROLL_OFFSET);
755 if (!animation || animation->run_state() != Animation::RUNNING) {
756 host_impl->BlockNotifyReadyToActivateForTesting(false);
757 return;
760 // Block activation until the running animation has a chance to produce a
761 // scroll delta.
762 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
763 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
764 return;
766 host_impl->BlockNotifyReadyToActivateForTesting(false);
769 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
770 if (host_impl->pending_tree()->source_frame_number() != 1)
771 return;
772 LayerImpl* scroll_layer_impl =
773 host_impl->pending_tree()->root_layer()->children()[0];
774 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
777 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
778 if (host_impl->active_tree()->source_frame_number() != 1)
779 return;
780 LayerImpl* scroll_layer_impl =
781 host_impl->active_tree()->root_layer()->children()[0];
782 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
783 EndTest();
786 void AfterTest() override {
787 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
790 private:
791 FakeContentLayerClient client_;
792 scoped_refptr<FakePictureLayer> scroll_layer_;
793 const gfx::ScrollOffset final_postion_;
796 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
798 // When animations are simultaneously added to an existing layer and to a new
799 // layer, they should start at the same time, even when there's already a
800 // running animation on the existing layer.
801 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
802 : public LayerTreeHostAnimationTest {
803 public:
804 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
805 : frame_count_with_pending_tree_(0) {}
807 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
809 void DidCommit() override {
810 if (layer_tree_host()->source_frame_number() == 1) {
811 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
812 } else if (layer_tree_host()->source_frame_number() == 2) {
813 AddOpacityTransitionToLayer(
814 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
816 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
817 layer_tree_host()->root_layer()->AddChild(layer);
818 layer->set_layer_animation_delegate(this);
819 layer->SetBounds(gfx::Size(4, 4));
820 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
824 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
825 host_impl->BlockNotifyReadyToActivateForTesting(true);
828 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
829 // For the commit that added animations to new and existing layers, keep
830 // blocking activation. We want to verify that even with activation blocked,
831 // the animation on the layer that's already in the active tree won't get a
832 // head start.
833 if (host_impl->pending_tree()->source_frame_number() != 2) {
834 host_impl->BlockNotifyReadyToActivateForTesting(false);
838 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
839 const BeginFrameArgs& args) override {
840 if (!host_impl->pending_tree() ||
841 host_impl->pending_tree()->source_frame_number() != 2)
842 return;
844 frame_count_with_pending_tree_++;
845 if (frame_count_with_pending_tree_ == 2) {
846 host_impl->BlockNotifyReadyToActivateForTesting(false);
850 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
851 bool has_unfinished_animation) override {
852 LayerAnimationController* root_controller_impl =
853 host_impl->active_tree()->root_layer()->layer_animation_controller();
854 Animation* root_animation =
855 root_controller_impl->GetAnimation(Animation::OPACITY);
856 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
857 return;
859 LayerAnimationController* child_controller_impl =
860 host_impl->active_tree()->root_layer()->children()
861 [0]->layer_animation_controller();
862 Animation* child_animation =
863 child_controller_impl->GetAnimation(Animation::OPACITY);
864 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
865 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
866 root_controller_impl->AbortAnimations(Animation::OPACITY);
867 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
868 child_controller_impl->AbortAnimations(Animation::OPACITY);
869 EndTest();
872 void AfterTest() override {}
874 private:
875 int frame_count_with_pending_tree_;
878 // This test blocks activation which is not supported for single thread mode.
879 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
880 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
882 // When a layer with an animation is removed from the tree and later re-added,
883 // the animation should resume.
884 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
885 : public LayerTreeHostAnimationTest {
886 public:
887 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
889 void SetupTree() override {
890 LayerTreeHostAnimationTest::SetupTree();
891 layer_ = Layer::Create(layer_settings());
892 layer_->SetBounds(gfx::Size(4, 4));
893 layer_tree_host()->root_layer()->AddChild(layer_);
894 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
897 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
899 void DidCommit() override {
900 switch (layer_tree_host()->source_frame_number()) {
901 case 1:
902 layer_->RemoveFromParent();
903 break;
904 case 2:
905 layer_tree_host()->root_layer()->AddChild(layer_);
906 break;
910 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
911 switch (host_impl->active_tree()->source_frame_number()) {
912 case 0:
913 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
914 break;
915 case 1:
916 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
917 break;
918 case 2:
919 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
920 EndTest();
921 break;
925 void AfterTest() override {}
927 private:
928 scoped_refptr<Layer> layer_;
931 SINGLE_AND_MULTI_THREAD_TEST_F(
932 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
934 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
935 : public LayerTreeHostAnimationTest {
936 public:
937 void SetupTree() override {
938 LayerTreeHostAnimationTest::SetupTree();
939 layer_ = Layer::Create(layer_settings());
940 layer_->SetBounds(gfx::Size(4, 4));
941 layer_tree_host()->root_layer()->AddChild(layer_);
944 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
946 void DidCommit() override {
947 switch (layer_tree_host()->source_frame_number()) {
948 case 1:
949 // First frame: add an animation to the root layer.
950 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
951 break;
952 case 2:
953 // Second frame: add an animation to the content layer. The root layer
954 // animation has caused us to animate already during this frame.
955 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
956 break;
960 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
961 // After both animations have started, verify that they have valid
962 // start times.
963 if (host_impl->active_tree()->source_frame_number() < 2)
964 return;
965 AnimationRegistrar::AnimationControllerMap controllers_copy =
966 host_impl->animation_registrar()
967 ->active_animation_controllers_for_testing();
968 EXPECT_EQ(2u, controllers_copy.size());
969 for (auto& it : controllers_copy) {
970 int id = it.first;
971 if (id == host_impl->RootLayer()->id()) {
972 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
973 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
974 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
975 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
976 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
978 EndTest();
982 void AfterTest() override {}
984 private:
985 scoped_refptr<Layer> layer_;
988 SINGLE_AND_MULTI_THREAD_TEST_F(
989 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
991 class LayerTreeHostAnimationTestRemoveAnimation
992 : public LayerTreeHostAnimationTest {
993 public:
994 void SetupTree() override {
995 LayerTreeHostAnimationTest::SetupTree();
996 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
997 layer_->SetBounds(gfx::Size(4, 4));
998 layer_tree_host()->root_layer()->AddChild(layer_);
1001 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1003 void DidCommit() override {
1004 switch (layer_tree_host()->source_frame_number()) {
1005 case 1:
1006 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1007 break;
1008 case 2:
1009 LayerAnimationController* controller =
1010 layer_->layer_animation_controller();
1011 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1012 controller->RemoveAnimation(animation->id());
1013 gfx::Transform transform;
1014 transform.Translate(10.f, 10.f);
1015 layer_->SetTransform(transform);
1017 // Do something that causes property trees to get rebuilt.
1018 layer_->AddChild(Layer::Create(layer_settings()));
1019 break;
1023 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1024 if (host_impl->active_tree()->source_frame_number() < 2)
1025 return;
1026 gfx::Transform expected_transform;
1027 expected_transform.Translate(10.f, 10.f);
1028 EXPECT_EQ(expected_transform, host_impl->active_tree()
1029 ->root_layer()
1030 ->children()[0]
1031 ->draw_transform());
1032 EndTest();
1035 void AfterTest() override {}
1037 private:
1038 scoped_refptr<Layer> layer_;
1039 FakeContentLayerClient client_;
1042 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation);
1044 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
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 if (layer_tree_host()->source_frame_number() == 1)
1058 AddAnimatedTransformToLayer(layer_.get(), 0.04, 5, 5);
1061 void WillCommit() override {
1062 if (layer_tree_host()->source_frame_number() == 2) {
1063 // Block until the animation finishes on the compositor thread. Since
1064 // animations have already been ticked on the main thread, when the commit
1065 // happens the state on the main thread will be consistent with having a
1066 // running animation but the state on the compositor thread will be
1067 // consistent with having only a finished animation.
1068 completion_.Wait();
1072 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1073 switch (host_impl->sync_tree()->source_frame_number()) {
1074 case 1:
1075 PostSetNeedsCommitToMainThread();
1076 break;
1077 case 2:
1078 gfx::Transform expected_transform;
1079 expected_transform.Translate(5.f, 5.f);
1080 LayerImpl* layer_impl =
1081 host_impl->sync_tree()->root_layer()->children()[0];
1082 EXPECT_EQ(expected_transform, layer_impl->draw_transform());
1083 EndTest();
1084 break;
1088 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1089 bool has_unfinished_animation) override {
1090 if (host_impl->active_tree()->source_frame_number() == 1 &&
1091 !has_unfinished_animation) {
1092 // The animation has finished, so allow the main thread to commit.
1093 completion_.Signal();
1097 void AfterTest() override {}
1099 private:
1100 scoped_refptr<Layer> layer_;
1101 FakeContentLayerClient client_;
1102 CompletionEvent completion_;
1105 // An animation finishing during commit can only happen when we have a separate
1106 // compositor thread.
1107 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit);
1109 class LayerTreeHostAnimationTestNotifyAnimationFinished
1110 : public LayerTreeHostAnimationTest {
1111 public:
1112 LayerTreeHostAnimationTestNotifyAnimationFinished()
1113 : called_animation_started_(false), called_animation_finished_(false) {}
1115 void SetupTree() override {
1116 LayerTreeHostAnimationTest::SetupTree();
1117 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1118 picture_->SetBounds(gfx::Size(4, 4));
1119 picture_->set_layer_animation_delegate(this);
1120 layer_tree_host()->root_layer()->AddChild(picture_);
1123 void BeginTest() override {
1124 PostAddLongAnimationToMainThread(picture_.get());
1127 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1128 Animation::TargetProperty target_property,
1129 int group) override {
1130 called_animation_started_ = true;
1131 layer_tree_host()->AnimateLayers(
1132 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1133 PostSetNeedsCommitToMainThread();
1136 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1137 Animation::TargetProperty target_property,
1138 int group) override {
1139 called_animation_finished_ = true;
1140 EndTest();
1143 void AfterTest() override {
1144 EXPECT_TRUE(called_animation_started_);
1145 EXPECT_TRUE(called_animation_finished_);
1148 private:
1149 bool called_animation_started_;
1150 bool called_animation_finished_;
1151 FakeContentLayerClient client_;
1152 scoped_refptr<FakePictureLayer> picture_;
1155 SINGLE_AND_MULTI_THREAD_TEST_F(
1156 LayerTreeHostAnimationTestNotifyAnimationFinished);
1158 } // namespace
1159 } // namespace cc