Use placeholders instead of vertical bars in string formatting.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobcfd8a1489af4a06f045b1b817c18b83ed721c852
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/layers/layer.h"
12 #include "cc/layers/layer_impl.h"
13 #include "cc/test/animation_test_common.h"
14 #include "cc/test/fake_content_layer.h"
15 #include "cc/test/fake_content_layer_client.h"
16 #include "cc/test/layer_tree_test.h"
17 #include "cc/trees/layer_tree_impl.h"
19 namespace cc {
20 namespace {
22 class LayerTreeHostAnimationTest : public LayerTreeTest {
23 public:
24 void SetupTree() override {
25 LayerTreeTest::SetupTree();
26 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
30 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
31 // be set.
32 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
33 : public LayerTreeHostAnimationTest {
34 public:
35 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
36 : num_commits_(0) {}
38 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
40 void BeginMainFrame(const BeginFrameArgs& args) override {
41 // We skip the first commit because its the commit that populates the
42 // impl thread with a tree. After the second commit, the test is done.
43 if (num_commits_ != 1)
44 return;
46 layer_tree_host()->SetNeedsAnimate();
47 // Right now, CommitRequested is going to be true, because during
48 // BeginFrame, we force CommitRequested to true to prevent requests from
49 // hitting the impl thread. But, when the next DidCommit happens, we should
50 // verify that CommitRequested has gone back to false.
53 void DidCommit() override {
54 if (!num_commits_) {
55 EXPECT_FALSE(layer_tree_host()->CommitRequested());
56 layer_tree_host()->SetNeedsAnimate();
57 EXPECT_FALSE(layer_tree_host()->CommitRequested());
60 // Verifies that the SetNeedsAnimate we made in ::Animate did not
61 // trigger CommitRequested.
62 EXPECT_FALSE(layer_tree_host()->CommitRequested());
63 EndTest();
64 num_commits_++;
67 void AfterTest() override {}
69 private:
70 int num_commits_;
73 MULTI_THREAD_TEST_F(
74 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested);
76 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
77 // callback, request another frame using SetNeedsAnimate. End the test when
78 // animate gets called yet-again, indicating that the proxy is correctly
79 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
80 // flow.
81 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
82 : public LayerTreeHostAnimationTest {
83 public:
84 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
85 : num_begin_frames_(0) {}
87 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
89 void BeginMainFrame(const BeginFrameArgs& args) override {
90 if (!num_begin_frames_) {
91 layer_tree_host()->SetNeedsAnimate();
92 num_begin_frames_++;
93 return;
95 EndTest();
98 void AfterTest() override {}
100 private:
101 int num_begin_frames_;
104 MULTI_THREAD_TEST_F(
105 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback);
107 // Add a layer animation and confirm that
108 // LayerTreeHostImpl::updateAnimationState does get called and continues to
109 // get called.
110 class LayerTreeHostAnimationTestAddAnimation
111 : public LayerTreeHostAnimationTest {
112 public:
113 LayerTreeHostAnimationTestAddAnimation()
114 : num_begin_frames_(0), received_animation_started_notification_(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 if (!num_begin_frames_) {
123 // The animation had zero duration so LayerTreeHostImpl should no
124 // longer need to animate its layers.
125 EXPECT_FALSE(has_unfinished_animation);
126 num_begin_frames_++;
127 return;
130 if (received_animation_started_notification_) {
131 EXPECT_LT(base::TimeTicks(), start_time_);
133 LayerAnimationController* controller_impl =
134 host_impl->active_tree()->root_layer()->layer_animation_controller();
135 Animation* animation_impl =
136 controller_impl->GetAnimation(Animation::Opacity);
137 if (animation_impl)
138 controller_impl->RemoveAnimation(animation_impl->id());
140 EndTest();
144 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
145 Animation::TargetProperty target_property,
146 int group) override {
147 received_animation_started_notification_ = true;
148 start_time_ = monotonic_time;
149 if (num_begin_frames_) {
150 EXPECT_LT(base::TimeTicks(), start_time_);
152 LayerAnimationController* controller =
153 layer_tree_host()->root_layer()->layer_animation_controller();
154 Animation* animation =
155 controller->GetAnimation(Animation::Opacity);
156 if (animation)
157 controller->RemoveAnimation(animation->id());
159 EndTest();
163 void AfterTest() override {}
165 private:
166 int num_begin_frames_;
167 bool received_animation_started_notification_;
168 base::TimeTicks start_time_;
171 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation);
173 // Add a layer animation to a layer, but continually fail to draw. Confirm that
174 // after a while, we do eventually force a draw.
175 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
176 : public LayerTreeHostAnimationTest {
177 public:
178 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
179 : started_animating_(false) {}
181 void BeginTest() override {
182 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
185 void AnimateLayers(LayerTreeHostImpl* host_impl,
186 base::TimeTicks monotonic_time) override {
187 started_animating_ = true;
190 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
191 if (started_animating_)
192 EndTest();
195 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
196 LayerTreeHostImpl::FrameData* frame,
197 DrawResult draw_result) override {
198 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
201 void AfterTest() override {}
203 private:
204 bool started_animating_;
207 // Starvation can only be an issue with the MT compositor.
208 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws);
210 // Ensures that animations eventually get deleted.
211 class LayerTreeHostAnimationTestAnimationsGetDeleted
212 : public LayerTreeHostAnimationTest {
213 public:
214 LayerTreeHostAnimationTestAnimationsGetDeleted()
215 : started_animating_(false) {}
217 void BeginTest() override {
218 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
221 void AnimateLayers(LayerTreeHostImpl* host_impl,
222 base::TimeTicks monotonic_time) override {
223 bool have_animations = !host_impl->animation_registrar()->
224 active_animation_controllers().empty();
225 if (!started_animating_ && have_animations) {
226 started_animating_ = true;
227 return;
230 if (started_animating_ && !have_animations)
231 EndTest();
234 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
235 Animation::TargetProperty target_property,
236 int group) override {
237 // Animations on the impl-side controller only get deleted during a commit,
238 // so we need to schedule a commit.
239 layer_tree_host()->SetNeedsCommit();
242 void AfterTest() override {}
244 private:
245 bool started_animating_;
248 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
250 // Ensures that animations continue to be ticked when we are backgrounded.
251 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
252 : public LayerTreeHostAnimationTest {
253 public:
254 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
255 : num_begin_frames_(0) {}
257 void BeginTest() override {
258 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
261 // Use WillAnimateLayers to set visible false before the animation runs and
262 // causes a commit, so we block the second visible animate in single-thread
263 // mode.
264 void WillAnimateLayers(LayerTreeHostImpl* host_impl,
265 base::TimeTicks monotonic_time) override {
266 // Verify that the host can draw, it's just not visible.
267 EXPECT_TRUE(host_impl->CanDraw());
268 if (num_begin_frames_ < 2) {
269 if (!num_begin_frames_) {
270 // We have a long animation running. It should continue to tick even
271 // if we are not visible.
272 PostSetVisibleToMainThread(false);
274 num_begin_frames_++;
275 return;
277 EndTest();
280 void AfterTest() override {}
282 private:
283 int num_begin_frames_;
286 SINGLE_AND_MULTI_THREAD_TEST_F(
287 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
289 // Ensures that animation time remains monotonic when we switch from foreground
290 // to background ticking and back, even if we're skipping draws due to
291 // checkerboarding when in the foreground.
292 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
293 : public LayerTreeHostAnimationTest {
294 public:
295 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
296 : has_background_ticked_(false), num_foreground_animates_(0) {}
298 void InitializeSettings(LayerTreeSettings* settings) override {
299 // Make sure that drawing many times doesn't cause a checkerboarded
300 // animation to start so we avoid flake in this test.
301 settings->timeout_and_draw_when_animation_checkerboards = false;
304 void BeginTest() override {
305 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
308 void AnimateLayers(LayerTreeHostImpl* host_impl,
309 base::TimeTicks monotonic_time) override {
310 EXPECT_GE(monotonic_time, last_tick_time_);
311 last_tick_time_ = monotonic_time;
312 if (host_impl->visible()) {
313 num_foreground_animates_++;
314 if (num_foreground_animates_ > 1 && !has_background_ticked_)
315 PostSetVisibleToMainThread(false);
316 else if (has_background_ticked_)
317 EndTest();
318 } else {
319 has_background_ticked_ = true;
320 PostSetVisibleToMainThread(true);
324 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
325 LayerTreeHostImpl::FrameData* frame,
326 DrawResult draw_result) override {
327 if (TestEnded())
328 return draw_result;
329 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
332 void AfterTest() override {}
334 private:
335 bool has_background_ticked_;
336 int num_foreground_animates_;
337 base::TimeTicks last_tick_time_;
340 SINGLE_AND_MULTI_THREAD_TEST_F(
341 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic);
343 // Ensures that animations do not tick when we are backgrounded and
344 // and we have an empty active tree.
345 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
346 : public LayerTreeHostAnimationTest {
347 protected:
348 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
349 : active_tree_was_animated_(false) {}
351 base::TimeDelta LowFrequencyAnimationInterval() const override {
352 return base::TimeDelta::FromMilliseconds(4);
355 void BeginTest() override {
356 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
359 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
360 Animation::TargetProperty target_property,
361 int group) override {
362 // Replace animated commits with an empty tree.
363 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
366 void DidCommit() override {
367 // This alternates setting an empty tree and a non-empty tree with an
368 // animation.
369 switch (layer_tree_host()->source_frame_number()) {
370 case 1:
371 // Wait for NotifyAnimationFinished to commit an empty tree.
372 break;
373 case 2:
374 SetupTree();
375 AddOpacityTransitionToLayer(
376 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
377 break;
378 case 3:
379 // Wait for NotifyAnimationFinished to commit an empty tree.
380 break;
381 case 4:
382 EndTest();
383 break;
387 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
388 // At the start of every commit, block activations and make sure
389 // we are backgrounded.
390 if (host_impl->settings().impl_side_painting)
391 host_impl->BlockNotifyReadyToActivateForTesting(true);
392 PostSetVisibleToMainThread(false);
395 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
396 if (!host_impl->settings().impl_side_painting) {
397 // There are no activations to block if we're not impl-side-painting,
398 // so just advance the test immediately.
399 if (host_impl->active_tree()->source_frame_number() < 3)
400 UnblockActivations(host_impl);
401 return;
404 // We block activation for several ticks to make sure that, even though
405 // there is a pending tree with animations, we still do not background
406 // tick if the active tree is empty.
407 if (host_impl->pending_tree()->source_frame_number() < 3) {
408 base::MessageLoopProxy::current()->PostDelayedTask(
409 FROM_HERE,
410 base::Bind(
411 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
412 UnblockActivations,
413 base::Unretained(this),
414 host_impl),
415 4 * LowFrequencyAnimationInterval());
419 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
420 if (host_impl->settings().impl_side_painting)
421 host_impl->BlockNotifyReadyToActivateForTesting(false);
424 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
425 active_tree_was_animated_ = false;
427 // Verify that commits are actually alternating with empty / non-empty
428 // trees.
429 int frame_number = host_impl->active_tree()->source_frame_number();
430 switch (frame_number) {
431 case 0:
432 case 2:
433 EXPECT_TRUE(host_impl->active_tree()->root_layer())
434 << "frame: " << frame_number;
435 break;
436 case 1:
437 case 3:
438 EXPECT_FALSE(host_impl->active_tree()->root_layer())
439 << "frame: " << frame_number;
440 break;
443 if (host_impl->active_tree()->source_frame_number() < 3) {
444 // Initiate the next commit after a delay to give us a chance to
445 // background tick if the active tree isn't empty.
446 base::MessageLoopProxy::current()->PostDelayedTask(
447 FROM_HERE,
448 base::Bind(
449 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
450 InitiateNextCommit,
451 base::Unretained(this),
452 host_impl),
453 4 * LowFrequencyAnimationInterval());
457 void WillAnimateLayers(LayerTreeHostImpl* host_impl,
458 base::TimeTicks monotonic_time) override {
459 EXPECT_TRUE(host_impl->active_tree()->root_layer());
460 active_tree_was_animated_ = true;
463 void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
464 // Verify that we actually animated when we should have.
465 bool has_active_tree = host_impl->active_tree()->root_layer();
466 EXPECT_EQ(has_active_tree, active_tree_was_animated_);
468 // The next commit is blocked until we become visible again.
469 PostSetVisibleToMainThread(true);
472 void AfterTest() override {}
474 bool active_tree_was_animated_;
477 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
478 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
480 // Ensure that an animation's timing function is respected.
481 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
482 : public LayerTreeHostAnimationTest {
483 public:
484 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
486 void SetupTree() override {
487 LayerTreeHostAnimationTest::SetupTree();
488 content_ = FakeContentLayer::Create(&client_);
489 content_->SetBounds(gfx::Size(4, 4));
490 layer_tree_host()->root_layer()->AddChild(content_);
493 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
495 void AnimateLayers(LayerTreeHostImpl* host_impl,
496 base::TimeTicks monotonic_time) override {
497 LayerAnimationController* controller_impl =
498 host_impl->active_tree()->root_layer()->children()[0]->
499 layer_animation_controller();
500 Animation* animation =
501 controller_impl->GetAnimation(Animation::Opacity);
502 if (!animation)
503 return;
505 const FloatAnimationCurve* curve =
506 animation->curve()->ToFloatAnimationCurve();
507 float start_opacity = curve->GetValue(0.0);
508 float end_opacity = curve->GetValue(curve->Duration());
509 float linearly_interpolated_opacity =
510 0.25f * end_opacity + 0.75f * start_opacity;
511 double time = curve->Duration() * 0.25;
512 // If the linear timing function associated with this animation was not
513 // picked up, then the linearly interpolated opacity would be different
514 // because of the default ease timing function.
515 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
517 EndTest();
520 void AfterTest() override {}
522 FakeContentLayerClient client_;
523 scoped_refptr<FakeContentLayer> content_;
526 SINGLE_AND_MULTI_THREAD_TEST_F(
527 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
529 // Ensures that main thread animations have their start times synchronized with
530 // impl thread animations.
531 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
532 : public LayerTreeHostAnimationTest {
533 public:
534 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
535 : main_start_time_(-1.0),
536 impl_start_time_(-1.0) {}
538 void SetupTree() override {
539 LayerTreeHostAnimationTest::SetupTree();
540 content_ = FakeContentLayer::Create(&client_);
541 content_->SetBounds(gfx::Size(4, 4));
542 content_->set_layer_animation_delegate(this);
543 layer_tree_host()->root_layer()->AddChild(content_);
546 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
548 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
549 Animation::TargetProperty target_property,
550 int group) override {
551 LayerAnimationController* controller =
552 layer_tree_host()->root_layer()->children()[0]->
553 layer_animation_controller();
554 Animation* animation =
555 controller->GetAnimation(Animation::Opacity);
556 main_start_time_ =
557 (animation->start_time() - base::TimeTicks()).InSecondsF();
558 controller->RemoveAnimation(animation->id());
560 if (impl_start_time_ > 0.0)
561 EndTest();
564 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
565 bool has_unfinished_animation) override {
566 LayerAnimationController* controller =
567 impl_host->active_tree()->root_layer()->children()[0]->
568 layer_animation_controller();
569 Animation* animation =
570 controller->GetAnimation(Animation::Opacity);
571 if (!animation)
572 return;
574 impl_start_time_ =
575 (animation->start_time() - base::TimeTicks()).InSecondsF();
576 controller->RemoveAnimation(animation->id());
578 if (main_start_time_ > 0.0)
579 EndTest();
582 void AfterTest() override {
583 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_);
586 private:
587 double main_start_time_;
588 double impl_start_time_;
589 FakeContentLayerClient client_;
590 scoped_refptr<FakeContentLayer> content_;
593 SINGLE_AND_MULTI_THREAD_TEST_F(
594 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
596 // Ensures that notify animation finished is called.
597 class LayerTreeHostAnimationTestAnimationFinishedEvents
598 : public LayerTreeHostAnimationTest {
599 public:
600 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
602 void BeginTest() override {
603 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
606 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
607 Animation::TargetProperty target_property,
608 int group) override {
609 LayerAnimationController* controller =
610 layer_tree_host()->root_layer()->layer_animation_controller();
611 Animation* animation =
612 controller->GetAnimation(Animation::Opacity);
613 if (animation)
614 controller->RemoveAnimation(animation->id());
615 EndTest();
618 void AfterTest() override {}
621 SINGLE_AND_MULTI_THREAD_TEST_F(
622 LayerTreeHostAnimationTestAnimationFinishedEvents);
624 // Ensures that when opacity is being animated, this value does not cause the
625 // subtree to be skipped.
626 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
627 : public LayerTreeHostAnimationTest {
628 public:
629 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
630 : update_check_layer_(FakeContentLayer::Create(&client_)) {
633 void SetupTree() override {
634 update_check_layer_->SetOpacity(0.f);
635 layer_tree_host()->SetRootLayer(update_check_layer_);
636 LayerTreeHostAnimationTest::SetupTree();
639 void BeginTest() override {
640 PostAddAnimationToMainThread(update_check_layer_.get());
643 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
644 LayerAnimationController* controller_impl =
645 host_impl->active_tree()->root_layer()->layer_animation_controller();
646 Animation* animation_impl =
647 controller_impl->GetAnimation(Animation::Opacity);
648 controller_impl->RemoveAnimation(animation_impl->id());
649 EndTest();
652 void AfterTest() override {
653 // Update() should have been called once, proving that the layer was not
654 // skipped.
655 EXPECT_EQ(1u, update_check_layer_->update_count());
657 // clear update_check_layer_ so LayerTreeHost dies.
658 update_check_layer_ = NULL;
661 private:
662 FakeContentLayerClient client_;
663 scoped_refptr<FakeContentLayer> update_check_layer_;
666 SINGLE_AND_MULTI_THREAD_TEST_F(
667 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
669 // Layers added to tree with existing active animations should have the
670 // animation correctly recognized.
671 class LayerTreeHostAnimationTestLayerAddedWithAnimation
672 : public LayerTreeHostAnimationTest {
673 public:
674 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
676 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
678 void DidCommit() override {
679 if (layer_tree_host()->source_frame_number() == 1) {
680 scoped_refptr<Layer> layer = Layer::Create();
681 layer->set_layer_animation_delegate(this);
683 // Any valid AnimationCurve will do here.
684 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
685 scoped_ptr<Animation> animation(
686 Animation::Create(curve.Pass(), 1, 1,
687 Animation::Opacity));
688 layer->layer_animation_controller()->AddAnimation(animation.Pass());
690 // We add the animation *before* attaching the layer to the tree.
691 layer_tree_host()->root_layer()->AddChild(layer);
695 void AnimateLayers(LayerTreeHostImpl* impl_host,
696 base::TimeTicks monotonic_time) override {
697 EndTest();
700 void AfterTest() override {}
703 SINGLE_AND_MULTI_THREAD_TEST_F(
704 LayerTreeHostAnimationTestLayerAddedWithAnimation);
706 class LayerTreeHostAnimationTestCancelAnimateCommit
707 : public LayerTreeHostAnimationTest {
708 public:
709 LayerTreeHostAnimationTestCancelAnimateCommit()
710 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
712 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
714 void BeginMainFrame(const BeginFrameArgs& args) override {
715 num_begin_frames_++;
716 // No-op animate will cancel the commit.
717 if (layer_tree_host()->source_frame_number() == 1) {
718 EndTest();
719 return;
721 layer_tree_host()->SetNeedsAnimate();
724 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
725 num_commit_calls_++;
726 if (impl->active_tree()->source_frame_number() > 1)
727 FAIL() << "Commit should have been canceled.";
730 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
731 num_draw_calls_++;
732 if (impl->active_tree()->source_frame_number() > 1)
733 FAIL() << "Draw should have been canceled.";
736 void AfterTest() override {
737 EXPECT_EQ(2, num_begin_frames_);
738 EXPECT_EQ(1, num_commit_calls_);
739 EXPECT_EQ(1, num_draw_calls_);
742 private:
743 int num_begin_frames_;
744 int num_commit_calls_;
745 int num_draw_calls_;
746 FakeContentLayerClient client_;
747 scoped_refptr<FakeContentLayer> content_;
750 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
752 class LayerTreeHostAnimationTestForceRedraw
753 : public LayerTreeHostAnimationTest {
754 public:
755 LayerTreeHostAnimationTestForceRedraw()
756 : num_animate_(0), num_draw_layers_(0) {}
758 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
760 void BeginMainFrame(const BeginFrameArgs& args) override {
761 if (++num_animate_ < 2)
762 layer_tree_host()->SetNeedsAnimate();
765 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); }
767 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
768 if (++num_draw_layers_ == 2)
769 EndTest();
772 void AfterTest() override {
773 // The first commit will always draw; make sure the second draw triggered
774 // by the animation was not cancelled.
775 EXPECT_EQ(2, num_draw_layers_);
776 EXPECT_EQ(2, num_animate_);
779 private:
780 int num_animate_;
781 int num_draw_layers_;
784 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
786 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
787 : public LayerTreeHostAnimationTest {
788 public:
789 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
790 : num_animate_(0), num_draw_layers_(0) {}
792 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
794 void BeginMainFrame(const BeginFrameArgs& args) override {
795 if (++num_animate_ <= 2) {
796 layer_tree_host()->SetNeedsCommit();
797 layer_tree_host()->SetNeedsAnimate();
801 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
802 if (++num_draw_layers_ == 2)
803 EndTest();
806 void AfterTest() override {
807 // The first commit will always draw; make sure the second draw triggered
808 // by the SetNeedsCommit was not cancelled.
809 EXPECT_EQ(2, num_draw_layers_);
810 EXPECT_GE(num_animate_, 2);
813 private:
814 int num_animate_;
815 int num_draw_layers_;
818 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
820 // Make sure the main thread can still execute animations when CanDraw() is not
821 // true.
822 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
823 : public LayerTreeHostAnimationTest {
824 public:
825 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
827 void SetupTree() override {
828 LayerTreeHostAnimationTest::SetupTree();
829 content_ = FakeContentLayer::Create(&client_);
830 content_->SetBounds(gfx::Size(4, 4));
831 content_->set_layer_animation_delegate(this);
832 layer_tree_host()->root_layer()->AddChild(content_);
835 void BeginTest() override {
836 layer_tree_host()->SetViewportSize(gfx::Size());
837 PostAddAnimationToMainThread(content_.get());
840 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
841 Animation::TargetProperty target_property,
842 int group) override {
843 started_times_++;
846 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
847 Animation::TargetProperty target_property,
848 int group) override {
849 EndTest();
852 void AfterTest() override { EXPECT_EQ(1, started_times_); }
854 private:
855 int started_times_;
856 FakeContentLayerClient client_;
857 scoped_refptr<FakeContentLayer> content_;
860 SINGLE_AND_MULTI_THREAD_TEST_F(
861 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
863 // Make sure the main thread can still execute animations when the renderer is
864 // backgrounded.
865 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
866 : public LayerTreeHostAnimationTest {
867 public:
868 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
870 void SetupTree() override {
871 LayerTreeHostAnimationTest::SetupTree();
872 content_ = FakeContentLayer::Create(&client_);
873 content_->SetBounds(gfx::Size(4, 4));
874 content_->set_layer_animation_delegate(this);
875 layer_tree_host()->root_layer()->AddChild(content_);
878 void BeginTest() override {
879 visible_ = true;
880 PostAddAnimationToMainThread(content_.get());
883 void DidCommit() override {
884 visible_ = false;
885 layer_tree_host()->SetVisible(false);
888 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
889 Animation::TargetProperty target_property,
890 int group) override {
891 EXPECT_FALSE(visible_);
892 started_times_++;
895 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
896 Animation::TargetProperty target_property,
897 int group) override {
898 EXPECT_FALSE(visible_);
899 EXPECT_EQ(1, started_times_);
900 EndTest();
903 void AfterTest() override {}
905 private:
906 bool visible_;
907 int started_times_;
908 FakeContentLayerClient client_;
909 scoped_refptr<FakeContentLayer> content_;
912 SINGLE_AND_MULTI_THREAD_TEST_F(
913 LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
915 // Animations should not be started when frames are being skipped due to
916 // checkerboard.
917 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
918 : public LayerTreeHostAnimationTest {
919 void SetupTree() override {
920 LayerTreeHostAnimationTest::SetupTree();
921 content_ = FakeContentLayer::Create(&client_);
922 content_->SetBounds(gfx::Size(4, 4));
923 content_->set_layer_animation_delegate(this);
924 layer_tree_host()->root_layer()->AddChild(content_);
927 void InitializeSettings(LayerTreeSettings* settings) override {
928 // Make sure that drawing many times doesn't cause a checkerboarded
929 // animation to start so we avoid flake in this test.
930 settings->timeout_and_draw_when_animation_checkerboards = false;
933 void BeginTest() override {
934 prevented_draw_ = 0;
935 added_animations_ = 0;
936 started_times_ = 0;
938 PostSetNeedsCommitToMainThread();
941 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
942 LayerTreeHostImpl::FrameData* frame_data,
943 DrawResult draw_result) override {
944 if (added_animations_ < 2)
945 return draw_result;
946 if (TestEnded())
947 return draw_result;
948 // Act like there is checkerboard when the second animation wants to draw.
949 ++prevented_draw_;
950 if (prevented_draw_ > 2)
951 EndTest();
952 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
955 void DidCommitAndDrawFrame() override {
956 switch (layer_tree_host()->source_frame_number()) {
957 case 1:
958 // The animation is longer than 1 BeginFrame interval.
959 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
960 added_animations_++;
961 break;
962 case 2:
963 // This second animation will not be drawn so it should not start.
964 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
965 added_animations_++;
966 break;
970 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
971 Animation::TargetProperty target_property,
972 int group) override {
973 if (TestEnded())
974 return;
975 started_times_++;
978 void AfterTest() override {
979 // Make sure we tried to draw the second animation but failed.
980 EXPECT_LT(0, prevented_draw_);
981 // The first animation should be started, but the second should not because
982 // of checkerboard.
983 EXPECT_EQ(1, started_times_);
986 int prevented_draw_;
987 int added_animations_;
988 int started_times_;
989 FakeContentLayerClient client_;
990 scoped_refptr<FakeContentLayer> content_;
993 MULTI_THREAD_TEST_F(
994 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
996 // Verifies that scroll offset animations are only accepted when impl-scrolling
997 // is supported, and that when scroll offset animations are accepted,
998 // scroll offset updates are sent back to the main thread.
999 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
1000 : public LayerTreeHostAnimationTest {
1001 public:
1002 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
1004 void SetupTree() override {
1005 LayerTreeHostAnimationTest::SetupTree();
1007 scroll_layer_ = FakeContentLayer::Create(&client_);
1008 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
1009 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
1010 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
1011 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
1014 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1016 void DidCommit() override {
1017 switch (layer_tree_host()->source_frame_number()) {
1018 case 1: {
1019 scoped_ptr<ScrollOffsetAnimationCurve> curve(
1020 ScrollOffsetAnimationCurve::Create(
1021 gfx::ScrollOffset(500.f, 550.f),
1022 EaseInOutTimingFunction::Create()));
1023 scoped_ptr<Animation> animation(
1024 Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset));
1025 animation->set_needs_synchronized_start_time(true);
1026 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
1027 bool impl_scrolling_supported =
1028 layer_tree_host()->proxy()->SupportsImplScrolling();
1029 EXPECT_EQ(impl_scrolling_supported, animation_added);
1030 if (!impl_scrolling_supported)
1031 EndTest();
1032 break;
1034 default:
1035 if (scroll_layer_->scroll_offset().x() > 10 &&
1036 scroll_layer_->scroll_offset().y() > 20)
1037 EndTest();
1041 void AfterTest() override {}
1043 private:
1044 FakeContentLayerClient client_;
1045 scoped_refptr<FakeContentLayer> scroll_layer_;
1048 SINGLE_AND_MULTI_THREAD_TEST_F(
1049 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
1051 // When animations are simultaneously added to an existing layer and to a new
1052 // layer, they should start at the same time, even when there's already a
1053 // running animation on the existing layer.
1054 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1055 : public LayerTreeHostAnimationTest {
1056 public:
1057 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1058 : frame_count_with_pending_tree_(0) {}
1060 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1062 void DidCommit() override {
1063 if (layer_tree_host()->source_frame_number() == 1) {
1064 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1065 } else if (layer_tree_host()->source_frame_number() == 2) {
1066 AddOpacityTransitionToLayer(
1067 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
1069 scoped_refptr<Layer> layer = Layer::Create();
1070 layer_tree_host()->root_layer()->AddChild(layer);
1071 layer->set_layer_animation_delegate(this);
1072 layer->SetBounds(gfx::Size(4, 4));
1073 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
1077 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
1078 if (host_impl->settings().impl_side_painting)
1079 host_impl->BlockNotifyReadyToActivateForTesting(true);
1082 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1083 // For the commit that added animations to new and existing layers, keep
1084 // blocking activation. We want to verify that even with activation blocked,
1085 // the animation on the layer that's already in the active tree won't get a
1086 // head start.
1087 if (host_impl->settings().impl_side_painting &&
1088 host_impl->pending_tree()->source_frame_number() != 2) {
1089 host_impl->BlockNotifyReadyToActivateForTesting(false);
1093 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1094 const BeginFrameArgs& args) override {
1095 if (!host_impl->pending_tree() ||
1096 host_impl->pending_tree()->source_frame_number() != 2)
1097 return;
1099 frame_count_with_pending_tree_++;
1100 if (frame_count_with_pending_tree_ == 2 &&
1101 host_impl->settings().impl_side_painting) {
1102 host_impl->BlockNotifyReadyToActivateForTesting(false);
1106 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1107 bool has_unfinished_animation) override {
1108 LayerAnimationController* root_controller_impl =
1109 host_impl->active_tree()->root_layer()->layer_animation_controller();
1110 Animation* root_animation =
1111 root_controller_impl->GetAnimation(Animation::Opacity);
1112 if (!root_animation || root_animation->run_state() != Animation::Running)
1113 return;
1115 LayerAnimationController* child_controller_impl =
1116 host_impl->active_tree()->root_layer()->children()
1117 [0]->layer_animation_controller();
1118 Animation* child_animation =
1119 child_controller_impl->GetAnimation(Animation::Opacity);
1120 EXPECT_EQ(Animation::Running, child_animation->run_state());
1121 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
1122 root_controller_impl->AbortAnimations(Animation::Opacity);
1123 root_controller_impl->AbortAnimations(Animation::Transform);
1124 child_controller_impl->AbortAnimations(Animation::Opacity);
1125 EndTest();
1128 void AfterTest() override {}
1130 private:
1131 int frame_count_with_pending_tree_;
1134 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1135 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
1137 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1138 : public LayerTreeHostAnimationTest {
1139 public:
1140 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1141 : num_swap_buffers_(0) {}
1143 void SetupTree() override {
1144 LayerTreeHostAnimationTest::SetupTree();
1145 content_ = Layer::Create();
1146 content_->SetBounds(gfx::Size(4, 4));
1147 layer_tree_host()->root_layer()->AddChild(content_);
1150 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1152 void DidCommit() override {
1153 switch (layer_tree_host()->source_frame_number()) {
1154 case 1:
1155 // First frame: add an animation to the root layer.
1156 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1157 break;
1158 case 2:
1159 // Second frame: add an animation to the content layer. The root layer
1160 // animation has caused us to animate already during this frame.
1161 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
1162 break;
1166 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1167 // After both animations have started, verify that they have valid
1168 // start times.
1169 num_swap_buffers_++;
1170 AnimationRegistrar::AnimationControllerMap copy =
1171 host_impl->animation_registrar()->active_animation_controllers();
1172 if (copy.size() == 2u) {
1173 EndTest();
1174 EXPECT_GE(num_swap_buffers_, 3);
1175 for (AnimationRegistrar::AnimationControllerMap::iterator iter =
1176 copy.begin();
1177 iter != copy.end();
1178 ++iter) {
1179 int id = ((*iter).second->id());
1180 if (id == host_impl->RootLayer()->id()) {
1181 Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
1182 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1183 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1184 Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
1185 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1191 void AfterTest() override {}
1193 private:
1194 scoped_refptr<Layer> content_;
1195 int num_swap_buffers_;
1198 SINGLE_AND_MULTI_THREAD_TEST_F(
1199 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1201 } // namespace
1202 } // namespace cc