Reland of Add channel-specific product logo to chrome://help (patchset #1 id:1 of...
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blob72f10730a84032b8b659fa400c7cc6dff5fad29e
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 // Make sure the main thread can still execute animations when CanDraw() is not
552 // true.
553 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
554 : public LayerTreeHostAnimationTest {
555 public:
556 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
558 void SetupTree() override {
559 LayerTreeHostAnimationTest::SetupTree();
560 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
561 picture_->SetBounds(gfx::Size(4, 4));
562 picture_->set_layer_animation_delegate(this);
563 layer_tree_host()->root_layer()->AddChild(picture_);
566 void BeginTest() override {
567 layer_tree_host()->SetViewportSize(gfx::Size());
568 PostAddAnimationToMainThread(picture_.get());
571 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
572 Animation::TargetProperty target_property,
573 int group) override {
574 started_times_++;
577 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
578 Animation::TargetProperty target_property,
579 int group) override {
580 EndTest();
583 void AfterTest() override { EXPECT_EQ(1, started_times_); }
585 private:
586 int started_times_;
587 FakeContentLayerClient client_;
588 scoped_refptr<FakePictureLayer> picture_;
591 SINGLE_AND_MULTI_THREAD_TEST_F(
592 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
594 // Animations should not be started when frames are being skipped due to
595 // checkerboard.
596 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
597 : public LayerTreeHostAnimationTest {
598 void SetupTree() override {
599 LayerTreeHostAnimationTest::SetupTree();
600 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
601 picture_->SetBounds(gfx::Size(4, 4));
602 picture_->set_layer_animation_delegate(this);
603 layer_tree_host()->root_layer()->AddChild(picture_);
606 void InitializeSettings(LayerTreeSettings* settings) override {
607 // Make sure that drawing many times doesn't cause a checkerboarded
608 // animation to start so we avoid flake in this test.
609 settings->timeout_and_draw_when_animation_checkerboards = false;
612 void BeginTest() override {
613 prevented_draw_ = 0;
614 added_animations_ = 0;
615 started_times_ = 0;
617 PostSetNeedsCommitToMainThread();
620 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
621 LayerTreeHostImpl::FrameData* frame_data,
622 DrawResult draw_result) override {
623 if (added_animations_ < 2)
624 return draw_result;
625 if (TestEnded())
626 return draw_result;
627 // Act like there is checkerboard when the second animation wants to draw.
628 ++prevented_draw_;
629 if (prevented_draw_ > 2)
630 EndTest();
631 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
634 void DidCommitAndDrawFrame() override {
635 switch (layer_tree_host()->source_frame_number()) {
636 case 1:
637 // The animation is longer than 1 BeginFrame interval.
638 AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
639 added_animations_++;
640 break;
641 case 2:
642 // This second animation will not be drawn so it should not start.
643 AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
644 added_animations_++;
645 break;
649 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
650 Animation::TargetProperty target_property,
651 int group) override {
652 if (TestEnded())
653 return;
654 started_times_++;
657 void AfterTest() override {
658 // Make sure we tried to draw the second animation but failed.
659 EXPECT_LT(0, prevented_draw_);
660 // The first animation should be started, but the second should not because
661 // of checkerboard.
662 EXPECT_EQ(1, started_times_);
665 int prevented_draw_;
666 int added_animations_;
667 int started_times_;
668 FakeContentLayerClient client_;
669 scoped_refptr<FakePictureLayer> picture_;
672 MULTI_THREAD_TEST_F(
673 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
675 // Verifies that scroll offset animations are only accepted when impl-scrolling
676 // is supported, and that when scroll offset animations are accepted,
677 // scroll offset updates are sent back to the main thread.
678 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
679 : public LayerTreeHostAnimationTest {
680 public:
681 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
683 void SetupTree() override {
684 LayerTreeHostAnimationTest::SetupTree();
686 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
687 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
688 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
689 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
690 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
693 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
695 void DidCommit() override {
696 switch (layer_tree_host()->source_frame_number()) {
697 case 1: {
698 scoped_ptr<ScrollOffsetAnimationCurve> curve(
699 ScrollOffsetAnimationCurve::Create(
700 gfx::ScrollOffset(500.f, 550.f),
701 EaseInOutTimingFunction::Create()));
702 scoped_ptr<Animation> animation(
703 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
704 animation->set_needs_synchronized_start_time(true);
705 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
706 bool impl_scrolling_supported =
707 layer_tree_host()->proxy()->SupportsImplScrolling();
708 EXPECT_EQ(impl_scrolling_supported, animation_added);
709 if (!impl_scrolling_supported)
710 EndTest();
711 break;
713 default:
714 if (scroll_layer_->scroll_offset().x() > 10 &&
715 scroll_layer_->scroll_offset().y() > 20)
716 EndTest();
720 void AfterTest() override {}
722 private:
723 FakeContentLayerClient client_;
724 scoped_refptr<FakePictureLayer> scroll_layer_;
727 SINGLE_AND_MULTI_THREAD_TEST_F(
728 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
730 // Verifies that when the main thread removes a scroll animation and sets a new
731 // scroll position, the active tree takes on exactly this new scroll position
732 // after activation, and the main thread doesn't receive a spurious scroll
733 // delta.
734 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
735 : public LayerTreeHostAnimationTest {
736 public:
737 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
738 : final_postion_(50.0, 100.0) {}
740 void SetupTree() override {
741 LayerTreeHostAnimationTest::SetupTree();
743 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
744 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
745 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
746 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
747 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
749 scoped_ptr<ScrollOffsetAnimationCurve> curve(
750 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
751 EaseInOutTimingFunction::Create()));
752 scoped_ptr<Animation> animation(
753 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
754 animation->set_needs_synchronized_start_time(true);
755 scroll_layer_->AddAnimation(animation.Pass());
758 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
760 void BeginMainFrame(const BeginFrameArgs& args) override {
761 switch (layer_tree_host()->source_frame_number()) {
762 case 0:
763 break;
764 case 1: {
765 Animation* animation =
766 scroll_layer_->layer_animation_controller()->GetAnimation(
767 Animation::SCROLL_OFFSET);
768 scroll_layer_->layer_animation_controller()->RemoveAnimation(
769 animation->id());
770 scroll_layer_->SetScrollOffset(final_postion_);
771 break;
773 default:
774 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
778 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
779 host_impl->BlockNotifyReadyToActivateForTesting(true);
782 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
783 const BeginFrameArgs& args) override {
784 if (!host_impl->pending_tree())
785 return;
787 if (!host_impl->active_tree()->root_layer()) {
788 host_impl->BlockNotifyReadyToActivateForTesting(false);
789 return;
792 LayerImpl* scroll_layer_impl =
793 host_impl->active_tree()->root_layer()->children()[0];
794 Animation* animation =
795 scroll_layer_impl->layer_animation_controller()->GetAnimation(
796 Animation::SCROLL_OFFSET);
798 if (!animation || animation->run_state() != Animation::RUNNING) {
799 host_impl->BlockNotifyReadyToActivateForTesting(false);
800 return;
803 // Block activation until the running animation has a chance to produce a
804 // scroll delta.
805 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
806 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
807 return;
809 host_impl->BlockNotifyReadyToActivateForTesting(false);
812 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
813 if (host_impl->pending_tree()->source_frame_number() != 1)
814 return;
815 LayerImpl* scroll_layer_impl =
816 host_impl->pending_tree()->root_layer()->children()[0];
817 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
820 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
821 if (host_impl->active_tree()->source_frame_number() != 1)
822 return;
823 LayerImpl* scroll_layer_impl =
824 host_impl->active_tree()->root_layer()->children()[0];
825 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
826 EndTest();
829 void AfterTest() override {
830 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
833 private:
834 FakeContentLayerClient client_;
835 scoped_refptr<FakePictureLayer> scroll_layer_;
836 const gfx::ScrollOffset final_postion_;
839 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
841 // When animations are simultaneously added to an existing layer and to a new
842 // layer, they should start at the same time, even when there's already a
843 // running animation on the existing layer.
844 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
845 : public LayerTreeHostAnimationTest {
846 public:
847 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
848 : frame_count_with_pending_tree_(0) {}
850 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
852 void DidCommit() override {
853 if (layer_tree_host()->source_frame_number() == 1) {
854 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
855 } else if (layer_tree_host()->source_frame_number() == 2) {
856 AddOpacityTransitionToLayer(
857 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
859 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
860 layer_tree_host()->root_layer()->AddChild(layer);
861 layer->set_layer_animation_delegate(this);
862 layer->SetBounds(gfx::Size(4, 4));
863 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
867 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
868 host_impl->BlockNotifyReadyToActivateForTesting(true);
871 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
872 // For the commit that added animations to new and existing layers, keep
873 // blocking activation. We want to verify that even with activation blocked,
874 // the animation on the layer that's already in the active tree won't get a
875 // head start.
876 if (host_impl->pending_tree()->source_frame_number() != 2) {
877 host_impl->BlockNotifyReadyToActivateForTesting(false);
881 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
882 const BeginFrameArgs& args) override {
883 if (!host_impl->pending_tree() ||
884 host_impl->pending_tree()->source_frame_number() != 2)
885 return;
887 frame_count_with_pending_tree_++;
888 if (frame_count_with_pending_tree_ == 2) {
889 host_impl->BlockNotifyReadyToActivateForTesting(false);
893 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
894 bool has_unfinished_animation) override {
895 LayerAnimationController* root_controller_impl =
896 host_impl->active_tree()->root_layer()->layer_animation_controller();
897 Animation* root_animation =
898 root_controller_impl->GetAnimation(Animation::OPACITY);
899 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
900 return;
902 LayerAnimationController* child_controller_impl =
903 host_impl->active_tree()->root_layer()->children()
904 [0]->layer_animation_controller();
905 Animation* child_animation =
906 child_controller_impl->GetAnimation(Animation::OPACITY);
907 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
908 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
909 root_controller_impl->AbortAnimations(Animation::OPACITY);
910 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
911 child_controller_impl->AbortAnimations(Animation::OPACITY);
912 EndTest();
915 void AfterTest() override {}
917 private:
918 int frame_count_with_pending_tree_;
921 // This test blocks activation which is not supported for single thread mode.
922 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
923 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
925 // When a layer with an animation is removed from the tree and later re-added,
926 // the animation should resume.
927 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
928 : public LayerTreeHostAnimationTest {
929 public:
930 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
932 void SetupTree() override {
933 LayerTreeHostAnimationTest::SetupTree();
934 layer_ = Layer::Create(layer_settings());
935 layer_->SetBounds(gfx::Size(4, 4));
936 layer_tree_host()->root_layer()->AddChild(layer_);
937 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
940 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
942 void DidCommit() override {
943 switch (layer_tree_host()->source_frame_number()) {
944 case 1:
945 layer_->RemoveFromParent();
946 break;
947 case 2:
948 layer_tree_host()->root_layer()->AddChild(layer_);
949 break;
953 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
954 switch (host_impl->active_tree()->source_frame_number()) {
955 case 0:
956 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
957 break;
958 case 1:
959 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
960 break;
961 case 2:
962 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
963 EndTest();
964 break;
968 void AfterTest() override {}
970 private:
971 scoped_refptr<Layer> layer_;
974 SINGLE_AND_MULTI_THREAD_TEST_F(
975 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
977 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
978 : public LayerTreeHostAnimationTest {
979 public:
980 void SetupTree() override {
981 LayerTreeHostAnimationTest::SetupTree();
982 layer_ = Layer::Create(layer_settings());
983 layer_->SetBounds(gfx::Size(4, 4));
984 layer_tree_host()->root_layer()->AddChild(layer_);
987 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
989 void DidCommit() override {
990 switch (layer_tree_host()->source_frame_number()) {
991 case 1:
992 // First frame: add an animation to the root layer.
993 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
994 break;
995 case 2:
996 // Second frame: add an animation to the content layer. The root layer
997 // animation has caused us to animate already during this frame.
998 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
999 break;
1003 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1004 // After both animations have started, verify that they have valid
1005 // start times.
1006 if (host_impl->active_tree()->source_frame_number() < 2)
1007 return;
1008 AnimationRegistrar::AnimationControllerMap controllers_copy =
1009 host_impl->animation_registrar()
1010 ->active_animation_controllers_for_testing();
1011 EXPECT_EQ(2u, controllers_copy.size());
1012 for (auto& it : controllers_copy) {
1013 int id = it.first;
1014 if (id == host_impl->RootLayer()->id()) {
1015 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
1016 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1017 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1018 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
1019 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1021 EndTest();
1025 void AfterTest() override {}
1027 private:
1028 scoped_refptr<Layer> layer_;
1031 SINGLE_AND_MULTI_THREAD_TEST_F(
1032 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1034 class LayerTreeHostAnimationTestRemoveAnimation
1035 : public LayerTreeHostAnimationTest {
1036 public:
1037 void SetupTree() override {
1038 LayerTreeHostAnimationTest::SetupTree();
1039 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1040 layer_->SetBounds(gfx::Size(4, 4));
1041 layer_tree_host()->root_layer()->AddChild(layer_);
1044 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1046 void DidCommit() override {
1047 switch (layer_tree_host()->source_frame_number()) {
1048 case 1:
1049 AddAnimatedTransformToLayer(layer_.get(), 1.0, 5, 5);
1050 break;
1051 case 2:
1052 LayerAnimationController* controller =
1053 layer_->layer_animation_controller();
1054 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
1055 controller->RemoveAnimation(animation->id());
1056 gfx::Transform transform;
1057 transform.Translate(10.f, 10.f);
1058 layer_->SetTransform(transform);
1060 // Do something that causes property trees to get rebuilt.
1061 layer_->AddChild(Layer::Create(layer_settings()));
1062 break;
1066 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
1067 if (host_impl->active_tree()->source_frame_number() < 2)
1068 return;
1069 gfx::Transform expected_transform;
1070 expected_transform.Translate(10.f, 10.f);
1071 EXPECT_EQ(expected_transform, host_impl->active_tree()
1072 ->root_layer()
1073 ->children()[0]
1074 ->draw_transform());
1075 EndTest();
1078 void AfterTest() override {}
1080 private:
1081 scoped_refptr<Layer> layer_;
1082 FakeContentLayerClient client_;
1085 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation);
1087 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1088 : public LayerTreeHostAnimationTest {
1089 public:
1090 void SetupTree() override {
1091 LayerTreeHostAnimationTest::SetupTree();
1092 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
1093 layer_->SetBounds(gfx::Size(4, 4));
1094 layer_tree_host()->root_layer()->AddChild(layer_);
1097 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1099 void DidCommit() override {
1100 if (layer_tree_host()->source_frame_number() == 1)
1101 AddAnimatedTransformToLayer(layer_.get(), 0.04, 5, 5);
1104 void WillCommit() override {
1105 if (layer_tree_host()->source_frame_number() == 2) {
1106 // Block until the animation finishes on the compositor thread. Since
1107 // animations have already been ticked on the main thread, when the commit
1108 // happens the state on the main thread will be consistent with having a
1109 // running animation but the state on the compositor thread will be
1110 // consistent with having only a finished animation.
1111 completion_.Wait();
1115 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1116 switch (host_impl->sync_tree()->source_frame_number()) {
1117 case 1:
1118 PostSetNeedsCommitToMainThread();
1119 break;
1120 case 2:
1121 gfx::Transform expected_transform;
1122 expected_transform.Translate(5.f, 5.f);
1123 LayerImpl* layer_impl =
1124 host_impl->sync_tree()->root_layer()->children()[0];
1125 EXPECT_EQ(expected_transform, layer_impl->draw_transform());
1126 EndTest();
1127 break;
1131 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1132 bool has_unfinished_animation) override {
1133 if (host_impl->active_tree()->source_frame_number() == 1 &&
1134 !has_unfinished_animation) {
1135 // The animation has finished, so allow the main thread to commit.
1136 completion_.Signal();
1140 void AfterTest() override {}
1142 private:
1143 scoped_refptr<Layer> layer_;
1144 FakeContentLayerClient client_;
1145 CompletionEvent completion_;
1148 // An animation finishing during commit can only happen when we have a separate
1149 // compositor thread.
1150 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit);
1152 class LayerTreeHostAnimationTestNotifyAnimationFinished
1153 : public LayerTreeHostAnimationTest {
1154 public:
1155 LayerTreeHostAnimationTestNotifyAnimationFinished()
1156 : called_animation_started_(false), called_animation_finished_(false) {}
1158 void SetupTree() override {
1159 LayerTreeHostAnimationTest::SetupTree();
1160 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1161 picture_->SetBounds(gfx::Size(4, 4));
1162 picture_->set_layer_animation_delegate(this);
1163 layer_tree_host()->root_layer()->AddChild(picture_);
1166 void BeginTest() override {
1167 layer_tree_host()->SetViewportSize(gfx::Size());
1168 PostAddLongAnimationToMainThread(picture_.get());
1171 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1172 Animation::TargetProperty target_property,
1173 int group) override {
1174 called_animation_started_ = true;
1175 layer_tree_host()->AnimateLayers(
1176 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1177 PostSetNeedsCommitToMainThread();
1180 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1181 Animation::TargetProperty target_property,
1182 int group) override {
1183 called_animation_finished_ = true;
1184 EndTest();
1187 void AfterTest() override {
1188 EXPECT_TRUE(called_animation_started_);
1189 EXPECT_TRUE(called_animation_finished_);
1192 private:
1193 bool called_animation_started_;
1194 bool called_animation_finished_;
1195 FakeContentLayerClient client_;
1196 scoped_refptr<FakePictureLayer> picture_;
1199 SINGLE_AND_MULTI_THREAD_TEST_F(
1200 LayerTreeHostAnimationTestNotifyAnimationFinished);
1202 } // namespace
1203 } // namespace cc