Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: cc/trees/layer_tree_host_unittest_animation_timelines.cc

Issue 1010663002: CC Animations: Redirect all compositor animation requests to AnimationHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@introduce
Patch Set: Add ported unittests. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host.h" 5 #include "cc/trees/layer_tree_host.h"
6 6
7 #include "cc/animation/animation_curve.h" 7 #include "cc/animation/animation_curve.h"
8 #include "cc/animation/animation_host.h"
9 #include "cc/animation/animation_player.h"
10 #include "cc/animation/animation_timeline.h"
8 #include "cc/animation/layer_animation_controller.h" 11 #include "cc/animation/layer_animation_controller.h"
9 #include "cc/animation/scroll_offset_animation_curve.h" 12 #include "cc/animation/scroll_offset_animation_curve.h"
10 #include "cc/animation/timing_function.h" 13 #include "cc/animation/timing_function.h"
11 #include "cc/base/time_util.h" 14 #include "cc/base/time_util.h"
12 #include "cc/layers/layer.h" 15 #include "cc/layers/layer.h"
13 #include "cc/layers/layer_impl.h" 16 #include "cc/layers/layer_impl.h"
14 #include "cc/test/animation_test_common.h" 17 #include "cc/test/animation_test_common.h"
15 #include "cc/test/fake_content_layer.h" 18 #include "cc/test/fake_content_layer.h"
16 #include "cc/test/fake_content_layer_client.h" 19 #include "cc/test/fake_content_layer_client.h"
17 #include "cc/test/layer_tree_test.h" 20 #include "cc/test/layer_tree_test.h"
18 #include "cc/trees/layer_tree_impl.h" 21 #include "cc/trees/layer_tree_impl.h"
19 22
20 namespace cc { 23 namespace cc {
21 namespace {} // namespace 24 namespace {
25
26 class LayerTreeHostTimelinesTest : public LayerTreeTest {
27 public:
28 LayerTreeHostTimelinesTest()
29 : timeline_id_(1), player_id_(2), player_child_id_(3) {
30 timeline_ = AnimationTimeline::Create(timeline_id_);
31 player_ = AnimationPlayer::Create(player_id_);
32 player_child_ = AnimationPlayer::Create(player_child_id_);
33
34 player_->set_layer_animation_delegate(this);
35 }
36
37 void InitializeSettings(LayerTreeSettings* settings) override {
38 settings->use_compositor_animation_timelines = true;
39 }
40
41 void SetupTree() override { LayerTreeTest::SetupTree(); }
42
43 void AttachPlayersToTimeline() {
44 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get());
45 timeline_->AttachPlayer(player_.get());
46 timeline_->AttachPlayer(player_child_.get());
47 }
48
49 protected:
50 scoped_refptr<AnimationTimeline> timeline_;
51 scoped_refptr<AnimationPlayer> player_;
52 scoped_refptr<AnimationPlayer> player_child_;
53
54 const int timeline_id_;
55 const int player_id_;
56 const int player_child_id_;
57 };
58
59 // Add a layer animation and confirm that
60 // LayerTreeHostImpl::UpdateAnimationState does get called.
61 // Evolved frome LayerTreeHostAnimationTestAddAnimation
62 class LayerTreeHostTimelinesTestAddAnimation
63 : public LayerTreeHostTimelinesTest {
64 public:
65 LayerTreeHostTimelinesTestAddAnimation()
66 : update_animation_state_was_called_(false) {}
67
68 void BeginTest() override {
69 AttachPlayersToTimeline();
70 player_->AttachLayer(layer_tree_host()->root_layer()->id());
71 PostAddInstantAnimationToMainThreadPlayer(player_.get());
72 }
73
74 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
75 bool has_unfinished_animation) override {
76 EXPECT_FALSE(has_unfinished_animation);
77 update_animation_state_was_called_ = true;
78 }
79
80 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
81 Animation::TargetProperty target_property,
82 int group) override {
83 EXPECT_LT(base::TimeTicks(), monotonic_time);
84
85 LayerAnimationController* controller =
86 player_->layer_animation_controller();
87 Animation* animation = controller->GetAnimation(Animation::OPACITY);
88 if (animation)
89 player_->RemoveAnimation(animation->id());
90
91 EndTest();
92 }
93
94 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); }
95
96 private:
97 bool update_animation_state_was_called_;
98 };
99
100 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation);
101
102 // Add a layer animation to a layer, but continually fail to draw. Confirm that
103 // after a while, we do eventually force a draw.
104 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws.
105 class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws
106 : public LayerTreeHostTimelinesTest {
107 public:
108 LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws()
109 : started_animating_(false) {}
110
111 void BeginTest() override {
112 AttachPlayersToTimeline();
113 player_->AttachLayer(layer_tree_host()->root_layer()->id());
114 PostAddAnimationToMainThreadPlayer(player_.get());
115 }
116
117 void AnimateLayers(LayerTreeHostImpl* host_impl,
118 base::TimeTicks monotonic_time) override {
119 started_animating_ = true;
120 }
121
122 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
123 if (started_animating_)
124 EndTest();
125 }
126
127 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
128 LayerTreeHostImpl::FrameData* frame,
129 DrawResult draw_result) override {
130 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
131 }
132
133 void AfterTest() override {}
134
135 private:
136 bool started_animating_;
137 };
138
139 // Starvation can only be an issue with the MT compositor.
140 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws);
141
142 // Ensures that animations eventually get deleted.
143 // Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted.
144 class LayerTreeHostTimelinesTestAnimationsGetDeleted
145 : public LayerTreeHostTimelinesTest {
146 public:
147 LayerTreeHostTimelinesTestAnimationsGetDeleted()
148 : started_animating_(false) {}
149
150 void BeginTest() override {
151 AttachPlayersToTimeline();
152 player_->AttachLayer(layer_tree_host()->root_layer()->id());
153 PostAddAnimationToMainThreadPlayer(player_.get());
154 }
155
156 void AnimateLayers(LayerTreeHostImpl* host_impl,
157 base::TimeTicks monotonic_time) override {
158 bool have_animations = !host_impl->animation_host()
159 ->animation_registrar()
160 ->active_animation_controllers_for_testing()
161 .empty();
162 if (!started_animating_ && have_animations) {
163 started_animating_ = true;
164 return;
165 }
166
167 if (started_animating_ && !have_animations)
168 EndTest();
169 }
170
171 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
172 Animation::TargetProperty target_property,
173 int group) override {
174 // Animations on the impl-side controller only get deleted during a commit,
175 // so we need to schedule a commit.
176 layer_tree_host()->SetNeedsCommit();
177 }
178
179 void AfterTest() override {}
180
181 private:
182 bool started_animating_;
183 };
184
185 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted);
186
187 // Ensure that an animation's timing function is respected.
188 // Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction.
189 class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction
190 : public LayerTreeHostTimelinesTest {
191 public:
192 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {}
193
194 void SetupTree() override {
195 LayerTreeHostTimelinesTest::SetupTree();
196 content_ = FakeContentLayer::Create(&client_);
197 content_->SetBounds(gfx::Size(4, 4));
198 layer_tree_host()->root_layer()->AddChild(content_);
199
200 AttachPlayersToTimeline();
201 player_child_->AttachLayer(content_->id());
202 }
203
204 void BeginTest() override {
205 PostAddAnimationToMainThreadPlayer(player_child_.get());
206 }
207
208 void AnimateLayers(LayerTreeHostImpl* host_impl,
209 base::TimeTicks monotonic_time) override {
210 scoped_refptr<AnimationTimeline> timeline_impl =
211 host_impl->animation_host()->GetTimelineById(timeline_id_);
212 scoped_refptr<AnimationPlayer> player_child_impl =
213 timeline_impl->GetPlayerById(player_child_id_);
214
215 LayerAnimationController* controller_impl =
216 player_child_impl->layer_animation_controller();
217 if (!controller_impl)
218 return;
219
220 Animation* animation = controller_impl->GetAnimation(Animation::OPACITY);
221 if (!animation)
222 return;
223
224 const FloatAnimationCurve* curve =
225 animation->curve()->ToFloatAnimationCurve();
226 float start_opacity = curve->GetValue(base::TimeDelta());
227 float end_opacity = curve->GetValue(curve->Duration());
228 float linearly_interpolated_opacity =
229 0.25f * end_opacity + 0.75f * start_opacity;
230 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f);
231 // If the linear timing function associated with this animation was not
232 // picked up, then the linearly interpolated opacity would be different
233 // because of the default ease timing function.
234 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time));
235
236 EndTest();
237 }
238
239 void AfterTest() override {}
240
241 FakeContentLayerClient client_;
242 scoped_refptr<FakeContentLayer> content_;
243 };
244
245 SINGLE_AND_MULTI_THREAD_TEST_F(
246 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction);
247
248 // Ensures that main thread animations have their start times synchronized with
249 // impl thread animations.
250 // Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes.
251 class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes
252 : public LayerTreeHostTimelinesTest {
253 public:
254 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {}
255
256 void SetupTree() override {
257 LayerTreeHostTimelinesTest::SetupTree();
258 content_ = FakeContentLayer::Create(&client_);
259 content_->SetBounds(gfx::Size(4, 4));
260
261 layer_tree_host()->root_layer()->AddChild(content_);
262
263 AttachPlayersToTimeline();
264 player_child_->set_layer_animation_delegate(this);
265 player_child_->AttachLayer(content_->id());
266 }
267
268 void BeginTest() override {
269 PostAddAnimationToMainThreadPlayer(player_child_.get());
270 }
271
272 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
273 Animation::TargetProperty target_property,
274 int group) override {
275 LayerAnimationController* controller =
276 player_child_->layer_animation_controller();
277 Animation* animation = controller->GetAnimation(Animation::OPACITY);
278 main_start_time_ = animation->start_time();
279 controller->RemoveAnimation(animation->id());
280 EndTest();
281 }
282
283 void UpdateAnimationState(LayerTreeHostImpl* impl_host,
284 bool has_unfinished_animation) override {
285 scoped_refptr<AnimationTimeline> timeline_impl =
286 impl_host->animation_host()->GetTimelineById(timeline_id_);
287 scoped_refptr<AnimationPlayer> player_child_impl =
288 timeline_impl->GetPlayerById(player_child_id_);
289
290 LayerAnimationController* controller =
291 player_child_impl->layer_animation_controller();
292 Animation* animation = controller->GetAnimation(Animation::OPACITY);
293 if (!animation)
294 return;
295
296 impl_start_time_ = animation->start_time();
297 }
298
299 void AfterTest() override {
300 EXPECT_EQ(impl_start_time_, main_start_time_);
301 EXPECT_LT(base::TimeTicks(), impl_start_time_);
302 }
303
304 private:
305 base::TimeTicks main_start_time_;
306 base::TimeTicks impl_start_time_;
307 FakeContentLayerClient client_;
308 scoped_refptr<FakeContentLayer> content_;
309 };
310
311 SINGLE_AND_MULTI_THREAD_TEST_F(
312 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes);
313
314 // Ensures that notify animation finished is called.
315 // Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents.
316 class LayerTreeHostTimelinesTestAnimationFinishedEvents
317 : public LayerTreeHostTimelinesTest {
318 public:
319 LayerTreeHostTimelinesTestAnimationFinishedEvents() {}
320
321 void BeginTest() override {
322 AttachPlayersToTimeline();
323 player_->AttachLayer(layer_tree_host()->root_layer()->id());
324 PostAddInstantAnimationToMainThreadPlayer(player_.get());
325 }
326
327 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
328 Animation::TargetProperty target_property,
329 int group) override {
330 LayerAnimationController* controller =
331 player_->layer_animation_controller();
332 Animation* animation = controller->GetAnimation(Animation::OPACITY);
333 if (animation)
334 controller->RemoveAnimation(animation->id());
335 EndTest();
336 }
337
338 void AfterTest() override {}
339 };
340
341 SINGLE_AND_MULTI_THREAD_TEST_F(
342 LayerTreeHostTimelinesTestAnimationFinishedEvents);
343
344 // Ensures that when opacity is being animated, this value does not cause the
345 // subtree to be skipped.
346 // Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity.
347 class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity
348 : public LayerTreeHostTimelinesTest {
349 public:
350 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity()
351 : update_check_layer_(FakeContentLayer::Create(&client_)) {}
352
353 void SetupTree() override {
354 update_check_layer_->SetOpacity(0.f);
355 layer_tree_host()->SetRootLayer(update_check_layer_);
356 LayerTreeHostTimelinesTest::SetupTree();
357
358 AttachPlayersToTimeline();
359 player_->AttachLayer(update_check_layer_->id());
360 }
361
362 void BeginTest() override {
363 PostAddAnimationToMainThreadPlayer(player_.get());
364 }
365
366 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
367 scoped_refptr<AnimationTimeline> timeline_impl =
368 host_impl->animation_host()->GetTimelineById(timeline_id_);
369 scoped_refptr<AnimationPlayer> player_impl =
370 timeline_impl->GetPlayerById(player_id_);
371
372 LayerAnimationController* controller_impl =
373 player_impl->layer_animation_controller();
374 Animation* animation_impl =
375 controller_impl->GetAnimation(Animation::OPACITY);
376 controller_impl->RemoveAnimation(animation_impl->id());
377 EndTest();
378 }
379
380 void AfterTest() override {
381 // Update() should have been called once, proving that the layer was not
382 // skipped.
383 EXPECT_EQ(1u, update_check_layer_->update_count());
384
385 // clear update_check_layer_ so LayerTreeHost dies.
386 update_check_layer_ = NULL;
387 }
388
389 private:
390 FakeContentLayerClient client_;
391 scoped_refptr<FakeContentLayer> update_check_layer_;
392 };
393
394 SINGLE_AND_MULTI_THREAD_TEST_F(
395 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity);
396
397 // Layers added to tree with existing active animations should have the
398 // animation correctly recognized.
399 // Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation.
400 class LayerTreeHostTimelinesTestLayerAddedWithAnimation
401 : public LayerTreeHostTimelinesTest {
402 public:
403 LayerTreeHostTimelinesTestLayerAddedWithAnimation() {}
404
405 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
406
407 void DidCommit() override {
408 if (layer_tree_host()->source_frame_number() == 1) {
409 AttachPlayersToTimeline();
410
411 scoped_refptr<Layer> layer = Layer::Create();
412 player_->AttachLayer(layer->id());
413 player_->set_layer_animation_delegate(this);
414
415 // Any valid AnimationCurve will do here.
416 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve());
417 scoped_ptr<Animation> animation(
418 Animation::Create(curve.Pass(), 1, 1, Animation::OPACITY));
419 player_->AddAnimation(animation.Pass());
420
421 // We add the animation *before* attaching the layer to the tree.
422 layer_tree_host()->root_layer()->AddChild(layer);
423 }
424 }
425
426 void AnimateLayers(LayerTreeHostImpl* impl_host,
427 base::TimeTicks monotonic_time) override {
428 EndTest();
429 }
430
431 void AfterTest() override {}
432 };
433
434 SINGLE_AND_MULTI_THREAD_TEST_F(
435 LayerTreeHostTimelinesTestLayerAddedWithAnimation);
436
437 // Make sure the main thread can still execute animations when CanDraw() is not
438 // true.
439 // Evolved from LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw
440 class LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw
441 : public LayerTreeHostTimelinesTest {
442 public:
443 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw() : started_times_(0) {}
444
445 void SetupTree() override {
446 LayerTreeHostTimelinesTest::SetupTree();
447 content_ = FakeContentLayer::Create(&client_);
448 content_->SetBounds(gfx::Size(4, 4));
449 layer_tree_host()->root_layer()->AddChild(content_);
450
451 AttachPlayersToTimeline();
452 player_child_->AttachLayer(content_->id());
453 player_child_->set_layer_animation_delegate(this);
454 }
455
456 void BeginTest() override {
457 layer_tree_host()->SetViewportSize(gfx::Size());
458 PostAddAnimationToMainThreadPlayer(player_child_.get());
459 }
460
461 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
462 Animation::TargetProperty target_property,
463 int group) override {
464 started_times_++;
465 }
466
467 void NotifyAnimationFinished(base::TimeTicks monotonic_time,
468 Animation::TargetProperty target_property,
469 int group) override {
470 EndTest();
471 }
472
473 void AfterTest() override { EXPECT_EQ(1, started_times_); }
474
475 private:
476 int started_times_;
477 FakeContentLayerClient client_;
478 scoped_refptr<FakeContentLayer> content_;
479 };
480
481 SINGLE_AND_MULTI_THREAD_TEST_F(
482 LayerTreeHostTimelinesTestRunAnimationWhenNotCanDraw);
483
484 // Animations should not be started when frames are being skipped due to
485 // checkerboard.
486 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.
487 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations
488 : public LayerTreeHostTimelinesTest {
489 void SetupTree() override {
490 LayerTreeHostTimelinesTest::SetupTree();
491 content_ = FakeContentLayer::Create(&client_);
492 content_->SetBounds(gfx::Size(4, 4));
493 layer_tree_host()->root_layer()->AddChild(content_);
494
495 AttachPlayersToTimeline();
496 player_child_->AttachLayer(content_->id());
497 player_child_->set_layer_animation_delegate(this);
498 }
499
500 void InitializeSettings(LayerTreeSettings* settings) override {
501 // Make sure that drawing many times doesn't cause a checkerboarded
502 // animation to start so we avoid flake in this test.
503 settings->timeout_and_draw_when_animation_checkerboards = false;
504 LayerTreeHostTimelinesTest::InitializeSettings(settings);
505 }
506
507 void BeginTest() override {
508 prevented_draw_ = 0;
509 added_animations_ = 0;
510 started_times_ = 0;
511
512 PostSetNeedsCommitToMainThread();
513 }
514
515 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
516 LayerTreeHostImpl::FrameData* frame_data,
517 DrawResult draw_result) override {
518 if (added_animations_ < 2)
519 return draw_result;
520 if (TestEnded())
521 return draw_result;
522 // Act like there is checkerboard when the second animation wants to draw.
523 ++prevented_draw_;
524 if (prevented_draw_ > 2)
525 EndTest();
526 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
527 }
528
529 void DidCommitAndDrawFrame() override {
530 switch (layer_tree_host()->source_frame_number()) {
531 case 1:
532 // The animation is longer than 1 BeginFrame interval.
533 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f,
534 false);
535 added_animations_++;
536 break;
537 case 2:
538 // This second animation will not be drawn so it should not start.
539 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5);
540 added_animations_++;
541 break;
542 }
543 }
544
545 void NotifyAnimationStarted(base::TimeTicks monotonic_time,
546 Animation::TargetProperty target_property,
547 int group) override {
548 if (TestEnded())
549 return;
550 started_times_++;
551 }
552
553 void AfterTest() override {
554 // Make sure we tried to draw the second animation but failed.
555 EXPECT_LT(0, prevented_draw_);
556 // The first animation should be started, but the second should not because
557 // of checkerboard.
558 EXPECT_EQ(1, started_times_);
559 }
560
561 int prevented_draw_;
562 int added_animations_;
563 int started_times_;
564 FakeContentLayerClient client_;
565 scoped_refptr<FakeContentLayer> content_;
566 };
567
568 MULTI_THREAD_TEST_F(
569 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations);
570
571 // When animations are simultaneously added to an existing layer and to a new
572 // layer, they should start at the same time, even when there's already a
573 // running animation on the existing layer.
574 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers.
575 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers
576 : public LayerTreeHostTimelinesTest {
577 public:
578 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers()
579 : frame_count_with_pending_tree_(0) {}
580
581 void BeginTest() override {
582 AttachPlayersToTimeline();
583 PostSetNeedsCommitToMainThread();
584 }
585
586 void DidCommit() override {
587 if (layer_tree_host()->source_frame_number() == 1) {
588 player_->AttachLayer(layer_tree_host()->root_layer()->id());
589 AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1);
590 } else if (layer_tree_host()->source_frame_number() == 2) {
591 AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true);
592
593 scoped_refptr<Layer> layer = Layer::Create();
594 layer_tree_host()->root_layer()->AddChild(layer);
595 layer->set_layer_animation_delegate(this);
596 layer->SetBounds(gfx::Size(4, 4));
597
598 player_child_->AttachLayer(layer->id());
599 AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true);
600 }
601 }
602
603 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override {
604 if (host_impl->settings().impl_side_painting)
605 host_impl->BlockNotifyReadyToActivateForTesting(true);
606 }
607
608 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
609 // For the commit that added animations to new and existing layers, keep
610 // blocking activation. We want to verify that even with activation blocked,
611 // the animation on the layer that's already in the active tree won't get a
612 // head start.
613 if (host_impl->settings().impl_side_painting &&
614 host_impl->pending_tree()->source_frame_number() != 2) {
615 host_impl->BlockNotifyReadyToActivateForTesting(false);
616 }
617 }
618
619 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
620 const BeginFrameArgs& args) override {
621 if (!host_impl->pending_tree() ||
622 host_impl->pending_tree()->source_frame_number() != 2)
623 return;
624
625 frame_count_with_pending_tree_++;
626 if (frame_count_with_pending_tree_ == 2 &&
627 host_impl->settings().impl_side_painting) {
628 host_impl->BlockNotifyReadyToActivateForTesting(false);
629 }
630 }
631
632 void UpdateAnimationState(LayerTreeHostImpl* host_impl,
633 bool has_unfinished_animation) override {
634 scoped_refptr<AnimationTimeline> timeline_impl =
635 host_impl->animation_host()->GetTimelineById(timeline_id_);
636 scoped_refptr<AnimationPlayer> player_impl =
637 timeline_impl->GetPlayerById(player_id_);
638 scoped_refptr<AnimationPlayer> player_child_impl =
639 timeline_impl->GetPlayerById(player_child_id_);
640
641 // wait for tree activation.
642 if (!player_impl->layer_animation_controller())
643 return;
644
645 LayerAnimationController* root_controller_impl =
646 player_impl->layer_animation_controller();
647 Animation* root_animation =
648 root_controller_impl->GetAnimation(Animation::OPACITY);
649 if (!root_animation || root_animation->run_state() != Animation::RUNNING)
650 return;
651
652 LayerAnimationController* child_controller_impl =
653 player_child_impl->layer_animation_controller();
654 Animation* child_animation =
655 child_controller_impl->GetAnimation(Animation::OPACITY);
656 EXPECT_EQ(Animation::RUNNING, child_animation->run_state());
657 EXPECT_EQ(root_animation->start_time(), child_animation->start_time());
658 root_controller_impl->AbortAnimations(Animation::OPACITY);
659 root_controller_impl->AbortAnimations(Animation::TRANSFORM);
660 child_controller_impl->AbortAnimations(Animation::OPACITY);
661 EndTest();
662 }
663
664 void AfterTest() override {}
665
666 private:
667 int frame_count_with_pending_tree_;
668 };
669
670 SINGLE_AND_MULTI_THREAD_BLOCKNOTIFY_TEST_F(
671 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers);
672
673 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating.
674 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating
675 : public LayerTreeHostTimelinesTest {
676 public:
677 LayerTreeHostTimelinesTestAddAnimationAfterAnimating()
678 : num_swap_buffers_(0) {}
679
680 void SetupTree() override {
681 LayerTreeHostTimelinesTest::SetupTree();
682 content_ = Layer::Create();
683 content_->SetBounds(gfx::Size(4, 4));
684 layer_tree_host()->root_layer()->AddChild(content_);
685
686 AttachPlayersToTimeline();
687
688 player_->AttachLayer(layer_tree_host()->root_layer()->id());
689 player_child_->AttachLayer(content_->id());
690 }
691
692 void BeginTest() override { PostSetNeedsCommitToMainThread(); }
693
694 void DidCommit() override {
695 switch (layer_tree_host()->source_frame_number()) {
696 case 1:
697 // First frame: add an animation to the root layer.
698 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5);
699 break;
700 case 2:
701 // Second frame: add an animation to the content layer. The root layer
702 // animation has caused us to animate already during this frame.
703 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false);
704 break;
705 }
706 }
707
708 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
709 // After both animations have started, verify that they have valid
710 // start times.
711 num_swap_buffers_++;
712 AnimationRegistrar::AnimationControllerMap controllers_copy =
713 host_impl->animation_host()
714 ->animation_registrar()
715 ->active_animation_controllers_for_testing();
716 if (controllers_copy.size() == 2u) {
717 EndTest();
718 EXPECT_GE(num_swap_buffers_, 3);
719 for (auto& it : controllers_copy) {
720 int id = it.first;
721 if (id == host_impl->RootLayer()->id()) {
722 Animation* anim = it.second->GetAnimation(Animation::TRANSFORM);
723 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
724 } else if (id == host_impl->RootLayer()->children()[0]->id()) {
725 Animation* anim = it.second->GetAnimation(Animation::OPACITY);
726 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0);
727 }
728 }
729 }
730 }
731
732 void AfterTest() override {}
733
734 private:
735 scoped_refptr<Layer> content_;
736 int num_swap_buffers_;
737 };
738
739 SINGLE_AND_MULTI_THREAD_TEST_F(
740 LayerTreeHostTimelinesTestAddAnimationAfterAnimating);
741
742 } // namespace
22 } // namespace cc 743 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698