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 <stdint.h> 8 #include <climits> 9 10 #include "base/bind.h" 11 #include "base/metrics/statistics_recorder.h" 12 #include "cc/animation/animation.h" 13 #include "cc/animation/animation_curve.h" 14 #include "cc/animation/animation_host.h" 15 #include "cc/animation/animation_id_provider.h" 16 #include "cc/animation/animation_timeline.h" 17 #include "cc/animation/element_animations.h" 18 #include "cc/animation/keyframe_effect.h" 19 #include "cc/animation/scroll_offset_animation_curve.h" 20 #include "cc/animation/scroll_offset_animation_curve_factory.h" 21 #include "cc/animation/scroll_offset_animations.h" 22 #include "cc/animation/timing_function.h" 23 #include "cc/animation/transform_operations.h" 24 #include "cc/base/completion_event.h" 25 #include "cc/layers/layer.h" 26 #include "cc/layers/layer_impl.h" 27 #include "cc/test/animation_test_common.h" 28 #include "cc/test/fake_content_layer_client.h" 29 #include "cc/test/fake_picture_layer.h" 30 #include "cc/test/layer_tree_test.h" 31 #include "cc/trees/effect_node.h" 32 #include "cc/trees/layer_tree_impl.h" 33 #include "cc/trees/target_property.h" 34 #include "cc/trees/transform_node.h" 35 #include "components/viz/common/quads/compositor_frame.h" 36 37 namespace cc { 38 namespace { 39 40 class LayerTreeHostAnimationTest : public LayerTreeTest { 41 public: LayerTreeHostAnimationTest()42 LayerTreeHostAnimationTest() 43 : timeline_id_(AnimationIdProvider::NextTimelineId()), 44 animation_id_(AnimationIdProvider::NextAnimationId()), 45 animation_child_id_(AnimationIdProvider::NextAnimationId()) { 46 timeline_ = AnimationTimeline::Create(timeline_id_); 47 animation_ = Animation::Create(animation_id_); 48 animation_child_ = Animation::Create(animation_child_id_); 49 50 animation_->set_animation_delegate(this); 51 } 52 AttachAnimationsToTimeline()53 void AttachAnimationsToTimeline() { 54 animation_host()->AddAnimationTimeline(timeline_.get()); 55 layer_tree_host()->SetElementIdsForTesting(); 56 timeline_->AttachAnimation(animation_.get()); 57 timeline_->AttachAnimation(animation_child_.get()); 58 } 59 GetImplTimelineAndAnimationByID(const LayerTreeHostImpl & host_impl)60 void GetImplTimelineAndAnimationByID(const LayerTreeHostImpl& host_impl) { 61 AnimationHost* animation_host_impl = GetImplAnimationHost(&host_impl); 62 timeline_impl_ = animation_host_impl->GetTimelineById(timeline_id_); 63 EXPECT_TRUE(timeline_impl_); 64 animation_impl_ = timeline_impl_->GetAnimationById(animation_id_); 65 EXPECT_TRUE(animation_impl_); 66 animation_child_impl_ = 67 timeline_impl_->GetAnimationById(animation_child_id_); 68 EXPECT_TRUE(animation_child_impl_); 69 } 70 GetImplAnimationHost(const LayerTreeHostImpl * host_impl) const71 AnimationHost* GetImplAnimationHost( 72 const LayerTreeHostImpl* host_impl) const { 73 return static_cast<AnimationHost*>(host_impl->mutator_host()); 74 } 75 76 protected: 77 scoped_refptr<AnimationTimeline> timeline_; 78 scoped_refptr<Animation> animation_; 79 scoped_refptr<Animation> animation_child_; 80 81 scoped_refptr<AnimationTimeline> timeline_impl_; 82 scoped_refptr<Animation> animation_impl_; 83 scoped_refptr<Animation> animation_child_impl_; 84 85 const int timeline_id_; 86 const int animation_id_; 87 const int animation_child_id_; 88 }; 89 90 // Makes sure that SetNeedsAnimate does not cause the CommitRequested() state to 91 // be set. 92 class LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested 93 : public LayerTreeHostAnimationTest { 94 public: LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested()95 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested() 96 : num_commits_(0) {} 97 BeginTest()98 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 99 BeginMainFrame(const viz::BeginFrameArgs & args)100 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 101 // We skip the first commit because its the commit that populates the 102 // impl thread with a tree. After the second commit, the test is done. 103 if (num_commits_ != 1) 104 return; 105 106 layer_tree_host()->SetNeedsAnimate(); 107 // Right now, CommitRequested is going to be true, because during 108 // BeginFrame, we force CommitRequested to true to prevent requests from 109 // hitting the impl thread. But, when the next DidCommit happens, we should 110 // verify that CommitRequested has gone back to false. 111 } 112 DidCommit()113 void DidCommit() override { 114 if (!num_commits_) { 115 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 116 layer_tree_host()->SetNeedsAnimate(); 117 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 118 } 119 120 // Verifies that the SetNeedsAnimate we made in ::Animate did not 121 // trigger CommitRequested. 122 EXPECT_FALSE(layer_tree_host()->CommitRequested()); 123 EndTest(); 124 num_commits_++; 125 } 126 127 private: 128 int num_commits_; 129 }; 130 131 MULTI_THREAD_TEST_F( 132 LayerTreeHostAnimationTestSetNeedsAnimateShouldNotSetCommitRequested); 133 134 // Trigger a frame with SetNeedsCommit. Then, inside the resulting animate 135 // callback, request another frame using SetNeedsAnimate. End the test when 136 // animate gets called yet-again, indicating that the proxy is correctly 137 // handling the case where SetNeedsAnimate() is called inside the BeginFrame 138 // flow. 139 class LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback 140 : public LayerTreeHostAnimationTest { 141 public: LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback()142 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback() 143 : num_begin_frames_(0) {} 144 BeginTest()145 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 146 BeginMainFrame(const viz::BeginFrameArgs & args)147 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 148 if (!num_begin_frames_) { 149 layer_tree_host()->SetNeedsAnimate(); 150 num_begin_frames_++; 151 return; 152 } 153 EndTest(); 154 } 155 156 private: 157 int num_begin_frames_; 158 }; 159 160 SINGLE_AND_MULTI_THREAD_TEST_F( 161 LayerTreeHostAnimationTestSetNeedsAnimateInsideAnimationCallback); 162 163 // Add a layer animation and confirm that 164 // LayerTreeHostImpl::UpdateAnimationState does get called. 165 class LayerTreeHostAnimationTestAddKeyframeModel 166 : public LayerTreeHostAnimationTest { 167 public: LayerTreeHostAnimationTestAddKeyframeModel()168 LayerTreeHostAnimationTestAddKeyframeModel() 169 : update_animation_state_was_called_(false) {} 170 BeginTest()171 void BeginTest() override { 172 AttachAnimationsToTimeline(); 173 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 174 PostAddOpacityAnimationToMainThreadInstantly(animation_.get()); 175 } 176 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)177 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 178 bool has_unfinished_animation) override { 179 EXPECT_FALSE(has_unfinished_animation); 180 update_animation_state_was_called_ = true; 181 } 182 NotifyAnimationStarted(base::TimeTicks monotonic_time,int target_property,int group)183 void NotifyAnimationStarted(base::TimeTicks monotonic_time, 184 int target_property, 185 int group) override { 186 EXPECT_LT(base::TimeTicks(), monotonic_time); 187 188 KeyframeModel* keyframe_model = 189 animation_->GetKeyframeModel(TargetProperty::OPACITY); 190 if (keyframe_model) 191 animation_->RemoveKeyframeModel(keyframe_model->id()); 192 193 EndTest(); 194 } 195 AfterTest()196 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); } 197 198 private: 199 bool update_animation_state_was_called_; 200 }; 201 202 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAddKeyframeModel); 203 204 // Add an animation that does not cause damage, followed by an animation that 205 // does. Confirm that the first animation finishes even though 206 // enable_early_damage_check should abort draws. 207 class LayerTreeHostAnimationTestNoDamageAnimation 208 : public LayerTreeHostAnimationTest { InitializeSettings(LayerTreeSettings * settings)209 void InitializeSettings(LayerTreeSettings* settings) override { 210 settings->using_synchronous_renderer_compositor = true; 211 settings->enable_early_damage_check = true; 212 } 213 214 public: LayerTreeHostAnimationTestNoDamageAnimation()215 LayerTreeHostAnimationTestNoDamageAnimation() 216 : started_animating_(false), finished_animating_(false) {} 217 BeginTest()218 void BeginTest() override { 219 AttachAnimationsToTimeline(); 220 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 221 PostAddNoDamageAnimationToMainThread(animation_.get()); 222 PostAddOpacityAnimationToMainThread(animation_.get()); 223 } 224 AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)225 void AnimateLayers(LayerTreeHostImpl* host_impl, 226 base::TimeTicks monotonic_time) override { 227 base::AutoLock auto_lock(lock_); 228 started_animating_ = true; 229 } 230 DrawLayersOnThread(LayerTreeHostImpl * host_impl)231 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 232 base::AutoLock auto_lock(lock_); 233 if (started_animating_ && finished_animating_) 234 EndTest(); 235 } 236 NotifyAnimationFinished(base::TimeTicks monotonic_time,int target_property,int group)237 void NotifyAnimationFinished(base::TimeTicks monotonic_time, 238 int target_property, 239 int group) override { 240 base::AutoLock auto_lock(lock_); 241 finished_animating_ = true; 242 } 243 244 private: 245 bool started_animating_; 246 bool finished_animating_; 247 base::Lock lock_; 248 }; 249 250 // This behavior is specific to Android WebView, which only uses 251 // multi-threaded compositor. 252 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestNoDamageAnimation); 253 254 // Add a layer animation to a layer, but continually fail to draw. Confirm that 255 // after a while, we do eventually force a draw. 256 class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws 257 : public LayerTreeHostAnimationTest { 258 public: LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws()259 LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws() 260 : started_animating_(false) {} 261 BeginTest()262 void BeginTest() override { 263 AttachAnimationsToTimeline(); 264 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 265 PostAddOpacityAnimationToMainThread(animation_.get()); 266 } 267 AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)268 void AnimateLayers(LayerTreeHostImpl* host_impl, 269 base::TimeTicks monotonic_time) override { 270 started_animating_ = true; 271 } 272 DrawLayersOnThread(LayerTreeHostImpl * host_impl)273 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 274 if (started_animating_) 275 EndTest(); 276 } 277 PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame,DrawResult draw_result)278 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 279 LayerTreeHostImpl::FrameData* frame, 280 DrawResult draw_result) override { 281 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 282 } 283 284 private: 285 bool started_animating_; 286 }; 287 288 // Starvation can only be an issue with the MT compositor. 289 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws); 290 291 // Ensures that animations eventually get deleted. 292 class LayerTreeHostAnimationTestAnimationsGetDeleted 293 : public LayerTreeHostAnimationTest { 294 public: LayerTreeHostAnimationTestAnimationsGetDeleted()295 LayerTreeHostAnimationTestAnimationsGetDeleted() 296 : started_animating_(false) {} 297 BeginTest()298 void BeginTest() override { 299 AttachAnimationsToTimeline(); 300 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 301 PostAddOpacityAnimationToMainThread(animation_.get()); 302 } 303 AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)304 void AnimateLayers(LayerTreeHostImpl* host_impl, 305 base::TimeTicks monotonic_time) override { 306 bool have_animations = !GetImplAnimationHost(host_impl) 307 ->ticking_animations_for_testing() 308 .empty(); 309 if (!started_animating_ && have_animations) { 310 started_animating_ = true; 311 return; 312 } 313 314 if (started_animating_ && !have_animations) 315 EndTest(); 316 } 317 NotifyAnimationFinished(base::TimeTicks monotonic_time,int target_property,int group)318 void NotifyAnimationFinished(base::TimeTicks monotonic_time, 319 int target_property, 320 int group) override { 321 // Animations on the impl-side ElementAnimations only get deleted during 322 // a commit, so we need to schedule a commit. 323 layer_tree_host()->SetNeedsCommit(); 324 } 325 326 private: 327 bool started_animating_; 328 }; 329 330 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); 331 332 // Ensure that an animation's timing function is respected. 333 class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction 334 : public LayerTreeHostAnimationTest { 335 public: SetupTree()336 void SetupTree() override { 337 LayerTreeHostAnimationTest::SetupTree(); 338 picture_ = FakePictureLayer::Create(&client_); 339 picture_->SetBounds(gfx::Size(4, 4)); 340 client_.set_bounds(picture_->bounds()); 341 layer_tree_host()->root_layer()->AddChild(picture_); 342 343 AttachAnimationsToTimeline(); 344 animation_child_->AttachElement(picture_->element_id()); 345 } 346 BeginTest()347 void BeginTest() override { 348 PostAddOpacityAnimationToMainThread(animation_child_.get()); 349 } 350 AnimateLayers(LayerTreeHostImpl * host_impl,base::TimeTicks monotonic_time)351 void AnimateLayers(LayerTreeHostImpl* host_impl, 352 base::TimeTicks monotonic_time) override { 353 // TODO(ajuma): This test only checks the active tree. Add checks for 354 // pending tree too. 355 if (!host_impl->active_tree()->root_layer()) 356 return; 357 358 // Wait for the commit with the animation to happen. 359 if (host_impl->active_tree()->source_frame_number() != 0) 360 return; 361 362 // The impl thread may start a second frame before the test finishes. This 363 // can lead to a race as if the main thread has committed a new sync tree 364 // the impl thread can now delete the KeyframeModel as the animation only 365 // lasts a single frame and no longer affects either tree. Only test the 366 // first frame the animation shows up for. 367 if (!first_animation_frame_) 368 return; 369 first_animation_frame_ = false; 370 371 scoped_refptr<AnimationTimeline> timeline_impl = 372 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 373 scoped_refptr<Animation> animation_child_impl = 374 timeline_impl->GetAnimationById(animation_child_id_); 375 376 KeyframeModel* keyframe_model = 377 animation_child_impl->GetKeyframeModel(TargetProperty::OPACITY); 378 379 const FloatAnimationCurve* curve = 380 keyframe_model->curve()->ToFloatAnimationCurve(); 381 float start_opacity = curve->GetValue(base::TimeDelta()); 382 float end_opacity = curve->GetValue(curve->Duration()); 383 float linearly_interpolated_opacity = 384 0.25f * end_opacity + 0.75f * start_opacity; 385 base::TimeDelta time = curve->Duration() * 0.25f; 386 // If the linear timing function associated with this animation was not 387 // picked up, then the linearly interpolated opacity would be different 388 // because of the default ease timing function. 389 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); 390 391 EndTest(); 392 } 393 394 FakeContentLayerClient client_; 395 scoped_refptr<FakePictureLayer> picture_; 396 bool first_animation_frame_ = true; 397 }; 398 399 SINGLE_AND_MULTI_THREAD_TEST_F( 400 LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction); 401 402 // Ensures that main thread animations have their start times synchronized with 403 // impl thread animations. 404 class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes 405 : public LayerTreeHostAnimationTest { 406 public: SetupTree()407 void SetupTree() override { 408 LayerTreeHostAnimationTest::SetupTree(); 409 picture_ = FakePictureLayer::Create(&client_); 410 picture_->SetBounds(gfx::Size(4, 4)); 411 client_.set_bounds(picture_->bounds()); 412 413 layer_tree_host()->root_layer()->AddChild(picture_); 414 415 AttachAnimationsToTimeline(); 416 animation_child_->set_animation_delegate(this); 417 animation_child_->AttachElement(picture_->element_id()); 418 } 419 BeginTest()420 void BeginTest() override { 421 PostAddOpacityAnimationToMainThread(animation_child_.get()); 422 } 423 NotifyAnimationStarted(base::TimeTicks monotonic_time,int target_property,int group)424 void NotifyAnimationStarted(base::TimeTicks monotonic_time, 425 int target_property, 426 int group) override { 427 KeyframeModel* keyframe_model = 428 animation_child_->GetKeyframeModel(TargetProperty::OPACITY); 429 main_start_time_ = keyframe_model->start_time(); 430 animation_child_->RemoveKeyframeModel(keyframe_model->id()); 431 EndTest(); 432 } 433 UpdateAnimationState(LayerTreeHostImpl * impl_host,bool has_unfinished_animation)434 void UpdateAnimationState(LayerTreeHostImpl* impl_host, 435 bool has_unfinished_animation) override { 436 scoped_refptr<AnimationTimeline> timeline_impl = 437 GetImplAnimationHost(impl_host)->GetTimelineById(timeline_id_); 438 scoped_refptr<Animation> animation_child_impl = 439 timeline_impl->GetAnimationById(animation_child_id_); 440 441 KeyframeModel* keyframe_model = 442 animation_child_impl->GetKeyframeModel(TargetProperty::OPACITY); 443 if (!keyframe_model) 444 return; 445 446 impl_start_time_ = keyframe_model->start_time(); 447 } 448 AfterTest()449 void AfterTest() override { 450 EXPECT_EQ(impl_start_time_, main_start_time_); 451 EXPECT_LT(base::TimeTicks(), impl_start_time_); 452 } 453 454 private: 455 base::TimeTicks main_start_time_; 456 base::TimeTicks impl_start_time_; 457 FakeContentLayerClient client_; 458 scoped_refptr<FakePictureLayer> picture_; 459 }; 460 461 SINGLE_AND_MULTI_THREAD_TEST_F( 462 LayerTreeHostAnimationTestSynchronizeAnimationStartTimes); 463 464 // Ensures that notify animation finished is called. 465 class LayerTreeHostAnimationTestAnimationFinishedEvents 466 : public LayerTreeHostAnimationTest { 467 public: BeginTest()468 void BeginTest() override { 469 AttachAnimationsToTimeline(); 470 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 471 PostAddOpacityAnimationToMainThreadInstantly(animation_.get()); 472 } 473 NotifyAnimationFinished(base::TimeTicks monotonic_time,int target_property,int group)474 void NotifyAnimationFinished(base::TimeTicks monotonic_time, 475 int target_property, 476 int group) override { 477 KeyframeModel* keyframe_model = 478 animation_->GetKeyframeModel(TargetProperty::OPACITY); 479 if (keyframe_model) 480 animation_->RemoveKeyframeModel(keyframe_model->id()); 481 EndTest(); 482 } 483 }; 484 485 SINGLE_AND_MULTI_THREAD_TEST_F( 486 LayerTreeHostAnimationTestAnimationFinishedEvents); 487 488 // Ensures that when opacity is being animated, this value does not cause the 489 // subtree to be skipped. 490 class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity 491 : public LayerTreeHostAnimationTest { 492 public: LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity()493 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity() 494 : update_check_layer_() {} 495 SetupTree()496 void SetupTree() override { 497 update_check_layer_ = FakePictureLayer::Create(&client_); 498 update_check_layer_->SetOpacity(0.f); 499 layer_tree_host()->SetRootLayer(update_check_layer_); 500 client_.set_bounds(update_check_layer_->bounds()); 501 LayerTreeHostAnimationTest::SetupTree(); 502 503 AttachAnimationsToTimeline(); 504 animation_->AttachElement(update_check_layer_->element_id()); 505 } 506 BeginTest()507 void BeginTest() override { 508 PostAddOpacityAnimationToMainThread(animation_.get()); 509 } 510 DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)511 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { 512 scoped_refptr<AnimationTimeline> timeline_impl = 513 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 514 scoped_refptr<Animation> animation_impl = 515 timeline_impl->GetAnimationById(animation_id_); 516 517 KeyframeModel* keyframe_model_impl = 518 animation_impl->GetKeyframeModel(TargetProperty::OPACITY); 519 animation_impl->RemoveKeyframeModel(keyframe_model_impl->id()); 520 EndTest(); 521 } 522 AfterTest()523 void AfterTest() override { 524 // Update() should have been called once, proving that the layer was not 525 // skipped. 526 EXPECT_EQ(1, update_check_layer_->update_count()); 527 528 // clear update_check_layer_ so LayerTreeHost dies. 529 update_check_layer_ = nullptr; 530 } 531 532 private: 533 FakeContentLayerClient client_; 534 scoped_refptr<FakePictureLayer> update_check_layer_; 535 }; 536 537 SINGLE_AND_MULTI_THREAD_TEST_F( 538 LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity); 539 540 // Layers added to tree with existing active animations should have the 541 // animation correctly recognized. 542 class LayerTreeHostAnimationTestLayerAddedWithAnimation 543 : public LayerTreeHostAnimationTest { 544 public: BeginTest()545 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 546 DidCommit()547 void DidCommit() override { 548 if (layer_tree_host()->SourceFrameNumber() == 1) { 549 AttachAnimationsToTimeline(); 550 551 scoped_refptr<Layer> layer = Layer::Create(); 552 layer->SetElementId(ElementId(42)); 553 animation_->AttachElement(layer->element_id()); 554 animation_->set_animation_delegate(this); 555 556 // Any valid AnimationCurve will do here. 557 std::unique_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); 558 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 559 std::move(curve), 1, 1, TargetProperty::OPACITY)); 560 animation_->AddKeyframeModel(std::move(keyframe_model)); 561 562 // We add the animation *before* attaching the layer to the tree. 563 layer_tree_host()->root_layer()->AddChild(layer); 564 } 565 } 566 AnimateLayers(LayerTreeHostImpl * impl_host,base::TimeTicks monotonic_time)567 void AnimateLayers(LayerTreeHostImpl* impl_host, 568 base::TimeTicks monotonic_time) override { 569 EndTest(); 570 } 571 }; 572 573 SINGLE_AND_MULTI_THREAD_TEST_F( 574 LayerTreeHostAnimationTestLayerAddedWithAnimation); 575 576 class LayerTreeHostAnimationTestCancelAnimateCommit 577 : public LayerTreeHostAnimationTest { 578 public: LayerTreeHostAnimationTestCancelAnimateCommit()579 LayerTreeHostAnimationTestCancelAnimateCommit() 580 : num_begin_frames_(0), num_commit_calls_(0), num_draw_calls_(0) {} 581 BeginTest()582 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 583 BeginMainFrame(const viz::BeginFrameArgs & args)584 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 585 num_begin_frames_++; 586 // No-op animate will cancel the commit. 587 if (layer_tree_host()->SourceFrameNumber() == 1) { 588 EndTest(); 589 return; 590 } 591 layer_tree_host()->SetNeedsAnimate(); 592 } 593 CommitCompleteOnThread(LayerTreeHostImpl * impl)594 void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { 595 num_commit_calls_++; 596 if (impl->active_tree()->source_frame_number() > 1) 597 FAIL() << "Commit should have been canceled."; 598 } 599 DrawLayersOnThread(LayerTreeHostImpl * impl)600 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { 601 num_draw_calls_++; 602 if (impl->active_tree()->source_frame_number() > 1) 603 FAIL() << "Draw should have been canceled."; 604 } 605 AfterTest()606 void AfterTest() override { 607 EXPECT_EQ(2, num_begin_frames_); 608 EXPECT_EQ(1, num_commit_calls_); 609 EXPECT_EQ(1, num_draw_calls_); 610 } 611 612 private: 613 int num_begin_frames_; 614 int num_commit_calls_; 615 int num_draw_calls_; 616 }; 617 618 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestCancelAnimateCommit); 619 620 class LayerTreeHostAnimationTestForceRedraw 621 : public LayerTreeHostAnimationTest { 622 public: LayerTreeHostAnimationTestForceRedraw()623 LayerTreeHostAnimationTestForceRedraw() 624 : num_animate_(0), num_draw_layers_(0) {} 625 BeginTest()626 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 627 BeginMainFrame(const viz::BeginFrameArgs & args)628 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 629 if (++num_animate_ < 2) 630 layer_tree_host()->SetNeedsAnimate(); 631 } 632 UpdateLayerTreeHost()633 void UpdateLayerTreeHost() override { 634 layer_tree_host()->SetNeedsCommitWithForcedRedraw(); 635 } 636 DrawLayersOnThread(LayerTreeHostImpl * impl)637 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { 638 if (++num_draw_layers_ == 2) 639 EndTest(); 640 } 641 AfterTest()642 void AfterTest() override { 643 // The first commit will always draw; make sure the second draw triggered 644 // by the animation was not cancelled. 645 EXPECT_EQ(2, num_draw_layers_); 646 EXPECT_EQ(2, num_animate_); 647 } 648 649 private: 650 int num_animate_; 651 int num_draw_layers_; 652 }; 653 654 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestForceRedraw); 655 656 class LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit 657 : public LayerTreeHostAnimationTest { 658 public: LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit()659 LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit() 660 : num_animate_(0), num_draw_layers_(0) {} 661 BeginTest()662 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 663 BeginMainFrame(const viz::BeginFrameArgs & args)664 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 665 if (++num_animate_ <= 2) { 666 layer_tree_host()->SetNeedsCommit(); 667 layer_tree_host()->SetNeedsAnimate(); 668 } 669 } 670 DrawLayersOnThread(LayerTreeHostImpl * impl)671 void DrawLayersOnThread(LayerTreeHostImpl* impl) override { 672 if (++num_draw_layers_ == 2) 673 EndTest(); 674 } 675 AfterTest()676 void AfterTest() override { 677 // The first commit will always draw; make sure the second draw triggered 678 // by the SetNeedsCommit was not cancelled. 679 EXPECT_EQ(2, num_draw_layers_); 680 EXPECT_GE(num_animate_, 2); 681 } 682 683 private: 684 int num_animate_; 685 int num_draw_layers_; 686 }; 687 688 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimateAfterSetNeedsCommit); 689 690 // Animations should not be started when frames are being skipped due to 691 // checkerboard. 692 class LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations 693 : public LayerTreeHostAnimationTest { SetupTree()694 void SetupTree() override { 695 LayerTreeHostAnimationTest::SetupTree(); 696 picture_ = FakePictureLayer::Create(&client_); 697 picture_->SetBounds(gfx::Size(4, 4)); 698 client_.set_bounds(picture_->bounds()); 699 layer_tree_host()->root_layer()->AddChild(picture_); 700 701 AttachAnimationsToTimeline(); 702 animation_child_->AttachElement(picture_->element_id()); 703 animation_child_->set_animation_delegate(this); 704 } 705 BeginTest()706 void BeginTest() override { 707 prevented_draw_ = 0; 708 started_times_ = 0; 709 710 PostSetNeedsCommitToMainThread(); 711 } 712 PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)713 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 714 LayerTreeHostImpl::FrameData* frame_data, 715 DrawResult draw_result) override { 716 // Don't checkerboard when the first animation wants to start. 717 if (host_impl->active_tree()->source_frame_number() < 2) 718 return draw_result; 719 if (TestEnded()) 720 return draw_result; 721 // Act like there is checkerboard when the second animation wants to draw. 722 ++prevented_draw_; 723 if (prevented_draw_ > 2) 724 EndTest(); 725 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; 726 } 727 DidCommitAndDrawFrame()728 void DidCommitAndDrawFrame() override { 729 switch (layer_tree_host()->SourceFrameNumber()) { 730 case 1: 731 // The animation is longer than 1 BeginFrame interval. 732 AddOpacityTransitionToAnimation(animation_child_.get(), 0.1, 0.2f, 0.8f, 733 false); 734 break; 735 case 2: 736 // This second animation will not be drawn so it should not start. 737 AddAnimatedTransformToAnimation(animation_child_.get(), 0.1, 5, 5); 738 break; 739 } 740 } 741 NotifyAnimationStarted(base::TimeTicks monotonic_time,int target_property,int group)742 void NotifyAnimationStarted(base::TimeTicks monotonic_time, 743 int target_property, 744 int group) override { 745 if (TestEnded()) 746 return; 747 started_times_++; 748 } 749 AfterTest()750 void AfterTest() override { 751 // Make sure we tried to draw the second animation but failed. 752 EXPECT_LT(0, prevented_draw_); 753 // The first animation should be started, but the second should not because 754 // of checkerboard. 755 EXPECT_EQ(1, started_times_); 756 } 757 758 int prevented_draw_; 759 int started_times_; 760 FakeContentLayerClient client_; 761 scoped_refptr<FakePictureLayer> picture_; 762 }; 763 764 MULTI_THREAD_TEST_F( 765 LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations); 766 767 // Verifies that scroll offset animations are only accepted when impl-scrolling 768 // is supported, and that when scroll offset animations are accepted, 769 // scroll offset updates are sent back to the main thread. 770 class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated 771 : public LayerTreeHostAnimationTest { 772 public: SetupTree()773 void SetupTree() override { 774 LayerTreeHostAnimationTest::SetupTree(); 775 776 scroll_layer_ = FakePictureLayer::Create(&client_); 777 scroll_layer_->SetScrollable(gfx::Size(100, 100)); 778 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); 779 client_.set_bounds(scroll_layer_->bounds()); 780 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); 781 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 782 783 AttachAnimationsToTimeline(); 784 animation_child_->AttachElement(scroll_layer_->element_id()); 785 } 786 BeginTest()787 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 788 DidCommit()789 void DidCommit() override { 790 switch (layer_tree_host()->SourceFrameNumber()) { 791 case 1: { 792 std::unique_ptr<ScrollOffsetAnimationCurve> curve( 793 ScrollOffsetAnimationCurveFactory:: 794 CreateEaseInOutAnimationForTesting( 795 gfx::ScrollOffset(500.f, 550.f))); 796 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 797 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); 798 keyframe_model->set_needs_synchronized_start_time(true); 799 bool impl_scrolling_supported = proxy()->SupportsImplScrolling(); 800 if (impl_scrolling_supported) 801 animation_child_->AddKeyframeModel(std::move(keyframe_model)); 802 else 803 EndTest(); 804 break; 805 } 806 default: 807 EXPECT_GE(scroll_layer_->scroll_offset().x(), 10); 808 EXPECT_GE(scroll_layer_->scroll_offset().y(), 20); 809 if (scroll_layer_->scroll_offset().x() > 10 && 810 scroll_layer_->scroll_offset().y() > 20) 811 EndTest(); 812 } 813 } 814 815 private: 816 FakeContentLayerClient client_; 817 scoped_refptr<FakePictureLayer> scroll_layer_; 818 }; 819 820 SINGLE_AND_MULTI_THREAD_TEST_F( 821 LayerTreeHostAnimationTestScrollOffsetChangesArePropagated); 822 823 // Verifies that when a main thread scrolling reason gets added, the 824 // notification to takover the animation on the main thread gets sent. 825 class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover 826 : public LayerTreeHostAnimationTest { 827 public: 828 LayerTreeHostAnimationTestScrollOffsetAnimationTakeover() = default; 829 SetupTree()830 void SetupTree() override { 831 LayerTreeHostAnimationTest::SetupTree(); 832 833 scroll_layer_ = FakePictureLayer::Create(&client_); 834 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 835 client_.set_bounds(scroll_layer_->bounds()); 836 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); 837 scroll_layer_->SetScrollable(gfx::Size(10, 10)); 838 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 839 840 AttachAnimationsToTimeline(); 841 animation_child_->AttachElement(scroll_layer_->element_id()); 842 // Allows NotifyAnimationTakeover to get called. 843 animation_child_->set_animation_delegate(this); 844 } 845 BeginTest()846 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 847 DidCommit()848 void DidCommit() override { 849 if (layer_tree_host()->SourceFrameNumber() == 1) { 850 // Add an update after the first commit to trigger the animation takeover 851 // path. 852 animation_host()->scroll_offset_animations().AddTakeoverUpdate( 853 scroll_layer_->element_id()); 854 EXPECT_TRUE( 855 animation_host()->scroll_offset_animations().HasUpdatesForTesting()); 856 } 857 } 858 WillCommitCompleteOnThread(LayerTreeHostImpl * host_impl)859 void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 860 if (host_impl->sync_tree()->source_frame_number() == 0) { 861 GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( 862 scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), 863 gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta()); 864 } 865 } 866 NotifyAnimationTakeover(base::TimeTicks monotonic_time,int target_property,base::TimeTicks animation_start_time,std::unique_ptr<AnimationCurve> curve)867 void NotifyAnimationTakeover(base::TimeTicks monotonic_time, 868 int target_property, 869 base::TimeTicks animation_start_time, 870 std::unique_ptr<AnimationCurve> curve) override { 871 EndTest(); 872 } 873 874 private: 875 FakeContentLayerClient client_; 876 scoped_refptr<FakePictureLayer> scroll_layer_; 877 }; 878 879 // TODO(crbug.com/1018213): [BlinkGenPropertyTrees] Scroll Animation should be 880 // taken over from cc when scroll is unpromoted. 881 // MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationTakeover); 882 883 // Verifies that an impl-only scroll offset animation gets updated when the 884 // scroll offset is adjusted on the main thread. 885 class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted 886 : public LayerTreeHostAnimationTest { 887 public: 888 LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted() = default; 889 SetupTree()890 void SetupTree() override { 891 LayerTreeHostAnimationTest::SetupTree(); 892 893 scroll_layer_ = FakePictureLayer::Create(&client_); 894 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 895 client_.set_bounds(scroll_layer_->bounds()); 896 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); 897 scroll_layer_->SetScrollable(gfx::Size(10, 10)); 898 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 899 900 AttachAnimationsToTimeline(); 901 } 902 ScrollOffsetKeyframeEffect(const LayerTreeHostImpl & host_impl,scoped_refptr<FakePictureLayer> layer) const903 KeyframeEffect& ScrollOffsetKeyframeEffect( 904 const LayerTreeHostImpl& host_impl, 905 scoped_refptr<FakePictureLayer> layer) const { 906 scoped_refptr<ElementAnimations> element_animations = 907 GetImplAnimationHost(&host_impl) 908 ->GetElementAnimationsForElementId(layer->element_id()); 909 DCHECK(element_animations); 910 KeyframeEffect* keyframe_effect = 911 &*element_animations->FirstKeyframeEffectForTesting(); 912 DCHECK(keyframe_effect); 913 return *keyframe_effect; 914 } 915 BeginTest()916 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 917 DidCommit()918 void DidCommit() override { 919 if (layer_tree_host()->SourceFrameNumber() == 1) { 920 // Add an update after the first commit to trigger the animation update 921 // path. 922 animation_host()->scroll_offset_animations().AddAdjustmentUpdate( 923 scroll_layer_->element_id(), gfx::Vector2dF(100.f, 100.f)); 924 EXPECT_TRUE( 925 animation_host()->scroll_offset_animations().HasUpdatesForTesting()); 926 } else if (layer_tree_host()->SourceFrameNumber() == 2) { 927 // Verify that the update queue is cleared after the update is applied. 928 EXPECT_FALSE( 929 animation_host()->scroll_offset_animations().HasUpdatesForTesting()); 930 } 931 } 932 BeginCommitOnThread(LayerTreeHostImpl * host_impl)933 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { 934 // Note that the frame number gets incremented after BeginCommitOnThread but 935 // before WillCommitCompleteOnThread and CommitCompleteOnThread. 936 if (host_impl->sync_tree()->source_frame_number() == 0) { 937 GetImplTimelineAndAnimationByID(*host_impl); 938 // This happens after the impl-only animation is added in 939 // WillCommitCompleteOnThread. 940 KeyframeModel* keyframe_model = 941 ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_) 942 .GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 943 DCHECK(keyframe_model); 944 ScrollOffsetAnimationCurve* curve = 945 keyframe_model->curve()->ToScrollOffsetAnimationCurve(); 946 947 // Verifiy the initial and target position before the scroll offset 948 // update from MT. 949 EXPECT_EQ(gfx::ScrollOffset(10.f, 20.f), 950 curve->GetValue(base::TimeDelta())); 951 EXPECT_EQ(gfx::ScrollOffset(650.f, 750.f), curve->target_value()); 952 } 953 } 954 WillCommitCompleteOnThread(LayerTreeHostImpl * host_impl)955 void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 956 if (host_impl->sync_tree()->source_frame_number() == 0) { 957 GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( 958 scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), 959 gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta()); 960 } 961 } 962 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)963 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 964 if (host_impl->sync_tree()->source_frame_number() == 1) { 965 KeyframeModel* keyframe_model = 966 ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_) 967 .GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 968 DCHECK(keyframe_model); 969 ScrollOffsetAnimationCurve* curve = 970 keyframe_model->curve()->ToScrollOffsetAnimationCurve(); 971 // Verifiy the initial and target position after the scroll offset 972 // update from MT 973 EXPECT_EQ(KeyframeModel::RunState::STARTING, keyframe_model->run_state()); 974 EXPECT_EQ(gfx::ScrollOffset(110.f, 120.f), 975 curve->GetValue(base::TimeDelta())); 976 EXPECT_EQ(gfx::ScrollOffset(750.f, 850.f), curve->target_value()); 977 978 EndTest(); 979 } 980 } 981 982 private: 983 FakeContentLayerClient client_; 984 scoped_refptr<FakePictureLayer> scroll_layer_; 985 }; 986 987 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted); 988 989 // Tests that presentation-time requested from the main-thread is attached to 990 // the correct frame (i.e. activation needs to happen before the 991 // presentation-request is attached to the frame). 992 class LayerTreeHostPresentationDuringAnimation 993 : public LayerTreeHostAnimationTest { 994 public: SetupTree()995 void SetupTree() override { 996 LayerTreeHostAnimationTest::SetupTree(); 997 998 scroll_layer_ = FakePictureLayer::Create(&client_); 999 scroll_layer_->SetScrollable(gfx::Size(100, 100)); 1000 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 1001 client_.set_bounds(scroll_layer_->bounds()); 1002 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); 1003 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 1004 1005 std::unique_ptr<ScrollOffsetAnimationCurve> curve( 1006 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting( 1007 gfx::ScrollOffset(6500.f, 7500.f))); 1008 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 1009 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); 1010 keyframe_model->set_needs_synchronized_start_time(true); 1011 1012 AttachAnimationsToTimeline(); 1013 animation_child_->AttachElement(scroll_layer_->element_id()); 1014 animation_child_->AddKeyframeModel(std::move(keyframe_model)); 1015 } 1016 BeginTest()1017 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1018 BeginMainFrame(const viz::BeginFrameArgs & args)1019 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 1020 PostSetNeedsCommitToMainThread(); 1021 } 1022 BeginCommitOnThread(LayerTreeHostImpl * host_impl)1023 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { 1024 if (host_impl->active_tree()->source_frame_number() == 1) { 1025 request_token_ = host_impl->next_frame_token(); 1026 layer_tree_host()->RequestPresentationTimeForNextFrame(base::BindOnce( 1027 &LayerTreeHostPresentationDuringAnimation::OnPresentation, 1028 base::Unretained(this))); 1029 host_impl->BlockNotifyReadyToActivateForTesting(true); 1030 } 1031 } 1032 WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)1033 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 1034 const viz::BeginFrameArgs& args) override { 1035 if (host_impl->next_frame_token() >= 5) 1036 host_impl->BlockNotifyReadyToActivateForTesting(false); 1037 } 1038 DisplayReceivedCompositorFrameOnThread(const viz::CompositorFrame & frame)1039 void DisplayReceivedCompositorFrameOnThread( 1040 const viz::CompositorFrame& frame) override { 1041 received_token_ = frame.metadata.frame_token; 1042 } 1043 AfterTest()1044 void AfterTest() override { 1045 EXPECT_GT(request_token_, 0u); 1046 EXPECT_GT(received_token_, request_token_); 1047 EXPECT_GE(received_token_, 5u); 1048 EXPECT_TRUE(base::StatisticsRecorder::FindHistogram( 1049 "CompositorLatency.TotalLatency")); 1050 EXPECT_FALSE(base::StatisticsRecorder::FindHistogram( 1051 "CompositorLatency.Universal.TotalLatency")); 1052 } 1053 1054 private: OnPresentation(const gfx::PresentationFeedback & feedback)1055 void OnPresentation(const gfx::PresentationFeedback& feedback) { EndTest(); } 1056 1057 FakeContentLayerClient client_; 1058 scoped_refptr<FakePictureLayer> scroll_layer_; 1059 uint32_t request_token_ = 0; 1060 uint32_t received_token_ = 0; 1061 }; 1062 1063 MULTI_THREAD_TEST_F(LayerTreeHostPresentationDuringAnimation); 1064 1065 // Verifies that when the main thread removes a scroll animation and sets a new 1066 // scroll position, the active tree takes on exactly this new scroll position 1067 // after activation, and the main thread doesn't receive a spurious scroll 1068 // delta. 1069 class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval 1070 : public LayerTreeHostAnimationTest { 1071 public: LayerTreeHostAnimationTestScrollOffsetAnimationRemoval()1072 LayerTreeHostAnimationTestScrollOffsetAnimationRemoval() 1073 : final_postion_(50.0, 100.0) {} 1074 SetupTree()1075 void SetupTree() override { 1076 LayerTreeHostAnimationTest::SetupTree(); 1077 1078 scroll_layer_ = FakePictureLayer::Create(&client_); 1079 scroll_layer_->SetScrollable(gfx::Size(100, 100)); 1080 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 1081 client_.set_bounds(scroll_layer_->bounds()); 1082 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); 1083 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 1084 1085 std::unique_ptr<ScrollOffsetAnimationCurve> curve( 1086 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting( 1087 gfx::ScrollOffset(6500.f, 7500.f))); 1088 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 1089 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); 1090 keyframe_model->set_needs_synchronized_start_time(true); 1091 1092 AttachAnimationsToTimeline(); 1093 animation_child_->AttachElement(scroll_layer_->element_id()); 1094 animation_child_->AddKeyframeModel(std::move(keyframe_model)); 1095 } 1096 BeginTest()1097 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1098 BeginMainFrame(const viz::BeginFrameArgs & args)1099 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 1100 switch (layer_tree_host()->SourceFrameNumber()) { 1101 case 0: 1102 EXPECT_EQ(scroll_layer_->scroll_offset().x(), 100); 1103 EXPECT_EQ(scroll_layer_->scroll_offset().y(), 200); 1104 break; 1105 case 1: { 1106 EXPECT_GE(scroll_layer_->scroll_offset().x(), 100); 1107 EXPECT_GE(scroll_layer_->scroll_offset().y(), 200); 1108 KeyframeModel* keyframe_model = 1109 animation_child_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 1110 animation_child_->RemoveKeyframeModel(keyframe_model->id()); 1111 scroll_layer_->SetScrollOffset(final_postion_); 1112 break; 1113 } 1114 default: 1115 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); 1116 } 1117 } 1118 BeginCommitOnThread(LayerTreeHostImpl * host_impl)1119 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { 1120 host_impl->BlockNotifyReadyToActivateForTesting( 1121 ShouldBlockActivation(host_impl)); 1122 } 1123 WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)1124 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 1125 const viz::BeginFrameArgs& args) override { 1126 host_impl->BlockNotifyReadyToActivateForTesting( 1127 ShouldBlockActivation(host_impl)); 1128 } 1129 WillActivateTreeOnThread(LayerTreeHostImpl * host_impl)1130 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { 1131 if (host_impl->pending_tree()->source_frame_number() != 1) 1132 return; 1133 LayerImpl* scroll_layer_impl = 1134 host_impl->pending_tree()->LayerById(scroll_layer_->id()); 1135 EXPECT_EQ(final_postion_, CurrentScrollOffset(scroll_layer_impl)); 1136 } 1137 DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1138 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { 1139 if (host_impl->active_tree()->source_frame_number() != 1) 1140 return; 1141 LayerImpl* scroll_layer_impl = 1142 host_impl->active_tree()->LayerById(scroll_layer_->id()); 1143 EXPECT_EQ(final_postion_, CurrentScrollOffset(scroll_layer_impl)); 1144 EndTest(); 1145 } 1146 AfterTest()1147 void AfterTest() override { 1148 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); 1149 } 1150 1151 private: ShouldBlockActivation(LayerTreeHostImpl * host_impl)1152 bool ShouldBlockActivation(LayerTreeHostImpl* host_impl) { 1153 if (!host_impl->pending_tree()) 1154 return false; 1155 1156 if (!host_impl->active_tree()->root_layer()) 1157 return false; 1158 1159 scoped_refptr<AnimationTimeline> timeline_impl = 1160 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 1161 scoped_refptr<Animation> animation_impl = 1162 timeline_impl->GetAnimationById(animation_child_id_); 1163 1164 LayerImpl* scroll_layer_impl = 1165 host_impl->active_tree()->LayerById(scroll_layer_->id()); 1166 KeyframeModel* keyframe_model = 1167 animation_impl->GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 1168 1169 if (!keyframe_model || 1170 keyframe_model->run_state() != KeyframeModel::RUNNING) 1171 return false; 1172 1173 // Block activation until the running animation has a chance to produce a 1174 // scroll delta. 1175 gfx::ScrollOffset scroll_delta = ScrollDelta(scroll_layer_impl); 1176 if (scroll_delta.x() > 0.f || scroll_delta.y() > 0.f) 1177 return false; 1178 1179 return true; 1180 } 1181 1182 FakeContentLayerClient client_; 1183 scoped_refptr<FakePictureLayer> scroll_layer_; 1184 const gfx::ScrollOffset final_postion_; 1185 }; 1186 1187 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval); 1188 1189 // Verifies that the state of a scroll animation is tracked correctly on the 1190 // main and compositor thread and that the KeyframeModel is removed when 1191 // the scroll animation completes. This is a regression test for 1192 // https://crbug.com/962346 and demonstrates the necessity of 1193 // LayerTreeHost::AnimateLayers for https://crbug.com/762717. 1194 class LayerTreeHostAnimationTestScrollOffsetAnimationCompletion 1195 : public LayerTreeHostAnimationTest { 1196 public: LayerTreeHostAnimationTestScrollOffsetAnimationCompletion()1197 LayerTreeHostAnimationTestScrollOffsetAnimationCompletion() 1198 : final_position_(80.0, 180.0) {} 1199 SetupTree()1200 void SetupTree() override { 1201 LayerTreeHostAnimationTest::SetupTree(); 1202 1203 scroll_layer_ = FakePictureLayer::Create(&client_); 1204 scroll_layer_->SetScrollable(gfx::Size(100, 100)); 1205 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); 1206 client_.set_bounds(scroll_layer_->bounds()); 1207 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); 1208 layer_tree_host()->root_layer()->AddChild(scroll_layer_); 1209 1210 std::unique_ptr<ScrollOffsetAnimationCurve> curve( 1211 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting( 1212 final_position_)); 1213 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 1214 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); 1215 keyframe_model->set_needs_synchronized_start_time(true); 1216 1217 AttachAnimationsToTimeline(); 1218 animation_child_->AttachElement(scroll_layer_->element_id()); 1219 animation_child_->AddKeyframeModel(std::move(keyframe_model)); 1220 } 1221 BeginTest()1222 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1223 BeginMainFrame(const viz::BeginFrameArgs & args)1224 void BeginMainFrame(const viz::BeginFrameArgs& args) override { 1225 KeyframeModel* keyframe_model = 1226 animation_child_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 1227 switch (layer_tree_host()->SourceFrameNumber()) { 1228 case 0: 1229 EXPECT_EQ(scroll_layer_->scroll_offset().x(), 100); 1230 EXPECT_EQ(scroll_layer_->scroll_offset().y(), 200); 1231 EXPECT_EQ(KeyframeModel::RunState::WAITING_FOR_TARGET_AVAILABILITY, 1232 keyframe_model->run_state()); 1233 break; 1234 case 1: 1235 EXPECT_EQ(KeyframeModel::RunState::RUNNING, 1236 keyframe_model->run_state()); 1237 break; 1238 default: 1239 break; 1240 } 1241 } 1242 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1243 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1244 if (host_impl->sync_tree()->source_frame_number() == 0) { 1245 GetImplTimelineAndAnimationByID(*host_impl); 1246 return; 1247 } 1248 KeyframeModel* keyframe_model = 1249 animation_child_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET); 1250 if (!keyframe_model || keyframe_model->run_state() == 1251 KeyframeModel::RunState::WAITING_FOR_DELETION) 1252 EndTest(); 1253 } 1254 DidFinishImplFrameOnThread(LayerTreeHostImpl * host_impl)1255 void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override { 1256 if (!animation_child_impl_) 1257 return; 1258 if (KeyframeModel* keyframe_model = animation_child_impl_->GetKeyframeModel( 1259 TargetProperty::SCROLL_OFFSET)) { 1260 if (keyframe_model->run_state() == KeyframeModel::RunState::RUNNING) { 1261 ran_animation_ = true; 1262 } 1263 } 1264 } 1265 AfterTest()1266 void AfterTest() override { 1267 // The animation should have run for some frames. 1268 EXPECT_TRUE(ran_animation_); 1269 1270 // The finished KeyframeModel should have been removed from both the 1271 // main and impl side animations. 1272 EXPECT_EQ(nullptr, animation_child_->GetKeyframeModel( 1273 TargetProperty::SCROLL_OFFSET)); 1274 EXPECT_EQ(nullptr, animation_child_impl_->GetKeyframeModel( 1275 TargetProperty::SCROLL_OFFSET)); 1276 1277 // The scroll should have been completed. 1278 EXPECT_EQ(final_position_, scroll_layer_->scroll_offset()); 1279 } 1280 1281 private: 1282 FakeContentLayerClient client_; 1283 scoped_refptr<FakePictureLayer> scroll_layer_; 1284 const gfx::ScrollOffset final_position_; 1285 bool ran_animation_ = false; 1286 }; 1287 1288 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationCompletion); 1289 1290 // When animations are simultaneously added to an existing layer and to a new 1291 // layer, they should start at the same time, even when there's already a 1292 // running animation on the existing layer. 1293 class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers 1294 : public LayerTreeHostAnimationTest { 1295 public: LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers()1296 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers() 1297 : frame_count_with_pending_tree_(0) {} 1298 SetupTree()1299 void SetupTree() override { 1300 LayerTreeHostAnimationTest::SetupTree(); 1301 layer_ = Layer::Create(); 1302 layer_->SetBounds(gfx::Size(4, 4)); 1303 layer_tree_host()->root_layer()->AddChild(layer_); 1304 layer_tree_host()->SetElementIdsForTesting(); 1305 } 1306 BeginTest()1307 void BeginTest() override { 1308 AttachAnimationsToTimeline(); 1309 PostSetNeedsCommitToMainThread(); 1310 } 1311 DidCommit()1312 void DidCommit() override { 1313 if (layer_tree_host()->SourceFrameNumber() == 1) { 1314 animation_->AttachElement(layer_->element_id()); 1315 AddAnimatedTransformToAnimation(animation_.get(), 4, 1, 1); 1316 } else if (layer_tree_host()->SourceFrameNumber() == 2) { 1317 AddOpacityTransitionToAnimation(animation_.get(), 1, 0.f, 0.5f, true); 1318 1319 scoped_refptr<Layer> child_layer = Layer::Create(); 1320 layer_->AddChild(child_layer); 1321 1322 layer_tree_host()->SetElementIdsForTesting(); 1323 child_layer->SetBounds(gfx::Size(4, 4)); 1324 1325 animation_child_->AttachElement(child_layer->element_id()); 1326 animation_child_->set_animation_delegate(this); 1327 AddOpacityTransitionToAnimation(animation_child_.get(), 1, 0.f, 0.5f, 1328 true); 1329 } 1330 } 1331 BeginCommitOnThread(LayerTreeHostImpl * host_impl)1332 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { 1333 host_impl->BlockNotifyReadyToActivateForTesting(true); 1334 } 1335 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1336 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1337 // For the commit that added animations to new and existing layers, keep 1338 // blocking activation. We want to verify that even with activation blocked, 1339 // the animation on the layer that's already in the active tree won't get a 1340 // head start. 1341 if (host_impl->pending_tree()->source_frame_number() != 2) { 1342 host_impl->BlockNotifyReadyToActivateForTesting(false); 1343 } 1344 } 1345 WillBeginImplFrameOnThread(LayerTreeHostImpl * host_impl,const viz::BeginFrameArgs & args)1346 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, 1347 const viz::BeginFrameArgs& args) override { 1348 if (!host_impl->pending_tree() || 1349 host_impl->pending_tree()->source_frame_number() != 2) 1350 return; 1351 1352 frame_count_with_pending_tree_++; 1353 if (frame_count_with_pending_tree_ == 2) { 1354 host_impl->BlockNotifyReadyToActivateForTesting(false); 1355 } 1356 } 1357 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)1358 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 1359 bool has_unfinished_animation) override { 1360 scoped_refptr<AnimationTimeline> timeline_impl = 1361 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 1362 scoped_refptr<Animation> animation_impl = 1363 timeline_impl->GetAnimationById(animation_id_); 1364 scoped_refptr<Animation> animation_child_impl = 1365 timeline_impl->GetAnimationById(animation_child_id_); 1366 1367 // wait for tree activation. 1368 if (!animation_impl->element_animations()) 1369 return; 1370 1371 KeyframeModel* root_keyframe_model = 1372 animation_impl->GetKeyframeModel(TargetProperty::OPACITY); 1373 if (!root_keyframe_model || 1374 root_keyframe_model->run_state() != KeyframeModel::RUNNING) 1375 return; 1376 1377 KeyframeModel* child_keyframe_model = 1378 animation_child_impl->GetKeyframeModel(TargetProperty::OPACITY); 1379 EXPECT_EQ(KeyframeModel::RUNNING, child_keyframe_model->run_state()); 1380 EXPECT_EQ(root_keyframe_model->start_time(), 1381 child_keyframe_model->start_time()); 1382 animation_impl->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY, 1383 false); 1384 animation_impl->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM, 1385 false); 1386 animation_child_impl->AbortKeyframeModelsWithProperty( 1387 TargetProperty::OPACITY, false); 1388 EndTest(); 1389 } 1390 1391 private: 1392 scoped_refptr<Layer> layer_; 1393 int frame_count_with_pending_tree_; 1394 }; 1395 1396 // This test blocks activation which is not supported for single thread mode. 1397 MULTI_THREAD_BLOCKNOTIFY_TEST_F( 1398 LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers); 1399 1400 class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit 1401 : public LayerTreeHostAnimationTest { 1402 public: SetupTree()1403 void SetupTree() override { 1404 LayerTreeHostAnimationTest::SetupTree(); 1405 1406 layer_ = FakePictureLayer::Create(&client_); 1407 layer_->SetBounds(gfx::Size(2, 2)); 1408 client_.set_bounds(layer_->bounds()); 1409 // Transform the layer to 4,4 to start. 1410 gfx::Transform start_transform; 1411 start_transform.Translate(4.0, 4.0); 1412 layer_->SetTransform(start_transform); 1413 1414 layer_tree_host()->root_layer()->AddChild(layer_); 1415 layer_tree_host()->SetElementIdsForTesting(); 1416 1417 animation_->AttachElement(layer_->element_id()); 1418 1419 AttachAnimationsToTimeline(); 1420 } 1421 BeginTest()1422 void BeginTest() override { 1423 // Add a translate from 6,7 to 8,9. 1424 TransformOperations start; 1425 start.AppendTranslate(6.f, 7.f, 0.f); 1426 TransformOperations end; 1427 end.AppendTranslate(8.f, 9.f, 0.f); 1428 AddAnimatedTransformToAnimation(animation_.get(), 4.0, start, end); 1429 1430 PostSetNeedsCommitToMainThread(); 1431 } 1432 WillPrepareTilesOnThread(LayerTreeHostImpl * host_impl)1433 void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { 1434 // After activating the sync tree PrepareTiles will be called 1435 // again (which races with the test exiting). 1436 LayerTreeImpl* sync_tree = host_impl->sync_tree(); 1437 if (!sync_tree || TestEnded()) 1438 return; 1439 1440 if (sync_tree->source_frame_number() != 0) 1441 return; 1442 1443 scoped_refptr<AnimationTimeline> timeline_impl = 1444 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 1445 scoped_refptr<Animation> animation_impl = 1446 timeline_impl->GetAnimationById(animation_id_); 1447 1448 LayerImpl* child = sync_tree->LayerById(layer_->id()); 1449 KeyframeModel* keyframe_model = 1450 animation_impl->GetKeyframeModel(TargetProperty::TRANSFORM); 1451 1452 // The animation should be starting for the first frame. 1453 EXPECT_EQ(KeyframeModel::STARTING, keyframe_model->run_state()); 1454 1455 // And the transform should be propogated to the sync tree layer, at its 1456 // starting state which is 6,7. 1457 gfx::Transform expected_transform; 1458 expected_transform.Translate(6.0, 7.0); 1459 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, child->DrawTransform()); 1460 // And the sync tree layer should know it is animating. 1461 EXPECT_TRUE(child->screen_space_transform_is_animating()); 1462 1463 animation_impl->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM, 1464 false); 1465 EndTest(); 1466 } 1467 1468 FakeContentLayerClient client_; 1469 scoped_refptr<Layer> layer_; 1470 }; 1471 1472 SINGLE_AND_MULTI_THREAD_TEST_F( 1473 LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit); 1474 1475 // When a layer with an animation is removed from the tree and later re-added, 1476 // the animation should resume. 1477 class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded 1478 : public LayerTreeHostAnimationTest { 1479 public: SetupTree()1480 void SetupTree() override { 1481 LayerTreeHostAnimationTest::SetupTree(); 1482 layer_ = Layer::Create(); 1483 layer_->SetBounds(gfx::Size(4, 4)); 1484 layer_tree_host()->root_layer()->AddChild(layer_); 1485 1486 layer_tree_host()->SetElementIdsForTesting(); 1487 1488 animation_host()->AddAnimationTimeline(timeline_.get()); 1489 timeline_->AttachAnimation(animation_.get()); 1490 animation_->AttachElement(layer_->element_id()); 1491 DCHECK(animation_->element_animations()); 1492 1493 AddOpacityTransitionToAnimation(animation_.get(), 10000.0, 0.1f, 0.9f, 1494 true); 1495 } 1496 BeginTest()1497 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1498 DidCommit()1499 void DidCommit() override { 1500 switch (layer_tree_host()->SourceFrameNumber()) { 1501 case 0: 1502 EXPECT_TRUE( 1503 animation_->element_animations()->has_element_in_active_list()); 1504 EXPECT_FALSE( 1505 animation_->element_animations()->has_element_in_pending_list()); 1506 EXPECT_TRUE(animation_host()->NeedsTickAnimations()); 1507 break; 1508 case 1: 1509 layer_->RemoveFromParent(); 1510 EXPECT_FALSE( 1511 animation_->element_animations()->has_element_in_active_list()); 1512 EXPECT_FALSE( 1513 animation_->element_animations()->has_element_in_pending_list()); 1514 // Animations still need one more tick to deliver finished event. 1515 EXPECT_TRUE(animation_host()->NeedsTickAnimations()); 1516 break; 1517 case 2: 1518 EXPECT_FALSE(animation_host()->NeedsTickAnimations()); 1519 layer_tree_host()->root_layer()->AddChild(layer_); 1520 EXPECT_TRUE( 1521 animation_->element_animations()->has_element_in_active_list()); 1522 EXPECT_FALSE( 1523 animation_->element_animations()->has_element_in_pending_list()); 1524 EXPECT_TRUE(animation_host()->NeedsTickAnimations()); 1525 break; 1526 } 1527 } 1528 DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1529 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { 1530 scoped_refptr<AnimationTimeline> timeline_impl = 1531 GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); 1532 scoped_refptr<Animation> animation_impl = 1533 timeline_impl->GetAnimationById(animation_id_); 1534 1535 switch (host_impl->active_tree()->source_frame_number()) { 1536 case 0: 1537 EXPECT_TRUE( 1538 animation_impl->element_animations()->has_element_in_active_list()); 1539 EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsTickAnimations()); 1540 break; 1541 case 1: 1542 EXPECT_FALSE( 1543 animation_impl->element_animations()->has_element_in_active_list()); 1544 // Having updated state on the host_impl during the commit, we no longer 1545 // need to tick animations. 1546 EXPECT_FALSE(GetImplAnimationHost(host_impl)->NeedsTickAnimations()); 1547 break; 1548 case 2: 1549 EXPECT_TRUE( 1550 animation_impl->element_animations()->has_element_in_active_list()); 1551 EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsTickAnimations()); 1552 EndTest(); 1553 break; 1554 } 1555 } 1556 1557 private: 1558 scoped_refptr<Layer> layer_; 1559 }; 1560 1561 SINGLE_AND_MULTI_THREAD_TEST_F( 1562 LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded); 1563 1564 class LayerTreeHostAnimationTestAddKeyframeModelAfterAnimating 1565 : public LayerTreeHostAnimationTest { 1566 public: SetupTree()1567 void SetupTree() override { 1568 LayerTreeHostAnimationTest::SetupTree(); 1569 layer_ = Layer::Create(); 1570 layer_->SetBounds(gfx::Size(4, 4)); 1571 layer_tree_host()->root_layer()->AddChild(layer_); 1572 child_layer_ = Layer::Create(); 1573 child_layer_->SetBounds(gfx::Size(4, 4)); 1574 layer_->AddChild(child_layer_); 1575 1576 AttachAnimationsToTimeline(); 1577 1578 animation_->AttachElement(layer_->element_id()); 1579 animation_child_->AttachElement(child_layer_->element_id()); 1580 } 1581 BeginTest()1582 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1583 DidCommit()1584 void DidCommit() override { 1585 switch (layer_tree_host()->SourceFrameNumber()) { 1586 case 1: 1587 // First frame: add an animation to the root layer. 1588 AddAnimatedTransformToAnimation(animation_.get(), 0.1, 5, 5); 1589 break; 1590 case 2: 1591 // Second frame: add an animation to the content layer. The root layer 1592 // animation has caused us to animate already during this frame. 1593 AddOpacityTransitionToAnimation(animation_child_.get(), 0.1, 5, 5, 1594 false); 1595 break; 1596 } 1597 } 1598 DrawLayersOnThread(LayerTreeHostImpl * host_impl)1599 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 1600 // After both animations have started, verify that they have valid 1601 // start times. 1602 if (host_impl->active_tree()->source_frame_number() < 2) 1603 return; 1604 1605 // Animation state is updated after drawing. Only do this once. 1606 if (!TestEnded()) { 1607 ImplThreadTaskRunner()->PostTask( 1608 FROM_HERE, 1609 base::BindOnce( 1610 &LayerTreeHostAnimationTestAddKeyframeModelAfterAnimating:: 1611 CheckAnimations, 1612 base::Unretained(this), host_impl)); 1613 } 1614 } 1615 CheckAnimations(LayerTreeHostImpl * host_impl)1616 void CheckAnimations(LayerTreeHostImpl* host_impl) { 1617 GetImplTimelineAndAnimationByID(*host_impl); 1618 1619 EXPECT_EQ(2u, GetImplAnimationHost(host_impl) 1620 ->ticking_animations_for_testing() 1621 .size()); 1622 1623 KeyframeModel* root_anim = 1624 animation_impl_->GetKeyframeModel(TargetProperty::TRANSFORM); 1625 EXPECT_LT(base::TimeTicks(), root_anim->start_time()); 1626 1627 KeyframeModel* anim = 1628 animation_child_impl_->GetKeyframeModel(TargetProperty::OPACITY); 1629 EXPECT_LT(base::TimeTicks(), anim->start_time()); 1630 1631 EndTest(); 1632 } 1633 1634 private: 1635 scoped_refptr<Layer> layer_; 1636 scoped_refptr<Layer> child_layer_; 1637 }; 1638 1639 SINGLE_AND_MULTI_THREAD_TEST_F( 1640 LayerTreeHostAnimationTestAddKeyframeModelAfterAnimating); 1641 1642 class LayerTreeHostAnimationTestRemoveKeyframeModel 1643 : public LayerTreeHostAnimationTest { 1644 public: SetupTree()1645 void SetupTree() override { 1646 LayerTreeHostAnimationTest::SetupTree(); 1647 layer_ = FakePictureLayer::Create(&client_); 1648 layer_->SetBounds(gfx::Size(4, 4)); 1649 client_.set_bounds(layer_->bounds()); 1650 layer_tree_host()->root_layer()->AddChild(layer_); 1651 1652 AttachAnimationsToTimeline(); 1653 1654 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 1655 animation_child_->AttachElement(layer_->element_id()); 1656 } 1657 BeginTest()1658 void BeginTest() override { 1659 animation_stopped_ = false; 1660 last_frame_number_ = INT_MAX; 1661 PostSetNeedsCommitToMainThread(); 1662 } 1663 DidCommit()1664 void DidCommit() override { 1665 switch (layer_tree_host()->SourceFrameNumber()) { 1666 case 1: 1667 AddAnimatedTransformToAnimation(animation_child_.get(), 1.0, 5, 5); 1668 break; 1669 case 2: 1670 KeyframeModel* keyframe_model = 1671 animation_child_->GetKeyframeModel(TargetProperty::TRANSFORM); 1672 animation_child_->RemoveKeyframeModel(keyframe_model->id()); 1673 gfx::Transform transform; 1674 transform.Translate(10.f, 10.f); 1675 layer_->SetTransform(transform); 1676 1677 // Do something that causes property trees to get rebuilt. This is 1678 // intended to simulate the conditions that caused the bug whose fix 1679 // this is testing (the test will pass without it but won't test what 1680 // we want it to). We were updating the wrong transform node at the end 1681 // of an animation (we were assuming the layer with the finished 1682 // animation still had its own transform node). But nodes can only get 1683 // added/deleted when something triggers a rebuild. Adding a layer 1684 // triggers a rebuild, and since the layer that had an animation before 1685 // no longer has one, it doesn't get a transform node in the rebuild. 1686 layer_->AddChild(Layer::Create()); 1687 break; 1688 } 1689 } 1690 DrawLayersOnThread(LayerTreeHostImpl * host_impl)1691 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 1692 GetImplTimelineAndAnimationByID(*host_impl); 1693 LayerImpl* child = host_impl->active_tree()->LayerById(layer_->id()); 1694 switch (host_impl->active_tree()->source_frame_number()) { 1695 case 0: 1696 // No animation yet. 1697 break; 1698 case 1: 1699 // Animation is started. 1700 EXPECT_TRUE(child->screen_space_transform_is_animating()); 1701 break; 1702 case 2: { 1703 // The animation is stopped, the transform that was set afterward is 1704 // applied. 1705 gfx::Transform expected_transform; 1706 expected_transform.Translate(10.f, 10.f); 1707 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 1708 child->DrawTransform()); 1709 EXPECT_FALSE(child->screen_space_transform_is_animating()); 1710 animation_stopped_ = true; 1711 PostSetNeedsCommitToMainThread(); 1712 break; 1713 } 1714 } 1715 } 1716 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1717 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1718 if (host_impl->sync_tree()->source_frame_number() >= last_frame_number_) { 1719 // Check that eventually the animation is removed. 1720 EXPECT_FALSE( 1721 animation_child_impl_->keyframe_effect()->has_any_keyframe_model()); 1722 EndTest(); 1723 } 1724 } 1725 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)1726 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 1727 bool has_unfinished_animation) override { 1728 // Non impl only animations are removed during commit. After the animation 1729 // is fully stopped on compositor thread, make sure another commit happens. 1730 if (animation_stopped_ && !has_unfinished_animation) { 1731 last_frame_number_ = 1732 std::min(last_frame_number_, 1733 host_impl->active_tree()->source_frame_number() + 1); 1734 PostSetNeedsCommitToMainThread(); 1735 } 1736 } 1737 1738 private: 1739 scoped_refptr<Layer> layer_; 1740 FakeContentLayerClient client_; 1741 1742 int last_frame_number_; 1743 bool animation_stopped_; 1744 }; 1745 1746 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestRemoveKeyframeModel); 1747 1748 class LayerTreeHostAnimationTestIsAnimating 1749 : public LayerTreeHostAnimationTest { 1750 public: SetupTree()1751 void SetupTree() override { 1752 LayerTreeHostAnimationTest::SetupTree(); 1753 layer_ = FakePictureLayer::Create(&client_); 1754 layer_->SetBounds(gfx::Size(4, 4)); 1755 client_.set_bounds(layer_->bounds()); 1756 layer_tree_host()->root_layer()->AddChild(layer_); 1757 1758 AttachAnimationsToTimeline(); 1759 animation_->AttachElement(layer_->element_id()); 1760 } 1761 BeginTest()1762 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1763 DidCommit()1764 void DidCommit() override { 1765 switch (layer_tree_host()->SourceFrameNumber()) { 1766 case 1: 1767 AddAnimatedTransformToAnimation(animation_.get(), 1.0, 5, 5); 1768 break; 1769 case 2: 1770 KeyframeModel* keyframe_model = 1771 animation_->GetKeyframeModel(TargetProperty::TRANSFORM); 1772 EXPECT_EQ(KeyframeModel::RunState::RUNNING, 1773 keyframe_model->run_state()); 1774 animation_->RemoveKeyframeModel(keyframe_model->id()); 1775 break; 1776 } 1777 } 1778 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1779 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1780 LayerImpl* child = host_impl->sync_tree()->LayerById(layer_->id()); 1781 switch (host_impl->sync_tree()->source_frame_number()) { 1782 case 0: 1783 // No animation yet. 1784 break; 1785 case 1: 1786 // Animation is started. 1787 EXPECT_TRUE(child->screen_space_transform_is_animating()); 1788 break; 1789 case 2: 1790 // The animation is removed/stopped. 1791 EXPECT_FALSE(child->screen_space_transform_is_animating()); 1792 break; 1793 case 3: 1794 break; 1795 default: 1796 NOTREACHED(); 1797 } 1798 } 1799 DidActivateTreeOnThread(LayerTreeHostImpl * host_impl)1800 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { 1801 GetImplTimelineAndAnimationByID(*host_impl); 1802 switch (host_impl->active_tree()->source_frame_number()) { 1803 case 0: 1804 // No animation yet. 1805 break; 1806 case 1: 1807 // Animation is starting. 1808 EXPECT_EQ(KeyframeModel::RunState::STARTING, 1809 animation_impl_->GetKeyframeModel(TargetProperty::TRANSFORM) 1810 ->run_state()); 1811 break; 1812 case 2: 1813 // After activation, the KeyframeModel should be waiting for deletion. 1814 EXPECT_EQ(KeyframeModel::RunState::WAITING_FOR_DELETION, 1815 animation_impl_->GetKeyframeModel(TargetProperty::TRANSFORM) 1816 ->run_state()); 1817 break; 1818 case 3: 1819 // The animation KeyframeModel is cleaned up. 1820 EXPECT_EQ(nullptr, 1821 animation_impl_->GetKeyframeModel(TargetProperty::TRANSFORM)); 1822 EndTest(); 1823 break; 1824 default: 1825 NOTREACHED(); 1826 } 1827 } 1828 DrawLayersOnThread(LayerTreeHostImpl * host_impl)1829 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 1830 LayerImpl* child = host_impl->active_tree()->LayerById(layer_->id()); 1831 switch (host_impl->active_tree()->source_frame_number()) { 1832 case 0: 1833 // No animation yet. 1834 break; 1835 case 1: 1836 // Animation is started. 1837 EXPECT_TRUE(child->screen_space_transform_is_animating()); 1838 break; 1839 case 2: 1840 case 3: 1841 // The animation is removed/stopped. 1842 EXPECT_FALSE(child->screen_space_transform_is_animating()); 1843 break; 1844 default: 1845 NOTREACHED(); 1846 } 1847 } 1848 1849 private: 1850 scoped_refptr<Layer> layer_; 1851 FakeContentLayerClient client_; 1852 }; 1853 1854 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestIsAnimating); 1855 1856 class LayerTreeHostAnimationTestAnimationFinishesDuringCommit 1857 : public LayerTreeHostAnimationTest { 1858 public: LayerTreeHostAnimationTestAnimationFinishesDuringCommit()1859 LayerTreeHostAnimationTestAnimationFinishesDuringCommit() 1860 : signalled_(false) {} 1861 SetupTree()1862 void SetupTree() override { 1863 LayerTreeHostAnimationTest::SetupTree(); 1864 layer_ = FakePictureLayer::Create(&client_); 1865 layer_->SetBounds(gfx::Size(4, 4)); 1866 client_.set_bounds(layer_->bounds()); 1867 layer_tree_host()->root_layer()->AddChild(layer_); 1868 1869 AttachAnimationsToTimeline(); 1870 1871 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 1872 animation_child_->AttachElement(layer_->element_id()); 1873 } 1874 BeginTest()1875 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1876 DidCommit()1877 void DidCommit() override { 1878 if (layer_tree_host()->SourceFrameNumber() == 1) 1879 AddAnimatedTransformToAnimation(animation_child_.get(), 0.04, 5, 5); 1880 } 1881 WillCommit()1882 void WillCommit() override { 1883 if (layer_tree_host()->SourceFrameNumber() == 2) { 1884 // Block until the animation finishes on the compositor thread. Since 1885 // animations have already been ticked on the main thread, when the commit 1886 // happens the state on the main thread will be consistent with having a 1887 // running animation but the state on the compositor thread will be 1888 // consistent with having only a finished animation. 1889 completion_.Wait(); 1890 } 1891 } 1892 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1893 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1894 switch (host_impl->sync_tree()->source_frame_number()) { 1895 case 1: 1896 PostSetNeedsCommitToMainThread(); 1897 break; 1898 case 2: 1899 gfx::Transform expected_transform; 1900 expected_transform.Translate(5.f, 5.f); 1901 LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); 1902 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 1903 layer_impl->DrawTransform()); 1904 EndTest(); 1905 break; 1906 } 1907 } 1908 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)1909 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 1910 bool has_unfinished_animation) override { 1911 if (host_impl->active_tree()->source_frame_number() == 1 && 1912 !has_unfinished_animation && !signalled_) { 1913 // The animation has finished, so allow the main thread to commit. 1914 completion_.Signal(); 1915 signalled_ = true; 1916 } 1917 } 1918 1919 private: 1920 scoped_refptr<Layer> layer_; 1921 FakeContentLayerClient client_; 1922 CompletionEvent completion_; 1923 bool signalled_; 1924 }; 1925 1926 // An animation finishing during commit can only happen when we have a separate 1927 // compositor thread. 1928 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationFinishesDuringCommit); 1929 1930 class LayerTreeHostAnimationTestImplSideInvalidation 1931 : public LayerTreeHostAnimationTest { 1932 public: SetupTree()1933 void SetupTree() override { 1934 LayerTreeHostAnimationTest::SetupTree(); 1935 layer_ = FakePictureLayer::Create(&client_); 1936 layer_->SetBounds(gfx::Size(4, 4)); 1937 client_.set_bounds(layer_->bounds()); 1938 layer_tree_host()->root_layer()->AddChild(layer_); 1939 1940 AttachAnimationsToTimeline(); 1941 1942 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 1943 animation_child_->AttachElement(layer_->element_id()); 1944 } 1945 BeginTest()1946 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 1947 DidCommit()1948 void DidCommit() override { 1949 if (layer_tree_host()->SourceFrameNumber() == 1) 1950 AddAnimatedTransformToAnimation(animation_child_.get(), 0.04, 5, 5); 1951 } 1952 WillCommit()1953 void WillCommit() override { 1954 if (layer_tree_host()->SourceFrameNumber() == 2) { 1955 // Block until the animation finishes on the compositor thread. Since 1956 // animations have already been ticked on the main thread, when the commit 1957 // happens the state on the main thread will be consistent with having a 1958 // running animation but the state on the compositor thread will be 1959 // consistent with having only a finished animation. 1960 completion_.Wait(); 1961 } 1962 } 1963 DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)1964 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 1965 DCHECK(did_request_impl_side_invalidation_); 1966 completion_.Signal(); 1967 } 1968 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)1969 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 1970 bool has_unfinished_animation) override { 1971 if (host_impl->active_tree()->source_frame_number() == 1 && 1972 !has_unfinished_animation && !did_request_impl_side_invalidation_) { 1973 // The animation on the active tree has finished, now request an impl-side 1974 // invalidation and make sure it finishes before the main thread is 1975 // released. 1976 did_request_impl_side_invalidation_ = true; 1977 host_impl->RequestImplSideInvalidationForCheckerImagedTiles(); 1978 } 1979 } 1980 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)1981 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 1982 switch (host_impl->sync_tree()->source_frame_number()) { 1983 case 1: 1984 PostSetNeedsCommitToMainThread(); 1985 break; 1986 case 2: 1987 gfx::Transform expected_transform; 1988 expected_transform.Translate(5.f, 5.f); 1989 LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); 1990 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 1991 layer_impl->DrawTransform()); 1992 EndTest(); 1993 break; 1994 } 1995 } 1996 1997 private: 1998 scoped_refptr<Layer> layer_; 1999 FakeContentLayerClient client_; 2000 CompletionEvent completion_; 2001 bool did_request_impl_side_invalidation_ = false; 2002 }; 2003 2004 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestImplSideInvalidation); 2005 2006 class LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit 2007 : public LayerTreeHostAnimationTest { 2008 public: SetupTree()2009 void SetupTree() override { 2010 LayerTreeHostAnimationTest::SetupTree(); 2011 layer_ = FakePictureLayer::Create(&client_); 2012 layer_->SetBounds(gfx::Size(4, 4)); 2013 client_.set_bounds(layer_->bounds()); 2014 layer_tree_host()->root_layer()->AddChild(layer_); 2015 AttachAnimationsToTimeline(); 2016 animation_child_->AttachElement(layer_->element_id()); 2017 num_draws_ = 0; 2018 } 2019 UpdateAnimationState(LayerTreeHostImpl * host_impl,bool has_unfinished_animation)2020 void UpdateAnimationState(LayerTreeHostImpl* host_impl, 2021 bool has_unfinished_animation) override { 2022 if (!has_unfinished_animation && !did_request_impl_side_invalidation_) { 2023 // The animation on the active tree has finished, now request an impl-side 2024 // invalidation and verify that the final value on an impl-side pending 2025 // tree is correct. 2026 did_request_impl_side_invalidation_ = true; 2027 host_impl->RequestImplSideInvalidationForCheckerImagedTiles(); 2028 } 2029 } DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2030 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 2031 completion_.Signal(); 2032 EndTest(); 2033 } 2034 WillCommit()2035 void WillCommit() override { 2036 if (layer_tree_host()->SourceFrameNumber() == 1) { 2037 // Block until the invalidation is done after animation finishes on the 2038 // compositor thread. We need to make sure the pending tree has valid 2039 // information based on invalidation only. 2040 completion_.Wait(); 2041 } 2042 } 2043 2044 protected: 2045 scoped_refptr<Layer> layer_; 2046 FakeContentLayerClient client_; 2047 bool did_request_impl_side_invalidation_ = false; 2048 int num_draws_; 2049 2050 private: 2051 CompletionEvent completion_; 2052 }; 2053 2054 class ImplSideInvalidationWithoutCommitTestOpacity 2055 : public LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit { 2056 public: BeginTest()2057 void BeginTest() override { 2058 AddOpacityTransitionToAnimation(animation_child_.get(), 0.04, 0.2f, 0.8f, 2059 false); 2060 PostSetNeedsCommitToMainThread(); 2061 } 2062 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2063 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2064 if (num_draws_++ > 0) 2065 return; 2066 EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); 2067 LayerImpl* layer_impl = host_impl->active_tree()->LayerById(layer_->id()); 2068 EXPECT_FLOAT_EQ(0.2f, layer_impl->Opacity()); 2069 } 2070 DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2071 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 2072 ASSERT_TRUE(did_request_impl_side_invalidation_); 2073 EXPECT_EQ(0, host_impl->sync_tree()->source_frame_number()); 2074 const float expected_opacity = 0.8f; 2075 LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); 2076 EXPECT_FLOAT_EQ(expected_opacity, layer_impl->Opacity()); 2077 LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit:: 2078 DidInvalidateContentOnImplSide(host_impl); 2079 } 2080 }; 2081 2082 MULTI_THREAD_TEST_F(ImplSideInvalidationWithoutCommitTestOpacity); 2083 2084 class ImplSideInvalidationWithoutCommitTestTransform 2085 : public LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit { 2086 public: BeginTest()2087 void BeginTest() override { 2088 AddAnimatedTransformToAnimation(animation_child_.get(), 0.04, 5, 5); 2089 PostSetNeedsCommitToMainThread(); 2090 } 2091 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2092 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2093 if (num_draws_++ > 0) 2094 return; 2095 EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); 2096 LayerImpl* layer_impl = host_impl->active_tree()->LayerById(layer_->id()); 2097 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), 2098 layer_impl->DrawTransform()); 2099 } 2100 DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2101 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 2102 ASSERT_TRUE(did_request_impl_side_invalidation_); 2103 EXPECT_EQ(0, host_impl->sync_tree()->source_frame_number()); 2104 gfx::Transform expected_transform; 2105 expected_transform.Translate(5.f, 5.f); 2106 LayerImpl* layer_impl = host_impl->sync_tree()->LayerById(layer_->id()); 2107 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, 2108 layer_impl->DrawTransform()); 2109 LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit:: 2110 DidInvalidateContentOnImplSide(host_impl); 2111 } 2112 }; 2113 2114 MULTI_THREAD_TEST_F(ImplSideInvalidationWithoutCommitTestTransform); 2115 2116 class ImplSideInvalidationWithoutCommitTestFilter 2117 : public LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit { 2118 public: BeginTest()2119 void BeginTest() override { 2120 AddAnimatedFilterToAnimation(animation_child_.get(), 0.04, 0.f, 1.f); 2121 PostSetNeedsCommitToMainThread(); 2122 } 2123 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2124 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2125 if (num_draws_++ > 0) 2126 return; 2127 EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); 2128 EXPECT_EQ( 2129 std::string("{\"FilterOperations\":[{\"type\":5,\"amount\":0.0}]}"), 2130 host_impl->active_tree() 2131 ->property_trees() 2132 ->effect_tree.FindNodeFromElementId(layer_->element_id()) 2133 ->filters.ToString()); 2134 } 2135 DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2136 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 2137 ASSERT_TRUE(did_request_impl_side_invalidation_); 2138 EXPECT_EQ(0, host_impl->sync_tree()->source_frame_number()); 2139 // AddAnimatedFilterToAnimation adds brightness filter which is type 5. 2140 EXPECT_EQ( 2141 std::string("{\"FilterOperations\":[{\"type\":5,\"amount\":1.0}]}"), 2142 host_impl->sync_tree() 2143 ->property_trees() 2144 ->effect_tree.FindNodeFromElementId(layer_->element_id()) 2145 ->filters.ToString()); 2146 LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit:: 2147 DidInvalidateContentOnImplSide(host_impl); 2148 } 2149 }; 2150 2151 MULTI_THREAD_TEST_F(ImplSideInvalidationWithoutCommitTestFilter); 2152 2153 class ImplSideInvalidationWithoutCommitTestScroll 2154 : public LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit { 2155 public: SetupTree()2156 void SetupTree() override { 2157 LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit::SetupTree(); 2158 2159 layer_->SetScrollable(gfx::Size(100, 100)); 2160 layer_->SetBounds(gfx::Size(1000, 1000)); 2161 client_.set_bounds(layer_->bounds()); 2162 layer_->SetScrollOffset(gfx::ScrollOffset(10.f, 20.f)); 2163 } 2164 BeginTest()2165 void BeginTest() override { 2166 std::unique_ptr<ScrollOffsetAnimationCurve> curve( 2167 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting( 2168 gfx::ScrollOffset(500.f, 550.f))); 2169 std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create( 2170 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); 2171 keyframe_model->set_needs_synchronized_start_time(true); 2172 ASSERT_TRUE(proxy()->SupportsImplScrolling()); 2173 animation_child_->AddKeyframeModel(std::move(keyframe_model)); 2174 PostSetNeedsCommitToMainThread(); 2175 } 2176 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2177 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2178 if (num_draws_++ > 0) 2179 return; 2180 EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); 2181 LayerImpl* layer_impl = host_impl->active_tree()->LayerById(layer_->id()); 2182 EXPECT_EQ(gfx::ScrollOffset(10.f, 20.f), CurrentScrollOffset(layer_impl)); 2183 } 2184 DidInvalidateContentOnImplSide(LayerTreeHostImpl * host_impl)2185 void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override { 2186 ASSERT_TRUE(did_request_impl_side_invalidation_); 2187 EXPECT_EQ(0, host_impl->sync_tree()->source_frame_number()); 2188 LayerImpl* layer_impl = host_impl->pending_tree()->LayerById(layer_->id()); 2189 EXPECT_EQ(gfx::ScrollOffset(500.f, 550.f), CurrentScrollOffset(layer_impl)); 2190 LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit:: 2191 DidInvalidateContentOnImplSide(host_impl); 2192 } 2193 }; 2194 2195 MULTI_THREAD_TEST_F(ImplSideInvalidationWithoutCommitTestScroll); 2196 2197 class LayerTreeHostAnimationTestNotifyAnimationFinished 2198 : public LayerTreeHostAnimationTest { 2199 public: LayerTreeHostAnimationTestNotifyAnimationFinished()2200 LayerTreeHostAnimationTestNotifyAnimationFinished() 2201 : called_animation_started_(false), called_animation_finished_(false) {} 2202 SetupTree()2203 void SetupTree() override { 2204 LayerTreeHostAnimationTest::SetupTree(); 2205 picture_ = FakePictureLayer::Create(&client_); 2206 picture_->SetBounds(gfx::Size(4, 4)); 2207 client_.set_bounds(picture_->bounds()); 2208 layer_tree_host()->root_layer()->AddChild(picture_); 2209 2210 AttachAnimationsToTimeline(); 2211 animation_->AttachElement(picture_->element_id()); 2212 animation_->set_animation_delegate(this); 2213 } 2214 BeginTest()2215 void BeginTest() override { 2216 PostAddOpacityAnimationToMainThreadDelayed(animation_.get()); 2217 } 2218 NotifyAnimationStarted(base::TimeTicks monotonic_time,int target_property,int group)2219 void NotifyAnimationStarted(base::TimeTicks monotonic_time, 2220 int target_property, 2221 int group) override { 2222 called_animation_started_ = true; 2223 layer_tree_host()->AnimateLayers(base::TimeTicks::Max()); 2224 PostSetNeedsCommitToMainThread(); 2225 } 2226 NotifyAnimationFinished(base::TimeTicks monotonic_time,int target_property,int group)2227 void NotifyAnimationFinished(base::TimeTicks monotonic_time, 2228 int target_property, 2229 int group) override { 2230 called_animation_finished_ = true; 2231 EndTest(); 2232 } 2233 AfterTest()2234 void AfterTest() override { 2235 EXPECT_TRUE(called_animation_started_); 2236 EXPECT_TRUE(called_animation_finished_); 2237 } 2238 2239 private: 2240 bool called_animation_started_; 2241 bool called_animation_finished_; 2242 FakeContentLayerClient client_; 2243 scoped_refptr<FakePictureLayer> picture_; 2244 }; 2245 2246 SINGLE_AND_MULTI_THREAD_TEST_F( 2247 LayerTreeHostAnimationTestNotifyAnimationFinished); 2248 2249 // Check that transform sync happens correctly at commit when we remove and add 2250 // a different animation animation to an element. 2251 class LayerTreeHostAnimationTestChangeAnimation 2252 : public LayerTreeHostAnimationTest { 2253 public: SetupTree()2254 void SetupTree() override { 2255 LayerTreeHostAnimationTest::SetupTree(); 2256 layer_ = Layer::Create(); 2257 layer_->SetBounds(gfx::Size(4, 4)); 2258 layer_tree_host()->root_layer()->AddChild(layer_); 2259 2260 AttachAnimationsToTimeline(); 2261 2262 timeline_->DetachAnimation(animation_child_.get()); 2263 animation_->AttachElement(layer_->element_id()); 2264 2265 TransformOperations start; 2266 start.AppendTranslate(5.f, 5.f, 0.f); 2267 TransformOperations end; 2268 end.AppendTranslate(5.f, 5.f, 0.f); 2269 AddAnimatedTransformToAnimation(animation_.get(), 1.0, start, end); 2270 } 2271 BeginTest()2272 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 2273 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2274 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 2275 PropertyTrees* property_trees = host_impl->sync_tree()->property_trees(); 2276 TransformNode* node = 2277 property_trees->transform_tree.Node(host_impl->sync_tree() 2278 ->LayerById(layer_->id()) 2279 ->transform_tree_index()); 2280 gfx::Transform translate; 2281 translate.Translate(5, 5); 2282 switch (host_impl->sync_tree()->source_frame_number()) { 2283 case 2: 2284 EXPECT_TRANSFORMATION_MATRIX_EQ(node->local, translate); 2285 EndTest(); 2286 break; 2287 default: 2288 break; 2289 } 2290 } 2291 DidCommit()2292 void DidCommit() override { PostSetNeedsCommitToMainThread(); } 2293 WillBeginMainFrame()2294 void WillBeginMainFrame() override { 2295 if (layer_tree_host()->SourceFrameNumber() == 2) { 2296 // Destroy animation. 2297 timeline_->DetachAnimation(animation_.get()); 2298 animation_ = nullptr; 2299 timeline_->AttachAnimation(animation_child_.get()); 2300 animation_child_->AttachElement(layer_->element_id()); 2301 AddAnimatedTransformToAnimation(animation_child_.get(), 1.0, 10, 10); 2302 KeyframeModel* keyframe_model = 2303 animation_child_->GetKeyframeModel(TargetProperty::TRANSFORM); 2304 keyframe_model->set_start_time(base::TimeTicks::Now() + 2305 base::TimeDelta::FromSecondsD(1000)); 2306 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); 2307 } 2308 } 2309 2310 private: 2311 scoped_refptr<Layer> layer_; 2312 }; 2313 2314 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestChangeAnimation); 2315 2316 // Check that SetTransformIsPotentiallyAnimatingChanged is called 2317 // if we destroy ElementAnimations. 2318 class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction 2319 : public LayerTreeHostAnimationTest { 2320 public: SetupTree()2321 void SetupTree() override { 2322 prev_screen_space_transform_is_animating_ = true; 2323 screen_space_transform_animation_stopped_ = false; 2324 2325 LayerTreeHostAnimationTest::SetupTree(); 2326 AttachAnimationsToTimeline(); 2327 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 2328 AddAnimatedTransformToAnimation(animation_.get(), 1.0, 5, 5); 2329 } 2330 BeginTest()2331 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 2332 CommitCompleteOnThread(LayerTreeHostImpl * host_impl)2333 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { 2334 if (host_impl->pending_tree()->source_frame_number() <= 1) { 2335 EXPECT_TRUE(host_impl->pending_tree() 2336 ->root_layer() 2337 ->screen_space_transform_is_animating()); 2338 } else { 2339 EXPECT_FALSE(host_impl->pending_tree() 2340 ->root_layer() 2341 ->screen_space_transform_is_animating()); 2342 } 2343 } 2344 DidCommit()2345 void DidCommit() override { PostSetNeedsCommitToMainThread(); } 2346 UpdateLayerTreeHost()2347 void UpdateLayerTreeHost() override { 2348 if (layer_tree_host()->SourceFrameNumber() == 2) { 2349 // Destroy animation. 2350 timeline_->DetachAnimation(animation_.get()); 2351 animation_ = nullptr; 2352 } 2353 } 2354 PrepareToDrawOnThread(LayerTreeHostImpl * host_impl,LayerTreeHostImpl::FrameData * frame_data,DrawResult draw_result)2355 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 2356 LayerTreeHostImpl::FrameData* frame_data, 2357 DrawResult draw_result) override { 2358 const bool screen_space_transform_is_animating = 2359 host_impl->active_tree() 2360 ->root_layer() 2361 ->screen_space_transform_is_animating(); 2362 2363 // Check that screen_space_transform_is_animating changes only once. 2364 if (screen_space_transform_is_animating && 2365 prev_screen_space_transform_is_animating_) 2366 EXPECT_FALSE(screen_space_transform_animation_stopped_); 2367 if (!screen_space_transform_is_animating && 2368 prev_screen_space_transform_is_animating_) { 2369 EXPECT_FALSE(screen_space_transform_animation_stopped_); 2370 screen_space_transform_animation_stopped_ = true; 2371 } 2372 if (!screen_space_transform_is_animating && 2373 !prev_screen_space_transform_is_animating_) 2374 EXPECT_TRUE(screen_space_transform_animation_stopped_); 2375 2376 prev_screen_space_transform_is_animating_ = 2377 screen_space_transform_is_animating; 2378 2379 return draw_result; 2380 } 2381 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2382 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2383 if (host_impl->active_tree()->source_frame_number() >= 2) 2384 EndTest(); 2385 } 2386 AfterTest()2387 void AfterTest() override { 2388 EXPECT_TRUE(screen_space_transform_animation_stopped_); 2389 } 2390 2391 bool prev_screen_space_transform_is_animating_; 2392 bool screen_space_transform_animation_stopped_; 2393 }; 2394 2395 MULTI_THREAD_TEST_F( 2396 LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction); 2397 2398 // Check that we invalidate property trees on Animation::SetNeedsCommit. 2399 class LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit 2400 : public LayerTreeHostAnimationTest { 2401 public: SetupTree()2402 void SetupTree() override { 2403 LayerTreeHostAnimationTest::SetupTree(); 2404 layer_ = FakePictureLayer::Create(&client_); 2405 layer_->SetBounds(gfx::Size(4, 4)); 2406 client_.set_bounds(layer_->bounds()); 2407 layer_tree_host()->root_layer()->AddChild(layer_); 2408 2409 AttachAnimationsToTimeline(); 2410 2411 animation_->AttachElement(layer_tree_host()->root_layer()->element_id()); 2412 animation_child_->AttachElement(layer_->element_id()); 2413 } 2414 BeginTest()2415 void BeginTest() override { PostSetNeedsCommitToMainThread(); } 2416 DidCommit()2417 void DidCommit() override { 2418 if (layer_tree_host()->SourceFrameNumber() == 1 || 2419 layer_tree_host()->SourceFrameNumber() == 2) 2420 PostSetNeedsCommitToMainThread(); 2421 } 2422 UpdateLayerTreeHost()2423 void UpdateLayerTreeHost() override { 2424 if (layer_tree_host()->SourceFrameNumber() == 1) 2425 AddAnimatedTransformToAnimation(animation_child_.get(), 1.0, 5, 5); 2426 EXPECT_TRUE(layer_tree_host()->proxy()->CommitRequested()); 2427 } 2428 DrawLayersOnThread(LayerTreeHostImpl * host_impl)2429 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { 2430 if (host_impl->active_tree()->source_frame_number() >= 2) 2431 EndTest(); 2432 } 2433 2434 private: 2435 scoped_refptr<Layer> layer_; 2436 FakeContentLayerClient client_; 2437 }; 2438 2439 MULTI_THREAD_TEST_F( 2440 LayerTreeHostAnimationTestRebuildPropertyTreesOnAnimationSetNeedsCommit); 2441 2442 } // namespace 2443 } // namespace cc 2444