Remove chrome/browser/chromeos/system/syslogs_provider.h/cc
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation.cc
blobf6bc4d9011b9db51a03597d52fcce8e377252d78
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.h"
16 #include "cc/test/fake_content_layer_client.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 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().empty();
200 if (!started_animating_ && have_animations) {
201 started_animating_ = true;
202 return;
205 if (started_animating_ && !have_animations)
206 EndTest();
209 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
210 Animation::TargetProperty target_property,
211 int group) override {
212 // Animations on the impl-side controller only get deleted during a commit,
213 // so we need to schedule a commit.
214 layer_tree_host()->SetNeedsCommit();
217 void AfterTest() override {}
219 private:
220 bool started_animating_;
223 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted);
225 // Ensures that animations continue to be ticked when we are backgrounded.
226 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
227 : public LayerTreeHostAnimationTest {
228 public:
229 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
230 : num_begin_frames_(0) {}
232 void BeginTest() override {
233 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
236 // Use WillAnimateLayers to set visible false before the animation runs and
237 // causes a commit, so we block the second visible animate in single-thread
238 // mode.
239 void WillAnimateLayers(LayerTreeHostImpl* host_impl,
240 base::TimeTicks monotonic_time) override {
241 // Verify that the host can draw, it's just not visible.
242 EXPECT_TRUE(host_impl->CanDraw());
243 if (num_begin_frames_ < 2) {
244 if (!num_begin_frames_) {
245 // We have a long animation running. It should continue to tick even
246 // if we are not visible.
247 PostSetVisibleToMainThread(false);
249 num_begin_frames_++;
250 return;
252 EndTest();
255 void AfterTest() override {}
257 private:
258 int num_begin_frames_;
261 SINGLE_AND_MULTI_THREAD_TEST_F(
262 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded);
264 // Ensures that animation time remains monotonic when we switch from foreground
265 // to background ticking and back, even if we're skipping draws due to
266 // checkerboarding when in the foreground.
267 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic
268 : public LayerTreeHostAnimationTest {
269 public:
270 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic()
271 : has_background_ticked_(false), num_foreground_animates_(0) {}
273 void InitializeSettings(LayerTreeSettings* settings) override {
274 // Make sure that drawing many times doesn't cause a checkerboarded
275 // animation to start so we avoid flake in this test.
276 settings->timeout_and_draw_when_animation_checkerboards = false;
279 void BeginTest() override {
280 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer());
283 void AnimateLayers(LayerTreeHostImpl* host_impl,
284 base::TimeTicks monotonic_time) override {
285 EXPECT_GE(monotonic_time, last_tick_time_);
286 last_tick_time_ = monotonic_time;
287 if (host_impl->visible()) {
288 num_foreground_animates_++;
289 if (num_foreground_animates_ > 1 && !has_background_ticked_)
290 PostSetVisibleToMainThread(false);
291 else if (has_background_ticked_)
292 EndTest();
293 } else {
294 has_background_ticked_ = true;
295 PostSetVisibleToMainThread(true);
299 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
300 LayerTreeHostImpl::FrameData* frame,
301 DrawResult draw_result) override {
302 if (TestEnded())
303 return draw_result;
304 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
307 void AfterTest() override {}
309 private:
310 bool has_background_ticked_;
311 int num_foreground_animates_;
312 base::TimeTicks last_tick_time_;
315 SINGLE_AND_MULTI_THREAD_TEST_F(
316 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic);
318 // Ensures that animations do not tick when we are backgrounded and
319 // and we have an empty active tree.
320 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
321 : public LayerTreeHostAnimationTest {
322 protected:
323 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
324 : active_tree_was_animated_(false) {}
326 base::TimeDelta BackgroundAnimationInterval(LayerTreeHostImpl* host_impl) {
327 return base::TimeDelta::FromSecondsD(
328 1.0 / host_impl->settings().background_animation_rate);
331 void BeginTest() override {
332 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
335 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
336 Animation::TargetProperty target_property,
337 int group) override {
338 // Replace animated commits with an empty tree.
339 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL));
342 void DidCommit() override {
343 // This alternates setting an empty tree and a non-empty tree with an
344 // animation.
345 switch (layer_tree_host()->source_frame_number()) {
346 case 1:
347 // Wait for NotifyAnimationFinished to commit an empty tree.
348 break;
349 case 2:
350 SetupTree();
351 AddOpacityTransitionToLayer(
352 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true);
353 break;
354 case 3:
355 // Wait for NotifyAnimationFinished to commit an empty tree.
356 break;
357 case 4:
358 EndTest();
359 break;
363 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
364 // At the start of every commit, block activations and make sure
365 // we are backgrounded.
366 if (host_impl->settings().impl_side_painting)
367 host_impl->BlockNotifyReadyToActivateForTesting(true);
368 PostSetVisibleToMainThread(false);
371 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
372 if (!host_impl->settings().impl_side_painting) {
373 // There are no activations to block if we're not impl-side-painting,
374 // so just advance the test immediately.
375 if (host_impl->active_tree()->source_frame_number() < 3)
376 UnblockActivations(host_impl);
377 return;
380 // We block activation for several ticks to make sure that, even though
381 // there is a pending tree with animations, we still do not background
382 // tick if the active tree is empty.
383 if (host_impl->pending_tree()->source_frame_number() < 3) {
384 base::MessageLoopProxy::current()->PostDelayedTask(
385 FROM_HERE,
386 base::Bind(
387 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
388 UnblockActivations,
389 base::Unretained(this), host_impl),
390 4 * BackgroundAnimationInterval(host_impl));
394 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) {
395 if (host_impl->settings().impl_side_painting)
396 host_impl->BlockNotifyReadyToActivateForTesting(false);
399 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
400 active_tree_was_animated_ = false;
402 // Verify that commits are actually alternating with empty / non-empty
403 // trees.
404 int frame_number = host_impl->active_tree()->source_frame_number();
405 switch (frame_number) {
406 case 0:
407 case 2:
408 EXPECT_TRUE(host_impl->active_tree()->root_layer())
409 << "frame: " << frame_number;
410 break;
411 case 1:
412 case 3:
413 EXPECT_FALSE(host_impl->active_tree()->root_layer())
414 << "frame: " << frame_number;
415 break;
418 if (host_impl->active_tree()->source_frame_number() < 3) {
419 // Initiate the next commit after a delay to give us a chance to
420 // background tick if the active tree isn't empty.
421 base::MessageLoopProxy::current()->PostDelayedTask(
422 FROM_HERE,
423 base::Bind(
424 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
425 InitiateNextCommit,
426 base::Unretained(this), host_impl),
427 4 * BackgroundAnimationInterval(host_impl));
431 void WillAnimateLayers(LayerTreeHostImpl* host_impl,
432 base::TimeTicks monotonic_time) override {
433 EXPECT_TRUE(host_impl->active_tree()->root_layer());
434 active_tree_was_animated_ = true;
437 void InitiateNextCommit(LayerTreeHostImpl* host_impl) {
438 // Verify that we actually animated when we should have.
439 bool has_active_tree = host_impl->active_tree()->root_layer();
440 EXPECT_EQ(has_active_tree, active_tree_was_animated_);
442 // The next commit is blocked until we become visible again.
443 PostSetVisibleToMainThread(true);
446 void AfterTest() override {}
448 bool active_tree_was_animated_;
451 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
452 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree);
454 // Ensure that an animation's timing function is respected.
455 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
456 : public LayerTreeHostAnimationTest {
457 public:
458 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
460 void SetupTree() override {
461 LayerTreeHostAnimationTest::SetupTree();
462 content_ = FakeContentLayer::Create(&client_);
463 content_->SetBounds(gfx::Size(4, 4));
464 layer_tree_host()->root_layer()->AddChild(content_);
467 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
469 void AnimateLayers(LayerTreeHostImpl* host_impl,
470 base::TimeTicks monotonic_time) override {
471 LayerAnimationController* controller_impl =
472 host_impl->active_tree()->root_layer()->children()[0]->
473 layer_animation_controller();
474 Animation* animation =
475 controller_impl->GetAnimation(Animation::Opacity);
476 if (!animation)
477 return;
479 const FloatAnimationCurve* curve =
480 animation->curve()->ToFloatAnimationCurve();
481 float start_opacity = curve->GetValue(base::TimeDelta());
482 float end_opacity = curve->GetValue(curve->Duration());
483 float linearly_interpolated_opacity =
484 0.25f * end_opacity + 0.75f * start_opacity;
485 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
486 // If the linear timing function associated with this animation was not
487 // picked up, then the linearly interpolated opacity would be different
488 // because of the default ease timing function.
489 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
491 EndTest();
494 void AfterTest() override {}
496 FakeContentLayerClient client_;
497 scoped_refptr<FakeContentLayer> content_;
500 SINGLE_AND_MULTI_THREAD_TEST_F(
501 LayerTreeHostAnimationTestAddAnimationWithTimingFunction);
503 // Ensures that main thread animations have their start times synchronized with
504 // impl thread animations.
505 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
506 : public LayerTreeHostAnimationTest {
507 public:
508 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
510 void SetupTree() override {
511 LayerTreeHostAnimationTest::SetupTree();
512 content_ = FakeContentLayer::Create(&client_);
513 content_->SetBounds(gfx::Size(4, 4));
514 content_->set_layer_animation_delegate(this);
515 layer_tree_host()->root_layer()->AddChild(content_);
518 void BeginTest() override { PostAddAnimationToMainThread(content_.get()); }
520 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
521 Animation::TargetProperty target_property,
522 int group) override {
523 LayerAnimationController* controller =
524 layer_tree_host()->root_layer()->children()[0]->
525 layer_animation_controller();
526 Animation* animation =
527 controller->GetAnimation(Animation::Opacity);
528 main_start_time_ = animation->start_time();
529 controller->RemoveAnimation(animation->id());
530 EndTest();
533 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
534 bool has_unfinished_animation) override {
535 LayerAnimationController* controller =
536 impl_host->active_tree()->root_layer()->children()[0]->
537 layer_animation_controller();
538 Animation* animation =
539 controller->GetAnimation(Animation::Opacity);
540 if (!animation)
541 return;
543 impl_start_time_ = animation->start_time();
546 void AfterTest() override {
547 EXPECT_EQ(impl_start_time_, main_start_time_);
548 EXPECT_LT(base::TimeTicks(), impl_start_time_);
551 private:
552 base::TimeTicks main_start_time_;
553 base::TimeTicks impl_start_time_;
554 FakeContentLayerClient client_;
555 scoped_refptr<FakeContentLayer> content_;
558 SINGLE_AND_MULTI_THREAD_TEST_F(
559 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes);
561 // Ensures that notify animation finished is called.
562 class LayerTreeHostAnimationTestAnimationFinishedEvents
563 : public LayerTreeHostAnimationTest {
564 public:
565 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
567 void BeginTest() override {
568 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
571 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
572 Animation::TargetProperty target_property,
573 int group) override {
574 LayerAnimationController* controller =
575 layer_tree_host()->root_layer()->layer_animation_controller();
576 Animation* animation =
577 controller->GetAnimation(Animation::Opacity);
578 if (animation)
579 controller->RemoveAnimation(animation->id());
580 EndTest();
583 void AfterTest() override {}
586 SINGLE_AND_MULTI_THREAD_TEST_F(
587 LayerTreeHostAnimationTestAnimationFinishedEvents);
589 // Ensures that when opacity is being animated, this value does not cause the
590 // subtree to be skipped.
591 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
592 : public LayerTreeHostAnimationTest {
593 public:
594 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
595 : update_check_layer_(FakeContentLayer::Create(&client_)) {
598 void SetupTree() override {
599 update_check_layer_->SetOpacity(0.f);
600 layer_tree_host()->SetRootLayer(update_check_layer_);
601 LayerTreeHostAnimationTest::SetupTree();
604 void BeginTest() override {
605 PostAddAnimationToMainThread(update_check_layer_.get());
608 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
609 LayerAnimationController* controller_impl =
610 host_impl->active_tree()->root_layer()->layer_animation_controller();
611 Animation* animation_impl =
612 controller_impl->GetAnimation(Animation::Opacity);
613 controller_impl->RemoveAnimation(animation_impl->id());
614 EndTest();
617 void AfterTest() override {
618 // Update() should have been called once, proving that the layer was not
619 // skipped.
620 EXPECT_EQ(1u, update_check_layer_->update_count());
622 // clear update_check_layer_ so LayerTreeHost dies.
623 update_check_layer_ = NULL;
626 private:
627 FakeContentLayerClient client_;
628 scoped_refptr<FakeContentLayer> update_check_layer_;
631 SINGLE_AND_MULTI_THREAD_TEST_F(
632 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity);
634 // Layers added to tree with existing active animations should have the
635 // animation correctly recognized.
636 class LayerTreeHostAnimationTestLayerAddedWithAnimation
637 : public LayerTreeHostAnimationTest {
638 public:
639 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
641 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
643 void DidCommit() override {
644 if (layer_tree_host()->source_frame_number() == 1) {
645 scoped_refptr<Layer> layer = Layer::Create();
646 layer->set_layer_animation_delegate(this);
648 // Any valid AnimationCurve will do here.
649 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
650 scoped_ptr<Animation> animation(
651 Animation::Create(curve.Pass(), 1, 1,
652 Animation::Opacity));
653 layer->layer_animation_controller()->AddAnimation(animation.Pass());
655 // We add the animation *before* attaching the layer to the tree.
656 layer_tree_host()->root_layer()->AddChild(layer);
660 void AnimateLayers(LayerTreeHostImpl* impl_host,
661 base::TimeTicks monotonic_time) override {
662 EndTest();
665 void AfterTest() override {}
668 SINGLE_AND_MULTI_THREAD_TEST_F(
669 LayerTreeHostAnimationTestLayerAddedWithAnimation);
671 class LayerTreeHostAnimationTestCancelAnimateCommit
672 : public LayerTreeHostAnimationTest {
673 public:
674 LayerTreeHostAnimationTestCancelAnimateCommit()
675 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
677 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
679 void BeginMainFrame(const BeginFrameArgs& args) override {
680 num_begin_frames_++;
681 // No-op animate will cancel the commit.
682 if (layer_tree_host()->source_frame_number() == 1) {
683 EndTest();
684 return;
686 layer_tree_host()->SetNeedsAnimate();
689 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override {
690 num_commit_calls_++;
691 if (impl->active_tree()->source_frame_number() > 1)
692 FAIL() << "Commit should have been canceled.";
695 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
696 num_draw_calls_++;
697 if (impl->active_tree()->source_frame_number() > 1)
698 FAIL() << "Draw should have been canceled.";
701 void AfterTest() override {
702 EXPECT_EQ(2, num_begin_frames_);
703 EXPECT_EQ(1, num_commit_calls_);
704 EXPECT_EQ(1, num_draw_calls_);
707 private:
708 int num_begin_frames_;
709 int num_commit_calls_;
710 int num_draw_calls_;
711 FakeContentLayerClient client_;
712 scoped_refptr<FakeContentLayer> content_;
715 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit);
717 class LayerTreeHostAnimationTestForceRedraw
718 : public LayerTreeHostAnimationTest {
719 public:
720 LayerTreeHostAnimationTestForceRedraw()
721 : num_animate_(0), num_draw_layers_(0) {}
723 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
725 void BeginMainFrame(const BeginFrameArgs& args) override {
726 if (++num_animate_ < 2)
727 layer_tree_host()->SetNeedsAnimate();
730 void Layout() override { layer_tree_host()->SetNextCommitForcesRedraw(); }
732 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
733 if (++num_draw_layers_ == 2)
734 EndTest();
737 void AfterTest() override {
738 // The first commit will always draw; make sure the second draw triggered
739 // by the animation was not cancelled.
740 EXPECT_EQ(2, num_draw_layers_);
741 EXPECT_EQ(2, num_animate_);
744 private:
745 int num_animate_;
746 int num_draw_layers_;
749 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw);
751 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
752 : public LayerTreeHostAnimationTest {
753 public:
754 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
755 : num_animate_(0), num_draw_layers_(0) {}
757 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
759 void BeginMainFrame(const BeginFrameArgs& args) override {
760 if (++num_animate_ <= 2) {
761 layer_tree_host()->SetNeedsCommit();
762 layer_tree_host()->SetNeedsAnimate();
766 void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
767 if (++num_draw_layers_ == 2)
768 EndTest();
771 void AfterTest() override {
772 // The first commit will always draw; make sure the second draw triggered
773 // by the SetNeedsCommit was not cancelled.
774 EXPECT_EQ(2, num_draw_layers_);
775 EXPECT_GE(num_animate_, 2);
778 private:
779 int num_animate_;
780 int num_draw_layers_;
783 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit);
785 // Make sure the main thread can still execute animations when CanDraw() is not
786 // true.
787 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
788 : public LayerTreeHostAnimationTest {
789 public:
790 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
792 void SetupTree() override {
793 LayerTreeHostAnimationTest::SetupTree();
794 content_ = FakeContentLayer::Create(&client_);
795 content_->SetBounds(gfx::Size(4, 4));
796 content_->set_layer_animation_delegate(this);
797 layer_tree_host()->root_layer()->AddChild(content_);
800 void BeginTest() override {
801 layer_tree_host()->SetViewportSize(gfx::Size());
802 PostAddAnimationToMainThread(content_.get());
805 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
806 Animation::TargetProperty target_property,
807 int group) override {
808 started_times_++;
811 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
812 Animation::TargetProperty target_property,
813 int group) override {
814 EndTest();
817 void AfterTest() override { EXPECT_EQ(1, started_times_); }
819 private:
820 int started_times_;
821 FakeContentLayerClient client_;
822 scoped_refptr<FakeContentLayer> content_;
825 SINGLE_AND_MULTI_THREAD_TEST_F(
826 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw);
828 // Make sure the main thread can still execute animations when the renderer is
829 // backgrounded.
830 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
831 : public LayerTreeHostAnimationTest {
832 public:
833 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
835 void SetupTree() override {
836 LayerTreeHostAnimationTest::SetupTree();
837 content_ = FakeContentLayer::Create(&client_);
838 content_->SetBounds(gfx::Size(4, 4));
839 content_->set_layer_animation_delegate(this);
840 layer_tree_host()->root_layer()->AddChild(content_);
843 void BeginTest() override {
844 visible_ = true;
845 PostAddAnimationToMainThread(content_.get());
848 void DidCommit() override {
849 visible_ = false;
850 layer_tree_host()->SetVisible(false);
853 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
854 Animation::TargetProperty target_property,
855 int group) override {
856 EXPECT_FALSE(visible_);
857 started_times_++;
860 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
861 Animation::TargetProperty target_property,
862 int group) override {
863 EXPECT_FALSE(visible_);
864 EXPECT_EQ(1, started_times_);
865 EndTest();
868 void AfterTest() override {}
870 private:
871 bool visible_;
872 int started_times_;
873 FakeContentLayerClient client_;
874 scoped_refptr<FakeContentLayer> content_;
877 SINGLE_AND_MULTI_THREAD_TEST_F(
878 LayerTreeHostAnimationTestRunAnimationWhenNotVisible);
880 // Animations should not be started when frames are being skipped due to
881 // checkerboard.
882 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
883 : public LayerTreeHostAnimationTest {
884 void SetupTree() override {
885 LayerTreeHostAnimationTest::SetupTree();
886 content_ = FakeContentLayer::Create(&client_);
887 content_->SetBounds(gfx::Size(4, 4));
888 content_->set_layer_animation_delegate(this);
889 layer_tree_host()->root_layer()->AddChild(content_);
892 void InitializeSettings(LayerTreeSettings* settings) override {
893 // Make sure that drawing many times doesn't cause a checkerboarded
894 // animation to start so we avoid flake in this test.
895 settings->timeout_and_draw_when_animation_checkerboards = false;
898 void BeginTest() override {
899 prevented_draw_ = 0;
900 added_animations_ = 0;
901 started_times_ = 0;
903 PostSetNeedsCommitToMainThread();
906 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
907 LayerTreeHostImpl::FrameData* frame_data,
908 DrawResult draw_result) override {
909 if (added_animations_ < 2)
910 return draw_result;
911 if (TestEnded())
912 return draw_result;
913 // Act like there is checkerboard when the second animation wants to draw.
914 ++prevented_draw_;
915 if (prevented_draw_ > 2)
916 EndTest();
917 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
920 void DidCommitAndDrawFrame() override {
921 switch (layer_tree_host()->source_frame_number()) {
922 case 1:
923 // The animation is longer than 1 BeginFrame interval.
924 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false);
925 added_animations_++;
926 break;
927 case 2:
928 // This second animation will not be drawn so it should not start.
929 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5);
930 added_animations_++;
931 break;
935 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
936 Animation::TargetProperty target_property,
937 int group) override {
938 if (TestEnded())
939 return;
940 started_times_++;
943 void AfterTest() override {
944 // Make sure we tried to draw the second animation but failed.
945 EXPECT_LT(0, prevented_draw_);
946 // The first animation should be started, but the second should not because
947 // of checkerboard.
948 EXPECT_EQ(1, started_times_);
951 int prevented_draw_;
952 int added_animations_;
953 int started_times_;
954 FakeContentLayerClient client_;
955 scoped_refptr<FakeContentLayer> content_;
958 MULTI_THREAD_TEST_F(
959 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations);
961 // Verifies that scroll offset animations are only accepted when impl-scrolling
962 // is supported, and that when scroll offset animations are accepted,
963 // scroll offset updates are sent back to the main thread.
964 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
965 : public LayerTreeHostAnimationTest {
966 public:
967 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
969 void SetupTree() override {
970 LayerTreeHostAnimationTest::SetupTree();
972 scroll_layer_ = FakeContentLayer::Create(&client_);
973 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
974 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
975 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
976 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
979 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
981 void DidCommit() override {
982 switch (layer_tree_host()->source_frame_number()) {
983 case 1: {
984 scoped_ptr<ScrollOffsetAnimationCurve> curve(
985 ScrollOffsetAnimationCurve::Create(
986 gfx::ScrollOffset(500.f, 550.f),
987 EaseInOutTimingFunction::Create()));
988 scoped_ptr<Animation> animation(
989 Animation::Create(curve.Pass(), 1, 0, Animation::ScrollOffset));
990 animation->set_needs_synchronized_start_time(true);
991 bool animation_added = scroll_layer_->AddAnimation(animation.Pass());
992 bool impl_scrolling_supported =
993 layer_tree_host()->proxy()->SupportsImplScrolling();
994 EXPECT_EQ(impl_scrolling_supported, animation_added);
995 if (!impl_scrolling_supported)
996 EndTest();
997 break;
999 default:
1000 if (scroll_layer_->scroll_offset().x() > 10 &&
1001 scroll_layer_->scroll_offset().y() > 20)
1002 EndTest();
1006 void AfterTest() override {}
1008 private:
1009 FakeContentLayerClient client_;
1010 scoped_refptr<FakeContentLayer> scroll_layer_;
1013 SINGLE_AND_MULTI_THREAD_TEST_F(
1014 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated);
1016 // When animations are simultaneously added to an existing layer and to a new
1017 // layer, they should start at the same time, even when there's already a
1018 // running animation on the existing layer.
1019 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
1020 : public LayerTreeHostAnimationTest {
1021 public:
1022 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
1023 : frame_count_with_pending_tree_(0) {}
1025 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1027 void DidCommit() override {
1028 if (layer_tree_host()->source_frame_number() == 1) {
1029 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
1030 } else if (layer_tree_host()->source_frame_number() == 2) {
1031 AddOpacityTransitionToLayer(
1032 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true);
1034 scoped_refptr<Layer> layer = Layer::Create();
1035 layer_tree_host()->root_layer()->AddChild(layer);
1036 layer->set_layer_animation_delegate(this);
1037 layer->SetBounds(gfx::Size(4, 4));
1038 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true);
1042 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
1043 if (host_impl->settings().impl_side_painting)
1044 host_impl->BlockNotifyReadyToActivateForTesting(true);
1047 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
1048 // For the commit that added animations to new and existing layers, keep
1049 // blocking activation. We want to verify that even with activation blocked,
1050 // the animation on the layer that's already in the active tree won't get a
1051 // head start.
1052 if (host_impl->settings().impl_side_painting &&
1053 host_impl->pending_tree()->source_frame_number() != 2) {
1054 host_impl->BlockNotifyReadyToActivateForTesting(false);
1058 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
1059 const BeginFrameArgs& args) override {
1060 if (!host_impl->pending_tree() ||
1061 host_impl->pending_tree()->source_frame_number() != 2)
1062 return;
1064 frame_count_with_pending_tree_++;
1065 if (frame_count_with_pending_tree_ == 2 &&
1066 host_impl->settings().impl_side_painting) {
1067 host_impl->BlockNotifyReadyToActivateForTesting(false);
1071 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
1072 bool has_unfinished_animation) override {
1073 LayerAnimationController* root_controller_impl =
1074 host_impl->active_tree()->root_layer()->layer_animation_controller();
1075 Animation* root_animation =
1076 root_controller_impl->GetAnimation(Animation::Opacity);
1077 if (!root_animation || root_animation->run_state() != Animation::Running)
1078 return;
1080 LayerAnimationController* child_controller_impl =
1081 host_impl->active_tree()->root_layer()->children()
1082 [0]->layer_animation_controller();
1083 Animation* child_animation =
1084 child_controller_impl->GetAnimation(Animation::Opacity);
1085 EXPECT_EQ(Animation::Running, child_animation->run_state());
1086 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
1087 root_controller_impl->AbortAnimations(Animation::Opacity);
1088 root_controller_impl->AbortAnimations(Animation::Transform);
1089 child_controller_impl->AbortAnimations(Animation::Opacity);
1090 EndTest();
1093 void AfterTest() override {}
1095 private:
1096 int frame_count_with_pending_tree_;
1099 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
1100 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers);
1102 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
1103 : public LayerTreeHostAnimationTest {
1104 public:
1105 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
1106 : num_swap_buffers_(0) {}
1108 void SetupTree() override {
1109 LayerTreeHostAnimationTest::SetupTree();
1110 content_ = Layer::Create();
1111 content_->SetBounds(gfx::Size(4, 4));
1112 layer_tree_host()->root_layer()->AddChild(content_);
1115 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
1117 void DidCommit() override {
1118 switch (layer_tree_host()->source_frame_number()) {
1119 case 1:
1120 // First frame: add an animation to the root layer.
1121 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
1122 break;
1123 case 2:
1124 // Second frame: add an animation to the content layer. The root layer
1125 // animation has caused us to animate already during this frame.
1126 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
1127 break;
1131 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
1132 // After both animations have started, verify that they have valid
1133 // start times.
1134 num_swap_buffers_++;
1135 AnimationRegistrar::AnimationControllerMap copy =
1136 host_impl->animation_registrar()->active_animation_controllers();
1137 if (copy.size() == 2u) {
1138 EndTest();
1139 EXPECT_GE(num_swap_buffers_, 3);
1140 for (AnimationRegistrar::AnimationControllerMap::iterator iter =
1141 copy.begin();
1142 iter != copy.end();
1143 ++iter) {
1144 int id = ((*iter).second->id());
1145 if (id == host_impl->RootLayer()->id()) {
1146 Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
1147 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1148 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
1149 Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
1150 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
1156 void AfterTest() override {}
1158 private:
1159 scoped_refptr<Layer> content_;
1160 int num_swap_buffers_;
1163 SINGLE_AND_MULTI_THREAD_TEST_F(
1164 LayerTreeHostAnimationTestAddAnimationAfterAnimating);
1166 } // namespace
1167 } // namespace cc