This sets up API to release OutputSurface from LTHClient.
[chromium-blink-merge.git] / cc / trees / layer_tree_host_unittest_animation_timelines.cc
blobca7e754b1fb31ae8ca7b5b868a69f220368eb2a3
1 // Copyright 2015 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/animation_host.h"
9 #include "cc/animation/animation_id_provider.h"
10 #include "cc/animation/animation_player.h"
11 #include "cc/animation/animation_timeline.h"
12 #include "cc/animation/element_animations.h"
13 #include "cc/animation/layer_animation_controller.h"
14 #include "cc/animation/scroll_offset_animation_curve.h"
15 #include "cc/animation/timing_function.h"
16 #include "cc/base/completion_event.h"
17 #include "cc/base/time_util.h"
18 #include "cc/layers/layer.h"
19 #include "cc/layers/layer_impl.h"
20 #include "cc/test/animation_test_common.h"
21 #include "cc/test/fake_content_layer_client.h"
22 #include "cc/test/fake_picture_layer.h"
23 #include "cc/test/layer_tree_test.h"
24 #include "cc/trees/layer_tree_impl.h"
26 namespace cc {
27 namespace {
29 class LayerTreeHostTimelinesTest : public LayerTreeTest {
30 public:
31 LayerTreeHostTimelinesTest()
32 : timeline_id_(AnimationIdProvider::NextTimelineId()),
33 player_id_(AnimationIdProvider::NextPlayerId()),
34 player_child_id_(AnimationIdProvider::NextPlayerId()) {
35 timeline_ = AnimationTimeline::Create(timeline_id_);
36 player_ = AnimationPlayer::Create(player_id_);
37 player_child_ = AnimationPlayer::Create(player_child_id_);
39 player_->set_layer_animation_delegate(this);
42 void InitializeSettings(LayerTreeSettings* settings) override {
43 settings->use_compositor_animation_timelines = true;
46 void InitializeLayerSettings(LayerSettings* layer_settings) override {
47 layer_settings->use_compositor_animation_timelines = true;
50 void SetupTree() override { LayerTreeTest::SetupTree(); }
52 void AttachPlayersToTimeline() {
53 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
54 timeline_->AttachPlayer(player_.get());
55 timeline_->AttachPlayer(player_child_.get());
58 protected:
59 scoped_refptr<AnimationTimeline> timeline_;
60 scoped_refptr<AnimationPlayer> player_;
61 scoped_refptr<AnimationPlayer> player_child_;
63 const int timeline_id_;
64 const int player_id_;
65 const int player_child_id_;
68 // Add a layer animation and confirm that
69 // LayerTreeHostImpl::UpdateAnimationState does get called.
70 // Evolved frome LayerTreeHostAnimationTestAddAnimation
71 class LayerTreeHostTimelinesTestAddAnimation
72 : public LayerTreeHostTimelinesTest {
73 public:
74 LayerTreeHostTimelinesTestAddAnimation()
75 : update_animation_state_was_called_(false) {}
77 void BeginTest() override {
78 AttachPlayersToTimeline();
79 player_->AttachLayer(layer_tree_host()->root_layer()->id());
80 PostAddInstantAnimationToMainThreadPlayer(player_.get());
83 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
84 bool has_unfinished_animation) override {
85 EXPECT_FALSE(has_unfinished_animation);
86 update_animation_state_was_called_ = true;
89 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
90 Animation::TargetProperty target_property,
91 int group) override {
92 EXPECT_LT(base::TimeTicks(), monotonic_time);
94 LayerAnimationController* controller =
95 player_->element_animations()->layer_animation_controller();
96 Animation* animation = controller->GetAnimation(Animation::OPACITY);
97 if (animation)
98 player_->RemoveAnimation(animation->id());
100 EndTest();
103 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
105 private:
106 bool update_animation_state_was_called_;
109 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation);
111 // Add a layer animation to a layer, but continually fail to draw. Confirm that
112 // after a while, we do eventually force a draw.
113 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
114 class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
115 : public LayerTreeHostTimelinesTest {
116 public:
117 LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
118 : started_animating_(false) {}
120 void BeginTest() override {
121 AttachPlayersToTimeline();
122 player_->AttachLayer(layer_tree_host()->root_layer()->id());
123 PostAddAnimationToMainThreadPlayer(player_.get());
126 void AnimateLayers(LayerTreeHostImpl* host_impl,
127 base::TimeTicks monotonic_time) override {
128 started_animating_ = true;
131 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
132 if (started_animating_)
133 EndTest();
136 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
137 LayerTreeHostImpl::FrameData* frame,
138 DrawResult draw_result) override {
139 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
142 void AfterTest() override {}
144 private:
145 bool started_animating_;
148 // Starvation can only be an issue with the MT compositor.
149 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws);
151 // Ensures that animations eventually get deleted.
152 // Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
153 class LayerTreeHostTimelinesTestAnimationsGetDeleted
154 : public LayerTreeHostTimelinesTest {
155 public:
156 LayerTreeHostTimelinesTestAnimationsGetDeleted()
157 : started_animating_(false) {}
159 void BeginTest() override {
160 AttachPlayersToTimeline();
161 player_->AttachLayer(layer_tree_host()->root_layer()->id());
162 PostAddAnimationToMainThreadPlayer(player_.get());
165 void AnimateLayers(LayerTreeHostImpl* host_impl,
166 base::TimeTicks monotonic_time) override {
167 bool have_animations = !host_impl->animation_host()
168 ->animation_registrar()
169 ->active_animation_controllers_for_testing()
170 .empty();
171 if (!started_animating_ && have_animations) {
172 started_animating_ = true;
173 return;
176 if (started_animating_ && !have_animations)
177 EndTest();
180 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
181 Animation::TargetProperty target_property,
182 int group) override {
183 // Animations on the impl-side controller only get deleted during a commit,
184 // so we need to schedule a commit.
185 layer_tree_host()->SetNeedsCommit();
188 void AfterTest() override {}
190 private:
191 bool started_animating_;
194 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted);
196 // Ensure that an animation's timing function is respected.
197 // Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
198 class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
199 : public LayerTreeHostTimelinesTest {
200 public:
201 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
203 void SetupTree() override {
204 LayerTreeHostTimelinesTest::SetupTree();
205 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
206 picture_->SetBounds(gfx::Size(4, 4));
207 layer_tree_host()->root_layer()->AddChild(picture_);
209 AttachPlayersToTimeline();
210 player_child_->AttachLayer(picture_->id());
213 void BeginTest() override {
214 PostAddAnimationToMainThreadPlayer(player_child_.get());
217 void AnimateLayers(LayerTreeHostImpl* host_impl,
218 base::TimeTicks monotonic_time) override {
219 scoped_refptr<AnimationTimeline> timeline_impl =
220 host_impl->animation_host()->GetTimelineById(timeline_id_);
221 scoped_refptr<AnimationPlayer> player_child_impl =
222 timeline_impl->GetPlayerById(player_child_id_);
224 LayerAnimationController* controller_impl =
225 player_child_impl->element_animations()->layer_animation_controller();
226 if (!controller_impl)
227 return;
229 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
230 if (!animation)
231 return;
233 const FloatAnimationCurve* curve =
234 animation->curve()->ToFloatAnimationCurve();
235 float start_opacity = curve->GetValue(base::TimeDelta());
236 float end_opacity = curve->GetValue(curve->Duration());
237 float linearly_interpolated_opacity =
238 0.25f * end_opacity + 0.75f * start_opacity;
239 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
240 // If the linear timing function associated with this animation was not
241 // picked up, then the linearly interpolated opacity would be different
242 // because of the default ease timing function.
243 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
245 EndTest();
248 void AfterTest() override {}
250 FakeContentLayerClient client_;
251 scoped_refptr<FakePictureLayer> picture_;
254 SINGLE_AND_MULTI_THREAD_TEST_F(
255 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction);
257 // Ensures that main thread animations have their start times synchronized with
258 // impl thread animations.
259 // Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
260 class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
261 : public LayerTreeHostTimelinesTest {
262 public:
263 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
265 void SetupTree() override {
266 LayerTreeHostTimelinesTest::SetupTree();
267 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
268 picture_->SetBounds(gfx::Size(4, 4));
270 layer_tree_host()->root_layer()->AddChild(picture_);
272 AttachPlayersToTimeline();
273 player_child_->set_layer_animation_delegate(this);
274 player_child_->AttachLayer(picture_->id());
277 void BeginTest() override {
278 PostAddAnimationToMainThreadPlayer(player_child_.get());
281 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
282 Animation::TargetProperty target_property,
283 int group) override {
284 LayerAnimationController* controller =
285 player_child_->element_animations()->layer_animation_controller();
286 Animation* animation = controller->GetAnimation(Animation::OPACITY);
287 main_start_time_ = animation->start_time();
288 controller->RemoveAnimation(animation->id());
289 EndTest();
292 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
293 bool has_unfinished_animation) override {
294 scoped_refptr<AnimationTimeline> timeline_impl =
295 impl_host->animation_host()->GetTimelineById(timeline_id_);
296 scoped_refptr<AnimationPlayer> player_child_impl =
297 timeline_impl->GetPlayerById(player_child_id_);
299 LayerAnimationController* controller =
300 player_child_impl->element_animations()->layer_animation_controller();
301 Animation* animation = controller->GetAnimation(Animation::OPACITY);
302 if (!animation)
303 return;
305 impl_start_time_ = animation->start_time();
308 void AfterTest() override {
309 EXPECT_EQ(impl_start_time_, main_start_time_);
310 EXPECT_LT(base::TimeTicks(), impl_start_time_);
313 private:
314 base::TimeTicks main_start_time_;
315 base::TimeTicks impl_start_time_;
316 FakeContentLayerClient client_;
317 scoped_refptr<FakePictureLayer> picture_;
320 SINGLE_AND_MULTI_THREAD_TEST_F(
321 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes);
323 // Ensures that notify animation finished is called.
324 // Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
325 class LayerTreeHostTimelinesTestAnimationFinishedEvents
326 : public LayerTreeHostTimelinesTest {
327 public:
328 LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
330 void BeginTest() override {
331 AttachPlayersToTimeline();
332 player_->AttachLayer(layer_tree_host()->root_layer()->id());
333 PostAddInstantAnimationToMainThreadPlayer(player_.get());
336 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
337 Animation::TargetProperty target_property,
338 int group) override {
339 LayerAnimationController* controller =
340 player_->element_animations()->layer_animation_controller();
341 Animation* animation = controller->GetAnimation(Animation::OPACITY);
342 if (animation)
343 controller->RemoveAnimation(animation->id());
344 EndTest();
347 void AfterTest() override {}
350 SINGLE_AND_MULTI_THREAD_TEST_F(
351 LayerTreeHostTimelinesTestAnimationFinishedEvents);
353 // Ensures that when opacity is being animated, this value does not cause the
354 // subtree to be skipped.
355 // Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
356 class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
357 : public LayerTreeHostTimelinesTest {
358 public:
359 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
360 : update_check_layer_(
361 FakePictureLayer::Create(layer_settings(), &client_)) {}
363 void SetupTree() override {
364 update_check_layer_->SetOpacity(0.f);
365 layer_tree_host()->SetRootLayer(update_check_layer_);
366 LayerTreeHostTimelinesTest::SetupTree();
368 AttachPlayersToTimeline();
369 player_->AttachLayer(update_check_layer_->id());
372 void BeginTest() override {
373 PostAddAnimationToMainThreadPlayer(player_.get());
376 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
377 scoped_refptr<AnimationTimeline> timeline_impl =
378 host_impl->animation_host()->GetTimelineById(timeline_id_);
379 scoped_refptr<AnimationPlayer> player_impl =
380 timeline_impl->GetPlayerById(player_id_);
382 LayerAnimationController* controller_impl =
383 player_impl->element_animations()->layer_animation_controller();
384 Animation* animation_impl =
385 controller_impl->GetAnimation(Animation::OPACITY);
386 controller_impl->RemoveAnimation(animation_impl->id());
387 EndTest();
390 void AfterTest() override {
391 // Update() should have been called once, proving that the layer was not
392 // skipped.
393 EXPECT_EQ(1, update_check_layer_->update_count());
395 // clear update_check_layer_ so LayerTreeHost dies.
396 update_check_layer_ = NULL;
399 private:
400 FakeContentLayerClient client_;
401 scoped_refptr<FakePictureLayer> update_check_layer_;
404 SINGLE_AND_MULTI_THREAD_TEST_F(
405 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity);
407 // Layers added to tree with existing active animations should have the
408 // animation correctly recognized.
409 // Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
410 class LayerTreeHostTimelinesTestLayerAddedWithAnimation
411 : public LayerTreeHostTimelinesTest {
412 public:
413 LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
415 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
417 void DidCommit() override {
418 if (layer_tree_host()->source_frame_number() == 1) {
419 AttachPlayersToTimeline();
421 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
422 player_->AttachLayer(layer->id());
423 player_->set_layer_animation_delegate(this);
425 // Any valid AnimationCurve will do here.
426 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
427 scoped_ptr<Animation> animation(
428 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
429 player_->AddAnimation(animation.Pass());
431 // We add the animation *before* attaching the layer to the tree.
432 layer_tree_host()->root_layer()->AddChild(layer);
436 void AnimateLayers(LayerTreeHostImpl* impl_host,
437 base::TimeTicks monotonic_time) override {
438 EndTest();
441 void AfterTest() override {}
444 SINGLE_AND_MULTI_THREAD_TEST_F(
445 LayerTreeHostTimelinesTestLayerAddedWithAnimation);
447 // Animations should not be started when frames are being skipped due to
448 // checkerboard.
449 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
450 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
451 : public LayerTreeHostTimelinesTest {
452 void SetupTree() override {
453 LayerTreeHostTimelinesTest::SetupTree();
454 picture_ = FakePictureLayer::Create(layer_settings(), &client_);
455 picture_->SetBounds(gfx::Size(4, 4));
456 layer_tree_host()->root_layer()->AddChild(picture_);
458 AttachPlayersToTimeline();
459 player_child_->AttachLayer(picture_->id());
460 player_child_->set_layer_animation_delegate(this);
463 void InitializeSettings(LayerTreeSettings* settings) override {
464 // Make sure that drawing many times doesn't cause a checkerboarded
465 // animation to start so we avoid flake in this test.
466 settings->timeout_and_draw_when_animation_checkerboards = false;
467 LayerTreeHostTimelinesTest::InitializeSettings(settings);
470 void BeginTest() override {
471 prevented_draw_ = 0;
472 started_times_ = 0;
474 PostSetNeedsCommitToMainThread();
477 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
478 LayerTreeHostImpl::FrameData* frame_data,
479 DrawResult draw_result) override {
480 // Don't checkerboard when the first animation wants to start.
481 if (host_impl->active_tree()->source_frame_number() < 2)
482 return draw_result;
483 if (TestEnded())
484 return draw_result;
485 // Act like there is checkerboard when the second animation wants to draw.
486 ++prevented_draw_;
487 if (prevented_draw_ > 2)
488 EndTest();
489 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
492 void DidCommitAndDrawFrame() override {
493 switch (layer_tree_host()->source_frame_number()) {
494 case 1:
495 // The animation is longer than 1 BeginFrame interval.
496 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
497 false);
498 break;
499 case 2:
500 // This second animation will not be drawn so it should not start.
501 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
502 break;
506 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
507 Animation::TargetProperty target_property,
508 int group) override {
509 if (TestEnded())
510 return;
511 started_times_++;
514 void AfterTest() override {
515 // Make sure we tried to draw the second animation but failed.
516 EXPECT_LT(0, prevented_draw_);
517 // The first animation should be started, but the second should not because
518 // of checkerboard.
519 EXPECT_EQ(1, started_times_);
522 int prevented_draw_;
523 int started_times_;
524 FakeContentLayerClient client_;
525 scoped_refptr<FakePictureLayer> picture_;
528 MULTI_THREAD_TEST_F(
529 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations);
531 // Verifies that scroll offset animations are only accepted when impl-scrolling
532 // is supported, and that when scroll offset animations are accepted,
533 // scroll offset updates are sent back to the main thread.
534 // Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
535 class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated
536 : public LayerTreeHostTimelinesTest {
537 public:
538 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {}
540 void SetupTree() override {
541 LayerTreeHostTimelinesTest::SetupTree();
543 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
544 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
545 scroll_layer_->SetBounds(gfx::Size(1000, 1000));
546 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
547 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
549 AttachPlayersToTimeline();
550 player_child_->AttachLayer(scroll_layer_->id());
553 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
555 void DidCommit() override {
556 switch (layer_tree_host()->source_frame_number()) {
557 case 1: {
558 scoped_ptr<ScrollOffsetAnimationCurve> curve(
559 ScrollOffsetAnimationCurve::Create(
560 gfx::ScrollOffset(500.f, 550.f),
561 EaseInOutTimingFunction::Create()));
562 scoped_ptr<Animation> animation(
563 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
564 animation->set_needs_synchronized_start_time(true);
565 bool impl_scrolling_supported =
566 layer_tree_host()->proxy()->SupportsImplScrolling();
567 if (impl_scrolling_supported)
568 player_child_->AddAnimation(animation.Pass());
569 else
570 EndTest();
571 break;
573 default:
574 if (scroll_layer_->scroll_offset().x() > 10 &&
575 scroll_layer_->scroll_offset().y() > 20)
576 EndTest();
580 void AfterTest() override {}
582 private:
583 FakeContentLayerClient client_;
584 scoped_refptr<FakePictureLayer> scroll_layer_;
587 SINGLE_AND_MULTI_THREAD_TEST_F(
588 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated);
590 // Verifies that when the main thread removes a scroll animation and sets a new
591 // scroll position, the active tree takes on exactly this new scroll position
592 // after activation, and the main thread doesn't receive a spurious scroll
593 // delta.
594 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
595 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval
596 : public LayerTreeHostTimelinesTest {
597 public:
598 LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval()
599 : final_postion_(50.0, 100.0) {}
601 void SetupTree() override {
602 LayerTreeHostTimelinesTest::SetupTree();
604 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_);
605 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id());
606 scroll_layer_->SetBounds(gfx::Size(10000, 10000));
607 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
608 layer_tree_host()->root_layer()->AddChild(scroll_layer_);
610 scoped_ptr<ScrollOffsetAnimationCurve> curve(
611 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f),
612 EaseInOutTimingFunction::Create()));
613 scoped_ptr<Animation> animation(
614 Animation::Create(curve.Pass(), 1, 0, Animation::SCROLL_OFFSET));
615 animation->set_needs_synchronized_start_time(true);
617 AttachPlayersToTimeline();
618 player_child_->AttachLayer(scroll_layer_->id());
619 player_child_->AddAnimation(animation.Pass());
622 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
624 void BeginMainFrame(const BeginFrameArgs& args) override {
625 switch (layer_tree_host()->source_frame_number()) {
626 case 0:
627 break;
628 case 1: {
629 Animation* animation = player_child_->element_animations()
630 ->layer_animation_controller()
631 ->GetAnimation(Animation::SCROLL_OFFSET);
632 player_child_->RemoveAnimation(animation->id());
633 scroll_layer_->SetScrollOffset(final_postion_);
634 break;
636 default:
637 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
641 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
642 host_impl->BlockNotifyReadyToActivateForTesting(true);
645 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
646 const BeginFrameArgs& args) override {
647 if (!host_impl->pending_tree())
648 return;
650 if (!host_impl->active_tree()->root_layer()) {
651 host_impl->BlockNotifyReadyToActivateForTesting(false);
652 return;
655 scoped_refptr<AnimationTimeline> timeline_impl =
656 host_impl->animation_host()->GetTimelineById(timeline_id_);
657 scoped_refptr<AnimationPlayer> player_impl =
658 timeline_impl->GetPlayerById(player_child_id_);
660 LayerImpl* scroll_layer_impl =
661 host_impl->active_tree()->root_layer()->children()[0];
662 Animation* animation = player_impl->element_animations()
663 ->layer_animation_controller()
664 ->GetAnimation(Animation::SCROLL_OFFSET);
666 if (!animation || animation->run_state() != Animation::RUNNING) {
667 host_impl->BlockNotifyReadyToActivateForTesting(false);
668 return;
671 // Block activation until the running animation has a chance to produce a
672 // scroll delta.
673 gfx::Vector2dF scroll_delta = scroll_layer_impl->ScrollDelta();
674 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f)
675 return;
677 host_impl->BlockNotifyReadyToActivateForTesting(false);
680 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
681 if (host_impl->pending_tree()->source_frame_number() != 1)
682 return;
683 LayerImpl* scroll_layer_impl =
684 host_impl->pending_tree()->root_layer()->children()[0];
685 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
688 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
689 if (host_impl->active_tree()->source_frame_number() != 1)
690 return;
691 LayerImpl* scroll_layer_impl =
692 host_impl->active_tree()->root_layer()->children()[0];
693 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset());
694 EndTest();
697 void AfterTest() override {
698 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset());
701 private:
702 FakeContentLayerClient client_;
703 scoped_refptr<FakePictureLayer> scroll_layer_;
704 const gfx::ScrollOffset final_postion_;
707 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval);
709 // When animations are simultaneously added to an existing layer and to a new
710 // layer, they should start at the same time, even when there's already a
711 // running animation on the existing layer.
712 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
713 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
714 : public LayerTreeHostTimelinesTest {
715 public:
716 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
717 : frame_count_with_pending_tree_(0) {}
719 void BeginTest() override {
720 AttachPlayersToTimeline();
721 PostSetNeedsCommitToMainThread();
724 void DidCommit() override {
725 if (layer_tree_host()->source_frame_number() == 1) {
726 player_->AttachLayer(layer_tree_host()->root_layer()->id());
727 AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
728 } else if (layer_tree_host()->source_frame_number() == 2) {
729 AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
731 scoped_refptr<Layer> layer = Layer::Create(layer_settings());
732 layer_tree_host()->root_layer()->AddChild(layer);
733 layer->SetBounds(gfx::Size(4, 4));
735 player_child_->AttachLayer(layer->id());
736 player_child_->set_layer_animation_delegate(this);
737 AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
741 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
742 host_impl->BlockNotifyReadyToActivateForTesting(true);
745 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
746 // For the commit that added animations to new and existing layers, keep
747 // blocking activation. We want to verify that even with activation blocked,
748 // the animation on the layer that's already in the active tree won't get a
749 // head start.
750 if (host_impl->pending_tree()->source_frame_number() != 2) {
751 host_impl->BlockNotifyReadyToActivateForTesting(false);
755 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
756 const BeginFrameArgs& args) override {
757 if (!host_impl->pending_tree() ||
758 host_impl->pending_tree()->source_frame_number() != 2)
759 return;
761 frame_count_with_pending_tree_++;
762 if (frame_count_with_pending_tree_ == 2) {
763 host_impl->BlockNotifyReadyToActivateForTesting(false);
767 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
768 bool has_unfinished_animation) override {
769 scoped_refptr<AnimationTimeline> timeline_impl =
770 host_impl->animation_host()->GetTimelineById(timeline_id_);
771 scoped_refptr<AnimationPlayer> player_impl =
772 timeline_impl->GetPlayerById(player_id_);
773 scoped_refptr<AnimationPlayer> player_child_impl =
774 timeline_impl->GetPlayerById(player_child_id_);
776 // wait for tree activation.
777 if (!player_impl->element_animations())
778 return;
780 LayerAnimationController* root_controller_impl =
781 player_impl->element_animations()->layer_animation_controller();
782 Animation* root_animation =
783 root_controller_impl->GetAnimation(Animation::OPACITY);
784 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
785 return;
787 LayerAnimationController* child_controller_impl =
788 player_child_impl->element_animations()->layer_animation_controller();
789 Animation* child_animation =
790 child_controller_impl->GetAnimation(Animation::OPACITY);
791 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
792 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
793 root_controller_impl->AbortAnimations(Animation::OPACITY);
794 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
795 child_controller_impl->AbortAnimations(Animation::OPACITY);
796 EndTest();
799 void AfterTest() override {}
801 private:
802 int frame_count_with_pending_tree_;
805 // This test blocks activation which is not supported for single thread mode.
806 MULTI_THREAD_BLOCKNOTIFY_TEST_F(
807 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers);
809 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
810 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
811 : public LayerTreeHostTimelinesTest {
812 public:
813 void SetupTree() override {
814 LayerTreeHostTimelinesTest::SetupTree();
815 content_ = Layer::Create(layer_settings());
816 content_->SetBounds(gfx::Size(4, 4));
817 layer_tree_host()->root_layer()->AddChild(content_);
819 AttachPlayersToTimeline();
821 player_->AttachLayer(layer_tree_host()->root_layer()->id());
822 player_child_->AttachLayer(content_->id());
825 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
827 void DidCommit() override {
828 switch (layer_tree_host()->source_frame_number()) {
829 case 1:
830 // First frame: add an animation to the root layer.
831 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
832 break;
833 case 2:
834 // Second frame: add an animation to the content layer. The root layer
835 // animation has caused us to animate already during this frame.
836 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
837 break;
841 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
842 // After both animations have started, verify that they have valid
843 // start times.
844 if (host_impl->active_tree()->source_frame_number() < 2)
845 return;
846 AnimationRegistrar::AnimationControllerMap controllers_copy =
847 host_impl->animation_host()
848 ->animation_registrar()
849 ->active_animation_controllers_for_testing();
850 EXPECT_EQ(2u, controllers_copy.size());
851 for (auto& it : controllers_copy) {
852 int id = it.first;
853 if (id == host_impl->RootLayer()->id()) {
854 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
855 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
856 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
857 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
858 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
860 EndTest();
864 void AfterTest() override {}
866 private:
867 scoped_refptr<Layer> content_;
870 SINGLE_AND_MULTI_THREAD_TEST_F(
871 LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
873 class LayerTreeHostTimelinesTestRemoveAnimation
874 : public LayerTreeHostTimelinesTest {
875 public:
876 void SetupTree() override {
877 LayerTreeHostTimelinesTest::SetupTree();
878 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
879 layer_->SetBounds(gfx::Size(4, 4));
880 layer_tree_host()->root_layer()->AddChild(layer_);
882 AttachPlayersToTimeline();
884 player_->AttachLayer(layer_tree_host()->root_layer()->id());
885 player_child_->AttachLayer(layer_->id());
888 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
890 void DidCommit() override {
891 switch (layer_tree_host()->source_frame_number()) {
892 case 1:
893 AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5);
894 break;
895 case 2:
896 LayerAnimationController* controller =
897 player_child_->element_animations()->layer_animation_controller();
898 Animation* animation = controller->GetAnimation(Animation::TRANSFORM);
899 player_child_->RemoveAnimation(animation->id());
900 gfx::Transform transform;
901 transform.Translate(10.f, 10.f);
902 layer_->SetTransform(transform);
904 // Do something that causes property trees to get rebuilt.
905 layer_->AddChild(Layer::Create(layer_settings()));
906 break;
910 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
911 if (host_impl->active_tree()->source_frame_number() < 2)
912 return;
913 gfx::Transform expected_transform;
914 expected_transform.Translate(10.f, 10.f);
915 EXPECT_EQ(expected_transform, host_impl->active_tree()
916 ->root_layer()
917 ->children()[0]
918 ->draw_transform());
919 EndTest();
922 void AfterTest() override {}
924 private:
925 scoped_refptr<Layer> layer_;
926 FakeContentLayerClient client_;
929 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation);
931 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit
932 : public LayerTreeHostTimelinesTest {
933 public:
934 void SetupTree() override {
935 LayerTreeHostTimelinesTest::SetupTree();
936 layer_ = FakePictureLayer::Create(layer_settings(), &client_);
937 layer_->SetBounds(gfx::Size(4, 4));
938 layer_tree_host()->root_layer()->AddChild(layer_);
940 AttachPlayersToTimeline();
942 player_->AttachLayer(layer_tree_host()->root_layer()->id());
943 player_child_->AttachLayer(layer_->id());
946 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
948 void DidCommit() override {
949 if (layer_tree_host()->source_frame_number() == 1)
950 AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5);
953 void WillCommit() override {
954 if (layer_tree_host()->source_frame_number() == 2) {
955 // Block until the animation finishes on the compositor thread. Since
956 // animations have already been ticked on the main thread, when the commit
957 // happens the state on the main thread will be consistent with having a
958 // running animation but the state on the compositor thread will be
959 // consistent with having only a finished animation.
960 completion_.Wait();
964 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
965 switch (host_impl->sync_tree()->source_frame_number()) {
966 case 1:
967 PostSetNeedsCommitToMainThread();
968 break;
969 case 2:
970 gfx::Transform expected_transform;
971 expected_transform.Translate(5.f, 5.f);
972 LayerImpl* layer_impl =
973 host_impl->sync_tree()->root_layer()->children()[0];
974 EXPECT_EQ(expected_transform, layer_impl->draw_transform());
975 EndTest();
976 break;
980 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
981 bool has_unfinished_animation) override {
982 if (host_impl->active_tree()->source_frame_number() == 1 &&
983 !has_unfinished_animation) {
984 // The animation has finished, so allow the main thread to commit.
985 completion_.Signal();
989 void AfterTest() override {}
991 private:
992 scoped_refptr<Layer> layer_;
993 FakeContentLayerClient client_;
994 CompletionEvent completion_;
997 // An animation finishing during commit can only happen when we have a separate
998 // compositor thread.
999 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit);
1001 } // namespace
1002 } // namespace cc