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. 4 5 #include "cc/trees/layer_tree_host.h" 6 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/layers/layer.h" 12 #include "cc/layers/layer_impl.h" 13 #include "cc/test/animation_test_common.h" 14 #include "cc/test/fake_content_layer.h" 15 #include "cc/test/fake_content_layer_client.h" 16 #include "cc/test/layer_tree_test.h" 17 #include "cc/trees/layer_tree_impl.h" 18 19 namespace cc { 20 namespace { 21 22 class LayerTreeHostAnimationTest : public LayerTreeTest { 23 public: 24 virtual void SetupTree() OVERRIDE { 25 LayerTreeTest::SetupTree(); 26 layer_tree_host()->root_layer()->set_layer_animation_delegate(this); 27 } 28 }; 29 30 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to 31 // be set. 32 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested 33 : public LayerTreeHostAnimationTest { 34 public: 35 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested() 36 : num_commits_(0) {} 37 38 virtual void BeginTest() OVERRIDE { 39 PostSetNeedsCommitToMainThread(); 40 } 41 42 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 43 // We skip the first commit because its the commit that populates the 44 // impl thread with a tree. After the second commit, the test is done. 45 if (num_commits_ != 1) 46 return; 47 48 layer_tree_host()->SetNeedsAnimate(); 49 // Right now, CommitRequested is going to be true, because during 50 // BeginFrame, we force CommitRequested to true to prevent requests from 51 // hitting the impl thread. But, when the next DidCommit happens, we should 52 // verify that CommitRequested has gone back to false. 53 } 54 55 virtual void DidCommit() OVERRIDE { 56 if (!num_commits_) { 57 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 58 layer_tree_host()->SetNeedsAnimate(); 59 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 60 } 61 62 // Verifies that the SetNeedsAnimate we made in ::Animate did not 63 // trigger CommitRequested. 64 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 65 EndTest(); 66 num_commits_++; 67 } 68 69 virtual void AfterTest() OVERRIDE {} 70 71 private: 72 int num_commits_; 73 }; 74 75 MULTI_THREAD_TEST_F( 76 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested); 77 78 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate 79 // callback, request another frame using SetNeedsAnimate. End the test when 80 // animate gets called yet-again, indicating that the proxy is correctly 81 // handling the case where SetNeedsAnimate() is called inside the BeginFrame 82 // flow. 83 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback 84 : public LayerTreeHostAnimationTest { 85 public: 86 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback() 87 : num_begin_frames_(0) {} 88 89 virtual void BeginTest() OVERRIDE { 90 PostSetNeedsCommitToMainThread(); 91 } 92 93 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 94 if (!num_begin_frames_) { 95 layer_tree_host()->SetNeedsAnimate(); 96 num_begin_frames_++; 97 return; 98 } 99 EndTest(); 100 } 101 102 virtual void AfterTest() OVERRIDE {} 103 104 private: 105 int num_begin_frames_; 106 }; 107 108 MULTI_THREAD_TEST_F( 109 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback); 110 111 // Add a layer animation and confirm that 112 // LayerTreeHostImpl::updateAnimationState does get called and continues to 113 // get called. 114 class LayerTreeHostAnimationTestAddAnimation 115 : public LayerTreeHostAnimationTest { 116 public: 117 LayerTreeHostAnimationTestAddAnimation() 118 : num_begin_frames_(0), received_animation_started_notification_(false) {} 119 120 virtual void BeginTest() OVERRIDE { 121 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); 122 } 123 124 virtual void UpdateAnimationState( 125 LayerTreeHostImpl* host_impl, 126 bool has_unfinished_animation) OVERRIDE { 127 if (!num_begin_frames_) { 128 // The animation had zero duration so LayerTreeHostImpl should no 129 // longer need to animate its layers. 130 EXPECT_FALSE(has_unfinished_animation); 131 num_begin_frames_++; 132 return; 133 } 134 135 if (received_animation_started_notification_) { 136 EXPECT_LT(base::TimeTicks(), start_time_); 137 138 LayerAnimationController* controller_impl = 139 host_impl->active_tree()->root_layer()->layer_animation_controller(); 140 Animation* animation_impl = 141 controller_impl->GetAnimation(Animation::Opacity); 142 if (animation_impl) 143 controller_impl->RemoveAnimation(animation_impl->id()); 144 145 EndTest(); 146 } 147 } 148 149 virtual void NotifyAnimationStarted( 150 base::TimeTicks monotonic_time, 151 Animation::TargetProperty target_property) OVERRIDE { 152 received_animation_started_notification_ = true; 153 start_time_ = monotonic_time; 154 if (num_begin_frames_) { 155 EXPECT_LT(base::TimeTicks(), start_time_); 156 157 LayerAnimationController* controller = 158 layer_tree_host()->root_layer()->layer_animation_controller(); 159 Animation* animation = 160 controller->GetAnimation(Animation::Opacity); 161 if (animation) 162 controller->RemoveAnimation(animation->id()); 163 164 EndTest(); 165 } 166 } 167 168 virtual void AfterTest() OVERRIDE {} 169 170 private: 171 int num_begin_frames_; 172 bool received_animation_started_notification_; 173 base::TimeTicks start_time_; 174 }; 175 176 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation); 177 178 // Add a layer animation to a layer, but continually fail to draw. Confirm that 179 // after a while, we do eventually force a draw. 180 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws 181 : public LayerTreeHostAnimationTest { 182 public: 183 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws() 184 : started_animating_(false) {} 185 186 virtual void BeginTest() OVERRIDE { 187 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 188 } 189 190 virtual void AnimateLayers( 191 LayerTreeHostImpl* host_impl, 192 base::TimeTicks monotonic_time) OVERRIDE { 193 started_animating_ = true; 194 } 195 196 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 197 if (started_animating_) 198 EndTest(); 199 } 200 201 virtual DrawResult PrepareToDrawOnThread( 202 LayerTreeHostImpl* host_impl, 203 LayerTreeHostImpl::FrameData* frame, 204 DrawResult draw_result) OVERRIDE { 205 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 206 } 207 208 virtual void AfterTest() OVERRIDE { } 209 210 private: 211 bool started_animating_; 212 }; 213 214 // Starvation can only be an issue with the MT compositor. 215 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws); 216 217 // Ensures that animations eventually get deleted. 218 class LayerTreeHostAnimationTestAnimationsGetDeleted 219 : public LayerTreeHostAnimationTest { 220 public: 221 LayerTreeHostAnimationTestAnimationsGetDeleted() 222 : started_animating_(false) {} 223 224 virtual void BeginTest() OVERRIDE { 225 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 226 } 227 228 virtual void AnimateLayers( 229 LayerTreeHostImpl* host_impl, 230 base::TimeTicks monotonic_time) OVERRIDE { 231 bool have_animations = !host_impl->animation_registrar()-> 232 active_animation_controllers().empty(); 233 if (!started_animating_ && have_animations) { 234 started_animating_ = true; 235 return; 236 } 237 238 if (started_animating_ && !have_animations) 239 EndTest(); 240 } 241 242 virtual void NotifyAnimationFinished( 243 base::TimeTicks monotonic_time, 244 Animation::TargetProperty target_property) OVERRIDE { 245 // Animations on the impl-side controller only get deleted during a commit, 246 // so we need to schedule a commit. 247 layer_tree_host()->SetNeedsCommit(); 248 } 249 250 virtual void AfterTest() OVERRIDE {} 251 252 private: 253 bool started_animating_; 254 }; 255 256 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); 257 258 // Ensures that animations continue to be ticked when we are backgrounded. 259 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded 260 : public LayerTreeHostAnimationTest { 261 public: 262 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded() 263 : num_begin_frames_(0) {} 264 265 virtual void BeginTest() OVERRIDE { 266 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); 267 } 268 269 // Use WillAnimateLayers to set visible false before the animation runs and 270 // causes a commit, so we block the second visible animate in single-thread 271 // mode. 272 virtual void WillAnimateLayers( 273 LayerTreeHostImpl* host_impl, 274 base::TimeTicks monotonic_time) OVERRIDE { 275 // Verify that the host can draw, it's just not visible. 276 EXPECT_TRUE(host_impl->CanDraw()); 277 if (num_begin_frames_ < 2) { 278 if (!num_begin_frames_) { 279 // We have a long animation running. It should continue to tick even 280 // if we are not visible. 281 PostSetVisibleToMainThread(false); 282 } 283 num_begin_frames_++; 284 return; 285 } 286 EndTest(); 287 } 288 289 virtual void AfterTest() OVERRIDE {} 290 291 private: 292 int num_begin_frames_; 293 }; 294 295 SINGLE_AND_MULTI_THREAD_TEST_F( 296 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded); 297 298 // Ensures that animation time remains monotonic when we switch from foreground 299 // to background ticking and back, even if we're skipping draws due to 300 // checkerboarding when in the foreground. 301 class LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic 302 : public LayerTreeHostAnimationTest { 303 public: 304 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic() 305 : has_background_ticked_(false), num_foreground_animates_(0) {} 306 307 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 308 // Make sure that drawing many times doesn't cause a checkerboarded 309 // animation to start so we avoid flake in this test. 310 settings->timeout_and_draw_when_animation_checkerboards = false; 311 } 312 313 virtual void BeginTest() OVERRIDE { 314 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); 315 } 316 317 virtual void AnimateLayers(LayerTreeHostImpl* host_impl, 318 base::TimeTicks monotonic_time) OVERRIDE { 319 EXPECT_GE(monotonic_time, last_tick_time_); 320 last_tick_time_ = monotonic_time; 321 if (host_impl->visible()) { 322 num_foreground_animates_++; 323 if (num_foreground_animates_ > 1 && !has_background_ticked_) 324 PostSetVisibleToMainThread(false); 325 else if (has_background_ticked_) 326 EndTest(); 327 } else { 328 has_background_ticked_ = true; 329 PostSetVisibleToMainThread(true); 330 } 331 } 332 333 virtual DrawResult PrepareToDrawOnThread( 334 LayerTreeHostImpl* host_impl, 335 LayerTreeHostImpl::FrameData* frame, 336 DrawResult draw_result) OVERRIDE { 337 if (TestEnded()) 338 return draw_result; 339 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 340 } 341 342 virtual void AfterTest() OVERRIDE {} 343 344 private: 345 bool has_background_ticked_; 346 int num_foreground_animates_; 347 base::TimeTicks last_tick_time_; 348 }; 349 350 SINGLE_AND_MULTI_THREAD_TEST_F( 351 LayerTreeHostAnimationTestAnimationTickTimeIsMonotonic); 352 353 // Ensures that animations do not tick when we are backgrounded and 354 // and we have an empty active tree. 355 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree 356 : public LayerTreeHostAnimationTest { 357 protected: 358 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree() 359 : active_tree_was_animated_(false) {} 360 361 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE { 362 return base::TimeDelta::FromMilliseconds(4); 363 } 364 365 virtual void BeginTest() OVERRIDE { 366 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 367 } 368 369 virtual void NotifyAnimationFinished( 370 base::TimeTicks monotonic_time, 371 Animation::TargetProperty target_property) OVERRIDE { 372 // Replace animated commits with an empty tree. 373 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL)); 374 } 375 376 virtual void DidCommit() OVERRIDE { 377 // This alternates setting an empty tree and a non-empty tree with an 378 // animation. 379 switch (layer_tree_host()->source_frame_number()) { 380 case 1: 381 // Wait for NotifyAnimationFinished to commit an empty tree. 382 break; 383 case 2: 384 SetupTree(); 385 AddOpacityTransitionToLayer( 386 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true); 387 break; 388 case 3: 389 // Wait for NotifyAnimationFinished to commit an empty tree. 390 break; 391 case 4: 392 EndTest(); 393 break; 394 } 395 } 396 397 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 398 // At the start of every commit, block activations and make sure 399 // we are backgrounded. 400 host_impl->BlockNotifyReadyToActivateForTesting(true); 401 PostSetVisibleToMainThread(false); 402 } 403 404 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 405 if (!host_impl->settings().impl_side_painting) { 406 // There are no activations to block if we're not impl-side-painting, 407 // so just advance the test immediately. 408 if (host_impl->active_tree()->source_frame_number() < 3) 409 UnblockActivations(host_impl); 410 return; 411 } 412 413 // We block activation for several ticks to make sure that, even though 414 // there is a pending tree with animations, we still do not background 415 // tick if the active tree is empty. 416 if (host_impl->pending_tree()->source_frame_number() < 3) { 417 base::MessageLoopProxy::current()->PostDelayedTask( 418 FROM_HERE, 419 base::Bind( 420 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: 421 UnblockActivations, 422 base::Unretained(this), 423 host_impl), 424 4 * LowFrequencyAnimationInterval()); 425 } 426 } 427 428 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) { 429 host_impl->BlockNotifyReadyToActivateForTesting(false); 430 } 431 432 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 433 active_tree_was_animated_ = false; 434 435 // Verify that commits are actually alternating with empty / non-empty 436 // trees. 437 int frame_number = host_impl->active_tree()->source_frame_number(); 438 switch (frame_number) { 439 case 0: 440 case 2: 441 EXPECT_TRUE(host_impl->active_tree()->root_layer()) 442 << "frame: " << frame_number; 443 break; 444 case 1: 445 case 3: 446 EXPECT_FALSE(host_impl->active_tree()->root_layer()) 447 << "frame: " << frame_number; 448 break; 449 } 450 451 if (host_impl->active_tree()->source_frame_number() < 3) { 452 // Initiate the next commit after a delay to give us a chance to 453 // background tick if the active tree isn't empty. 454 base::MessageLoopProxy::current()->PostDelayedTask( 455 FROM_HERE, 456 base::Bind( 457 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: 458 InitiateNextCommit, 459 base::Unretained(this), 460 host_impl), 461 4 * LowFrequencyAnimationInterval()); 462 } 463 } 464 465 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, 466 base::TimeTicks monotonic_time) OVERRIDE { 467 EXPECT_TRUE(host_impl->active_tree()->root_layer()); 468 active_tree_was_animated_ = true; 469 } 470 471 void InitiateNextCommit(LayerTreeHostImpl* host_impl) { 472 // Verify that we actually animated when we should have. 473 bool has_active_tree = host_impl->active_tree()->root_layer(); 474 EXPECT_EQ(has_active_tree, active_tree_was_animated_); 475 476 // The next commit is blocked until we become visible again. 477 PostSetVisibleToMainThread(true); 478 } 479 480 virtual void AfterTest() OVERRIDE {} 481 482 bool active_tree_was_animated_; 483 }; 484 485 SINGLE_AND_MULTI_THREAD_TEST_F( 486 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree); 487 488 // Ensure that an animation's timing function is respected. 489 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction 490 : public LayerTreeHostAnimationTest { 491 public: 492 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} 493 494 virtual void SetupTree() OVERRIDE { 495 LayerTreeHostAnimationTest::SetupTree(); 496 content_ = FakeContentLayer::Create(&client_); 497 content_->SetBounds(gfx::Size(4, 4)); 498 layer_tree_host()->root_layer()->AddChild(content_); 499 } 500 501 virtual void BeginTest() OVERRIDE { 502 PostAddAnimationToMainThread(content_.get()); 503 } 504 505 virtual void AnimateLayers( 506 LayerTreeHostImpl* host_impl, 507 base::TimeTicks monotonic_time) OVERRIDE { 508 LayerAnimationController* controller_impl = 509 host_impl->active_tree()->root_layer()->children()[0]-> 510 layer_animation_controller(); 511 Animation* animation = 512 controller_impl->GetAnimation(Animation::Opacity); 513 if (!animation) 514 return; 515 516 const FloatAnimationCurve* curve = 517 animation->curve()->ToFloatAnimationCurve(); 518 float start_opacity = curve->GetValue(0.0); 519 float end_opacity = curve->GetValue(curve->Duration()); 520 float linearly_interpolated_opacity = 521 0.25f * end_opacity + 0.75f * start_opacity; 522 double time = curve->Duration() * 0.25; 523 // If the linear timing function associated with this animation was not 524 // picked up, then the linearly interpolated opacity would be different 525 // because of the default ease timing function. 526 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); 527 528 EndTest(); 529 } 530 531 virtual void AfterTest() OVERRIDE {} 532 533 FakeContentLayerClient client_; 534 scoped_refptr<FakeContentLayer> content_; 535 }; 536 537 SINGLE_AND_MULTI_THREAD_TEST_F( 538 LayerTreeHostAnimationTestAddAnimationWithTimingFunction); 539 540 // Ensures that main thread animations have their start times synchronized with 541 // impl thread animations. 542 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 543 : public LayerTreeHostAnimationTest { 544 public: 545 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() 546 : main_start_time_(-1.0), 547 impl_start_time_(-1.0) {} 548 549 virtual void SetupTree() OVERRIDE { 550 LayerTreeHostAnimationTest::SetupTree(); 551 content_ = FakeContentLayer::Create(&client_); 552 content_->SetBounds(gfx::Size(4, 4)); 553 content_->set_layer_animation_delegate(this); 554 layer_tree_host()->root_layer()->AddChild(content_); 555 } 556 557 virtual void BeginTest() OVERRIDE { 558 PostAddAnimationToMainThread(content_.get()); 559 } 560 561 virtual void NotifyAnimationStarted( 562 base::TimeTicks monotonic_time, 563 Animation::TargetProperty target_property) OVERRIDE { 564 LayerAnimationController* controller = 565 layer_tree_host()->root_layer()->children()[0]-> 566 layer_animation_controller(); 567 Animation* animation = 568 controller->GetAnimation(Animation::Opacity); 569 main_start_time_ = 570 (animation->start_time() - base::TimeTicks()).InSecondsF(); 571 controller->RemoveAnimation(animation->id()); 572 573 if (impl_start_time_ > 0.0) 574 EndTest(); 575 } 576 577 virtual void UpdateAnimationState( 578 LayerTreeHostImpl* impl_host, 579 bool has_unfinished_animation) OVERRIDE { 580 LayerAnimationController* controller = 581 impl_host->active_tree()->root_layer()->children()[0]-> 582 layer_animation_controller(); 583 Animation* animation = 584 controller->GetAnimation(Animation::Opacity); 585 if (!animation) 586 return; 587 588 impl_start_time_ = 589 (animation->start_time() - base::TimeTicks()).InSecondsF(); 590 controller->RemoveAnimation(animation->id()); 591 592 if (main_start_time_ > 0.0) 593 EndTest(); 594 } 595 596 virtual void AfterTest() OVERRIDE { 597 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_); 598 } 599 600 private: 601 double main_start_time_; 602 double impl_start_time_; 603 FakeContentLayerClient client_; 604 scoped_refptr<FakeContentLayer> content_; 605 }; 606 607 SINGLE_AND_MULTI_THREAD_TEST_F( 608 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes); 609 610 // Ensures that notify animation finished is called. 611 class LayerTreeHostAnimationTestAnimationFinishedEvents 612 : public LayerTreeHostAnimationTest { 613 public: 614 LayerTreeHostAnimationTestAnimationFinishedEvents() {} 615 616 virtual void BeginTest() OVERRIDE { 617 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); 618 } 619 620 virtual void NotifyAnimationFinished( 621 base::TimeTicks monotonic_time, 622 Animation::TargetProperty target_property) OVERRIDE { 623 LayerAnimationController* controller = 624 layer_tree_host()->root_layer()->layer_animation_controller(); 625 Animation* animation = 626 controller->GetAnimation(Animation::Opacity); 627 if (animation) 628 controller->RemoveAnimation(animation->id()); 629 EndTest(); 630 } 631 632 virtual void AfterTest() OVERRIDE {} 633 }; 634 635 SINGLE_AND_MULTI_THREAD_TEST_F( 636 LayerTreeHostAnimationTestAnimationFinishedEvents); 637 638 // Ensures that when opacity is being animated, this value does not cause the 639 // subtree to be skipped. 640 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 641 : public LayerTreeHostAnimationTest { 642 public: 643 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() 644 : update_check_layer_(FakeContentLayer::Create(&client_)) { 645 } 646 647 virtual void SetupTree() OVERRIDE { 648 update_check_layer_->SetOpacity(0.f); 649 layer_tree_host()->SetRootLayer(update_check_layer_); 650 LayerTreeHostAnimationTest::SetupTree(); 651 } 652 653 virtual void BeginTest() OVERRIDE { 654 PostAddAnimationToMainThread(update_check_layer_.get()); 655 } 656 657 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 658 LayerAnimationController* controller_impl = 659 host_impl->active_tree()->root_layer()->layer_animation_controller(); 660 Animation* animation_impl = 661 controller_impl->GetAnimation(Animation::Opacity); 662 controller_impl->RemoveAnimation(animation_impl->id()); 663 EndTest(); 664 } 665 666 virtual void AfterTest() OVERRIDE { 667 // Update() should have been called once, proving that the layer was not 668 // skipped. 669 EXPECT_EQ(1u, update_check_layer_->update_count()); 670 671 // clear update_check_layer_ so LayerTreeHost dies. 672 update_check_layer_ = NULL; 673 } 674 675 private: 676 FakeContentLayerClient client_; 677 scoped_refptr<FakeContentLayer> update_check_layer_; 678 }; 679 680 SINGLE_AND_MULTI_THREAD_TEST_F( 681 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity); 682 683 // Layers added to tree with existing active animations should have the 684 // animation correctly recognized. 685 class LayerTreeHostAnimationTestLayerAddedWithAnimation 686 : public LayerTreeHostAnimationTest { 687 public: 688 LayerTreeHostAnimationTestLayerAddedWithAnimation() {} 689 690 virtual void BeginTest() OVERRIDE { 691 PostSetNeedsCommitToMainThread(); 692 } 693 694 virtual void DidCommit() OVERRIDE { 695 if (layer_tree_host()->source_frame_number() == 1) { 696 scoped_refptr<Layer> layer = Layer::Create(); 697 layer->set_layer_animation_delegate(this); 698 699 // Any valid AnimationCurve will do here. 700 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); 701 scoped_ptr<Animation> animation( 702 Animation::Create(curve.Pass(), 1, 1, 703 Animation::Opacity)); 704 layer->layer_animation_controller()->AddAnimation(animation.Pass()); 705 706 // We add the animation *before* attaching the layer to the tree. 707 layer_tree_host()->root_layer()->AddChild(layer); 708 } 709 } 710 711 virtual void AnimateLayers( 712 LayerTreeHostImpl* impl_host, 713 base::TimeTicks monotonic_time) OVERRIDE { 714 EndTest(); 715 } 716 717 virtual void AfterTest() OVERRIDE {} 718 }; 719 720 SINGLE_AND_MULTI_THREAD_TEST_F( 721 LayerTreeHostAnimationTestLayerAddedWithAnimation); 722 723 class LayerTreeHostAnimationTestCancelAnimateCommit 724 : public LayerTreeHostAnimationTest { 725 public: 726 LayerTreeHostAnimationTestCancelAnimateCommit() 727 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {} 728 729 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 730 731 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 732 num_begin_frames_++; 733 // No-op animate will cancel the commit. 734 if (layer_tree_host()->source_frame_number() == 1) { 735 EndTest(); 736 return; 737 } 738 layer_tree_host()->SetNeedsAnimate(); 739 } 740 741 virtual void CommitCompleteOnThread(LayerTreeHostImpl* impl) OVERRIDE { 742 num_commit_calls_++; 743 if (impl->active_tree()->source_frame_number() > 1) 744 FAIL() << "Commit should have been canceled."; 745 } 746 747 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 748 num_draw_calls_++; 749 if (impl->active_tree()->source_frame_number() > 1) 750 FAIL() << "Draw should have been canceled."; 751 } 752 753 virtual void AfterTest() OVERRIDE { 754 EXPECT_EQ(2, num_begin_frames_); 755 EXPECT_EQ(1, num_commit_calls_); 756 EXPECT_EQ(1, num_draw_calls_); 757 } 758 759 private: 760 int num_begin_frames_; 761 int num_commit_calls_; 762 int num_draw_calls_; 763 FakeContentLayerClient client_; 764 scoped_refptr<FakeContentLayer> content_; 765 }; 766 767 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit); 768 769 class LayerTreeHostAnimationTestForceRedraw 770 : public LayerTreeHostAnimationTest { 771 public: 772 LayerTreeHostAnimationTestForceRedraw() 773 : num_animate_(0), num_draw_layers_(0) {} 774 775 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 776 777 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 778 if (++num_animate_ < 2) 779 layer_tree_host()->SetNeedsAnimate(); 780 } 781 782 virtual void Layout() OVERRIDE { 783 layer_tree_host()->SetNextCommitForcesRedraw(); 784 } 785 786 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 787 if (++num_draw_layers_ == 2) 788 EndTest(); 789 } 790 791 virtual void AfterTest() OVERRIDE { 792 // The first commit will always draw; make sure the second draw triggered 793 // by the animation was not cancelled. 794 EXPECT_EQ(2, num_draw_layers_); 795 EXPECT_EQ(2, num_animate_); 796 } 797 798 private: 799 int num_animate_; 800 int num_draw_layers_; 801 }; 802 803 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw); 804 805 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit 806 : public LayerTreeHostAnimationTest { 807 public: 808 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit() 809 : num_animate_(0), num_draw_layers_(0) {} 810 811 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 812 813 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 814 if (++num_animate_ <= 2) { 815 layer_tree_host()->SetNeedsCommit(); 816 layer_tree_host()->SetNeedsAnimate(); 817 } 818 } 819 820 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 821 if (++num_draw_layers_ == 2) 822 EndTest(); 823 } 824 825 virtual void AfterTest() OVERRIDE { 826 // The first commit will always draw; make sure the second draw triggered 827 // by the SetNeedsCommit was not cancelled. 828 EXPECT_EQ(2, num_draw_layers_); 829 EXPECT_GE(num_animate_, 2); 830 } 831 832 private: 833 int num_animate_; 834 int num_draw_layers_; 835 }; 836 837 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit); 838 839 // Make sure the main thread can still execute animations when CanDraw() is not 840 // true. 841 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw 842 : public LayerTreeHostAnimationTest { 843 public: 844 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} 845 846 virtual void SetupTree() OVERRIDE { 847 LayerTreeHostAnimationTest::SetupTree(); 848 content_ = FakeContentLayer::Create(&client_); 849 content_->SetBounds(gfx::Size(4, 4)); 850 content_->set_layer_animation_delegate(this); 851 layer_tree_host()->root_layer()->AddChild(content_); 852 } 853 854 virtual void BeginTest() OVERRIDE { 855 layer_tree_host()->SetViewportSize(gfx::Size()); 856 PostAddAnimationToMainThread(content_.get()); 857 } 858 859 virtual void NotifyAnimationStarted( 860 base::TimeTicks monotonic_time, 861 Animation::TargetProperty target_property) OVERRIDE { 862 started_times_++; 863 } 864 865 virtual void NotifyAnimationFinished( 866 base::TimeTicks monotonic_time, 867 Animation::TargetProperty target_property) OVERRIDE { 868 EndTest(); 869 } 870 871 virtual void AfterTest() OVERRIDE { 872 EXPECT_EQ(1, started_times_); 873 } 874 875 private: 876 int started_times_; 877 FakeContentLayerClient client_; 878 scoped_refptr<FakeContentLayer> content_; 879 }; 880 881 SINGLE_AND_MULTI_THREAD_TEST_F( 882 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw); 883 884 // Make sure the main thread can still execute animations when the renderer is 885 // backgrounded. 886 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible 887 : public LayerTreeHostAnimationTest { 888 public: 889 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {} 890 891 virtual void SetupTree() OVERRIDE { 892 LayerTreeHostAnimationTest::SetupTree(); 893 content_ = FakeContentLayer::Create(&client_); 894 content_->SetBounds(gfx::Size(4, 4)); 895 content_->set_layer_animation_delegate(this); 896 layer_tree_host()->root_layer()->AddChild(content_); 897 } 898 899 virtual void BeginTest() OVERRIDE { 900 visible_ = true; 901 PostAddAnimationToMainThread(content_.get()); 902 } 903 904 virtual void DidCommit() OVERRIDE { 905 visible_ = false; 906 layer_tree_host()->SetVisible(false); 907 } 908 909 virtual void NotifyAnimationStarted( 910 base::TimeTicks monotonic_time, 911 Animation::TargetProperty target_property) OVERRIDE { 912 EXPECT_FALSE(visible_); 913 started_times_++; 914 } 915 916 virtual void NotifyAnimationFinished( 917 base::TimeTicks monotonic_time, 918 Animation::TargetProperty target_property) OVERRIDE { 919 EXPECT_FALSE(visible_); 920 EXPECT_EQ(1, started_times_); 921 EndTest(); 922 } 923 924 virtual void AfterTest() OVERRIDE {} 925 926 private: 927 bool visible_; 928 int started_times_; 929 FakeContentLayerClient client_; 930 scoped_refptr<FakeContentLayer> content_; 931 }; 932 933 SINGLE_AND_MULTI_THREAD_TEST_F( 934 LayerTreeHostAnimationTestRunAnimationWhenNotVisible); 935 936 // Animations should not be started when frames are being skipped due to 937 // checkerboard. 938 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations 939 : public LayerTreeHostAnimationTest { 940 virtual void SetupTree() OVERRIDE { 941 LayerTreeHostAnimationTest::SetupTree(); 942 content_ = FakeContentLayer::Create(&client_); 943 content_->SetBounds(gfx::Size(4, 4)); 944 content_->set_layer_animation_delegate(this); 945 layer_tree_host()->root_layer()->AddChild(content_); 946 } 947 948 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 949 // Make sure that drawing many times doesn't cause a checkerboarded 950 // animation to start so we avoid flake in this test. 951 settings->timeout_and_draw_when_animation_checkerboards = false; 952 } 953 954 virtual void BeginTest() OVERRIDE { 955 prevented_draw_ = 0; 956 added_animations_ = 0; 957 started_times_ = 0; 958 959 PostSetNeedsCommitToMainThread(); 960 } 961 962 virtual DrawResult PrepareToDrawOnThread( 963 LayerTreeHostImpl* host_impl, 964 LayerTreeHostImpl::FrameData* frame_data, 965 DrawResult draw_result) OVERRIDE { 966 if (added_animations_ < 2) 967 return draw_result; 968 if (TestEnded()) 969 return draw_result; 970 // Act like there is checkerboard when the second animation wants to draw. 971 ++prevented_draw_; 972 if (prevented_draw_ > 2) 973 EndTest(); 974 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 975 } 976 977 virtual void DidCommitAndDrawFrame() OVERRIDE { 978 switch (layer_tree_host()->source_frame_number()) { 979 case 1: 980 // The animation is longer than 1 BeginFrame interval. 981 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false); 982 added_animations_++; 983 break; 984 case 2: 985 // This second animation will not be drawn so it should not start. 986 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5); 987 added_animations_++; 988 break; 989 } 990 } 991 992 virtual void NotifyAnimationStarted( 993 base::TimeTicks monotonic_time, 994 Animation::TargetProperty target_property) OVERRIDE { 995 if (TestEnded()) 996 return; 997 started_times_++; 998 } 999 1000 virtual void AfterTest() OVERRIDE { 1001 // Make sure we tried to draw the second animation but failed. 1002 EXPECT_LT(0, prevented_draw_); 1003 // The first animation should be started, but the second should not because 1004 // of checkerboard. 1005 EXPECT_EQ(1, started_times_); 1006 } 1007 1008 int prevented_draw_; 1009 int added_animations_; 1010 int started_times_; 1011 FakeContentLayerClient client_; 1012 scoped_refptr<FakeContentLayer> content_; 1013 }; 1014 1015 MULTI_THREAD_TEST_F( 1016 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); 1017 1018 // Verifies that scroll offset animations are only accepted when impl-scrolling 1019 // is supported, and that when scroll offset animations are accepted, 1020 // scroll offset updates are sent back to the main thread. 1021 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated 1022 : public LayerTreeHostAnimationTest { 1023 public: 1024 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} 1025 1026 virtual void SetupTree() OVERRIDE { 1027 LayerTreeHostAnimationTest::SetupTree(); 1028 1029 scroll_layer_ = FakeContentLayer::Create(&client_); 1030 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); 1031 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); 1032 scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20)); 1033 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 1034 } 1035 1036 virtual void BeginTest() OVERRIDE { 1037 PostSetNeedsCommitToMainThread(); 1038 } 1039 1040 virtual void DidCommit() OVERRIDE { 1041 switch (layer_tree_host()->source_frame_number()) { 1042 case 1: { 1043 scoped_ptr<ScrollOffsetAnimationCurve> curve( 1044 ScrollOffsetAnimationCurve::Create( 1045 gfx::Vector2dF(500.f, 550.f), 1046 EaseInOutTimingFunction::Create())); 1047 scoped_ptr<Animation> animation(Animation::Create( 1048 curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset)); 1049 animation->set_needs_synchronized_start_time(true); 1050 bool animation_added = scroll_layer_->AddAnimation(animation.Pass()); 1051 bool impl_scrolling_supported = 1052 layer_tree_host()->proxy()->SupportsImplScrolling(); 1053 EXPECT_EQ(impl_scrolling_supported, animation_added); 1054 if (!impl_scrolling_supported) 1055 EndTest(); 1056 break; 1057 } 1058 default: 1059 if (scroll_layer_->scroll_offset().x() > 10 && 1060 scroll_layer_->scroll_offset().y() > 20) 1061 EndTest(); 1062 } 1063 } 1064 1065 virtual void AfterTest() OVERRIDE {} 1066 1067 private: 1068 FakeContentLayerClient client_; 1069 scoped_refptr<FakeContentLayer> scroll_layer_; 1070 }; 1071 1072 SINGLE_AND_MULTI_THREAD_TEST_F( 1073 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); 1074 1075 // Ensure that animation time is correctly updated when animations are frozen 1076 // because of checkerboarding. 1077 class LayerTreeHostAnimationTestFrozenAnimationTickTime 1078 : public LayerTreeHostAnimationTest { 1079 public: 1080 LayerTreeHostAnimationTestFrozenAnimationTickTime() 1081 : started_animating_(false), num_commits_(0), num_draw_attempts_(2) {} 1082 1083 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 1084 // Make sure that drawing many times doesn't cause a checkerboarded 1085 // animation to start so we avoid flake in this test. 1086 settings->timeout_and_draw_when_animation_checkerboards = false; 1087 } 1088 1089 virtual void BeginTest() OVERRIDE { 1090 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 1091 } 1092 1093 virtual void BeginMainFrame(const BeginFrameArgs& args) OVERRIDE { 1094 last_main_thread_tick_time_ = args.frame_time; 1095 } 1096 1097 virtual void AnimateLayers(LayerTreeHostImpl* host_impl, 1098 base::TimeTicks monotonic_time) OVERRIDE { 1099 if (TestEnded()) 1100 return; 1101 if (!started_animating_) { 1102 started_animating_ = true; 1103 expected_impl_tick_time_ = monotonic_time; 1104 } else { 1105 EXPECT_EQ(expected_impl_tick_time_, monotonic_time); 1106 if (num_commits_ > 2) 1107 EndTest(); 1108 } 1109 } 1110 1111 virtual DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 1112 LayerTreeHostImpl::FrameData* frame, 1113 DrawResult draw_result) OVERRIDE { 1114 if (TestEnded()) 1115 return draw_result; 1116 num_draw_attempts_++; 1117 if (num_draw_attempts_ > 2) { 1118 num_draw_attempts_ = 0; 1119 PostSetNeedsCommitToMainThread(); 1120 } 1121 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 1122 } 1123 1124 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 1125 if (!started_animating_) 1126 return; 1127 expected_impl_tick_time_ = 1128 std::max(expected_impl_tick_time_, last_main_thread_tick_time_); 1129 num_commits_++; 1130 } 1131 1132 virtual void AfterTest() OVERRIDE {} 1133 1134 private: 1135 bool started_animating_; 1136 int num_commits_; 1137 int num_draw_attempts_; 1138 base::TimeTicks last_main_thread_tick_time_; 1139 base::TimeTicks expected_impl_tick_time_; 1140 }; 1141 1142 // Only the non-impl-paint multi-threaded compositor freezes animations. 1143 MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime); 1144 1145 // When animations are simultaneously added to an existing layer and to a new 1146 // layer, they should start at the same time, even when there's already a 1147 // running animation on the existing layer. 1148 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers 1149 : public LayerTreeHostAnimationTest { 1150 public: 1151 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers() 1152 : frame_count_with_pending_tree_(0) {} 1153 1154 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 1155 1156 virtual void DidCommit() OVERRIDE { 1157 if (layer_tree_host()->source_frame_number() == 1) { 1158 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 4, 1, 1); 1159 } else if (layer_tree_host()->source_frame_number() == 2) { 1160 AddOpacityTransitionToLayer( 1161 layer_tree_host()->root_layer(), 1, 0.f, 0.5f, true); 1162 1163 scoped_refptr<Layer> layer = Layer::Create(); 1164 layer_tree_host()->root_layer()->AddChild(layer); 1165 layer->set_layer_animation_delegate(this); 1166 layer->SetBounds(gfx::Size(4, 4)); 1167 AddOpacityTransitionToLayer(layer.get(), 1, 0.f, 0.5f, true); 1168 } 1169 } 1170 1171 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 1172 host_impl->BlockNotifyReadyToActivateForTesting(true); 1173 } 1174 1175 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 1176 // For the commit that added animations to new and existing layers, keep 1177 // blocking activation. We want to verify that even with activation blocked, 1178 // the animation on the layer that's already in the active tree won't get a 1179 // head start. 1180 if (!host_impl->settings().impl_side_painting || 1181 host_impl->pending_tree()->source_frame_number() != 2) 1182 host_impl->BlockNotifyReadyToActivateForTesting(false); 1183 } 1184 1185 virtual void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 1186 const BeginFrameArgs& args) OVERRIDE { 1187 if (!host_impl->pending_tree() || 1188 host_impl->pending_tree()->source_frame_number() != 2) 1189 return; 1190 1191 frame_count_with_pending_tree_++; 1192 if (frame_count_with_pending_tree_ == 2) 1193 host_impl->BlockNotifyReadyToActivateForTesting(false); 1194 } 1195 1196 virtual void UpdateAnimationState(LayerTreeHostImpl* host_impl, 1197 bool has_unfinished_animation) OVERRIDE { 1198 LayerAnimationController* root_controller_impl = 1199 host_impl->active_tree()->root_layer()->layer_animation_controller(); 1200 Animation* root_animation = 1201 root_controller_impl->GetAnimation(Animation::Opacity); 1202 if (!root_animation || root_animation->run_state() != Animation::Running) 1203 return; 1204 1205 LayerAnimationController* child_controller_impl = 1206 host_impl->active_tree()->root_layer()->children() 1207 [0]->layer_animation_controller(); 1208 Animation* child_animation = 1209 child_controller_impl->GetAnimation(Animation::Opacity); 1210 EXPECT_EQ(Animation::Running, child_animation->run_state()); 1211 EXPECT_EQ(root_animation->start_time(), child_animation->start_time()); 1212 root_controller_impl->AbortAnimations(Animation::Opacity); 1213 root_controller_impl->AbortAnimations(Animation::Transform); 1214 child_controller_impl->AbortAnimations(Animation::Opacity); 1215 EndTest(); 1216 } 1217 1218 virtual void AfterTest() OVERRIDE {} 1219 1220 private: 1221 int frame_count_with_pending_tree_; 1222 }; 1223 1224 SINGLE_AND_MULTI_THREAD_TEST_F( 1225 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers); 1226 1227 class LayerTreeHostAnimationTestAddAnimationAfterAnimating 1228 : public LayerTreeHostAnimationTest { 1229 public: 1230 LayerTreeHostAnimationTestAddAnimationAfterAnimating() 1231 : num_swap_buffers_(0) {} 1232 1233 virtual void SetupTree() OVERRIDE { 1234 LayerTreeHostAnimationTest::SetupTree(); 1235 content_ = Layer::Create(); 1236 content_->SetBounds(gfx::Size(4, 4)); 1237 layer_tree_host()->root_layer()->AddChild(content_); 1238 } 1239 1240 virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); } 1241 1242 virtual void DidCommit() OVERRIDE { 1243 switch (layer_tree_host()->source_frame_number()) { 1244 case 1: 1245 // First frame: add an animation to the root layer. 1246 AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5); 1247 break; 1248 case 2: 1249 // Second frame: add an animation to the content layer. The root layer 1250 // animation has caused us to animate already during this frame. 1251 AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false); 1252 break; 1253 } 1254 } 1255 1256 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, 1257 bool result) OVERRIDE { 1258 // After both animations have started, verify that they have valid 1259 // start times. 1260 num_swap_buffers_++; 1261 AnimationRegistrar::AnimationControllerMap copy = 1262 host_impl->animation_registrar()->active_animation_controllers(); 1263 if (copy.size() == 2u) { 1264 EndTest(); 1265 EXPECT_GE(num_swap_buffers_, 3); 1266 for (AnimationRegistrar::AnimationControllerMap::iterator iter = 1267 copy.begin(); 1268 iter != copy.end(); 1269 ++iter) { 1270 int id = ((*iter).second->id()); 1271 if (id == host_impl->RootLayer()->id()) { 1272 Animation* anim = (*iter).second->GetAnimation(Animation::Transform); 1273 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); 1274 } else if (id == host_impl->RootLayer()->children()[0]->id()) { 1275 Animation* anim = (*iter).second->GetAnimation(Animation::Opacity); 1276 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); 1277 } 1278 } 1279 } 1280 } 1281 1282 virtual void AfterTest() OVERRIDE {} 1283 1284 private: 1285 scoped_refptr<Layer> content_; 1286 int num_swap_buffers_; 1287 }; 1288 1289 SINGLE_AND_MULTI_THREAD_TEST_F( 1290 LayerTreeHostAnimationTestAddAnimationAfterAnimating); 1291 1292 } // namespace 1293 } // namespace cc 1294