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 Animate(base::TimeTicks monotonic_time) OVERRIDE { 43 // We skip the first commit becasue 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_animates_(0) {} 88 89 virtual void BeginTest() OVERRIDE { 90 PostSetNeedsCommitToMainThread(); 91 } 92 93 virtual void Animate(base::TimeTicks) OVERRIDE { 94 if (!num_animates_) { 95 layer_tree_host()->SetNeedsAnimate(); 96 num_animates_++; 97 return; 98 } 99 EndTest(); 100 } 101 102 virtual void AfterTest() OVERRIDE {} 103 104 private: 105 int num_animates_; 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_animates_(0), 119 received_animation_started_notification_(false) { 120 } 121 122 virtual void BeginTest() OVERRIDE { 123 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); 124 } 125 126 virtual void UpdateAnimationState( 127 LayerTreeHostImpl* host_impl, 128 bool has_unfinished_animation) OVERRIDE { 129 if (!num_animates_) { 130 // The animation had zero duration so LayerTreeHostImpl should no 131 // longer need to animate its layers. 132 EXPECT_FALSE(has_unfinished_animation); 133 num_animates_++; 134 return; 135 } 136 137 if (received_animation_started_notification_) { 138 EXPECT_LT(base::TimeTicks(), start_time_); 139 140 LayerAnimationController* controller_impl = 141 host_impl->active_tree()->root_layer()->layer_animation_controller(); 142 Animation* animation_impl = 143 controller_impl->GetAnimation(Animation::Opacity); 144 if (animation_impl) 145 controller_impl->RemoveAnimation(animation_impl->id()); 146 147 EndTest(); 148 } 149 } 150 151 virtual void NotifyAnimationStarted( 152 double wall_clock_time, 153 base::TimeTicks monotonic_time, 154 Animation::TargetProperty target_property) OVERRIDE { 155 received_animation_started_notification_ = true; 156 start_time_ = monotonic_time; 157 if (num_animates_) { 158 EXPECT_LT(base::TimeTicks(), start_time_); 159 160 LayerAnimationController* controller = 161 layer_tree_host()->root_layer()->layer_animation_controller(); 162 Animation* animation = 163 controller->GetAnimation(Animation::Opacity); 164 if (animation) 165 controller->RemoveAnimation(animation->id()); 166 167 EndTest(); 168 } 169 } 170 171 virtual void AfterTest() OVERRIDE {} 172 173 private: 174 int num_animates_; 175 bool received_animation_started_notification_; 176 base::TimeTicks start_time_; 177 }; 178 179 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddAnimation); 180 181 // Add a layer animation to a layer, but continually fail to draw. Confirm that 182 // after a while, we do eventually force a draw. 183 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws 184 : public LayerTreeHostAnimationTest { 185 public: 186 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws() 187 : started_animating_(false) {} 188 189 virtual void BeginTest() OVERRIDE { 190 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 191 } 192 193 virtual void AnimateLayers( 194 LayerTreeHostImpl* host_impl, 195 base::TimeTicks monotonic_time) OVERRIDE { 196 started_animating_ = true; 197 } 198 199 virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 200 if (started_animating_) 201 EndTest(); 202 } 203 204 virtual bool PrepareToDrawOnThread( 205 LayerTreeHostImpl* host_impl, 206 LayerTreeHostImpl::FrameData* frame, 207 bool result) OVERRIDE { 208 return false; 209 } 210 211 virtual void AfterTest() OVERRIDE { } 212 213 private: 214 bool started_animating_; 215 }; 216 217 // Starvation can only be an issue with the MT compositor. 218 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws); 219 220 // Ensures that animations eventually get deleted. 221 class LayerTreeHostAnimationTestAnimationsGetDeleted 222 : public LayerTreeHostAnimationTest { 223 public: 224 LayerTreeHostAnimationTestAnimationsGetDeleted() 225 : started_animating_(false) {} 226 227 virtual void BeginTest() OVERRIDE { 228 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 229 } 230 231 virtual void AnimateLayers( 232 LayerTreeHostImpl* host_impl, 233 base::TimeTicks monotonic_time) OVERRIDE { 234 bool have_animations = !host_impl->animation_registrar()-> 235 active_animation_controllers().empty(); 236 if (!started_animating_ && have_animations) { 237 started_animating_ = true; 238 return; 239 } 240 241 if (started_animating_ && !have_animations) 242 EndTest(); 243 } 244 245 virtual void NotifyAnimationFinished( 246 double wall_clock_time, 247 base::TimeTicks monotonic_time, 248 Animation::TargetProperty target_property) OVERRIDE { 249 // Animations on the impl-side controller only get deleted during a commit, 250 // so we need to schedule a commit. 251 layer_tree_host()->SetNeedsCommit(); 252 } 253 254 virtual void AfterTest() OVERRIDE {} 255 256 private: 257 bool started_animating_; 258 }; 259 260 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); 261 262 // Ensures that animations continue to be ticked when we are backgrounded. 263 class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded 264 : public LayerTreeHostAnimationTest { 265 public: 266 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded() 267 : num_animates_(0) {} 268 269 virtual void BeginTest() OVERRIDE { 270 PostAddLongAnimationToMainThread(layer_tree_host()->root_layer()); 271 } 272 273 // Use WillAnimateLayers to set visible false before the animation runs and 274 // causes a commit, so we block the second visible animate in single-thread 275 // mode. 276 virtual void WillAnimateLayers( 277 LayerTreeHostImpl* host_impl, 278 base::TimeTicks monotonic_time) OVERRIDE { 279 // Verify that the host can draw, it's just not visible. 280 EXPECT_TRUE(host_impl->CanDraw()); 281 if (num_animates_ < 2) { 282 if (!num_animates_) { 283 // We have a long animation running. It should continue to tick even 284 // if we are not visible. 285 PostSetVisibleToMainThread(false); 286 } 287 num_animates_++; 288 return; 289 } 290 EndTest(); 291 } 292 293 virtual void AfterTest() OVERRIDE {} 294 295 private: 296 int num_animates_; 297 }; 298 299 SINGLE_AND_MULTI_THREAD_TEST_F( 300 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded); 301 302 // Ensures that animations do not tick when we are backgrounded and 303 // and we have an empty active tree. 304 class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree 305 : public LayerTreeHostAnimationTest { 306 protected: 307 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree() 308 : active_tree_was_animated_(false) {} 309 310 virtual base::TimeDelta LowFrequencyAnimationInterval() const OVERRIDE { 311 return base::TimeDelta::FromMilliseconds(4); 312 } 313 314 virtual void BeginTest() OVERRIDE { 315 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 316 } 317 318 virtual void NotifyAnimationFinished( 319 double wall_clock_time, 320 base::TimeTicks monotonic_time, 321 Animation::TargetProperty target_property) OVERRIDE { 322 // Replace animated commits with an empty tree. 323 layer_tree_host()->SetRootLayer(make_scoped_refptr<Layer>(NULL)); 324 } 325 326 virtual void DidCommit() OVERRIDE { 327 // This alternates setting an empty tree and a non-empty tree with an 328 // animation. 329 switch (layer_tree_host()->source_frame_number()) { 330 case 1: 331 // Wait for NotifyAnimationFinished to commit an empty tree. 332 break; 333 case 2: 334 SetupTree(); 335 AddOpacityTransitionToLayer( 336 layer_tree_host()->root_layer(), 0.000001, 0, 0.5, true); 337 break; 338 case 3: 339 // Wait for NotifyAnimationFinished to commit an empty tree. 340 break; 341 case 4: 342 EndTest(); 343 break; 344 } 345 } 346 347 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 348 // At the start of every commit, block activations and make sure 349 // we are backgrounded. 350 host_impl->BlockNotifyReadyToActivateForTesting(true); 351 PostSetVisibleToMainThread(false); 352 } 353 354 virtual void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 355 if (!host_impl->settings().impl_side_painting) { 356 // There are no activations to block if we're not impl-side-painting, 357 // so just advance the test immediately. 358 if (host_impl->active_tree()->source_frame_number() < 3) 359 UnblockActivations(host_impl); 360 return; 361 } 362 363 // We block activation for several ticks to make sure that, even though 364 // there is a pending tree with animations, we still do not background 365 // tick if the active tree is empty. 366 if (host_impl->pending_tree()->source_frame_number() < 3) { 367 base::MessageLoopProxy::current()->PostDelayedTask( 368 FROM_HERE, 369 base::Bind( 370 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: 371 UnblockActivations, 372 base::Unretained(this), 373 host_impl), 374 4 * LowFrequencyAnimationInterval()); 375 } 376 } 377 378 virtual void UnblockActivations(LayerTreeHostImpl* host_impl) { 379 host_impl->BlockNotifyReadyToActivateForTesting(false); 380 } 381 382 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 383 active_tree_was_animated_ = false; 384 385 // Verify that commits are actually alternating with empty / non-empty 386 // trees. 387 int frame_number = host_impl->active_tree()->source_frame_number(); 388 switch (frame_number) { 389 case 0: 390 case 2: 391 EXPECT_TRUE(host_impl->active_tree()->root_layer()) 392 << "frame: " << frame_number; 393 break; 394 case 1: 395 case 3: 396 EXPECT_FALSE(host_impl->active_tree()->root_layer()) 397 << "frame: " << frame_number; 398 break; 399 } 400 401 if (host_impl->active_tree()->source_frame_number() < 3) { 402 // Initiate the next commit after a delay to give us a chance to 403 // background tick if the active tree isn't empty. 404 base::MessageLoopProxy::current()->PostDelayedTask( 405 FROM_HERE, 406 base::Bind( 407 &LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree:: 408 InitiateNextCommit, 409 base::Unretained(this), 410 host_impl), 411 4 * LowFrequencyAnimationInterval()); 412 } 413 } 414 415 virtual void WillAnimateLayers(LayerTreeHostImpl* host_impl, 416 base::TimeTicks monotonic_time) OVERRIDE { 417 EXPECT_TRUE(host_impl->active_tree()->root_layer()); 418 active_tree_was_animated_ = true; 419 } 420 421 void InitiateNextCommit(LayerTreeHostImpl* host_impl) { 422 // Verify that we actually animated when we should have. 423 bool has_active_tree = host_impl->active_tree()->root_layer(); 424 EXPECT_EQ(has_active_tree, active_tree_was_animated_); 425 426 // The next commit is blocked until we become visible again. 427 PostSetVisibleToMainThread(true); 428 } 429 430 virtual void AfterTest() OVERRIDE {} 431 432 bool active_tree_was_animated_; 433 }; 434 435 SINGLE_AND_MULTI_THREAD_TEST_F( 436 LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree); 437 438 // Ensure that an animation's timing function is respected. 439 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction 440 : public LayerTreeHostAnimationTest { 441 public: 442 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} 443 444 virtual void SetupTree() OVERRIDE { 445 LayerTreeHostAnimationTest::SetupTree(); 446 content_ = FakeContentLayer::Create(&client_); 447 content_->SetBounds(gfx::Size(4, 4)); 448 layer_tree_host()->root_layer()->AddChild(content_); 449 } 450 451 virtual void BeginTest() OVERRIDE { 452 PostAddAnimationToMainThread(content_.get()); 453 } 454 455 virtual void AnimateLayers( 456 LayerTreeHostImpl* host_impl, 457 base::TimeTicks monotonic_time) OVERRIDE { 458 LayerAnimationController* controller_impl = 459 host_impl->active_tree()->root_layer()->children()[0]-> 460 layer_animation_controller(); 461 Animation* animation = 462 controller_impl->GetAnimation(Animation::Opacity); 463 if (!animation) 464 return; 465 466 const FloatAnimationCurve* curve = 467 animation->curve()->ToFloatAnimationCurve(); 468 float start_opacity = curve->GetValue(0.0); 469 float end_opacity = curve->GetValue(curve->Duration()); 470 float linearly_interpolated_opacity = 471 0.25f * end_opacity + 0.75f * start_opacity; 472 double time = curve->Duration() * 0.25; 473 // If the linear timing function associated with this animation was not 474 // picked up, then the linearly interpolated opacity would be different 475 // because of the default ease timing function. 476 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); 477 478 EndTest(); 479 } 480 481 virtual void AfterTest() OVERRIDE {} 482 483 FakeContentLayerClient client_; 484 scoped_refptr<FakeContentLayer> content_; 485 }; 486 487 SINGLE_AND_MULTI_THREAD_TEST_F( 488 LayerTreeHostAnimationTestAddAnimationWithTimingFunction); 489 490 // Ensures that main thread animations have their start times synchronized with 491 // impl thread animations. 492 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 493 : public LayerTreeHostAnimationTest { 494 public: 495 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() 496 : main_start_time_(-1.0), 497 impl_start_time_(-1.0) {} 498 499 virtual void SetupTree() OVERRIDE { 500 LayerTreeHostAnimationTest::SetupTree(); 501 content_ = FakeContentLayer::Create(&client_); 502 content_->SetBounds(gfx::Size(4, 4)); 503 content_->set_layer_animation_delegate(this); 504 layer_tree_host()->root_layer()->AddChild(content_); 505 } 506 507 virtual void BeginTest() OVERRIDE { 508 PostAddAnimationToMainThread(content_.get()); 509 } 510 511 virtual void NotifyAnimationStarted( 512 double wall_clock_time, 513 base::TimeTicks monotonic_time, 514 Animation::TargetProperty target_property) OVERRIDE { 515 LayerAnimationController* controller = 516 layer_tree_host()->root_layer()->children()[0]-> 517 layer_animation_controller(); 518 Animation* animation = 519 controller->GetAnimation(Animation::Opacity); 520 main_start_time_ = animation->start_time(); 521 controller->RemoveAnimation(animation->id()); 522 523 if (impl_start_time_ > 0.0) 524 EndTest(); 525 } 526 527 virtual void UpdateAnimationState( 528 LayerTreeHostImpl* impl_host, 529 bool has_unfinished_animation) OVERRIDE { 530 LayerAnimationController* controller = 531 impl_host->active_tree()->root_layer()->children()[0]-> 532 layer_animation_controller(); 533 Animation* animation = 534 controller->GetAnimation(Animation::Opacity); 535 if (!animation) 536 return; 537 538 impl_start_time_ = animation->start_time(); 539 controller->RemoveAnimation(animation->id()); 540 541 if (main_start_time_ > 0.0) 542 EndTest(); 543 } 544 545 virtual void AfterTest() OVERRIDE { 546 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_); 547 } 548 549 private: 550 double main_start_time_; 551 double impl_start_time_; 552 FakeContentLayerClient client_; 553 scoped_refptr<FakeContentLayer> content_; 554 }; 555 556 SINGLE_AND_MULTI_THREAD_TEST_F( 557 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes); 558 559 // Ensures that notify animation finished is called. 560 class LayerTreeHostAnimationTestAnimationFinishedEvents 561 : public LayerTreeHostAnimationTest { 562 public: 563 LayerTreeHostAnimationTestAnimationFinishedEvents() {} 564 565 virtual void BeginTest() OVERRIDE { 566 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); 567 } 568 569 virtual void NotifyAnimationFinished( 570 double wall_clock_time, 571 base::TimeTicks monotonic_time, 572 Animation::TargetProperty target_property) OVERRIDE { 573 LayerAnimationController* controller = 574 layer_tree_host()->root_layer()->layer_animation_controller(); 575 Animation* animation = 576 controller->GetAnimation(Animation::Opacity); 577 if (animation) 578 controller->RemoveAnimation(animation->id()); 579 EndTest(); 580 } 581 582 virtual void AfterTest() OVERRIDE {} 583 }; 584 585 SINGLE_AND_MULTI_THREAD_TEST_F( 586 LayerTreeHostAnimationTestAnimationFinishedEvents); 587 588 // Ensures that when opacity is being animated, this value does not cause the 589 // subtree to be skipped. 590 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 591 : public LayerTreeHostAnimationTest { 592 public: 593 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() 594 : update_check_layer_(FakeContentLayer::Create(&client_)) { 595 } 596 597 virtual void SetupTree() OVERRIDE { 598 update_check_layer_->SetOpacity(0.f); 599 layer_tree_host()->SetRootLayer(update_check_layer_); 600 LayerTreeHostAnimationTest::SetupTree(); 601 } 602 603 virtual void BeginTest() OVERRIDE { 604 PostAddAnimationToMainThread(update_check_layer_.get()); 605 } 606 607 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 608 LayerAnimationController* controller_impl = 609 host_impl->active_tree()->root_layer()->layer_animation_controller(); 610 Animation* animation_impl = 611 controller_impl->GetAnimation(Animation::Opacity); 612 controller_impl->RemoveAnimation(animation_impl->id()); 613 EndTest(); 614 } 615 616 virtual void AfterTest() OVERRIDE { 617 // Update() should have been called once, proving that the layer was not 618 // skipped. 619 EXPECT_EQ(1u, update_check_layer_->update_count()); 620 621 // clear update_check_layer_ so LayerTreeHost dies. 622 update_check_layer_ = NULL; 623 } 624 625 private: 626 FakeContentLayerClient client_; 627 scoped_refptr<FakeContentLayer> update_check_layer_; 628 }; 629 630 SINGLE_AND_MULTI_THREAD_TEST_F( 631 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity); 632 633 // Layers added to tree with existing active animations should have the 634 // animation correctly recognized. 635 class LayerTreeHostAnimationTestLayerAddedWithAnimation 636 : public LayerTreeHostAnimationTest { 637 public: 638 LayerTreeHostAnimationTestLayerAddedWithAnimation() {} 639 640 virtual void BeginTest() OVERRIDE { 641 PostSetNeedsCommitToMainThread(); 642 } 643 644 virtual void DidCommit() OVERRIDE { 645 if (layer_tree_host()->source_frame_number() == 1) { 646 scoped_refptr<Layer> layer = Layer::Create(); 647 layer->set_layer_animation_delegate(this); 648 649 // Any valid AnimationCurve will do here. 650 scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create()); 651 scoped_ptr<Animation> animation( 652 Animation::Create(curve.Pass(), 1, 1, 653 Animation::Opacity)); 654 layer->layer_animation_controller()->AddAnimation(animation.Pass()); 655 656 // We add the animation *before* attaching the layer to the tree. 657 layer_tree_host()->root_layer()->AddChild(layer); 658 } 659 } 660 661 virtual void AnimateLayers( 662 LayerTreeHostImpl* impl_host, 663 base::TimeTicks monotonic_time) OVERRIDE { 664 EndTest(); 665 } 666 667 virtual void AfterTest() OVERRIDE {} 668 }; 669 670 SINGLE_AND_MULTI_THREAD_TEST_F( 671 LayerTreeHostAnimationTestLayerAddedWithAnimation); 672 673 class LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount 674 : public LayerTreeHostAnimationTest { 675 public: 676 LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount() 677 : animated_commit_(-1) { 678 } 679 680 virtual void Animate(base::TimeTicks) OVERRIDE { 681 // We shouldn't animate on the CompositeAndReadback-forced commit, but we 682 // should for the SetNeedsCommit-triggered commit. 683 animated_commit_ = layer_tree_host()->source_frame_number(); 684 EXPECT_NE(2, animated_commit_); 685 } 686 687 virtual void BeginTest() OVERRIDE { 688 PostSetNeedsCommitToMainThread(); 689 } 690 691 virtual void DidCommit() OVERRIDE { 692 switch (layer_tree_host()->source_frame_number()) { 693 case 1: 694 layer_tree_host()->SetNeedsCommit(); 695 break; 696 case 2: { 697 char pixels[4]; 698 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1)); 699 break; 700 } 701 case 3: 702 // This is finishing the readback's commit. 703 break; 704 case 4: 705 // This is finishing the followup commit. 706 EndTest(); 707 break; 708 default: 709 NOTREACHED(); 710 } 711 } 712 713 virtual void AfterTest() OVERRIDE { 714 EXPECT_EQ(3, animated_commit_); 715 } 716 717 private: 718 int animated_commit_; 719 }; 720 721 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount); 722 723 class LayerTreeHostAnimationTestContinuousAnimate 724 : public LayerTreeHostAnimationTest { 725 public: 726 LayerTreeHostAnimationTestContinuousAnimate() 727 : num_commit_complete_(0), 728 num_draw_layers_(0) { 729 } 730 731 virtual void BeginTest() OVERRIDE { 732 PostSetNeedsCommitToMainThread(); 733 } 734 735 virtual void Animate(base::TimeTicks) OVERRIDE { 736 if (num_draw_layers_ == 2) 737 return; 738 layer_tree_host()->SetNeedsAnimate(); 739 } 740 741 virtual void Layout() OVERRIDE { 742 layer_tree_host()->root_layer()->SetNeedsDisplay(); 743 } 744 745 virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE { 746 if (num_draw_layers_ == 1) 747 num_commit_complete_++; 748 } 749 750 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 751 num_draw_layers_++; 752 if (num_draw_layers_ == 2) 753 EndTest(); 754 } 755 756 virtual void AfterTest() OVERRIDE { 757 // Check that we didn't commit twice between first and second draw. 758 EXPECT_EQ(1, num_commit_complete_); 759 } 760 761 private: 762 int num_commit_complete_; 763 int num_draw_layers_; 764 }; 765 766 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate); 767 768 // Make sure the main thread can still execute animations when CanDraw() is not 769 // true. 770 class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw 771 : public LayerTreeHostAnimationTest { 772 public: 773 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} 774 775 virtual void SetupTree() OVERRIDE { 776 LayerTreeHostAnimationTest::SetupTree(); 777 content_ = FakeContentLayer::Create(&client_); 778 content_->SetBounds(gfx::Size(4, 4)); 779 content_->set_layer_animation_delegate(this); 780 layer_tree_host()->root_layer()->AddChild(content_); 781 } 782 783 virtual void BeginTest() OVERRIDE { 784 layer_tree_host()->SetViewportSize(gfx::Size()); 785 PostAddAnimationToMainThread(content_.get()); 786 } 787 788 virtual void NotifyAnimationStarted( 789 double wall_clock_time, 790 base::TimeTicks monotonic_time, 791 Animation::TargetProperty target_property) OVERRIDE { 792 started_times_++; 793 } 794 795 virtual void NotifyAnimationFinished( 796 double wall_clock_time, 797 base::TimeTicks monotonic_time, 798 Animation::TargetProperty target_property) OVERRIDE { 799 EndTest(); 800 } 801 802 virtual void AfterTest() OVERRIDE { 803 EXPECT_EQ(1, started_times_); 804 } 805 806 private: 807 int started_times_; 808 FakeContentLayerClient client_; 809 scoped_refptr<FakeContentLayer> content_; 810 }; 811 812 SINGLE_AND_MULTI_THREAD_TEST_F( 813 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw); 814 815 // Make sure the main thread can still execute animations when the renderer is 816 // backgrounded. 817 class LayerTreeHostAnimationTestRunAnimationWhenNotVisible 818 : public LayerTreeHostAnimationTest { 819 public: 820 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {} 821 822 virtual void SetupTree() OVERRIDE { 823 LayerTreeHostAnimationTest::SetupTree(); 824 content_ = FakeContentLayer::Create(&client_); 825 content_->SetBounds(gfx::Size(4, 4)); 826 content_->set_layer_animation_delegate(this); 827 layer_tree_host()->root_layer()->AddChild(content_); 828 } 829 830 virtual void BeginTest() OVERRIDE { 831 visible_ = true; 832 PostAddAnimationToMainThread(content_.get()); 833 } 834 835 virtual void DidCommit() OVERRIDE { 836 visible_ = false; 837 layer_tree_host()->SetVisible(false); 838 } 839 840 virtual void NotifyAnimationStarted( 841 double wall_clock_time, 842 base::TimeTicks monotonic_time, 843 Animation::TargetProperty target_property) OVERRIDE { 844 EXPECT_FALSE(visible_); 845 started_times_++; 846 } 847 848 virtual void NotifyAnimationFinished( 849 double wall_clock_time, 850 base::TimeTicks monotonic_time, 851 Animation::TargetProperty target_property) OVERRIDE { 852 EXPECT_FALSE(visible_); 853 EXPECT_EQ(1, started_times_); 854 EndTest(); 855 } 856 857 virtual void AfterTest() OVERRIDE {} 858 859 private: 860 bool visible_; 861 int started_times_; 862 FakeContentLayerClient client_; 863 scoped_refptr<FakeContentLayer> content_; 864 }; 865 866 SINGLE_AND_MULTI_THREAD_TEST_F( 867 LayerTreeHostAnimationTestRunAnimationWhenNotVisible); 868 869 // Animations should not be started when frames are being skipped due to 870 // checkerboard. 871 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations 872 : public LayerTreeHostAnimationTest { 873 virtual void SetupTree() OVERRIDE { 874 LayerTreeHostAnimationTest::SetupTree(); 875 content_ = FakeContentLayer::Create(&client_); 876 content_->SetBounds(gfx::Size(4, 4)); 877 content_->set_layer_animation_delegate(this); 878 layer_tree_host()->root_layer()->AddChild(content_); 879 } 880 881 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 882 // Make sure that drawing many times doesn't cause a checkerboarded 883 // animation to start so we avoid flake in this test. 884 settings->timeout_and_draw_when_animation_checkerboards = false; 885 } 886 887 virtual void BeginTest() OVERRIDE { 888 prevented_draw_ = 0; 889 added_animations_ = 0; 890 started_times_ = 0; 891 finished_times_ = 0; 892 893 PostSetNeedsCommitToMainThread(); 894 } 895 896 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 897 LayerTreeHostImpl::FrameData* frame_data, 898 bool result) OVERRIDE { 899 if (added_animations_ < 2) 900 return result; 901 if (TestEnded()) 902 return result; 903 // Act like there is checkerboard when the second animation wants to draw. 904 ++prevented_draw_; 905 return false; 906 } 907 908 virtual void DidCommitAndDrawFrame() OVERRIDE { 909 switch (layer_tree_host()->source_frame_number()) { 910 case 1: 911 // The animation is longer than 1 BeginFrame interval. 912 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false); 913 added_animations_++; 914 break; 915 case 2: 916 // This second animation will not be drawn so it should not start. 917 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5); 918 added_animations_++; 919 break; 920 } 921 } 922 923 virtual void NotifyAnimationStarted( 924 double wall_clock_time, 925 base::TimeTicks monotonic_time, 926 Animation::TargetProperty target_property) OVERRIDE { 927 if (TestEnded()) 928 return; 929 started_times_++; 930 } 931 932 virtual void NotifyAnimationFinished( 933 double wall_clock_time, 934 base::TimeTicks monotonic_time, 935 Animation::TargetProperty target_property) OVERRIDE { 936 // We should be checkerboarding already, but it should still finish the 937 // first animation. 938 EXPECT_EQ(2, added_animations_); 939 finished_times_++; 940 EndTest(); 941 } 942 943 virtual void AfterTest() OVERRIDE { 944 // Make sure we tried to draw the second animation but failed. 945 EXPECT_LT(0, prevented_draw_); 946 // The first animation should be started, but the second should not because 947 // of checkerboard. 948 EXPECT_EQ(1, started_times_); 949 // The first animation should still be finished. 950 EXPECT_EQ(1, finished_times_); 951 } 952 953 int prevented_draw_; 954 int added_animations_; 955 int started_times_; 956 int finished_times_; 957 FakeContentLayerClient client_; 958 scoped_refptr<FakeContentLayer> content_; 959 }; 960 961 MULTI_THREAD_TEST_F( 962 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); 963 964 // Verifies that when scroll offset is animated on the impl thread, updates 965 // are sent back to the main thread. 966 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated 967 : public LayerTreeHostAnimationTest { 968 public: 969 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated() {} 970 971 virtual void SetupTree() OVERRIDE { 972 LayerTreeHostAnimationTest::SetupTree(); 973 974 scroll_layer_ = FakeContentLayer::Create(&client_); 975 scroll_layer_->SetScrollable(true); 976 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); 977 scroll_layer_->SetScrollOffset(gfx::Vector2d(10, 20)); 978 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 979 } 980 981 virtual void BeginTest() OVERRIDE { 982 PostSetNeedsCommitToMainThread(); 983 } 984 985 virtual void DidCommit() OVERRIDE { 986 switch (layer_tree_host()->source_frame_number()) { 987 case 1: { 988 scoped_ptr<ScrollOffsetAnimationCurve> curve( 989 ScrollOffsetAnimationCurve::Create( 990 gfx::Vector2dF(500.f, 550.f), 991 EaseInOutTimingFunction::Create())); 992 scoped_ptr<Animation> animation(Animation::Create( 993 curve.PassAs<AnimationCurve>(), 1, 0, Animation::ScrollOffset)); 994 animation->set_needs_synchronized_start_time(true); 995 scroll_layer_->AddAnimation(animation.Pass()); 996 break; 997 } 998 default: 999 if (scroll_layer_->scroll_offset().x() > 10 && 1000 scroll_layer_->scroll_offset().y() > 20) 1001 EndTest(); 1002 } 1003 } 1004 1005 virtual void AfterTest() OVERRIDE {} 1006 1007 private: 1008 FakeContentLayerClient client_; 1009 scoped_refptr<FakeContentLayer> scroll_layer_; 1010 }; 1011 1012 // SingleThreadProxy doesn't send scroll updates from LayerTreeHostImpl to 1013 // LayerTreeHost. 1014 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); 1015 1016 } // namespace 1017 } // namespace cc 1018