1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/layer_tree_host.h"
7 #include "cc/animation/animation_curve.h"
8 #include "cc/animation/layer_animation_controller.h"
9 #include "cc/animation/scroll_offset_animation_curve.h"
10 #include "cc/animation/timing_function.h"
11 #include "cc/base/completion_event.h"
12 #include "cc/base/time_util.h"
13 #include "cc/layers/layer.h"
14 #include "cc/layers/layer_impl.h"
15 #include "cc/test/animation_test_common.h"
16 #include "cc/test/fake_content_layer_client.h"
17 #include "cc/test/fake_picture_layer.h"
18 #include "cc/test/layer_tree_test.h"
19 #include "cc/trees/layer_tree_impl.h"
24 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
26 void SetupTree() override
{
27 LayerTreeTest::SetupTree();
28 layer_tree_host()->root_layer()->set_layer_animation_delegate(this);
32 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to
34 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
35 : public LayerTreeHostAnimationTest
{
37 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
40 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
42 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
43 // We skip the first commit because its the commit that populates the
44 // impl thread with a tree. After the second commit, the test is done.
45 if (num_commits_
!= 1)
48 layer_tree_host()->SetNeedsAnimate();
49 // Right now, CommitRequested is going to be true, because during
50 // BeginFrame, we force CommitRequested to true to prevent requests from
51 // hitting the impl thread. But, when the next DidCommit happens, we should
52 // verify that CommitRequested has gone back to false.
55 void DidCommit() override
{
57 EXPECT_FALSE(layer_tree_host()->CommitRequested());
58 layer_tree_host()->SetNeedsAnimate();
59 EXPECT_FALSE(layer_tree_host()->CommitRequested());
62 // Verifies that the SetNeedsAnimate we made in ::Animate did not
63 // trigger CommitRequested.
64 EXPECT_FALSE(layer_tree_host()->CommitRequested());
69 void AfterTest() override
{}
76 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
);
78 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate
79 // callback, request another frame using SetNeedsAnimate. End the test when
80 // animate gets called yet-again, indicating that the proxy is correctly
81 // handling the case where SetNeedsAnimate() is called inside the BeginFrame
83 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
84 : public LayerTreeHostAnimationTest
{
86 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()
87 : num_begin_frames_(0) {}
89 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
91 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
92 if (!num_begin_frames_
) {
93 layer_tree_host()->SetNeedsAnimate();
100 void AfterTest() override
{}
103 int num_begin_frames_
;
106 SINGLE_AND_MULTI_THREAD_TEST_F(
107 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
109 // Add a layer animation and confirm that
110 // LayerTreeHostImpl::UpdateAnimationState does get called.
111 class LayerTreeHostAnimationTestAddAnimation
112 : public LayerTreeHostAnimationTest
{
114 LayerTreeHostAnimationTestAddAnimation()
115 : update_animation_state_was_called_(false) {}
117 void BeginTest() override
{
118 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
121 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
122 bool has_unfinished_animation
) override
{
123 EXPECT_FALSE(has_unfinished_animation
);
124 update_animation_state_was_called_
= true;
127 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
128 Animation::TargetProperty target_property
,
129 int group
) override
{
130 EXPECT_LT(base::TimeTicks(), monotonic_time
);
132 LayerAnimationController
* controller
=
133 layer_tree_host()->root_layer()->layer_animation_controller();
134 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
136 controller
->RemoveAnimation(animation
->id());
141 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
144 bool update_animation_state_was_called_
;
147 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation
);
149 // Add a layer animation to a layer, but continually fail to draw. Confirm that
150 // after a while, we do eventually force a draw.
151 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
152 : public LayerTreeHostAnimationTest
{
154 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()
155 : started_animating_(false) {}
157 void BeginTest() override
{
158 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
161 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
162 base::TimeTicks monotonic_time
) override
{
163 started_animating_
= true;
166 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
167 if (started_animating_
)
171 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
172 LayerTreeHostImpl::FrameData
* frame
,
173 DrawResult draw_result
) override
{
174 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
177 void AfterTest() override
{}
180 bool started_animating_
;
183 // Starvation can only be an issue with the MT compositor.
184 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws
);
186 // Ensures that animations eventually get deleted.
187 class LayerTreeHostAnimationTestAnimationsGetDeleted
188 : public LayerTreeHostAnimationTest
{
190 LayerTreeHostAnimationTestAnimationsGetDeleted()
191 : started_animating_(false) {}
193 void BeginTest() override
{
194 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
197 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
198 base::TimeTicks monotonic_time
) override
{
199 bool have_animations
= !host_impl
->animation_registrar()
200 ->active_animation_controllers_for_testing()
202 if (!started_animating_
&& have_animations
) {
203 started_animating_
= true;
207 if (started_animating_
&& !have_animations
)
211 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
212 Animation::TargetProperty target_property
,
213 int group
) override
{
214 // Animations on the impl-side controller only get deleted during a commit,
215 // so we need to schedule a commit.
216 layer_tree_host()->SetNeedsCommit();
219 void AfterTest() override
{}
222 bool started_animating_
;
225 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
227 // Ensure that an animation's timing function is respected.
228 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
229 : public LayerTreeHostAnimationTest
{
231 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
233 void SetupTree() override
{
234 LayerTreeHostAnimationTest::SetupTree();
235 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
236 picture_
->SetBounds(gfx::Size(4, 4));
237 layer_tree_host()->root_layer()->AddChild(picture_
);
240 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
242 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
243 base::TimeTicks monotonic_time
) override
{
244 LayerAnimationController
* controller_impl
=
245 host_impl
->active_tree()->root_layer()->children()[0]->
246 layer_animation_controller();
247 Animation
* animation
= controller_impl
->GetAnimation(Animation::OPACITY
);
251 const FloatAnimationCurve
* curve
=
252 animation
->curve()->ToFloatAnimationCurve();
253 float start_opacity
= curve
->GetValue(base::TimeDelta());
254 float end_opacity
= curve
->GetValue(curve
->Duration());
255 float linearly_interpolated_opacity
=
256 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
257 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
258 // If the linear timing function associated with this animation was not
259 // picked up, then the linearly interpolated opacity would be different
260 // because of the default ease timing function.
261 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
266 void AfterTest() override
{}
268 FakeContentLayerClient client_
;
269 scoped_refptr
<FakePictureLayer
> picture_
;
272 SINGLE_AND_MULTI_THREAD_TEST_F(
273 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
275 // Ensures that main thread animations have their start times synchronized with
276 // impl thread animations.
277 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
278 : public LayerTreeHostAnimationTest
{
280 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
282 void SetupTree() override
{
283 LayerTreeHostAnimationTest::SetupTree();
284 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
285 picture_
->SetBounds(gfx::Size(4, 4));
286 picture_
->set_layer_animation_delegate(this);
287 layer_tree_host()->root_layer()->AddChild(picture_
);
290 void BeginTest() override
{ PostAddAnimationToMainThread(picture_
.get()); }
292 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
293 Animation::TargetProperty target_property
,
294 int group
) override
{
295 LayerAnimationController
* controller
=
296 layer_tree_host()->root_layer()->children()[0]->
297 layer_animation_controller();
298 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
299 main_start_time_
= animation
->start_time();
300 controller
->RemoveAnimation(animation
->id());
304 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
305 bool has_unfinished_animation
) override
{
306 LayerAnimationController
* controller
=
307 impl_host
->active_tree()->root_layer()->children()[0]->
308 layer_animation_controller();
309 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
313 impl_start_time_
= animation
->start_time();
316 void AfterTest() override
{
317 EXPECT_EQ(impl_start_time_
, main_start_time_
);
318 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
322 base::TimeTicks main_start_time_
;
323 base::TimeTicks impl_start_time_
;
324 FakeContentLayerClient client_
;
325 scoped_refptr
<FakePictureLayer
> picture_
;
328 SINGLE_AND_MULTI_THREAD_TEST_F(
329 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
331 // Ensures that notify animation finished is called.
332 class LayerTreeHostAnimationTestAnimationFinishedEvents
333 : public LayerTreeHostAnimationTest
{
335 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
337 void BeginTest() override
{
338 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
341 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
342 Animation::TargetProperty target_property
,
343 int group
) override
{
344 LayerAnimationController
* controller
=
345 layer_tree_host()->root_layer()->layer_animation_controller();
346 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
348 controller
->RemoveAnimation(animation
->id());
352 void AfterTest() override
{}
355 SINGLE_AND_MULTI_THREAD_TEST_F(
356 LayerTreeHostAnimationTestAnimationFinishedEvents
);
358 // Ensures that when opacity is being animated, this value does not cause the
359 // subtree to be skipped.
360 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
361 : public LayerTreeHostAnimationTest
{
363 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
364 : update_check_layer_(
365 FakePictureLayer::Create(layer_settings(), &client_
)) {}
367 void SetupTree() override
{
368 update_check_layer_
->SetOpacity(0.f
);
369 layer_tree_host()->SetRootLayer(update_check_layer_
);
370 LayerTreeHostAnimationTest::SetupTree();
373 void BeginTest() override
{
374 PostAddAnimationToMainThread(update_check_layer_
.get());
377 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
378 LayerAnimationController
* controller_impl
=
379 host_impl
->active_tree()->root_layer()->layer_animation_controller();
380 Animation
* animation_impl
=
381 controller_impl
->GetAnimation(Animation::OPACITY
);
382 controller_impl
->RemoveAnimation(animation_impl
->id());
386 void AfterTest() override
{
387 // Update() should have been called once, proving that the layer was not
389 EXPECT_EQ(1, update_check_layer_
->update_count());
391 // clear update_check_layer_ so LayerTreeHost dies.
392 update_check_layer_
= NULL
;
396 FakeContentLayerClient client_
;
397 scoped_refptr
<FakePictureLayer
> update_check_layer_
;
400 SINGLE_AND_MULTI_THREAD_TEST_F(
401 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
403 // Layers added to tree with existing active animations should have the
404 // animation correctly recognized.
405 class LayerTreeHostAnimationTestLayerAddedWithAnimation
406 : public LayerTreeHostAnimationTest
{
408 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
410 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
412 void DidCommit() override
{
413 if (layer_tree_host()->source_frame_number() == 1) {
414 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
415 layer
->set_layer_animation_delegate(this);
417 // Any valid AnimationCurve will do here.
418 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
419 scoped_ptr
<Animation
> animation(
420 Animation::Create(curve
.Pass(), 1, 1, Animation::OPACITY
));
421 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
423 // We add the animation *before* attaching the layer to the tree.
424 layer_tree_host()->root_layer()->AddChild(layer
);
428 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
429 base::TimeTicks monotonic_time
) override
{
433 void AfterTest() override
{}
436 SINGLE_AND_MULTI_THREAD_TEST_F(
437 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
439 class LayerTreeHostAnimationTestCancelAnimateCommit
440 : public LayerTreeHostAnimationTest
{
442 LayerTreeHostAnimationTestCancelAnimateCommit()
443 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
445 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
447 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
449 // No-op animate will cancel the commit.
450 if (layer_tree_host()->source_frame_number() == 1) {
454 layer_tree_host()->SetNeedsAnimate();
457 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
459 if (impl
->active_tree()->source_frame_number() > 1)
460 FAIL() << "Commit should have been canceled.";
463 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
465 if (impl
->active_tree()->source_frame_number() > 1)
466 FAIL() << "Draw should have been canceled.";
469 void AfterTest() override
{
470 EXPECT_EQ(2, num_begin_frames_
);
471 EXPECT_EQ(1, num_commit_calls_
);
472 EXPECT_EQ(1, num_draw_calls_
);
476 int num_begin_frames_
;
477 int num_commit_calls_
;
481 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
483 class LayerTreeHostAnimationTestForceRedraw
484 : public LayerTreeHostAnimationTest
{
486 LayerTreeHostAnimationTestForceRedraw()
487 : num_animate_(0), num_draw_layers_(0) {}
489 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
491 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
492 if (++num_animate_
< 2)
493 layer_tree_host()->SetNeedsAnimate();
496 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
498 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
499 if (++num_draw_layers_
== 2)
503 void AfterTest() override
{
504 // The first commit will always draw; make sure the second draw triggered
505 // by the animation was not cancelled.
506 EXPECT_EQ(2, num_draw_layers_
);
507 EXPECT_EQ(2, num_animate_
);
512 int num_draw_layers_
;
515 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
517 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
518 : public LayerTreeHostAnimationTest
{
520 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
521 : num_animate_(0), num_draw_layers_(0) {}
523 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
525 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
526 if (++num_animate_
<= 2) {
527 layer_tree_host()->SetNeedsCommit();
528 layer_tree_host()->SetNeedsAnimate();
532 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
533 if (++num_draw_layers_
== 2)
537 void AfterTest() override
{
538 // The first commit will always draw; make sure the second draw triggered
539 // by the SetNeedsCommit was not cancelled.
540 EXPECT_EQ(2, num_draw_layers_
);
541 EXPECT_GE(num_animate_
, 2);
546 int num_draw_layers_
;
549 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
551 // Make sure the main thread can still execute animations when CanDraw() is not
553 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
554 : public LayerTreeHostAnimationTest
{
556 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
558 void SetupTree() override
{
559 LayerTreeHostAnimationTest::SetupTree();
560 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
561 picture_
->SetBounds(gfx::Size(4, 4));
562 picture_
->set_layer_animation_delegate(this);
563 layer_tree_host()->root_layer()->AddChild(picture_
);
566 void BeginTest() override
{
567 layer_tree_host()->SetViewportSize(gfx::Size());
568 PostAddAnimationToMainThread(picture_
.get());
571 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
572 Animation::TargetProperty target_property
,
573 int group
) override
{
577 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
578 Animation::TargetProperty target_property
,
579 int group
) override
{
583 void AfterTest() override
{ EXPECT_EQ(1, started_times_
); }
587 FakeContentLayerClient client_
;
588 scoped_refptr
<FakePictureLayer
> picture_
;
591 SINGLE_AND_MULTI_THREAD_TEST_F(
592 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
);
594 // Animations should not be started when frames are being skipped due to
596 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
597 : public LayerTreeHostAnimationTest
{
598 void SetupTree() override
{
599 LayerTreeHostAnimationTest::SetupTree();
600 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
601 picture_
->SetBounds(gfx::Size(4, 4));
602 picture_
->set_layer_animation_delegate(this);
603 layer_tree_host()->root_layer()->AddChild(picture_
);
606 void InitializeSettings(LayerTreeSettings
* settings
) override
{
607 // Make sure that drawing many times doesn't cause a checkerboarded
608 // animation to start so we avoid flake in this test.
609 settings
->timeout_and_draw_when_animation_checkerboards
= false;
612 void BeginTest() override
{
614 added_animations_
= 0;
617 PostSetNeedsCommitToMainThread();
620 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
621 LayerTreeHostImpl::FrameData
* frame_data
,
622 DrawResult draw_result
) override
{
623 if (added_animations_
< 2)
627 // Act like there is checkerboard when the second animation wants to draw.
629 if (prevented_draw_
> 2)
631 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
634 void DidCommitAndDrawFrame() override
{
635 switch (layer_tree_host()->source_frame_number()) {
637 // The animation is longer than 1 BeginFrame interval.
638 AddOpacityTransitionToLayer(picture_
.get(), 0.1, 0.2f
, 0.8f
, false);
642 // This second animation will not be drawn so it should not start.
643 AddAnimatedTransformToLayer(picture_
.get(), 0.1, 5, 5);
649 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
650 Animation::TargetProperty target_property
,
651 int group
) override
{
657 void AfterTest() override
{
658 // Make sure we tried to draw the second animation but failed.
659 EXPECT_LT(0, prevented_draw_
);
660 // The first animation should be started, but the second should not because
662 EXPECT_EQ(1, started_times_
);
666 int added_animations_
;
668 FakeContentLayerClient client_
;
669 scoped_refptr
<FakePictureLayer
> picture_
;
673 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
675 // Verifies that scroll offset animations are only accepted when impl-scrolling
676 // is supported, and that when scroll offset animations are accepted,
677 // scroll offset updates are sent back to the main thread.
678 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
679 : public LayerTreeHostAnimationTest
{
681 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
683 void SetupTree() override
{
684 LayerTreeHostAnimationTest::SetupTree();
686 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
687 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
688 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
689 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
690 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
693 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
695 void DidCommit() override
{
696 switch (layer_tree_host()->source_frame_number()) {
698 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
699 ScrollOffsetAnimationCurve::Create(
700 gfx::ScrollOffset(500.f
, 550.f
),
701 EaseInOutTimingFunction::Create()));
702 scoped_ptr
<Animation
> animation(
703 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
704 animation
->set_needs_synchronized_start_time(true);
705 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
706 bool impl_scrolling_supported
=
707 layer_tree_host()->proxy()->SupportsImplScrolling();
708 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
709 if (!impl_scrolling_supported
)
714 if (scroll_layer_
->scroll_offset().x() > 10 &&
715 scroll_layer_
->scroll_offset().y() > 20)
720 void AfterTest() override
{}
723 FakeContentLayerClient client_
;
724 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
727 SINGLE_AND_MULTI_THREAD_TEST_F(
728 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
730 // Verifies that when the main thread removes a scroll animation and sets a new
731 // scroll position, the active tree takes on exactly this new scroll position
732 // after activation, and the main thread doesn't receive a spurious scroll
734 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
735 : public LayerTreeHostAnimationTest
{
737 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
738 : final_postion_(50.0, 100.0) {}
740 void SetupTree() override
{
741 LayerTreeHostAnimationTest::SetupTree();
743 scroll_layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
744 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
745 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
746 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
747 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
749 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
750 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
751 EaseInOutTimingFunction::Create()));
752 scoped_ptr
<Animation
> animation(
753 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
754 animation
->set_needs_synchronized_start_time(true);
755 scroll_layer_
->AddAnimation(animation
.Pass());
758 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
760 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
761 switch (layer_tree_host()->source_frame_number()) {
765 Animation
* animation
=
766 scroll_layer_
->layer_animation_controller()->GetAnimation(
767 Animation::SCROLL_OFFSET
);
768 scroll_layer_
->layer_animation_controller()->RemoveAnimation(
770 scroll_layer_
->SetScrollOffset(final_postion_
);
774 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
778 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
779 host_impl
->BlockNotifyReadyToActivateForTesting(true);
782 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
783 const BeginFrameArgs
& args
) override
{
784 if (!host_impl
->pending_tree())
787 if (!host_impl
->active_tree()->root_layer()) {
788 host_impl
->BlockNotifyReadyToActivateForTesting(false);
792 LayerImpl
* scroll_layer_impl
=
793 host_impl
->active_tree()->root_layer()->children()[0];
794 Animation
* animation
=
795 scroll_layer_impl
->layer_animation_controller()->GetAnimation(
796 Animation::SCROLL_OFFSET
);
798 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
799 host_impl
->BlockNotifyReadyToActivateForTesting(false);
803 // Block activation until the running animation has a chance to produce a
805 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
806 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
809 host_impl
->BlockNotifyReadyToActivateForTesting(false);
812 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
813 if (host_impl
->pending_tree()->source_frame_number() != 1)
815 LayerImpl
* scroll_layer_impl
=
816 host_impl
->pending_tree()->root_layer()->children()[0];
817 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
820 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
821 if (host_impl
->active_tree()->source_frame_number() != 1)
823 LayerImpl
* scroll_layer_impl
=
824 host_impl
->active_tree()->root_layer()->children()[0];
825 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
829 void AfterTest() override
{
830 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
834 FakeContentLayerClient client_
;
835 scoped_refptr
<FakePictureLayer
> scroll_layer_
;
836 const gfx::ScrollOffset final_postion_
;
839 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
);
841 // When animations are simultaneously added to an existing layer and to a new
842 // layer, they should start at the same time, even when there's already a
843 // running animation on the existing layer.
844 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
845 : public LayerTreeHostAnimationTest
{
847 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
848 : frame_count_with_pending_tree_(0) {}
850 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
852 void DidCommit() override
{
853 if (layer_tree_host()->source_frame_number() == 1) {
854 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
855 } else if (layer_tree_host()->source_frame_number() == 2) {
856 AddOpacityTransitionToLayer(
857 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
859 scoped_refptr
<Layer
> layer
= Layer::Create(layer_settings());
860 layer_tree_host()->root_layer()->AddChild(layer
);
861 layer
->set_layer_animation_delegate(this);
862 layer
->SetBounds(gfx::Size(4, 4));
863 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
867 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
868 host_impl
->BlockNotifyReadyToActivateForTesting(true);
871 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
872 // For the commit that added animations to new and existing layers, keep
873 // blocking activation. We want to verify that even with activation blocked,
874 // the animation on the layer that's already in the active tree won't get a
876 if (host_impl
->pending_tree()->source_frame_number() != 2) {
877 host_impl
->BlockNotifyReadyToActivateForTesting(false);
881 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
882 const BeginFrameArgs
& args
) override
{
883 if (!host_impl
->pending_tree() ||
884 host_impl
->pending_tree()->source_frame_number() != 2)
887 frame_count_with_pending_tree_
++;
888 if (frame_count_with_pending_tree_
== 2) {
889 host_impl
->BlockNotifyReadyToActivateForTesting(false);
893 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
894 bool has_unfinished_animation
) override
{
895 LayerAnimationController
* root_controller_impl
=
896 host_impl
->active_tree()->root_layer()->layer_animation_controller();
897 Animation
* root_animation
=
898 root_controller_impl
->GetAnimation(Animation::OPACITY
);
899 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
902 LayerAnimationController
* child_controller_impl
=
903 host_impl
->active_tree()->root_layer()->children()
904 [0]->layer_animation_controller();
905 Animation
* child_animation
=
906 child_controller_impl
->GetAnimation(Animation::OPACITY
);
907 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
908 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
909 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
910 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
911 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
915 void AfterTest() override
{}
918 int frame_count_with_pending_tree_
;
921 // This test blocks activation which is not supported for single thread mode.
922 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
923 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
925 // When a layer with an animation is removed from the tree and later re-added,
926 // the animation should resume.
927 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
928 : public LayerTreeHostAnimationTest
{
930 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded() {}
932 void SetupTree() override
{
933 LayerTreeHostAnimationTest::SetupTree();
934 layer_
= Layer::Create(layer_settings());
935 layer_
->SetBounds(gfx::Size(4, 4));
936 layer_tree_host()->root_layer()->AddChild(layer_
);
937 AddOpacityTransitionToLayer(layer_
.get(), 10000.0, 0.1f
, 0.9f
, true);
940 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
942 void DidCommit() override
{
943 switch (layer_tree_host()->source_frame_number()) {
945 layer_
->RemoveFromParent();
948 layer_tree_host()->root_layer()->AddChild(layer_
);
953 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
954 switch (host_impl
->active_tree()->source_frame_number()) {
956 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
959 EXPECT_FALSE(host_impl
->animation_registrar()->needs_animate_layers());
962 EXPECT_TRUE(host_impl
->animation_registrar()->needs_animate_layers());
968 void AfterTest() override
{}
971 scoped_refptr
<Layer
> layer_
;
974 SINGLE_AND_MULTI_THREAD_TEST_F(
975 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded
);
977 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
978 : public LayerTreeHostAnimationTest
{
980 void SetupTree() override
{
981 LayerTreeHostAnimationTest::SetupTree();
982 layer_
= Layer::Create(layer_settings());
983 layer_
->SetBounds(gfx::Size(4, 4));
984 layer_tree_host()->root_layer()->AddChild(layer_
);
987 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
989 void DidCommit() override
{
990 switch (layer_tree_host()->source_frame_number()) {
992 // First frame: add an animation to the root layer.
993 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
996 // Second frame: add an animation to the content layer. The root layer
997 // animation has caused us to animate already during this frame.
998 AddOpacityTransitionToLayer(layer_
.get(), 0.1, 5, 5, false);
1003 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
1004 // After both animations have started, verify that they have valid
1006 if (host_impl
->active_tree()->source_frame_number() < 2)
1008 AnimationRegistrar::AnimationControllerMap controllers_copy
=
1009 host_impl
->animation_registrar()
1010 ->active_animation_controllers_for_testing();
1011 EXPECT_EQ(2u, controllers_copy
.size());
1012 for (auto& it
: controllers_copy
) {
1014 if (id
== host_impl
->RootLayer()->id()) {
1015 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
1016 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1017 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
1018 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
1019 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
1025 void AfterTest() override
{}
1028 scoped_refptr
<Layer
> layer_
;
1031 SINGLE_AND_MULTI_THREAD_TEST_F(
1032 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);
1034 class LayerTreeHostAnimationTestRemoveAnimation
1035 : public LayerTreeHostAnimationTest
{
1037 void SetupTree() override
{
1038 LayerTreeHostAnimationTest::SetupTree();
1039 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1040 layer_
->SetBounds(gfx::Size(4, 4));
1041 layer_tree_host()->root_layer()->AddChild(layer_
);
1044 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1046 void DidCommit() override
{
1047 switch (layer_tree_host()->source_frame_number()) {
1049 AddAnimatedTransformToLayer(layer_
.get(), 1.0, 5, 5);
1052 LayerAnimationController
* controller
=
1053 layer_
->layer_animation_controller();
1054 Animation
* animation
= controller
->GetAnimation(Animation::TRANSFORM
);
1055 controller
->RemoveAnimation(animation
->id());
1056 gfx::Transform transform
;
1057 transform
.Translate(10.f
, 10.f
);
1058 layer_
->SetTransform(transform
);
1060 // Do something that causes property trees to get rebuilt.
1061 layer_
->AddChild(Layer::Create(layer_settings()));
1066 void DrawLayersOnThread(LayerTreeHostImpl
* host_impl
) override
{
1067 if (host_impl
->active_tree()->source_frame_number() < 2)
1069 gfx::Transform expected_transform
;
1070 expected_transform
.Translate(10.f
, 10.f
);
1071 EXPECT_EQ(expected_transform
, host_impl
->active_tree()
1074 ->draw_transform());
1078 void AfterTest() override
{}
1081 scoped_refptr
<Layer
> layer_
;
1082 FakeContentLayerClient client_
;
1085 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveAnimation
);
1087 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit
1088 : public LayerTreeHostAnimationTest
{
1090 void SetupTree() override
{
1091 LayerTreeHostAnimationTest::SetupTree();
1092 layer_
= FakePictureLayer::Create(layer_settings(), &client_
);
1093 layer_
->SetBounds(gfx::Size(4, 4));
1094 layer_tree_host()->root_layer()->AddChild(layer_
);
1097 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
1099 void DidCommit() override
{
1100 if (layer_tree_host()->source_frame_number() == 1)
1101 AddAnimatedTransformToLayer(layer_
.get(), 0.04, 5, 5);
1104 void WillCommit() override
{
1105 if (layer_tree_host()->source_frame_number() == 2) {
1106 // Block until the animation finishes on the compositor thread. Since
1107 // animations have already been ticked on the main thread, when the commit
1108 // happens the state on the main thread will be consistent with having a
1109 // running animation but the state on the compositor thread will be
1110 // consistent with having only a finished animation.
1115 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
1116 switch (host_impl
->sync_tree()->source_frame_number()) {
1118 PostSetNeedsCommitToMainThread();
1121 gfx::Transform expected_transform
;
1122 expected_transform
.Translate(5.f
, 5.f
);
1123 LayerImpl
* layer_impl
=
1124 host_impl
->sync_tree()->root_layer()->children()[0];
1125 EXPECT_EQ(expected_transform
, layer_impl
->draw_transform());
1131 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
1132 bool has_unfinished_animation
) override
{
1133 if (host_impl
->active_tree()->source_frame_number() == 1 &&
1134 !has_unfinished_animation
) {
1135 // The animation has finished, so allow the main thread to commit.
1136 completion_
.Signal();
1140 void AfterTest() override
{}
1143 scoped_refptr
<Layer
> layer_
;
1144 FakeContentLayerClient client_
;
1145 CompletionEvent completion_
;
1148 // An animation finishing during commit can only happen when we have a separate
1149 // compositor thread.
1150 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit
);
1152 class LayerTreeHostAnimationTestNotifyAnimationFinished
1153 : public LayerTreeHostAnimationTest
{
1155 LayerTreeHostAnimationTestNotifyAnimationFinished()
1156 : called_animation_started_(false), called_animation_finished_(false) {}
1158 void SetupTree() override
{
1159 LayerTreeHostAnimationTest::SetupTree();
1160 picture_
= FakePictureLayer::Create(layer_settings(), &client_
);
1161 picture_
->SetBounds(gfx::Size(4, 4));
1162 picture_
->set_layer_animation_delegate(this);
1163 layer_tree_host()->root_layer()->AddChild(picture_
);
1166 void BeginTest() override
{
1167 layer_tree_host()->SetViewportSize(gfx::Size());
1168 PostAddLongAnimationToMainThread(picture_
.get());
1171 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
1172 Animation::TargetProperty target_property
,
1173 int group
) override
{
1174 called_animation_started_
= true;
1175 layer_tree_host()->AnimateLayers(
1176 base::TimeTicks::FromInternalValue(std::numeric_limits
<int64
>::max()));
1177 PostSetNeedsCommitToMainThread();
1180 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
1181 Animation::TargetProperty target_property
,
1182 int group
) override
{
1183 called_animation_finished_
= true;
1187 void AfterTest() override
{
1188 EXPECT_TRUE(called_animation_started_
);
1189 EXPECT_TRUE(called_animation_finished_
);
1193 bool called_animation_started_
;
1194 bool called_animation_finished_
;
1195 FakeContentLayerClient client_
;
1196 scoped_refptr
<FakePictureLayer
> picture_
;
1199 SINGLE_AND_MULTI_THREAD_TEST_F(
1200 LayerTreeHostAnimationTestNotifyAnimationFinished
);