roll libyuv to r1437 to resolve msan overread on odd width ARGBToYUY2.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blob45e345623d8f4de7e608a54725ec31fccb3df4bc
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/time_util.h"
12 #include "cc/layers/layer.h"
13 #include "cc/layers/layer_impl.h"
14 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_content_layer_client.h"
16 #include "cc/test/fake_picture_layer.h"
17 #include "cc/test/layer_tree_test.h"
18 #include "cc/trees/layer_tree_impl.h"
20 namespace cc {
21 namespace {
23 class LayerTreeHostAnimationTest : public LayerTreeTest {
24 public:
25 void SetupTree() override {
26 LayerTreeTest::SetupTree();
27 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
31 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
32 // be set.
33 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
34 : public LayerTreeHostAnimationTest {
35 public:
36 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
37 : num_commits_(0) {}
39 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
41 void BeginMainFrame(const BeginFrameArgs& args) override {
42 // We skip the first commit because its the commit that populates the
43 // impl thread with a tree. After the second commit, the test is done.
44 if (num_commits_ != 1)
45 return;
47 layer_tree_host()->SetNeedsAnimate();
48 // Right now, CommitRequested is going to be true, because during
49 // BeginFrame, we force CommitRequested to true to prevent requests from
50 // hitting the impl thread. But, when the next DidCommit happens, we should
51 // verify that CommitRequested has gone back to false.
54 void DidCommit() override {
55 if (!num_commits_) {
56 EXPECT_FALSE(layer_tree_host()->CommitRequested());
57 layer_tree_host()->SetNeedsAnimate();
58 EXPECT_FALSE(layer_tree_host()->CommitRequested());
61 // Verifies that the SetNeedsAnimate we made in ::Animate did not
62 // trigger CommitRequested.
63 EXPECT_FALSE(layer_tree_host()->CommitRequested());
64 EndTest();
65 num_commits_++;
68 void AfterTest() override {}
70 private:
71 int num_commits_;
74 MULTI_THREAD_TEST_F(
75 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
77 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
78 // callback, request another frame using SetNeedsAnimate. End the test when
79 // animate gets called yet-again, indicating that the proxy is correctly
80 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
81 // flow.
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
83 : public LayerTreeHostAnimationTest {
84 public:
85 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
86 : num_begin_frames_(0) {}
88 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
90 void BeginMainFrame(const BeginFrameArgs& args) override {
91 if (!num_begin_frames_) {
92 layer_tree_host()->SetNeedsAnimate();
93 num_begin_frames_++;
94 return;
96 EndTest();
99 void AfterTest() override {}
101 private:
102 int num_begin_frames_;
105 SINGLE_AND_MULTI_THREAD_TEST_F(
106 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
108 // Add a layer animation and confirm that
109 // LayerTreeHostImpl::UpdateAnimationState does get called.
110 class LayerTreeHostAnimationTestAddAnimation
111 : public LayerTreeHostAnimationTest {
112 public:
113 LayerTreeHostAnimationTestAddAnimation()
114 : update_animation_state_was_called_(false) {}
116 void BeginTest() override {
117 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
120 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
121 bool has_unfinished_animation) override {
122 EXPECT_FALSE(has_unfinished_animation);
123 update_animation_state_was_called_ = true;
126 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
127 Animation::TargetProperty target_property,
128 int group) override {
129 EXPECT_LT(base::TimeTicks(), monotonic_time);
131 LayerAnimationController* controller =
132 layer_tree_host()->root_layer()->layer_animation_controller();
133 Animation* animation = controller->GetAnimation(Animation::OPACITY);
134 if (animation)
135 controller->RemoveAnimation(animation->id());
137 EndTest();
140 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
142 private:
143 bool update_animation_state_was_called_;
146 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
148 // Add a layer animation to a layer, but continually fail to draw. Confirm that
149 // after a while, we do eventually force a draw.
150 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
151 : public LayerTreeHostAnimationTest {
152 public:
153 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
154 : started_animating_(false) {}
156 void BeginTest() override {
157 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
160 void AnimateLayers(LayerTreeHostImpl* host_impl,
161 base::TimeTicks monotonic_time) override {
162 started_animating_ = true;
165 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
166 if (started_animating_)
167 EndTest();
170 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
171 LayerTreeHostImpl::FrameData* frame,
172 DrawResult draw_result) override {
173 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
176 void AfterTest() override {}
178 private:
179 bool started_animating_;
182 // Starvation can only be an issue with the MT compositor.
183 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
185 // Ensures that animations eventually get deleted.
186 class LayerTreeHostAnimationTestAnimationsGetDeleted
187 : public LayerTreeHostAnimationTest {
188 public:
189 LayerTreeHostAnimationTestAnimationsGetDeleted()
190 : started_animating_(false) {}
192 void BeginTest() override {
193 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
196 void AnimateLayers(LayerTreeHostImpl* host_impl,
197 base::TimeTicks monotonic_time) override {
198 bool have_animations = !host_impl->animation_registrar()
199 ->active_animation_controllers_for_testing()
200 .empty();
201 if (!started_animating_ && have_animations) {
202 started_animating_ = true;
203 return;
206 if (started_animating_ && !have_animations)
207 EndTest();
210 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
211 Animation::TargetProperty target_property,
212 int group) override {
213 // Animations on the impl-side controller only get deleted during a commit,
214 // so we need to schedule a commit.
215 layer_tree_host()->SetNeedsCommit();
218 void AfterTest() override {}
220 private:
221 bool started_animating_;
224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
226 // Ensure that an animation's timing function is respected.
227 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
228 : public LayerTreeHostAnimationTest {
229 public:
230 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
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 LayerAnimationController* controller_impl =
244 host_impl->active_tree()->root_layer()->children()[0]->
245 layer_animation_controller();
246 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
247 if (!animation)
248 return;
250 const FloatAnimationCurve* curve =
251 animation->curve()->ToFloatAnimationCurve();
252 float start_opacity = curve->GetValue(base::TimeDelta());
253 float end_opacity = curve->GetValue(curve->Duration());
254 float linearly_interpolated_opacity =
255 0.25f * end_opacity + 0.75f * start_opacity;
256 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
257 // If the linear timing function associated with this animation was not
258 // picked up, then the linearly interpolated opacity would be different
259 // because of the default ease timing function.
260 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
262 EndTest();
265 void AfterTest() override {}
267 FakeContentLayerClient client_;
268 scoped_refptr<FakePictureLayer> picture_;
271 SINGLE_AND_MULTI_THREAD_TEST_F(
272 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
274 // Ensures that main thread animations have their start times synchronized with
275 // impl thread animations.
276 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
277 : public LayerTreeHostAnimationTest {
278 public:
279 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
281 void SetupTree() override {
282 LayerTreeHostAnimationTest::SetupTree();
283 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
284 picture_->SetBounds(gfx::Size(4, 4));
285 picture_->set_layer_animation_delegate(this);
286 layer_tree_host()->root_layer()->AddChild(picture_);
289 void BeginTest() override { PostAddAnimationToMainThread(picture_.get()); }
291 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
292 Animation::TargetProperty target_property,
293 int group) override {
294 LayerAnimationController* controller =
295 layer_tree_host()->root_layer()->children()[0]->
296 layer_animation_controller();
297 Animation* animation = controller->GetAnimation(Animation::OPACITY);
298 main_start_time_ = animation->start_time();
299 controller->RemoveAnimation(animation->id());
300 EndTest();
303 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
304 bool has_unfinished_animation) override {
305 LayerAnimationController* controller =
306 impl_host->active_tree()->root_layer()->children()[0]->
307 layer_animation_controller();
308 Animation* animation = controller->GetAnimation(Animation::OPACITY);
309 if (!animation)
310 return;
312 impl_start_time_ = animation->start_time();
315 void AfterTest() override {
316 EXPECT_EQ(impl_start_time_, main_start_time_);
317 EXPECT_LT(base::TimeTicks(), impl_start_time_);
320 private:
321 base::TimeTicks main_start_time_;
322 base::TimeTicks impl_start_time_;
323 FakeContentLayerClient client_;
324 scoped_refptr<FakePictureLayer> picture_;
327 SINGLE_AND_MULTI_THREAD_TEST_F(
328 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
330 // Ensures that notify animation finished is called.
331 class LayerTreeHostAnimationTestAnimationFinishedEvents
332 : public LayerTreeHostAnimationTest {
333 public:
334 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
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 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
409 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
411 void DidCommit() override {
412 if (layer_tree_host()->source_frame_number() == 1) {
413 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
414 layer->set_layer_animation_delegate(this);
416 // Any valid AnimationCurve will do here.
417 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
418 scoped_ptr<Animation> animation(
419 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
420 layer->layer_animation_controller()->AddAnimation(animation.Pass());
422 // We add the animation *before* attaching the layer to the tree.
423 layer_tree_host()->root_layer()->AddChild(layer);
427 void AnimateLayers(LayerTreeHostImpl* impl_host,
428 base::TimeTicks monotonic_time) override {
429 EndTest();
432 void AfterTest() override {}
435 SINGLE_AND_MULTI_THREAD_TEST_F(
436 LayerTreeHostAnimationTestLayerAddedWithAnimation);
438 class LayerTreeHostAnimationTestCancelAnimateCommit
439 : public LayerTreeHostAnimationTest {
440 public:
441 LayerTreeHostAnimationTestCancelAnimateCommit()
442 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
444 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
446 void BeginMainFrame(const BeginFrameArgs& args) override {
447 num_begin_frames_++;
448 // No-op animate will cancel the commit.
449 if (layer_tree_host()->source_frame_number() == 1) {
450 EndTest();
451 return;
453 layer_tree_host()->SetNeedsAnimate();
456 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
457 num_commit_calls_++;
458 if (impl->active_tree()->source_frame_number() > 1)
459 FAIL() << "Commit should have been canceled.";
462 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
463 num_draw_calls_++;
464 if (impl->active_tree()->source_frame_number() > 1)
465 FAIL() << "Draw should have been canceled.";
468 void AfterTest() override {
469 EXPECT_EQ(2, num_begin_frames_);
470 EXPECT_EQ(1, num_commit_calls_);
471 EXPECT_EQ(1, num_draw_calls_);
474 private:
475 int num_begin_frames_;
476 int num_commit_calls_;
477 int num_draw_calls_;
480 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
482 class LayerTreeHostAnimationTestForceRedraw
483 : public LayerTreeHostAnimationTest {
484 public:
485 LayerTreeHostAnimationTestForceRedraw()
486 : num_animate_(0), num_draw_layers_(0) {}
488 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
490 void BeginMainFrame(const BeginFrameArgs& args) override {
491 if (++num_animate_ < 2)
492 layer_tree_host()->SetNeedsAnimate();
495 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); }
497 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
498 if (++num_draw_layers_ == 2)
499 EndTest();
502 void AfterTest() override {
503 // The first commit will always draw; make sure the second draw triggered
504 // by the animation was not cancelled.
505 EXPECT_EQ(2, num_draw_layers_);
506 EXPECT_EQ(2, num_animate_);
509 private:
510 int num_animate_;
511 int num_draw_layers_;
514 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
516 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
517 : public LayerTreeHostAnimationTest {
518 public:
519 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
520 : num_animate_(0), num_draw_layers_(0) {}
522 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
524 void BeginMainFrame(const BeginFrameArgs& args) override {
525 if (++num_animate_ <= 2) {
526 layer_tree_host()->SetNeedsCommit();
527 layer_tree_host()->SetNeedsAnimate();
531 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
532 if (++num_draw_layers_ == 2)
533 EndTest();
536 void AfterTest() override {
537 // The first commit will always draw; make sure the second draw triggered
538 // by the SetNeedsCommit was not cancelled.
539 EXPECT_EQ(2, num_draw_layers_);
540 EXPECT_GE(num_animate_, 2);
543 private:
544 int num_animate_;
545 int num_draw_layers_;
548 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
550 // Make sure the main thread can still execute animations when CanDraw() is not
551 // true.
552 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
553 : public LayerTreeHostAnimationTest {
554 public:
555 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
557 void SetupTree() override {
558 LayerTreeHostAnimationTest::SetupTree();
559 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
560 picture_->SetBounds(gfx::Size(4, 4));
561 picture_->set_layer_animation_delegate(this);
562 layer_tree_host()->root_layer()->AddChild(picture_);
565 void BeginTest() override {
566 layer_tree_host()->SetViewportSize(gfx::Size());
567 PostAddAnimationToMainThread(picture_.get());
570 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
571 Animation::TargetProperty target_property,
572 int group) override {
573 started_times_++;
576 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
577 Animation::TargetProperty target_property,
578 int group) override {
579 EndTest();
582 void AfterTest() override { EXPECT_EQ(1, started_times_); }
584 private:
585 int started_times_;
586 FakeContentLayerClient client_;
587 scoped_refptr<FakePictureLayer> picture_;
590 SINGLE_AND_MULTI_THREAD_TEST_F(
591 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
593 // Animations should not be started when frames are being skipped due to
594 // checkerboard.
595 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
596 : public LayerTreeHostAnimationTest {
597 void SetupTree() override {
598 LayerTreeHostAnimationTest::SetupTree();
599 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
600 picture_->SetBounds(gfx::Size(4, 4));
601 picture_->set_layer_animation_delegate(this);
602 layer_tree_host()->root_layer()->AddChild(picture_);
605 void InitializeSettings(LayerTreeSettings* settings) override {
606 // Make sure that drawing many times doesn't cause a checkerboarded
607 // animation to start so we avoid flake in this test.
608 settings->timeout_and_draw_when_animation_checkerboards = false;
611 void BeginTest() override {
612 prevented_draw_ = 0;
613 added_animations_ = 0;
614 started_times_ = 0;
616 PostSetNeedsCommitToMainThread();
619 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
620 LayerTreeHostImpl::FrameData* frame_data,
621 DrawResult draw_result) override {
622 if (added_animations_ < 2)
623 return draw_result;
624 if (TestEnded())
625 return draw_result;
626 // Act like there is checkerboard when the second animation wants to draw.
627 ++prevented_draw_;
628 if (prevented_draw_ > 2)
629 EndTest();
630 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
633 void DidCommitAndDrawFrame() override {
634 switch (layer_tree_host()->source_frame_number()) {
635 case 1:
636 // The animation is longer than 1 BeginFrame interval.
637 AddOpacityTransitionToLayer(picture_.get(), 0.1, 0.2f, 0.8f, false);
638 added_animations_++;
639 break;
640 case 2:
641 // This second animation will not be drawn so it should not start.
642 AddAnimatedTransformToLayer(picture_.get(), 0.1, 5, 5);
643 added_animations_++;
644 break;
648 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
649 Animation::TargetProperty target_property,
650 int group) override {
651 if (TestEnded())
652 return;
653 started_times_++;
656 void AfterTest() override {
657 // Make sure we tried to draw the second animation but failed.
658 EXPECT_LT(0, prevented_draw_);
659 // The first animation should be started, but the second should not because
660 // of checkerboard.
661 EXPECT_EQ(1, started_times_);
664 int prevented_draw_;
665 int added_animations_;
666 int started_times_;
667 FakeContentLayerClient client_;
668 scoped_refptr<FakePictureLayer> picture_;
671 MULTI_THREAD_TEST_F(
672 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
674 // Verifies that scroll offset animations are only accepted when impl-scrolling
675 // is supported, and that when scroll offset animations are accepted,
676 // scroll offset updates are sent back to the main thread.
677 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
678 : public LayerTreeHostAnimationTest {
679 public:
680 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
682 void SetupTree() override {
683 LayerTreeHostAnimationTest::SetupTree();
685 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
686 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
687 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
688 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
689 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
692 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
694 void DidCommit() override {
695 switch (layer_tree_host()->source_frame_number()) {
696 case 1: {
697 scoped_ptr<ScrollOffsetAnimationCurve> curve(
698 ScrollOffsetAnimationCurve::Create(
699 gfx::ScrollOffset(500.f, 550.f),
700 EaseInOutTimingFunction::Create()));
701 scoped_ptr<Animation> animation(
702 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
703 animation->set_needs_synchronized_start_time(true);
704 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
705 bool impl_scrolling_supported =
706 layer_tree_host()->proxy()->SupportsImplScrolling();
707 EXPECT_EQ(impl_scrolling_supported, animation_added);
708 if (!impl_scrolling_supported)
709 EndTest();
710 break;
712 default:
713 if (scroll_layer_->scroll_offset().x() > 10 &&
714 scroll_layer_->scroll_offset().y() > 20)
715 EndTest();
719 void AfterTest() override {}
721 private:
722 FakeContentLayerClient client_;
723 scoped_refptr<FakePictureLayer> scroll_layer_;
726 SINGLE_AND_MULTI_THREAD_TEST_F(
727 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
729 // Verifies that when the main thread removes a scroll animation and sets a new
730 // scroll position, the active tree takes on exactly this new scroll position
731 // after activation, and the main thread doesn't receive a spurious scroll
732 // delta.
733 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
734 : public LayerTreeHostAnimationTest {
735 public:
736 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
737 : final_postion_(50.0, 100.0) {}
739 void SetupTree() override {
740 LayerTreeHostAnimationTest::SetupTree();
742 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
743 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
744 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
745 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
746 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
748 scoped_ptr<ScrollOffsetAnimationCurve> curve(
749 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
750 EaseInOutTimingFunction::Create()));
751 scoped_ptr<Animation> animation(
752 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
753 animation->set_needs_synchronized_start_time(true);
754 scroll_layer_->AddAnimation(animation.Pass());
757 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
759 void BeginMainFrame(const BeginFrameArgs& args) override {
760 switch (layer_tree_host()->source_frame_number()) {
761 case 0:
762 break;
763 case 1: {
764 Animation* animation =
765 scroll_layer_->layer_animation_controller()->GetAnimation(
766 Animation::SCROLL_OFFSET);
767 scroll_layer_->layer_animation_controller()->RemoveAnimation(
768 animation->id());
769 scroll_layer_->SetScrollOffset(final_postion_);
770 break;
772 default:
773 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
777 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
778 host_impl->BlockNotifyReadyToActivateForTesting(true);
781 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
782 const BeginFrameArgs& args) override {
783 if (!host_impl->pending_tree())
784 return;
786 if (!host_impl->active_tree()->root_layer()) {
787 host_impl->BlockNotifyReadyToActivateForTesting(false);
788 return;
791 LayerImpl* scroll_layer_impl =
792 host_impl->active_tree()->root_layer()->children()[0];
793 Animation* animation =
794 scroll_layer_impl->layer_animation_controller()->GetAnimation(
795 Animation::SCROLL_OFFSET);
797 if (!animation || animation->run_state() != Animation::RUNNING) {
798 host_impl->BlockNotifyReadyToActivateForTesting(false);
799 return;
802 // Block activation until the running animation has a chance to produce a
803 // scroll delta.
804 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
805 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
806 return;
808 host_impl->BlockNotifyReadyToActivateForTesting(false);
811 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
812 if (host_impl->pending_tree()->source_frame_number() != 1)
813 return;
814 LayerImpl* scroll_layer_impl =
815 host_impl->pending_tree()->root_layer()->children()[0];
816 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
819 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
820 if (host_impl->active_tree()->source_frame_number() != 1)
821 return;
822 LayerImpl* scroll_layer_impl =
823 host_impl->active_tree()->root_layer()->children()[0];
824 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
825 EndTest();
828 void AfterTest() override {
829 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
832 private:
833 FakeContentLayerClient client_;
834 scoped_refptr<FakePictureLayer> scroll_layer_;
835 const gfx::ScrollOffset final_postion_;
838 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
840 // When animations are simultaneously added to an existing layer and to a new
841 // layer, they should start at the same time, even when there's already a
842 // running animation on the existing layer.
843 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
844 : public LayerTreeHostAnimationTest {
845 public:
846 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
847 : frame_count_with_pending_tree_(0) {}
849 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
851 void DidCommit() override {
852 if (layer_tree_host()->source_frame_number() == 1) {
853 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
854 } else if (layer_tree_host()->source_frame_number() == 2) {
855 AddOpacityTransitionToLayer(
856 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
858 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
859 layer_tree_host()->root_layer()->AddChild(layer);
860 layer->set_layer_animation_delegate(this);
861 layer->SetBounds(gfx::Size(4, 4));
862 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
866 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
867 host_impl->BlockNotifyReadyToActivateForTesting(true);
870 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
871 // For the commit that added animations to new and existing layers, keep
872 // blocking activation. We want to verify that even with activation blocked,
873 // the animation on the layer that's already in the active tree won't get a
874 // head start.
875 if (host_impl->pending_tree()->source_frame_number() != 2) {
876 host_impl->BlockNotifyReadyToActivateForTesting(false);
880 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
881 const BeginFrameArgs& args) override {
882 if (!host_impl->pending_tree() ||
883 host_impl->pending_tree()->source_frame_number() != 2)
884 return;
886 frame_count_with_pending_tree_++;
887 if (frame_count_with_pending_tree_ == 2) {
888 host_impl->BlockNotifyReadyToActivateForTesting(false);
892 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
893 bool has_unfinished_animation) override {
894 LayerAnimationController* root_controller_impl =
895 host_impl->active_tree()->root_layer()->layer_animation_controller();
896 Animation* root_animation =
897 root_controller_impl->GetAnimation(Animation::OPACITY);
898 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
899 return;
901 LayerAnimationController* child_controller_impl =
902 host_impl->active_tree()->root_layer()->children()
903 [0]->layer_animation_controller();
904 Animation* child_animation =
905 child_controller_impl->GetAnimation(Animation::OPACITY);
906 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
907 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
908 root_controller_impl->AbortAnimations(Animation::OPACITY);
909 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
910 child_controller_impl->AbortAnimations(Animation::OPACITY);
911 EndTest();
914 void AfterTest() override {}
916 private:
917 int frame_count_with_pending_tree_;
920 // This test blocks activation which is not supported for single thread mode.
921 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
922 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
924 // When a layer with an animation is removed from the tree and later re-added,
925 // the animation should resume.
926 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
927 : public LayerTreeHostAnimationTest {
928 public:
929 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
931 void SetupTree() override {
932 LayerTreeHostAnimationTest::SetupTree();
933 layer_ = Layer::Create(layer_settings());
934 layer_->SetBounds(gfx::Size(4, 4));
935 layer_tree_host()->root_layer()->AddChild(layer_);
936 AddOpacityTransitionToLayer(layer_.get(), 10000.0, 0.1f, 0.9f, true);
939 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
941 void DidCommit() override {
942 switch (layer_tree_host()->source_frame_number()) {
943 case 1:
944 layer_->RemoveFromParent();
945 break;
946 case 2:
947 layer_tree_host()->root_layer()->AddChild(layer_);
948 break;
952 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
953 switch (host_impl->active_tree()->source_frame_number()) {
954 case 0:
955 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
956 break;
957 case 1:
958 EXPECT_FALSE(host_impl->animation_registrar()->needs_animate_layers());
959 break;
960 case 2:
961 EXPECT_TRUE(host_impl->animation_registrar()->needs_animate_layers());
962 EndTest();
963 break;
967 void AfterTest() override {}
969 private:
970 scoped_refptr<Layer> layer_;
973 SINGLE_AND_MULTI_THREAD_TEST_F(
974 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded);
976 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
977 : public LayerTreeHostAnimationTest {
978 public:
979 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
980 : num_swap_buffers_(0) {}
982 void SetupTree() override {
983 LayerTreeHostAnimationTest::SetupTree();
984 layer_ = Layer::Create(layer_settings());
985 layer_->SetBounds(gfx::Size(4, 4));
986 layer_tree_host()->root_layer()->AddChild(layer_);
989 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
991 void DidCommit() override {
992 switch (layer_tree_host()->source_frame_number()) {
993 case 1:
994 // First frame: add an animation to the root layer.
995 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
996 break;
997 case 2:
998 // Second frame: add an animation to the content layer. The root layer
999 // animation has caused us to animate already during this frame.
1000 AddOpacityTransitionToLayer(layer_.get(), 0.1, 5, 5, false);
1001 break;
1005 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1006 // After both animations have started, verify that they have valid
1007 // start times.
1008 num_swap_buffers_++;
1009 AnimationRegistrar::AnimationControllerMap controllers_copy =
1010 host_impl->animation_registrar()
1011 ->active_animation_controllers_for_testing();
1012 if (controllers_copy.size() == 2u) {
1013 EndTest();
1014 EXPECT_GE(num_swap_buffers_, 3);
1015 for (auto& it : controllers_copy) {
1016 int id = it.first;
1017 if (id == host_impl->RootLayer()->id()) {
1018 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
1019 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1020 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1021 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
1022 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1028 void AfterTest() override {}
1030 private:
1031 scoped_refptr<Layer> layer_;
1032 int num_swap_buffers_;
1035 SINGLE_AND_MULTI_THREAD_TEST_F(
1036 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1038 class LayerTreeHostAnimationTestNotifyAnimationFinished
1039 : public LayerTreeHostAnimationTest {
1040 public:
1041 LayerTreeHostAnimationTestNotifyAnimationFinished()
1042 : called_animation_started_(false), called_animation_finished_(false) {}
1044 void SetupTree() override {
1045 LayerTreeHostAnimationTest::SetupTree();
1046 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
1047 picture_->SetBounds(gfx::Size(4, 4));
1048 picture_->set_layer_animation_delegate(this);
1049 layer_tree_host()->root_layer()->AddChild(picture_);
1052 void BeginTest() override {
1053 layer_tree_host()->SetViewportSize(gfx::Size());
1054 PostAddLongAnimationToMainThread(picture_.get());
1057 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
1058 Animation::TargetProperty target_property,
1059 int group) override {
1060 called_animation_started_ = true;
1061 layer_tree_host()->AnimateLayers(
1062 base::TimeTicks::FromInternalValue(std::numeric_limits<int64>::max()));
1063 PostSetNeedsCommitToMainThread();
1066 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
1067 Animation::TargetProperty target_property,
1068 int group) override {
1069 called_animation_finished_ = true;
1070 EndTest();
1073 void AfterTest() override {
1074 EXPECT_TRUE(called_animation_started_);
1075 EXPECT_TRUE(called_animation_finished_);
1078 private:
1079 bool called_animation_started_;
1080 bool called_animation_finished_;
1081 FakeContentLayerClient client_;
1082 scoped_refptr<FakePictureLayer> picture_;
1085 SINGLE_AND_MULTI_THREAD_TEST_F(
1086 LayerTreeHostAnimationTestNotifyAnimationFinished);
1088 } // namespace
1089 } // namespace cc