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"
23 class LayerTreeHostAnimationTest
: public LayerTreeTest
{
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
33 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested
34 : public LayerTreeHostAnimationTest
{
36 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()
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)
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
{
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 void AfterTest() override
{}
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
82 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
83 : public LayerTreeHostAnimationTest
{
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();
99 void AfterTest() override
{}
102 int num_begin_frames_
;
105 SINGLE_AND_MULTI_THREAD_TEST_F(
106 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback
);
108 // Add a layer animation and confirm that
109 // LayerTreeHostImpl::UpdateAnimationState does get called.
110 class LayerTreeHostAnimationTestAddAnimation
111 : public LayerTreeHostAnimationTest
{
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
);
135 controller
->RemoveAnimation(animation
->id());
140 void AfterTest() override
{ EXPECT_TRUE(update_animation_state_was_called_
); }
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
{
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_
)
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
{}
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
{
189 LayerTreeHostAnimationTestAnimationsGetDeleted()
190 : started_animating_(false) {}
192 void BeginTest() override
{
193 PostAddAnimationToMainThread(layer_tree_host()->root_layer());
196 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
197 base::TimeTicks monotonic_time
) override
{
198 bool have_animations
= !host_impl
->animation_registrar()
199 ->active_animation_controllers_for_testing()
201 if (!started_animating_
&& have_animations
) {
202 started_animating_
= true;
206 if (started_animating_
&& !have_animations
)
210 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
211 Animation::TargetProperty target_property
,
212 int group
) override
{
213 // Animations on the impl-side controller only get deleted during a commit,
214 // so we need to schedule a commit.
215 layer_tree_host()->SetNeedsCommit();
218 void AfterTest() override
{}
221 bool started_animating_
;
224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted
);
226 // Ensure that an animation's timing function is respected.
227 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction
228 : public LayerTreeHostAnimationTest
{
230 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {}
232 void SetupTree() override
{
233 LayerTreeHostAnimationTest::SetupTree();
234 content_
= FakeContentLayer::Create(&client_
);
235 content_
->SetBounds(gfx::Size(4, 4));
236 layer_tree_host()->root_layer()->AddChild(content_
);
239 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
241 void AnimateLayers(LayerTreeHostImpl
* host_impl
,
242 base::TimeTicks monotonic_time
) override
{
243 LayerAnimationController
* controller_impl
=
244 host_impl
->active_tree()->root_layer()->children()[0]->
245 layer_animation_controller();
246 Animation
* animation
= controller_impl
->GetAnimation(Animation::OPACITY
);
250 const FloatAnimationCurve
* curve
=
251 animation
->curve()->ToFloatAnimationCurve();
252 float start_opacity
= curve
->GetValue(base::TimeDelta());
253 float end_opacity
= curve
->GetValue(curve
->Duration());
254 float linearly_interpolated_opacity
=
255 0.25f
* end_opacity
+ 0.75f
* start_opacity
;
256 base::TimeDelta time
= TimeUtil::Scale(curve
->Duration(), 0.25f
);
257 // If the linear timing function associated with this animation was not
258 // picked up, then the linearly interpolated opacity would be different
259 // because of the default ease timing function.
260 EXPECT_FLOAT_EQ(linearly_interpolated_opacity
, curve
->GetValue(time
));
265 void AfterTest() override
{}
267 FakeContentLayerClient client_
;
268 scoped_refptr
<FakeContentLayer
> content_
;
271 SINGLE_AND_MULTI_THREAD_TEST_F(
272 LayerTreeHostAnimationTestAddAnimationWithTimingFunction
);
274 // Ensures that main thread animations have their start times synchronized with
275 // impl thread animations.
276 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
277 : public LayerTreeHostAnimationTest
{
279 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() {}
281 void SetupTree() override
{
282 LayerTreeHostAnimationTest::SetupTree();
283 content_
= FakeContentLayer::Create(&client_
);
284 content_
->SetBounds(gfx::Size(4, 4));
285 content_
->set_layer_animation_delegate(this);
286 layer_tree_host()->root_layer()->AddChild(content_
);
289 void BeginTest() override
{ PostAddAnimationToMainThread(content_
.get()); }
291 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
292 Animation::TargetProperty target_property
,
293 int group
) override
{
294 LayerAnimationController
* controller
=
295 layer_tree_host()->root_layer()->children()[0]->
296 layer_animation_controller();
297 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
298 main_start_time_
= animation
->start_time();
299 controller
->RemoveAnimation(animation
->id());
303 void UpdateAnimationState(LayerTreeHostImpl
* impl_host
,
304 bool has_unfinished_animation
) override
{
305 LayerAnimationController
* controller
=
306 impl_host
->active_tree()->root_layer()->children()[0]->
307 layer_animation_controller();
308 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
312 impl_start_time_
= animation
->start_time();
315 void AfterTest() override
{
316 EXPECT_EQ(impl_start_time_
, main_start_time_
);
317 EXPECT_LT(base::TimeTicks(), impl_start_time_
);
321 base::TimeTicks main_start_time_
;
322 base::TimeTicks impl_start_time_
;
323 FakeContentLayerClient client_
;
324 scoped_refptr
<FakeContentLayer
> content_
;
327 SINGLE_AND_MULTI_THREAD_TEST_F(
328 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes
);
330 // Ensures that notify animation finished is called.
331 class LayerTreeHostAnimationTestAnimationFinishedEvents
332 : public LayerTreeHostAnimationTest
{
334 LayerTreeHostAnimationTestAnimationFinishedEvents() {}
336 void BeginTest() override
{
337 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer());
340 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
341 Animation::TargetProperty target_property
,
342 int group
) override
{
343 LayerAnimationController
* controller
=
344 layer_tree_host()->root_layer()->layer_animation_controller();
345 Animation
* animation
= controller
->GetAnimation(Animation::OPACITY
);
347 controller
->RemoveAnimation(animation
->id());
351 void AfterTest() override
{}
354 SINGLE_AND_MULTI_THREAD_TEST_F(
355 LayerTreeHostAnimationTestAnimationFinishedEvents
);
357 // Ensures that when opacity is being animated, this value does not cause the
358 // subtree to be skipped.
359 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
360 : public LayerTreeHostAnimationTest
{
362 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()
363 : update_check_layer_(FakeContentLayer::Create(&client_
)) {
366 void SetupTree() override
{
367 update_check_layer_
->SetOpacity(0.f
);
368 layer_tree_host()->SetRootLayer(update_check_layer_
);
369 LayerTreeHostAnimationTest::SetupTree();
372 void BeginTest() override
{
373 PostAddAnimationToMainThread(update_check_layer_
.get());
376 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
377 LayerAnimationController
* controller_impl
=
378 host_impl
->active_tree()->root_layer()->layer_animation_controller();
379 Animation
* animation_impl
=
380 controller_impl
->GetAnimation(Animation::OPACITY
);
381 controller_impl
->RemoveAnimation(animation_impl
->id());
385 void AfterTest() override
{
386 // Update() should have been called once, proving that the layer was not
388 EXPECT_EQ(1u, update_check_layer_
->update_count());
390 // clear update_check_layer_ so LayerTreeHost dies.
391 update_check_layer_
= NULL
;
395 FakeContentLayerClient client_
;
396 scoped_refptr
<FakeContentLayer
> update_check_layer_
;
399 SINGLE_AND_MULTI_THREAD_TEST_F(
400 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity
);
402 // Layers added to tree with existing active animations should have the
403 // animation correctly recognized.
404 class LayerTreeHostAnimationTestLayerAddedWithAnimation
405 : public LayerTreeHostAnimationTest
{
407 LayerTreeHostAnimationTestLayerAddedWithAnimation() {}
409 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
411 void DidCommit() override
{
412 if (layer_tree_host()->source_frame_number() == 1) {
413 scoped_refptr
<Layer
> layer
= Layer::Create();
414 layer
->set_layer_animation_delegate(this);
416 // Any valid AnimationCurve will do here.
417 scoped_ptr
<AnimationCurve
> curve(new FakeFloatAnimationCurve());
418 scoped_ptr
<Animation
> animation(
419 Animation::Create(curve
.Pass(), 1, 1, Animation::OPACITY
));
420 layer
->layer_animation_controller()->AddAnimation(animation
.Pass());
422 // We add the animation *before* attaching the layer to the tree.
423 layer_tree_host()->root_layer()->AddChild(layer
);
427 void AnimateLayers(LayerTreeHostImpl
* impl_host
,
428 base::TimeTicks monotonic_time
) override
{
432 void AfterTest() override
{}
435 SINGLE_AND_MULTI_THREAD_TEST_F(
436 LayerTreeHostAnimationTestLayerAddedWithAnimation
);
438 class LayerTreeHostAnimationTestCancelAnimateCommit
439 : public LayerTreeHostAnimationTest
{
441 LayerTreeHostAnimationTestCancelAnimateCommit()
442 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {}
444 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
446 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
448 // No-op animate will cancel the commit.
449 if (layer_tree_host()->source_frame_number() == 1) {
453 layer_tree_host()->SetNeedsAnimate();
456 void CommitCompleteOnThread(LayerTreeHostImpl
* impl
) override
{
458 if (impl
->active_tree()->source_frame_number() > 1)
459 FAIL() << "Commit should have been canceled.";
462 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
464 if (impl
->active_tree()->source_frame_number() > 1)
465 FAIL() << "Draw should have been canceled.";
468 void AfterTest() override
{
469 EXPECT_EQ(2, num_begin_frames_
);
470 EXPECT_EQ(1, num_commit_calls_
);
471 EXPECT_EQ(1, num_draw_calls_
);
475 int num_begin_frames_
;
476 int num_commit_calls_
;
478 FakeContentLayerClient client_
;
479 scoped_refptr
<FakeContentLayer
> content_
;
482 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit
);
484 class LayerTreeHostAnimationTestForceRedraw
485 : public LayerTreeHostAnimationTest
{
487 LayerTreeHostAnimationTestForceRedraw()
488 : num_animate_(0), num_draw_layers_(0) {}
490 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
492 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
493 if (++num_animate_
< 2)
494 layer_tree_host()->SetNeedsAnimate();
497 void Layout() override
{ layer_tree_host()->SetNextCommitForcesRedraw(); }
499 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
500 if (++num_draw_layers_
== 2)
504 void AfterTest() override
{
505 // The first commit will always draw; make sure the second draw triggered
506 // by the animation was not cancelled.
507 EXPECT_EQ(2, num_draw_layers_
);
508 EXPECT_EQ(2, num_animate_
);
513 int num_draw_layers_
;
516 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw
);
518 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
519 : public LayerTreeHostAnimationTest
{
521 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()
522 : num_animate_(0), num_draw_layers_(0) {}
524 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
526 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
527 if (++num_animate_
<= 2) {
528 layer_tree_host()->SetNeedsCommit();
529 layer_tree_host()->SetNeedsAnimate();
533 void DrawLayersOnThread(LayerTreeHostImpl
* impl
) override
{
534 if (++num_draw_layers_
== 2)
538 void AfterTest() override
{
539 // The first commit will always draw; make sure the second draw triggered
540 // by the SetNeedsCommit was not cancelled.
541 EXPECT_EQ(2, num_draw_layers_
);
542 EXPECT_GE(num_animate_
, 2);
547 int num_draw_layers_
;
550 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit
);
552 // Make sure the main thread can still execute animations when CanDraw() is not
554 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
555 : public LayerTreeHostAnimationTest
{
557 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
559 void SetupTree() override
{
560 LayerTreeHostAnimationTest::SetupTree();
561 content_
= FakeContentLayer::Create(&client_
);
562 content_
->SetBounds(gfx::Size(4, 4));
563 content_
->set_layer_animation_delegate(this);
564 layer_tree_host()->root_layer()->AddChild(content_
);
567 void BeginTest() override
{
568 layer_tree_host()->SetViewportSize(gfx::Size());
569 PostAddAnimationToMainThread(content_
.get());
572 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
573 Animation::TargetProperty target_property
,
574 int group
) override
{
578 void NotifyAnimationFinished(base::TimeTicks monotonic_time
,
579 Animation::TargetProperty target_property
,
580 int group
) override
{
584 void AfterTest() override
{ EXPECT_EQ(1, started_times_
); }
588 FakeContentLayerClient client_
;
589 scoped_refptr
<FakeContentLayer
> content_
;
592 SINGLE_AND_MULTI_THREAD_TEST_F(
593 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
);
595 // Animations should not be started when frames are being skipped due to
597 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
598 : public LayerTreeHostAnimationTest
{
599 void SetupTree() override
{
600 LayerTreeHostAnimationTest::SetupTree();
601 content_
= FakeContentLayer::Create(&client_
);
602 content_
->SetBounds(gfx::Size(4, 4));
603 content_
->set_layer_animation_delegate(this);
604 layer_tree_host()->root_layer()->AddChild(content_
);
607 void InitializeSettings(LayerTreeSettings
* settings
) override
{
608 // Make sure that drawing many times doesn't cause a checkerboarded
609 // animation to start so we avoid flake in this test.
610 settings
->timeout_and_draw_when_animation_checkerboards
= false;
613 void BeginTest() override
{
615 added_animations_
= 0;
618 PostSetNeedsCommitToMainThread();
621 DrawResult
PrepareToDrawOnThread(LayerTreeHostImpl
* host_impl
,
622 LayerTreeHostImpl::FrameData
* frame_data
,
623 DrawResult draw_result
) override
{
624 if (added_animations_
< 2)
628 // Act like there is checkerboard when the second animation wants to draw.
630 if (prevented_draw_
> 2)
632 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
635 void DidCommitAndDrawFrame() override
{
636 switch (layer_tree_host()->source_frame_number()) {
638 // The animation is longer than 1 BeginFrame interval.
639 AddOpacityTransitionToLayer(content_
.get(), 0.1, 0.2f
, 0.8f
, false);
643 // This second animation will not be drawn so it should not start.
644 AddAnimatedTransformToLayer(content_
.get(), 0.1, 5, 5);
650 void NotifyAnimationStarted(base::TimeTicks monotonic_time
,
651 Animation::TargetProperty target_property
,
652 int group
) override
{
658 void AfterTest() override
{
659 // Make sure we tried to draw the second animation but failed.
660 EXPECT_LT(0, prevented_draw_
);
661 // The first animation should be started, but the second should not because
663 EXPECT_EQ(1, started_times_
);
667 int added_animations_
;
669 FakeContentLayerClient client_
;
670 scoped_refptr
<FakeContentLayer
> content_
;
674 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations
);
676 // Verifies that scroll offset animations are only accepted when impl-scrolling
677 // is supported, and that when scroll offset animations are accepted,
678 // scroll offset updates are sent back to the main thread.
679 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
680 : public LayerTreeHostAnimationTest
{
682 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {}
684 void SetupTree() override
{
685 LayerTreeHostAnimationTest::SetupTree();
687 scroll_layer_
= FakeContentLayer::Create(&client_
);
688 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
689 scroll_layer_
->SetBounds(gfx::Size(1000, 1000));
690 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(10, 20));
691 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
694 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
696 void DidCommit() override
{
697 switch (layer_tree_host()->source_frame_number()) {
699 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
700 ScrollOffsetAnimationCurve::Create(
701 gfx::ScrollOffset(500.f
, 550.f
),
702 EaseInOutTimingFunction::Create()));
703 scoped_ptr
<Animation
> animation(
704 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
705 animation
->set_needs_synchronized_start_time(true);
706 bool animation_added
= scroll_layer_
->AddAnimation(animation
.Pass());
707 bool impl_scrolling_supported
=
708 layer_tree_host()->proxy()->SupportsImplScrolling();
709 EXPECT_EQ(impl_scrolling_supported
, animation_added
);
710 if (!impl_scrolling_supported
)
715 if (scroll_layer_
->scroll_offset().x() > 10 &&
716 scroll_layer_
->scroll_offset().y() > 20)
721 void AfterTest() override
{}
724 FakeContentLayerClient client_
;
725 scoped_refptr
<FakeContentLayer
> scroll_layer_
;
728 SINGLE_AND_MULTI_THREAD_TEST_F(
729 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
);
731 // Verifies that when the main thread removes a scroll animation and sets a new
732 // scroll position, the active tree takes on exactly this new scroll position
733 // after activation, and the main thread doesn't receive a spurious scroll
735 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
736 : public LayerTreeHostAnimationTest
{
738 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()
739 : final_postion_(50.0, 100.0) {}
741 void SetupTree() override
{
742 LayerTreeHostAnimationTest::SetupTree();
744 scroll_layer_
= FakeContentLayer::Create(&client_
);
745 scroll_layer_
->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
746 scroll_layer_
->SetBounds(gfx::Size(10000, 10000));
747 scroll_layer_
->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
748 layer_tree_host()->root_layer()->AddChild(scroll_layer_
);
750 scoped_ptr
<ScrollOffsetAnimationCurve
> curve(
751 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f
, 7500.f
),
752 EaseInOutTimingFunction::Create()));
753 scoped_ptr
<Animation
> animation(
754 Animation::Create(curve
.Pass(), 1, 0, Animation::SCROLL_OFFSET
));
755 animation
->set_needs_synchronized_start_time(true);
756 scroll_layer_
->AddAnimation(animation
.Pass());
759 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
761 void BeginMainFrame(const BeginFrameArgs
& args
) override
{
762 switch (layer_tree_host()->source_frame_number()) {
766 Animation
* animation
=
767 scroll_layer_
->layer_animation_controller()->GetAnimation(
768 Animation::SCROLL_OFFSET
);
769 scroll_layer_
->layer_animation_controller()->RemoveAnimation(
771 scroll_layer_
->SetScrollOffset(final_postion_
);
775 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
779 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
780 if (host_impl
->settings().impl_side_painting
)
781 host_impl
->BlockNotifyReadyToActivateForTesting(true);
784 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
785 const BeginFrameArgs
& args
) override
{
786 if (!host_impl
->pending_tree())
789 if (!host_impl
->active_tree()->root_layer()) {
790 host_impl
->BlockNotifyReadyToActivateForTesting(false);
794 LayerImpl
* scroll_layer_impl
=
795 host_impl
->active_tree()->root_layer()->children()[0];
796 Animation
* animation
=
797 scroll_layer_impl
->layer_animation_controller()->GetAnimation(
798 Animation::SCROLL_OFFSET
);
800 if (!animation
|| animation
->run_state() != Animation::RUNNING
) {
801 host_impl
->BlockNotifyReadyToActivateForTesting(false);
805 // Block activation until the running animation has a chance to produce a
807 gfx::Vector2dF scroll_delta
= scroll_layer_impl
->ScrollDelta();
808 if (scroll_delta
.x() < 1.f
|| scroll_delta
.y() < 1.f
)
811 host_impl
->BlockNotifyReadyToActivateForTesting(false);
814 void WillActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
815 if (!host_impl
->settings().impl_side_painting
)
817 if (host_impl
->pending_tree()->source_frame_number() != 1)
819 LayerImpl
* scroll_layer_impl
=
820 host_impl
->pending_tree()->root_layer()->children()[0];
821 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
824 void DidActivateTreeOnThread(LayerTreeHostImpl
* host_impl
) override
{
825 if (host_impl
->active_tree()->source_frame_number() != 1)
827 LayerImpl
* scroll_layer_impl
=
828 host_impl
->active_tree()->root_layer()->children()[0];
829 EXPECT_EQ(final_postion_
, scroll_layer_impl
->CurrentScrollOffset());
833 void AfterTest() override
{
834 EXPECT_EQ(final_postion_
, scroll_layer_
->scroll_offset());
838 FakeContentLayerClient client_
;
839 scoped_refptr
<FakeContentLayer
> scroll_layer_
;
840 const gfx::ScrollOffset final_postion_
;
843 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
);
845 // When animations are simultaneously added to an existing layer and to a new
846 // layer, they should start at the same time, even when there's already a
847 // running animation on the existing layer.
848 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
849 : public LayerTreeHostAnimationTest
{
851 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()
852 : frame_count_with_pending_tree_(0) {}
854 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
856 void DidCommit() override
{
857 if (layer_tree_host()->source_frame_number() == 1) {
858 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1);
859 } else if (layer_tree_host()->source_frame_number() == 2) {
860 AddOpacityTransitionToLayer(
861 layer_tree_host()->root_layer(), 1, 0.f
, 0.5f
, true);
863 scoped_refptr
<Layer
> layer
= Layer::Create();
864 layer_tree_host()->root_layer()->AddChild(layer
);
865 layer
->set_layer_animation_delegate(this);
866 layer
->SetBounds(gfx::Size(4, 4));
867 AddOpacityTransitionToLayer(layer
.get(), 1, 0.f
, 0.5f
, true);
871 void BeginCommitOnThread(LayerTreeHostImpl
* host_impl
) override
{
872 if (host_impl
->settings().impl_side_painting
)
873 host_impl
->BlockNotifyReadyToActivateForTesting(true);
876 void CommitCompleteOnThread(LayerTreeHostImpl
* host_impl
) override
{
877 // For the commit that added animations to new and existing layers, keep
878 // blocking activation. We want to verify that even with activation blocked,
879 // the animation on the layer that's already in the active tree won't get a
881 if (host_impl
->settings().impl_side_painting
&&
882 host_impl
->pending_tree()->source_frame_number() != 2) {
883 host_impl
->BlockNotifyReadyToActivateForTesting(false);
887 void WillBeginImplFrameOnThread(LayerTreeHostImpl
* host_impl
,
888 const BeginFrameArgs
& args
) override
{
889 if (!host_impl
->pending_tree() ||
890 host_impl
->pending_tree()->source_frame_number() != 2)
893 frame_count_with_pending_tree_
++;
894 if (frame_count_with_pending_tree_
== 2 &&
895 host_impl
->settings().impl_side_painting
) {
896 host_impl
->BlockNotifyReadyToActivateForTesting(false);
900 void UpdateAnimationState(LayerTreeHostImpl
* host_impl
,
901 bool has_unfinished_animation
) override
{
902 LayerAnimationController
* root_controller_impl
=
903 host_impl
->active_tree()->root_layer()->layer_animation_controller();
904 Animation
* root_animation
=
905 root_controller_impl
->GetAnimation(Animation::OPACITY
);
906 if (!root_animation
|| root_animation
->run_state() != Animation::RUNNING
)
909 LayerAnimationController
* child_controller_impl
=
910 host_impl
->active_tree()->root_layer()->children()
911 [0]->layer_animation_controller();
912 Animation
* child_animation
=
913 child_controller_impl
->GetAnimation(Animation::OPACITY
);
914 EXPECT_EQ(Animation::RUNNING
, child_animation
->run_state());
915 EXPECT_EQ(root_animation
->start_time(), child_animation
->start_time());
916 root_controller_impl
->AbortAnimations(Animation::OPACITY
);
917 root_controller_impl
->AbortAnimations(Animation::TRANSFORM
);
918 child_controller_impl
->AbortAnimations(Animation::OPACITY
);
922 void AfterTest() override
{}
925 int frame_count_with_pending_tree_
;
928 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
929 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers
);
931 class LayerTreeHostAnimationTestAddAnimationAfterAnimating
932 : public LayerTreeHostAnimationTest
{
934 LayerTreeHostAnimationTestAddAnimationAfterAnimating()
935 : num_swap_buffers_(0) {}
937 void SetupTree() override
{
938 LayerTreeHostAnimationTest::SetupTree();
939 content_
= Layer::Create();
940 content_
->SetBounds(gfx::Size(4, 4));
941 layer_tree_host()->root_layer()->AddChild(content_
);
944 void BeginTest() override
{ PostSetNeedsCommitToMainThread(); }
946 void DidCommit() override
{
947 switch (layer_tree_host()->source_frame_number()) {
949 // First frame: add an animation to the root layer.
950 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
953 // Second frame: add an animation to the content layer. The root layer
954 // animation has caused us to animate already during this frame.
955 AddOpacityTransitionToLayer(content_
.get(), 0.1, 5, 5, false);
960 void SwapBuffersOnThread(LayerTreeHostImpl
* host_impl
, bool result
) override
{
961 // After both animations have started, verify that they have valid
964 AnimationRegistrar::AnimationControllerMap controllers_copy
=
965 host_impl
->animation_registrar()
966 ->active_animation_controllers_for_testing();
967 if (controllers_copy
.size() == 2u) {
969 EXPECT_GE(num_swap_buffers_
, 3);
970 for (auto& it
: controllers_copy
) {
972 if (id
== host_impl
->RootLayer()->id()) {
973 Animation
* anim
= it
.second
->GetAnimation(Animation::TRANSFORM
);
974 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
975 } else if (id
== host_impl
->RootLayer()->children()[0]->id()) {
976 Animation
* anim
= it
.second
->GetAnimation(Animation::OPACITY
);
977 EXPECT_GT((anim
->start_time() - base::TimeTicks()).InSecondsF(), 0);
983 void AfterTest() override
{}
986 scoped_refptr
<Layer
> content_
;
987 int num_swap_buffers_
;
990 SINGLE_AND_MULTI_THREAD_TEST_F(
991 LayerTreeHostAnimationTestAddAnimationAfterAnimating
);