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/timing_function.h" 10#include "cc/layers/layer.h" 11#include "cc/layers/layer_impl.h" 12#include "cc/test/animation_test_common.h" 13#include "cc/test/fake_content_layer.h" 14#include "cc/test/fake_content_layer_client.h" 15#include "cc/test/layer_tree_test.h" 16#include "cc/trees/layer_tree_impl.h" 17 18namespace cc { 19namespace { 20 21class LayerTreeHostAnimationTest : public LayerTreeTest { 22 public: 23 virtual void SetupTree() OVERRIDE { 24 LayerTreeTest::SetupTree(); 25 layer_tree_host()->root_layer()->set_layer_animation_delegate(this); 26 } 27}; 28 29// Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to 30// be set. 31class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested 32 : public LayerTreeHostAnimationTest { 33 public: 34 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested() 35 : num_commits_(0) {} 36 37 virtual void BeginTest() OVERRIDE { 38 PostSetNeedsCommitToMainThread(); 39 } 40 41 virtual void Animate(base::TimeTicks monotonic_time) OVERRIDE { 42 // We skip the first commit becasue its the commit that populates the 43 // impl thread with a tree. After the second commit, the test is done. 44 if (num_commits_ != 1) 45 return; 46 47 layer_tree_host()->SetNeedsAnimate(); 48 // Right now, CommitRequested is going to be true, because during 49 // BeginFrame, we force CommitRequested to true to prevent requests from 50 // hitting the impl thread. But, when the next DidCommit happens, we should 51 // verify that CommitRequested has gone back to false. 52 } 53 54 virtual void DidCommit() OVERRIDE { 55 if (!num_commits_) { 56 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 57 layer_tree_host()->SetNeedsAnimate(); 58 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 59 } 60 61 // Verifies that the SetNeedsAnimate we made in ::Animate did not 62 // trigger CommitRequested. 63 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 64 EndTest(); 65 num_commits_++; 66 } 67 68 virtual void AfterTest() OVERRIDE {} 69 70 private: 71 int num_commits_; 72}; 73 74MULTI_THREAD_TEST_F( 75 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested); 76 77// Trigger a frame with SetNeedsCommit. Then, inside the resulting animate 78// callback, request another frame using SetNeedsAnimate. End the test when 79// animate gets called yet-again, indicating that the proxy is correctly 80// handling the case where SetNeedsAnimate() is called inside the BeginFrame 81// flow. 82class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback 83 : public LayerTreeHostAnimationTest { 84 public: 85 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback() 86 : num_animates_(0) {} 87 88 virtual void BeginTest() OVERRIDE { 89 PostSetNeedsCommitToMainThread(); 90 } 91 92 virtual void Animate(base::TimeTicks) OVERRIDE { 93 if (!num_animates_) { 94 layer_tree_host()->SetNeedsAnimate(); 95 num_animates_++; 96 return; 97 } 98 EndTest(); 99 } 100 101 virtual void AfterTest() OVERRIDE {} 102 103 private: 104 int num_animates_; 105}; 106 107MULTI_THREAD_TEST_F( 108 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback); 109 110// Add a layer animation and confirm that 111// LayerTreeHostImpl::updateAnimationState does get called and continues to 112// get called. 113class LayerTreeHostAnimationTestAddAnimation 114 : public LayerTreeHostAnimationTest { 115 public: 116 LayerTreeHostAnimationTestAddAnimation() 117 : num_animates_(0), 118 received_animation_started_notification_(false), 119 start_time_(0.0) { 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(0.0, 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(double wall_clock_time) OVERRIDE { 152 received_animation_started_notification_ = true; 153 start_time_ = wall_clock_time; 154 if (num_animates_) { 155 EXPECT_LT(0.0, 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_animates_; 172 bool received_animation_started_notification_; 173 double start_time_; 174}; 175 176SINGLE_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. 180class 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 bool PrepareToDrawOnThread( 202 LayerTreeHostImpl* host_impl, 203 LayerTreeHostImpl::FrameData* frame, 204 bool result) OVERRIDE { 205 return false; 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. 215MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws); 216 217// Ensures that animations eventually get deleted. 218class 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(double time) OVERRIDE { 243 // Animations on the impl-side controller only get deleted during a commit, 244 // so we need to schedule a commit. 245 layer_tree_host()->SetNeedsCommit(); 246 } 247 248 virtual void AfterTest() OVERRIDE {} 249 250 private: 251 bool started_animating_; 252}; 253 254SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); 255 256// Ensures that animations continue to be ticked when we are backgrounded. 257class LayerTreeHostAnimationTestTickAnimationWhileBackgrounded 258 : public LayerTreeHostAnimationTest { 259 public: 260 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded() 261 : num_animates_(0) {} 262 263 virtual void BeginTest() OVERRIDE { 264 PostAddAnimationToMainThread(layer_tree_host()->root_layer()); 265 } 266 267 // Use WillAnimateLayers to set visible false before the animation runs and 268 // causes a commit, so we block the second visible animate in single-thread 269 // mode. 270 virtual void WillAnimateLayers( 271 LayerTreeHostImpl* host_impl, 272 base::TimeTicks monotonic_time) OVERRIDE { 273 // Verify that the host can draw, it's just not visible. 274 EXPECT_TRUE(host_impl->CanDraw()); 275 if (num_animates_ < 2) { 276 if (!num_animates_) { 277 // We have a long animation running. It should continue to tick even 278 // if we are not visible. 279 PostSetVisibleToMainThread(false); 280 } 281 num_animates_++; 282 return; 283 } 284 EndTest(); 285 } 286 287 virtual void AfterTest() OVERRIDE {} 288 289 private: 290 int num_animates_; 291}; 292 293SINGLE_AND_MULTI_THREAD_TEST_F( 294 LayerTreeHostAnimationTestTickAnimationWhileBackgrounded); 295 296// Ensure that an animation's timing function is respected. 297class LayerTreeHostAnimationTestAddAnimationWithTimingFunction 298 : public LayerTreeHostAnimationTest { 299 public: 300 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} 301 302 virtual void SetupTree() OVERRIDE { 303 LayerTreeHostAnimationTest::SetupTree(); 304 content_ = FakeContentLayer::Create(&client_); 305 content_->SetBounds(gfx::Size(4, 4)); 306 layer_tree_host()->root_layer()->AddChild(content_); 307 } 308 309 virtual void BeginTest() OVERRIDE { 310 PostAddAnimationToMainThread(content_.get()); 311 } 312 313 virtual void AnimateLayers( 314 LayerTreeHostImpl* host_impl, 315 base::TimeTicks monotonic_time) OVERRIDE { 316 LayerAnimationController* controller_impl = 317 host_impl->active_tree()->root_layer()->children()[0]-> 318 layer_animation_controller(); 319 Animation* animation = 320 controller_impl->GetAnimation(Animation::Opacity); 321 if (!animation) 322 return; 323 324 const FloatAnimationCurve* curve = 325 animation->curve()->ToFloatAnimationCurve(); 326 float start_opacity = curve->GetValue(0.0); 327 float end_opacity = curve->GetValue(curve->Duration()); 328 float linearly_interpolated_opacity = 329 0.25f * end_opacity + 0.75f * start_opacity; 330 double time = curve->Duration() * 0.25; 331 // If the linear timing function associated with this animation was not 332 // picked up, then the linearly interpolated opacity would be different 333 // because of the default ease timing function. 334 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); 335 336 EndTest(); 337 } 338 339 virtual void AfterTest() OVERRIDE {} 340 341 FakeContentLayerClient client_; 342 scoped_refptr<FakeContentLayer> content_; 343}; 344 345SINGLE_AND_MULTI_THREAD_TEST_F( 346 LayerTreeHostAnimationTestAddAnimationWithTimingFunction); 347 348// Ensures that main thread animations have their start times synchronized with 349// impl thread animations. 350class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 351 : public LayerTreeHostAnimationTest { 352 public: 353 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes() 354 : main_start_time_(-1.0), 355 impl_start_time_(-1.0) {} 356 357 virtual void SetupTree() OVERRIDE { 358 LayerTreeHostAnimationTest::SetupTree(); 359 content_ = FakeContentLayer::Create(&client_); 360 content_->SetBounds(gfx::Size(4, 4)); 361 content_->set_layer_animation_delegate(this); 362 layer_tree_host()->root_layer()->AddChild(content_); 363 } 364 365 virtual void BeginTest() OVERRIDE { 366 PostAddAnimationToMainThread(content_.get()); 367 } 368 369 virtual void NotifyAnimationStarted(double time) OVERRIDE { 370 LayerAnimationController* controller = 371 layer_tree_host()->root_layer()->children()[0]-> 372 layer_animation_controller(); 373 Animation* animation = 374 controller->GetAnimation(Animation::Opacity); 375 main_start_time_ = animation->start_time(); 376 controller->RemoveAnimation(animation->id()); 377 378 if (impl_start_time_ > 0.0) 379 EndTest(); 380 } 381 382 virtual void UpdateAnimationState( 383 LayerTreeHostImpl* impl_host, 384 bool has_unfinished_animation) OVERRIDE { 385 LayerAnimationController* controller = 386 impl_host->active_tree()->root_layer()->children()[0]-> 387 layer_animation_controller(); 388 Animation* animation = 389 controller->GetAnimation(Animation::Opacity); 390 if (!animation) 391 return; 392 393 impl_start_time_ = animation->start_time(); 394 controller->RemoveAnimation(animation->id()); 395 396 if (main_start_time_ > 0.0) 397 EndTest(); 398 } 399 400 virtual void AfterTest() OVERRIDE { 401 EXPECT_FLOAT_EQ(impl_start_time_, main_start_time_); 402 } 403 404 private: 405 double main_start_time_; 406 double impl_start_time_; 407 FakeContentLayerClient client_; 408 scoped_refptr<FakeContentLayer> content_; 409}; 410 411SINGLE_AND_MULTI_THREAD_TEST_F( 412 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes); 413 414// Ensures that notify animation finished is called. 415class LayerTreeHostAnimationTestAnimationFinishedEvents 416 : public LayerTreeHostAnimationTest { 417 public: 418 LayerTreeHostAnimationTestAnimationFinishedEvents() {} 419 420 virtual void BeginTest() OVERRIDE { 421 PostAddInstantAnimationToMainThread(layer_tree_host()->root_layer()); 422 } 423 424 virtual void NotifyAnimationFinished(double time) OVERRIDE { 425 LayerAnimationController* controller = 426 layer_tree_host()->root_layer()->layer_animation_controller(); 427 Animation* animation = 428 controller->GetAnimation(Animation::Opacity); 429 if (animation) 430 controller->RemoveAnimation(animation->id()); 431 EndTest(); 432 } 433 434 virtual void AfterTest() OVERRIDE {} 435}; 436 437SINGLE_AND_MULTI_THREAD_TEST_F( 438 LayerTreeHostAnimationTestAnimationFinishedEvents); 439 440// Ensures that when opacity is being animated, this value does not cause the 441// subtree to be skipped. 442class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 443 : public LayerTreeHostAnimationTest { 444 public: 445 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() 446 : update_check_layer_(FakeContentLayer::Create(&client_)) { 447 } 448 449 virtual void SetupTree() OVERRIDE { 450 update_check_layer_->SetOpacity(0.f); 451 layer_tree_host()->SetRootLayer(update_check_layer_); 452 LayerTreeHostAnimationTest::SetupTree(); 453 } 454 455 virtual void BeginTest() OVERRIDE { 456 PostAddAnimationToMainThread(update_check_layer_.get()); 457 } 458 459 virtual void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 460 LayerAnimationController* controller_impl = 461 host_impl->active_tree()->root_layer()->layer_animation_controller(); 462 Animation* animation_impl = 463 controller_impl->GetAnimation(Animation::Opacity); 464 controller_impl->RemoveAnimation(animation_impl->id()); 465 EndTest(); 466 } 467 468 virtual void AfterTest() OVERRIDE { 469 // Update() should have been called once, proving that the layer was not 470 // skipped. 471 EXPECT_EQ(1u, update_check_layer_->update_count()); 472 473 // clear update_check_layer_ so LayerTreeHost dies. 474 update_check_layer_ = NULL; 475 } 476 477 private: 478 FakeContentLayerClient client_; 479 scoped_refptr<FakeContentLayer> update_check_layer_; 480}; 481 482SINGLE_AND_MULTI_THREAD_TEST_F( 483 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity); 484 485// Layers added to tree with existing active animations should have the 486// animation correctly recognized. 487class LayerTreeHostAnimationTestLayerAddedWithAnimation 488 : public LayerTreeHostAnimationTest { 489 public: 490 LayerTreeHostAnimationTestLayerAddedWithAnimation() {} 491 492 virtual void BeginTest() OVERRIDE { 493 PostSetNeedsCommitToMainThread(); 494 } 495 496 virtual void DidCommit() OVERRIDE { 497 if (layer_tree_host()->source_frame_number() == 1) { 498 scoped_refptr<Layer> layer = Layer::Create(); 499 layer->set_layer_animation_delegate(this); 500 501 // Any valid AnimationCurve will do here. 502 scoped_ptr<AnimationCurve> curve(EaseTimingFunction::Create()); 503 scoped_ptr<Animation> animation( 504 Animation::Create(curve.Pass(), 1, 1, 505 Animation::Opacity)); 506 layer->layer_animation_controller()->AddAnimation(animation.Pass()); 507 508 // We add the animation *before* attaching the layer to the tree. 509 layer_tree_host()->root_layer()->AddChild(layer); 510 } 511 } 512 513 virtual void AnimateLayers( 514 LayerTreeHostImpl* impl_host, 515 base::TimeTicks monotonic_time) OVERRIDE { 516 EndTest(); 517 } 518 519 virtual void AfterTest() OVERRIDE {} 520}; 521 522SINGLE_AND_MULTI_THREAD_TEST_F( 523 LayerTreeHostAnimationTestLayerAddedWithAnimation); 524 525class LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount 526 : public LayerTreeHostAnimationTest { 527 public: 528 LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount() 529 : animated_commit_(-1) { 530 } 531 532 virtual void Animate(base::TimeTicks) OVERRIDE { 533 // We shouldn't animate on the CompositeAndReadback-forced commit, but we 534 // should for the SetNeedsCommit-triggered commit. 535 animated_commit_ = layer_tree_host()->source_frame_number(); 536 EXPECT_NE(2, animated_commit_); 537 } 538 539 virtual void BeginTest() OVERRIDE { 540 PostSetNeedsCommitToMainThread(); 541 } 542 543 virtual void DidCommit() OVERRIDE { 544 switch (layer_tree_host()->source_frame_number()) { 545 case 1: 546 layer_tree_host()->SetNeedsCommit(); 547 break; 548 case 2: { 549 char pixels[4]; 550 layer_tree_host()->CompositeAndReadback(&pixels, gfx::Rect(0, 0, 1, 1)); 551 break; 552 } 553 case 3: 554 // This is finishing the readback's commit. 555 break; 556 case 4: 557 // This is finishing the followup commit. 558 EndTest(); 559 break; 560 default: 561 NOTREACHED(); 562 } 563 } 564 565 virtual void AfterTest() OVERRIDE { 566 EXPECT_EQ(3, animated_commit_); 567 } 568 569 private: 570 int animated_commit_; 571}; 572 573MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCompositeAndReadbackAnimateCount); 574 575class LayerTreeHostAnimationTestContinuousAnimate 576 : public LayerTreeHostAnimationTest { 577 public: 578 LayerTreeHostAnimationTestContinuousAnimate() 579 : num_commit_complete_(0), 580 num_draw_layers_(0) { 581 } 582 583 virtual void BeginTest() OVERRIDE { 584 PostSetNeedsCommitToMainThread(); 585 } 586 587 virtual void Animate(base::TimeTicks) OVERRIDE { 588 if (num_draw_layers_ == 2) 589 return; 590 layer_tree_host()->SetNeedsAnimate(); 591 } 592 593 virtual void Layout() OVERRIDE { 594 layer_tree_host()->root_layer()->SetNeedsDisplay(); 595 } 596 597 virtual void CommitCompleteOnThread(LayerTreeHostImpl* tree_impl) OVERRIDE { 598 if (num_draw_layers_ == 1) 599 num_commit_complete_++; 600 } 601 602 virtual void DrawLayersOnThread(LayerTreeHostImpl* impl) OVERRIDE { 603 num_draw_layers_++; 604 if (num_draw_layers_ == 2) 605 EndTest(); 606 } 607 608 virtual void AfterTest() OVERRIDE { 609 // Check that we didn't commit twice between first and second draw. 610 EXPECT_EQ(1, num_commit_complete_); 611 } 612 613 private: 614 int num_commit_complete_; 615 int num_draw_layers_; 616}; 617 618MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestContinuousAnimate); 619 620// Make sure the main thread can still execute animations when CanDraw() is not 621// true. 622class LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw 623 : public LayerTreeHostAnimationTest { 624 public: 625 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw() : started_times_(0) {} 626 627 virtual void SetupTree() OVERRIDE { 628 LayerTreeHostAnimationTest::SetupTree(); 629 content_ = FakeContentLayer::Create(&client_); 630 content_->SetBounds(gfx::Size(4, 4)); 631 content_->set_layer_animation_delegate(this); 632 layer_tree_host()->root_layer()->AddChild(content_); 633 } 634 635 virtual void BeginTest() OVERRIDE { 636 layer_tree_host()->SetViewportSize(gfx::Size()); 637 PostAddAnimationToMainThread(content_.get()); 638 } 639 640 virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE { 641 started_times_++; 642 } 643 644 virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE { 645 EndTest(); 646 } 647 648 virtual void AfterTest() OVERRIDE { 649 EXPECT_EQ(1, started_times_); 650 } 651 652 private: 653 int started_times_; 654 FakeContentLayerClient client_; 655 scoped_refptr<FakeContentLayer> content_; 656}; 657 658SINGLE_AND_MULTI_THREAD_TEST_F( 659 LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw); 660 661// Make sure the main thread can still execute animations when the renderer is 662// backgrounded. 663class LayerTreeHostAnimationTestRunAnimationWhenNotVisible 664 : public LayerTreeHostAnimationTest { 665 public: 666 LayerTreeHostAnimationTestRunAnimationWhenNotVisible() : started_times_(0) {} 667 668 virtual void SetupTree() OVERRIDE { 669 LayerTreeHostAnimationTest::SetupTree(); 670 content_ = FakeContentLayer::Create(&client_); 671 content_->SetBounds(gfx::Size(4, 4)); 672 content_->set_layer_animation_delegate(this); 673 layer_tree_host()->root_layer()->AddChild(content_); 674 } 675 676 virtual void BeginTest() OVERRIDE { 677 visible_ = true; 678 PostAddAnimationToMainThread(content_.get()); 679 } 680 681 virtual void DidCommit() OVERRIDE { 682 visible_ = false; 683 layer_tree_host()->SetVisible(false); 684 } 685 686 virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE { 687 EXPECT_FALSE(visible_); 688 started_times_++; 689 } 690 691 virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE { 692 EXPECT_FALSE(visible_); 693 EXPECT_EQ(1, started_times_); 694 EndTest(); 695 } 696 697 virtual void AfterTest() OVERRIDE {} 698 699 private: 700 bool visible_; 701 int started_times_; 702 FakeContentLayerClient client_; 703 scoped_refptr<FakeContentLayer> content_; 704}; 705 706SINGLE_AND_MULTI_THREAD_TEST_F( 707 LayerTreeHostAnimationTestRunAnimationWhenNotVisible); 708 709// Animations should not be started when frames are being skipped due to 710// checkerboard. 711class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations 712 : public LayerTreeHostAnimationTest { 713 virtual void SetupTree() OVERRIDE { 714 LayerTreeHostAnimationTest::SetupTree(); 715 content_ = FakeContentLayer::Create(&client_); 716 content_->SetBounds(gfx::Size(4, 4)); 717 content_->set_layer_animation_delegate(this); 718 layer_tree_host()->root_layer()->AddChild(content_); 719 } 720 721 virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { 722 // Make sure that drawing many times doesn't cause a checkerboarded 723 // animation to start so we avoid flake in this test. 724 settings->timeout_and_draw_when_animation_checkerboards = false; 725 } 726 727 virtual void BeginTest() OVERRIDE { 728 prevented_draw_ = 0; 729 added_animations_ = 0; 730 started_times_ = 0; 731 finished_times_ = 0; 732 733 PostSetNeedsCommitToMainThread(); 734 } 735 736 virtual void DispatchAddInstantAnimation(Layer* layer_to_receive_animation) 737 OVERRIDE { 738 LayerTreeHostAnimationTest::DispatchAddInstantAnimation( 739 layer_to_receive_animation); 740 added_animations_++; 741 } 742 743 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 744 LayerTreeHostImpl::FrameData* frame_data, 745 bool result) OVERRIDE { 746 if (added_animations_ < 2) 747 return result; 748 if (TestEnded()) 749 return result; 750 // Act like there is checkerboard when the second animation wants to draw. 751 ++prevented_draw_; 752 return false; 753 } 754 755 virtual void DidCommitAndDrawFrame() OVERRIDE { 756 switch (layer_tree_host()->source_frame_number()) { 757 case 1: 758 // The animation is longer than 1 BeginFrame interval. 759 AddOpacityTransitionToLayer(content_.get(), 0.1, 0.2f, 0.8f, false); 760 added_animations_++; 761 break; 762 case 2: 763 // This second animation will not be drawn so it should not start. 764 AddAnimatedTransformToLayer(content_.get(), 0.1, 5, 5); 765 added_animations_++; 766 break; 767 } 768 } 769 770 virtual void NotifyAnimationStarted(double wall_clock_time) OVERRIDE { 771 if (TestEnded()) 772 return; 773 started_times_++; 774 } 775 776 virtual void NotifyAnimationFinished(double wall_clock_time) OVERRIDE { 777 // We should be checkerboarding already, but it should still finish the 778 // first animation. 779 EXPECT_EQ(2, added_animations_); 780 finished_times_++; 781 EndTest(); 782 } 783 784 virtual void AfterTest() OVERRIDE { 785 // Make sure we tried to draw the second animation but failed. 786 EXPECT_LT(0, prevented_draw_); 787 // The first animation should be started, but the second should not because 788 // of checkerboard. 789 EXPECT_EQ(1, started_times_); 790 // The first animation should still be finished. 791 EXPECT_EQ(1, finished_times_); 792 } 793 794 int prevented_draw_; 795 int added_animations_; 796 int started_times_; 797 int finished_times_; 798 FakeContentLayerClient client_; 799 scoped_refptr<FakeContentLayer> content_; 800}; 801 802MULTI_THREAD_TEST_F( 803 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); 804 805} // namespace 806} // namespace cc 807