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/timing_function.h"
10 #include "cc/layers/layer.h"
11 #include "cc/layers/layer_impl.h"
12 #include "cc/test/animation_test_common.h"
13 #include "cc/test/fake_content_layer.h"
14 #include "cc/test/fake_content_layer_client.h"
15 #include "cc/test/layer_tree_test.h"
16 #include "cc/trees/layer_tree_impl.h"
21 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
23 virtual void SetupTree() OVERRIDE
{
24 LayerTreeTest::SetupTree();
25 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
29 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
31 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
32 : public LayerTreeHostAnimationTest
{
34 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
37 virtual void BeginTest() OVERRIDE
{
38 PostSetNeedsCommitToMainThread();
41 virtual void Animate(base::TimeTicks monotonic_time
) OVERRIDE
{
42 // We skip the first commit becasue 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)
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 virtual void DidCommit() OVERRIDE
{
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());
68 virtual void AfterTest() OVERRIDE
{}
75 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
77 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
78 // callback, requet 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 begin frame
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
83 : public LayerTreeHostAnimationTest
{
85 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
88 virtual void BeginTest() OVERRIDE
{
89 PostSetNeedsCommitToMainThread();
92 virtual void Animate(base::TimeTicks
) OVERRIDE
{
94 layer_tree_host()->SetNeedsAnimate();
101 virtual void AfterTest() OVERRIDE
{}
108 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
110 // Add a layer animation and confirm that
111 // LayerTreeHostImpl::updateAnimationState does get called and continues to
113 class LayerTreeHostAnimationTestAddAnimation
114 : public LayerTreeHostAnimationTest
{
116 LayerTreeHostAnimationTestAddAnimation()
118 received_animation_started_notification_(false),
122 virtual void BeginTest() OVERRIDE
{
123 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
126 virtual void UpdateAnimationState(
127 LayerTreeHostImpl
* host_impl
,
128 bool has_unfinished_animation
) OVERRIDE
{
129 if (!num_animates_
) {
130 // The animation had zero duration so LayerTreeHostImpl should no
131 // longer need to animate its layers.
132 EXPECT_FALSE(has_unfinished_animation
);
137 if (received_animation_started_notification_
) {
138 EXPECT_LT(0.0, start_time_
);
140 LayerAnimationController
* controller_impl
=
141 host_impl
->active_tree()->root_layer()->layer_animation_controller();
142 Animation
* animation_impl
=
143 controller_impl
->GetAnimation(0, Animation::Opacity
);
145 controller_impl
->RemoveAnimation(animation_impl
->id());
151 virtual void notifyAnimationStarted(double wall_clock_time
) OVERRIDE
{
152 received_animation_started_notification_
= true;
153 start_time_
= wall_clock_time
;
155 EXPECT_LT(0.0, start_time_
);
157 LayerAnimationController
* controller
=
158 layer_tree_host()->root_layer()->layer_animation_controller();
159 Animation
* animation
=
160 controller
->GetAnimation(0, Animation::Opacity
);
162 controller
->RemoveAnimation(animation
->id());
168 virtual void AfterTest() OVERRIDE
{}
172 bool received_animation_started_notification_
;
176 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
178 // Add a layer animation to a layer, but continually fail to draw. Confirm that
179 // after a while, we do eventually force a draw.
180 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
181 : public LayerTreeHostAnimationTest
{
183 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
184 : started_animating_(false) {}
186 virtual void BeginTest() OVERRIDE
{
187 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
190 virtual void AnimateLayers(
191 LayerTreeHostImpl
* host_impl
,
192 base::TimeTicks monotonic_time
) OVERRIDE
{
193 started_animating_
= true;
196 virtual void DrawLayersOnThread(LayerTreeHostImpl
* tree_impl
) OVERRIDE
{
197 if (started_animating_
)
201 virtual bool PrepareToDrawOnThread(
202 LayerTreeHostImpl
* host_impl
,
203 LayerTreeHostImpl::FrameData
* frame
,
204 bool result
) OVERRIDE
{
208 virtual void AfterTest() OVERRIDE
{}
211 bool started_animating_
;
214 // Starvation can only be an issue with the MT compositor.
215 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
217 // Ensures that animations continue to be ticked when we are backgrounded.
218 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
219 : public LayerTreeHostAnimationTest
{
221 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded()
222 : num_animates_(0) {}
224 virtual void BeginTest() OVERRIDE
{
225 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
228 // Use WillAnimateLayers to set visible false before the animation runs and
229 // causes a commit, so we block the second visible animate in single-thread
231 virtual void WillAnimateLayers(
232 LayerTreeHostImpl
* host_impl
,
233 base::TimeTicks monotonic_time
) OVERRIDE
{
234 if (num_animates_
< 2) {
235 if (!num_animates_
) {
236 // We have a long animation running. It should continue to tick even
237 // if we are not visible.
238 PostSetVisibleToMainThread(false);
246 virtual void AfterTest() OVERRIDE
{}
252 SINGLE_AND_MULTI_THREAD_TEST_F(
253 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded
);
255 // Ensures that animations continue to be ticked when we are backgrounded.
256 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
257 : public LayerTreeHostAnimationTest
{
259 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
261 virtual void SetupTree() OVERRIDE
{
262 LayerTreeHostAnimationTest::SetupTree();
263 content_
= FakeContentLayer::Create(&client_
);
264 content_
->SetBounds(gfx::Size(4, 4));
265 layer_tree_host()->root_layer()->AddChild(content_
);
268 virtual void BeginTest() OVERRIDE
{
269 PostAddAnimationToMainThread(content_
);
272 virtual void AnimateLayers(
273 LayerTreeHostImpl
* host_impl
,
274 base::TimeTicks monotonic_time
) OVERRIDE
{
275 LayerAnimationController
* controller
=
276 layer_tree_host()->root_layer()->children()[0]->
277 layer_animation_controller();
278 Animation
* animation
=
279 controller
->GetAnimation(0, Animation::Opacity
);
283 const FloatAnimationCurve
* curve
=
284 animation
->curve()->ToFloatAnimationCurve();
285 float start_opacity
= curve
->GetValue(0.0);
286 float end_opacity
= curve
->GetValue(curve
->Duration());
287 float linearly_interpolated_opacity
=
288 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
289 double time
= curve
->Duration() * 0.25;
290 // If the linear timing function associated with this animation was not
291 // picked up, then the linearly interpolated opacity would be different
292 // because of the default ease timing function.
293 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
295 LayerAnimationController
* controller_impl
=
296 host_impl
->active_tree()->root_layer()->children()[0]->
297 layer_animation_controller();
298 Animation
* animation_impl
=
299 controller_impl
->GetAnimation(0, Animation::Opacity
);
301 controller
->RemoveAnimation(animation
->id());
302 controller_impl
->RemoveAnimation(animation_impl
->id());
306 virtual void AfterTest() OVERRIDE
{}
308 FakeContentLayerClient client_
;
309 scoped_refptr
<FakeContentLayer
> content_
;
312 SINGLE_AND_MULTI_THREAD_TEST_F(
313 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
315 // Ensures that main thread animations have their start times synchronized with
316 // impl thread animations.
317 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
318 : public LayerTreeHostAnimationTest
{
320 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes()
321 : main_start_time_(-1.0),
322 impl_start_time_(-1.0) {}
324 virtual void SetupTree() OVERRIDE
{
325 LayerTreeHostAnimationTest::SetupTree();
326 content_
= FakeContentLayer::Create(&client_
);
327 content_
->SetBounds(gfx::Size(4, 4));
328 content_
->set_layer_animation_delegate(this);
329 layer_tree_host()->root_layer()->AddChild(content_
);
332 virtual void BeginTest() OVERRIDE
{
333 PostAddAnimationToMainThread(content_
);
336 virtual void notifyAnimationStarted(double time
) OVERRIDE
{
337 LayerAnimationController
* controller
=
338 layer_tree_host()->root_layer()->children()[0]->
339 layer_animation_controller();
340 Animation
* animation
=
341 controller
->GetAnimation(0, Animation::Opacity
);
342 main_start_time_
= animation
->start_time();
343 controller
->RemoveAnimation(animation
->id());
345 if (impl_start_time_
> 0.0)
349 virtual void UpdateAnimationState(
350 LayerTreeHostImpl
* impl_host
,
351 bool has_unfinished_animation
) OVERRIDE
{
352 LayerAnimationController
* controller
=
353 impl_host
->active_tree()->root_layer()->children()[0]->
354 layer_animation_controller();
355 Animation
* animation
=
356 controller
->GetAnimation(0, Animation::Opacity
);
360 impl_start_time_
= animation
->start_time();
361 controller
->RemoveAnimation(animation
->id());
363 if (main_start_time_
> 0.0)
367 virtual void AfterTest() OVERRIDE
{
368 EXPECT_FLOAT_EQ(impl_start_time_
, main_start_time_
);
372 double main_start_time_
;
373 double impl_start_time_
;
374 FakeContentLayerClient client_
;
375 scoped_refptr
<FakeContentLayer
> content_
;
378 SINGLE_AND_MULTI_THREAD_TEST_F(
379 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
381 // Ensures that notify animation finished is called.
382 class LayerTreeHostAnimationTestAnimationFinishedEvents
383 : public LayerTreeHostAnimationTest
{
385 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
387 virtual void BeginTest() OVERRIDE
{
388 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
391 virtual void notifyAnimationFinished(double time
) OVERRIDE
{
392 LayerAnimationController
* controller
=
393 layer_tree_host()->root_layer()->layer_animation_controller();
394 Animation
* animation
=
395 controller
->GetAnimation(0, Animation::Opacity
);
397 controller
->RemoveAnimation(animation
->id());
401 virtual void AfterTest() OVERRIDE
{}
404 SINGLE_AND_MULTI_THREAD_TEST_F(
405 LayerTreeHostAnimationTestAnimationFinishedEvents
);
407 // Ensures that when opacity is being animated, this value does not cause the
408 // subtree to be skipped.
409 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
410 : public LayerTreeHostAnimationTest
{
412 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
413 : update_check_layer_(FakeContentLayer::Create(&client_
)) {
416 virtual void SetupTree() OVERRIDE
{
417 update_check_layer_
->SetOpacity(0.f
);
418 layer_tree_host()->SetRootLayer(update_check_layer_
);
419 LayerTreeHostAnimationTest::SetupTree();
422 virtual void BeginTest() OVERRIDE
{
423 PostAddAnimationToMainThread(update_check_layer_
.get());
426 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) OVERRIDE
{
427 LayerAnimationController
* controller_impl
=
428 host_impl
->active_tree()->root_layer()->layer_animation_controller();
429 Animation
* animation_impl
=
430 controller_impl
->GetAnimation(0, Animation::Opacity
);
431 controller_impl
->RemoveAnimation(animation_impl
->id());
435 virtual void AfterTest() OVERRIDE
{
436 // Update() should have been called once, proving that the layer was not
438 EXPECT_EQ(1u, update_check_layer_
->update_count());
440 // clear update_check_layer_ so LayerTreeHost dies.
441 update_check_layer_
= NULL
;
445 FakeContentLayerClient client_
;
446 scoped_refptr
<FakeContentLayer
> update_check_layer_
;
449 SINGLE_AND_MULTI_THREAD_TEST_F(
450 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
452 // Layers added to tree with existing active animations should have the
453 // animation correctly recognized.
454 class LayerTreeHostAnimationTestLayerAddedWithAnimation
455 : public LayerTreeHostAnimationTest
{
457 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
459 virtual void BeginTest() OVERRIDE
{
460 PostSetNeedsCommitToMainThread();
463 virtual void DidCommit() OVERRIDE
{
464 if (layer_tree_host()->commit_number() == 1) {
465 scoped_refptr
<Layer
> layer
= Layer::Create();
466 layer
->set_layer_animation_delegate(this);
468 // Any valid AnimationCurve will do here.
469 scoped_ptr
<AnimationCurve
> curve(EaseTimingFunction::Create());
470 scoped_ptr
<Animation
> animation(
471 Animation::Create(curve
.Pass(), 1, 1,
472 Animation::Opacity
));
473 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
475 // We add the animation *before* attaching the layer to the tree.
476 layer_tree_host()->root_layer()->AddChild(layer
);
480 virtual void AnimateLayers(
481 LayerTreeHostImpl
* impl_host
,
482 base::TimeTicks monotonic_time
) OVERRIDE
{
486 virtual void AfterTest() OVERRIDE
{}
489 SINGLE_AND_MULTI_THREAD_TEST_F(
490 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
492 class LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount
493 : public LayerTreeHostAnimationTest
{
495 LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount()
496 : animated_commit_(-1) {
499 virtual void Animate(base::TimeTicks
) OVERRIDE
{
500 // We shouldn't animate on the CompositeAndReadback-forced commit, but we
501 // should for the SetNeedsCommit-triggered commit.
502 animated_commit_
= layer_tree_host()->commit_number();
503 EXPECT_NE(2, animated_commit_
);
506 virtual void BeginTest() OVERRIDE
{
507 PostSetNeedsCommitToMainThread();
510 virtual void DidCommit() OVERRIDE
{
511 switch (layer_tree_host()->commit_number()) {
513 layer_tree_host()->SetNeedsCommit();
517 layer_tree_host()->CompositeAndReadback(&pixels
, gfx::Rect(0, 0, 1, 1));
521 // This is finishing the readback's commit.
524 // This is finishing the followup commit.
532 virtual void AfterTest() OVERRIDE
{
533 EXPECT_EQ(3, animated_commit_
);
537 int animated_commit_
;
540 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount
);
542 class LayerTreeHostAnimationTestContinuousAnimate
543 : public LayerTreeHostAnimationTest
{
545 LayerTreeHostAnimationTestContinuousAnimate()
546 : num_commit_complete_(0),
547 num_draw_layers_(0) {
550 virtual void BeginTest() OVERRIDE
{
551 PostSetNeedsCommitToMainThread();
554 virtual void Animate(base::TimeTicks
) OVERRIDE
{
555 if (num_draw_layers_
== 2)
557 layer_tree_host()->SetNeedsAnimate();
560 virtual void Layout() OVERRIDE
{
561 layer_tree_host()->root_layer()->SetNeedsDisplay();
564 virtual void CommitCompleteOnThread(LayerTreeHostImpl
* tree_impl
) OVERRIDE
{
565 if (num_draw_layers_
== 1)
566 num_commit_complete_
++;
569 virtual void DrawLayersOnThread(LayerTreeHostImpl
* impl
) OVERRIDE
{
571 if (num_draw_layers_
== 2)
575 virtual void AfterTest() OVERRIDE
{
576 // Check that we didn't commit twice between first and second draw.
577 EXPECT_EQ(1, num_commit_complete_
);
581 int num_commit_complete_
;
582 int num_draw_layers_
;
585 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate
);
587 // Make sure the main thread can still execute animations when CanDraw() is not
589 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
590 : public LayerTreeHostAnimationTest
{
592 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
594 virtual void SetupTree() OVERRIDE
{
595 LayerTreeHostAnimationTest::SetupTree();
596 content_
= FakeContentLayer::Create(&client_
);
597 content_
->SetBounds(gfx::Size(4, 4));
598 content_
->set_layer_animation_delegate(this);
599 layer_tree_host()->root_layer()->AddChild(content_
);
602 virtual void BeginTest() OVERRIDE
{
603 layer_tree_host()->SetViewportSize(gfx::Size());
604 PostAddAnimationToMainThread(content_
);
607 virtual void notifyAnimationStarted(double wall_clock_time
) OVERRIDE
{
609 // TODO(ajuma): Remove this EndTest() so we test animation finishing.
613 virtual void notifyAnimationFinished(double wall_clock_time
) OVERRIDE
{
617 virtual void AfterTest() OVERRIDE
{
618 EXPECT_EQ(1, started_times_
);
623 FakeContentLayerClient client_
;
624 scoped_refptr
<FakeContentLayer
> content_
;
627 SINGLE_AND_MULTI_THREAD_TEST_F(
628 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
);
630 // Make sure the main thread can still execute animations when the renderer is
632 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible
633 : public LayerTreeHostAnimationTest
{
635 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {}
637 virtual void SetupTree() OVERRIDE
{
638 LayerTreeHostAnimationTest::SetupTree();
639 content_
= FakeContentLayer::Create(&client_
);
640 content_
->SetBounds(gfx::Size(4, 4));
641 content_
->set_layer_animation_delegate(this);
642 layer_tree_host()->root_layer()->AddChild(content_
);
645 virtual void BeginTest() OVERRIDE
{
647 PostAddAnimationToMainThread(content_
);
650 virtual void DidCommit() OVERRIDE
{
652 layer_tree_host()->SetVisible(false);
655 virtual void notifyAnimationStarted(double wall_clock_time
) OVERRIDE
{
656 EXPECT_FALSE(visible_
);
660 virtual void notifyAnimationFinished(double wall_clock_time
) OVERRIDE
{
661 EXPECT_FALSE(visible_
);
662 EXPECT_EQ(1, started_times_
);
666 virtual void AfterTest() OVERRIDE
{}
671 FakeContentLayerClient client_
;
672 scoped_refptr
<FakeContentLayer
> content_
;
675 SINGLE_AND_MULTI_THREAD_TEST_F(
676 LayerTreeHostAnimationTestRunAnimationWhenNotVisible
);
678 // Animations should not be started when frames are being skipped due to
680 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
681 : public LayerTreeHostAnimationTest
{
682 virtual void SetupTree() OVERRIDE
{
683 LayerTreeHostAnimationTest::SetupTree();
684 content_
= FakeContentLayer::Create(&client_
);
685 content_
->SetBounds(gfx::Size(4, 4));
686 content_
->set_layer_animation_delegate(this);
687 layer_tree_host()->root_layer()->AddChild(content_
);
690 virtual void InitializeSettings(LayerTreeSettings
* settings
) OVERRIDE
{
691 // Make sure that drawing many times doesn't cause a checkerboarded
692 // animation to start so we avoid flake in this test.
693 settings
->timeout_and_draw_when_animation_checkerboards
= false;
696 virtual void BeginTest() OVERRIDE
{
697 added_animations_
= 0;
701 PostSetNeedsCommitToMainThread();
704 virtual void DispatchAddInstantAnimation(Layer
* layer_to_receive_animation
)
706 LayerTreeHostAnimationTest::DispatchAddInstantAnimation(
707 layer_to_receive_animation
);
711 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
712 LayerTreeHostImpl::FrameData
* frame_data
,
714 if (added_animations_
< 2)
716 // Act like there is checkerboard when the second animation wants to draw.
720 virtual void DidCommitAndDrawFrame() OVERRIDE
{
721 switch (layer_tree_host()->commit_number()) {
723 // The animation is longer than 1 vsync.
724 AddOpacityTransitionToLayer(content_
, 0.1, 0.2f
, 0.8f
, false);
728 // This second animation will not be drawn so it should not start.
729 AddAnimatedTransformToLayer(content_
, 0.1, 5, 5);
738 virtual void notifyAnimationStarted(double wall_clock_time
) OVERRIDE
{
742 virtual void notifyAnimationFinished(double wall_clock_time
) OVERRIDE
{
743 // We should be checkerboarding already, but it should still finish the
745 EXPECT_EQ(2, added_animations_
);
749 virtual void AfterTest() OVERRIDE
{
750 // The first animation should be started, but the second should not because
752 EXPECT_EQ(1, started_times_
);
753 // The first animation should still be finished.
754 // TODO(ajuma): The first animation is not being finished, but it should be.
755 //EXPECT_EQ(1, finished_times_);
758 int added_animations_
;
761 FakeContentLayerClient client_
;
762 scoped_refptr
<FakeContentLayer
> content_
;
766 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);