| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cc/trees/layer_tree_host.h" | |
| 6 | |
| 7 #include "cc/animation/animation_curve.h" | |
| 8 #include "cc/animation/animation_host.h" | |
| 9 #include "cc/animation/animation_id_provider.h" | |
| 10 #include "cc/animation/animation_player.h" | |
| 11 #include "cc/animation/animation_timeline.h" | |
| 12 #include "cc/animation/element_animations.h" | |
| 13 #include "cc/animation/layer_animation_controller.h" | |
| 14 #include "cc/animation/scroll_offset_animation_curve.h" | |
| 15 #include "cc/animation/timing_function.h" | |
| 16 #include "cc/base/completion_event.h" | |
| 17 #include "cc/base/time_util.h" | |
| 18 #include "cc/layers/layer.h" | |
| 19 #include "cc/layers/layer_impl.h" | |
| 20 #include "cc/test/animation_test_common.h" | |
| 21 #include "cc/test/fake_content_layer_client.h" | |
| 22 #include "cc/test/fake_picture_layer.h" | |
| 23 #include "cc/test/layer_tree_test.h" | |
| 24 #include "cc/trees/layer_tree_impl.h" | |
| 25 | |
| 26 namespace cc { | |
| 27 namespace { | |
| 28 | |
| 29 class LayerTreeHostTimelinesTest : public LayerTreeTest { | |
| 30 public: | |
| 31 LayerTreeHostTimelinesTest() | |
| 32 : timeline_id_(AnimationIdProvider::NextTimelineId()), | |
| 33 player_id_(AnimationIdProvider::NextPlayerId()), | |
| 34 player_child_id_(AnimationIdProvider::NextPlayerId()) { | |
| 35 timeline_ = AnimationTimeline::Create(timeline_id_); | |
| 36 player_ = AnimationPlayer::Create(player_id_); | |
| 37 player_child_ = AnimationPlayer::Create(player_child_id_); | |
| 38 | |
| 39 player_->set_layer_animation_delegate(this); | |
| 40 } | |
| 41 | |
| 42 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 43 settings->use_compositor_animation_timelines = true; | |
| 44 } | |
| 45 | |
| 46 void InitializeLayerSettings(LayerSettings* layer_settings) override { | |
| 47 layer_settings->use_compositor_animation_timelines = true; | |
| 48 } | |
| 49 | |
| 50 void SetupTree() override { LayerTreeTest::SetupTree(); } | |
| 51 | |
| 52 void AttachPlayersToTimeline() { | |
| 53 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get()); | |
| 54 timeline_->AttachPlayer(player_.get()); | |
| 55 timeline_->AttachPlayer(player_child_.get()); | |
| 56 } | |
| 57 | |
| 58 protected: | |
| 59 scoped_refptr<AnimationTimeline> timeline_; | |
| 60 scoped_refptr<AnimationPlayer> player_; | |
| 61 scoped_refptr<AnimationPlayer> player_child_; | |
| 62 | |
| 63 const int timeline_id_; | |
| 64 const int player_id_; | |
| 65 const int player_child_id_; | |
| 66 }; | |
| 67 | |
| 68 // Add a layer animation and confirm that | |
| 69 // LayerTreeHostImpl::UpdateAnimationState does get called. | |
| 70 // Evolved from LayerTreeHostAnimationTestAddAnimation | |
| 71 class LayerTreeHostTimelinesTestAddAnimation | |
| 72 : public LayerTreeHostTimelinesTest { | |
| 73 public: | |
| 74 LayerTreeHostTimelinesTestAddAnimation() | |
| 75 : update_animation_state_was_called_(false) {} | |
| 76 | |
| 77 void BeginTest() override { | |
| 78 AttachPlayersToTimeline(); | |
| 79 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 80 PostAddInstantAnimationToMainThreadPlayer(player_.get()); | |
| 81 } | |
| 82 | |
| 83 void UpdateAnimationState(LayerTreeHostImpl* host_impl, | |
| 84 bool has_unfinished_animation) override { | |
| 85 EXPECT_FALSE(has_unfinished_animation); | |
| 86 update_animation_state_was_called_ = true; | |
| 87 } | |
| 88 | |
| 89 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
| 90 TargetProperty::Type target_property, | |
| 91 int group) override { | |
| 92 EXPECT_LT(base::TimeTicks(), monotonic_time); | |
| 93 | |
| 94 LayerAnimationController* controller = | |
| 95 player_->element_animations()->layer_animation_controller(); | |
| 96 Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); | |
| 97 if (animation) | |
| 98 player_->RemoveAnimation(animation->id()); | |
| 99 | |
| 100 EndTest(); | |
| 101 } | |
| 102 | |
| 103 void AfterTest() override { EXPECT_TRUE(update_animation_state_was_called_); } | |
| 104 | |
| 105 private: | |
| 106 bool update_animation_state_was_called_; | |
| 107 }; | |
| 108 | |
| 109 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAddAnimation); | |
| 110 | |
| 111 // Add a layer animation to a layer, but continually fail to draw. Confirm that | |
| 112 // after a while, we do eventually force a draw. | |
| 113 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws. | |
| 114 class LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws | |
| 115 : public LayerTreeHostTimelinesTest { | |
| 116 public: | |
| 117 LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws() | |
| 118 : started_animating_(false) {} | |
| 119 | |
| 120 void BeginTest() override { | |
| 121 AttachPlayersToTimeline(); | |
| 122 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 123 PostAddAnimationToMainThreadPlayer(player_.get()); | |
| 124 } | |
| 125 | |
| 126 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
| 127 base::TimeTicks monotonic_time) override { | |
| 128 started_animating_ = true; | |
| 129 } | |
| 130 | |
| 131 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 132 if (started_animating_) | |
| 133 EndTest(); | |
| 134 } | |
| 135 | |
| 136 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 137 LayerTreeHostImpl::FrameData* frame, | |
| 138 DrawResult draw_result) override { | |
| 139 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; | |
| 140 } | |
| 141 | |
| 142 void AfterTest() override {} | |
| 143 | |
| 144 private: | |
| 145 bool started_animating_; | |
| 146 }; | |
| 147 | |
| 148 // Starvation can only be an issue with the MT compositor. | |
| 149 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestCheckerboardDoesNotStarveDraws); | |
| 150 | |
| 151 // Ensures that animations eventually get deleted. | |
| 152 // Evolved from LayerTreeHostAnimationTestAnimationsGetDeleted. | |
| 153 class LayerTreeHostTimelinesTestAnimationsGetDeleted | |
| 154 : public LayerTreeHostTimelinesTest { | |
| 155 public: | |
| 156 LayerTreeHostTimelinesTestAnimationsGetDeleted() | |
| 157 : started_animating_(false) {} | |
| 158 | |
| 159 void BeginTest() override { | |
| 160 AttachPlayersToTimeline(); | |
| 161 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 162 PostAddAnimationToMainThreadPlayer(player_.get()); | |
| 163 } | |
| 164 | |
| 165 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
| 166 base::TimeTicks monotonic_time) override { | |
| 167 bool have_animations = !host_impl->animation_host() | |
| 168 ->animation_registrar() | |
| 169 ->active_animation_controllers_for_testing() | |
| 170 .empty(); | |
| 171 if (!started_animating_ && have_animations) { | |
| 172 started_animating_ = true; | |
| 173 return; | |
| 174 } | |
| 175 | |
| 176 if (started_animating_ && !have_animations) | |
| 177 EndTest(); | |
| 178 } | |
| 179 | |
| 180 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
| 181 TargetProperty::Type target_property, | |
| 182 int group) override { | |
| 183 // Animations on the impl-side controller only get deleted during a commit, | |
| 184 // so we need to schedule a commit. | |
| 185 layer_tree_host()->SetNeedsCommit(); | |
| 186 } | |
| 187 | |
| 188 void AfterTest() override {} | |
| 189 | |
| 190 private: | |
| 191 bool started_animating_; | |
| 192 }; | |
| 193 | |
| 194 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationsGetDeleted); | |
| 195 | |
| 196 // Ensure that an animation's timing function is respected. | |
| 197 // Evolved from LayerTreeHostAnimationTestAddAnimationWithTimingFunction. | |
| 198 class LayerTreeHostTimelinesTestAddAnimationWithTimingFunction | |
| 199 : public LayerTreeHostTimelinesTest { | |
| 200 public: | |
| 201 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction() {} | |
| 202 | |
| 203 void SetupTree() override { | |
| 204 LayerTreeHostTimelinesTest::SetupTree(); | |
| 205 picture_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 206 picture_->SetBounds(gfx::Size(4, 4)); | |
| 207 client_.set_bounds(picture_->bounds()); | |
| 208 layer_tree_host()->root_layer()->AddChild(picture_); | |
| 209 | |
| 210 AttachPlayersToTimeline(); | |
| 211 player_child_->AttachLayer(picture_->id()); | |
| 212 } | |
| 213 | |
| 214 void BeginTest() override { | |
| 215 PostAddAnimationToMainThreadPlayer(player_child_.get()); | |
| 216 } | |
| 217 | |
| 218 void AnimateLayers(LayerTreeHostImpl* host_impl, | |
| 219 base::TimeTicks monotonic_time) override { | |
| 220 // Wait for the commit with the animation to happen. | |
| 221 if (host_impl->sync_tree()->source_frame_number() != 0) | |
| 222 return; | |
| 223 | |
| 224 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 225 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 226 scoped_refptr<AnimationPlayer> player_child_impl = | |
| 227 timeline_impl->GetPlayerById(player_child_id_); | |
| 228 | |
| 229 LayerAnimationController* controller_impl = | |
| 230 player_child_impl->element_animations()->layer_animation_controller(); | |
| 231 Animation* animation = | |
| 232 controller_impl->GetAnimation(TargetProperty::OPACITY); | |
| 233 | |
| 234 const FloatAnimationCurve* curve = | |
| 235 animation->curve()->ToFloatAnimationCurve(); | |
| 236 float start_opacity = curve->GetValue(base::TimeDelta()); | |
| 237 float end_opacity = curve->GetValue(curve->Duration()); | |
| 238 float linearly_interpolated_opacity = | |
| 239 0.25f * end_opacity + 0.75f * start_opacity; | |
| 240 base::TimeDelta time = TimeUtil::Scale(curve->Duration(), 0.25f); | |
| 241 // If the linear timing function associated with this animation was not | |
| 242 // picked up, then the linearly interpolated opacity would be different | |
| 243 // because of the default ease timing function. | |
| 244 EXPECT_FLOAT_EQ(linearly_interpolated_opacity, curve->GetValue(time)); | |
| 245 | |
| 246 EndTest(); | |
| 247 } | |
| 248 | |
| 249 void AfterTest() override {} | |
| 250 | |
| 251 FakeContentLayerClient client_; | |
| 252 scoped_refptr<FakePictureLayer> picture_; | |
| 253 }; | |
| 254 | |
| 255 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 256 LayerTreeHostTimelinesTestAddAnimationWithTimingFunction); | |
| 257 | |
| 258 // Ensures that main thread animations have their start times synchronized with | |
| 259 // impl thread animations. | |
| 260 // Evolved from LayerTreeHostAnimationTestSynchronizeAnimationStartTimes. | |
| 261 class LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes | |
| 262 : public LayerTreeHostTimelinesTest { | |
| 263 public: | |
| 264 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes() {} | |
| 265 | |
| 266 void SetupTree() override { | |
| 267 LayerTreeHostTimelinesTest::SetupTree(); | |
| 268 picture_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 269 picture_->SetBounds(gfx::Size(4, 4)); | |
| 270 client_.set_bounds(picture_->bounds()); | |
| 271 | |
| 272 layer_tree_host()->root_layer()->AddChild(picture_); | |
| 273 | |
| 274 AttachPlayersToTimeline(); | |
| 275 player_child_->set_layer_animation_delegate(this); | |
| 276 player_child_->AttachLayer(picture_->id()); | |
| 277 } | |
| 278 | |
| 279 void BeginTest() override { | |
| 280 PostAddAnimationToMainThreadPlayer(player_child_.get()); | |
| 281 } | |
| 282 | |
| 283 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
| 284 TargetProperty::Type target_property, | |
| 285 int group) override { | |
| 286 LayerAnimationController* controller = | |
| 287 player_child_->element_animations()->layer_animation_controller(); | |
| 288 Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); | |
| 289 main_start_time_ = animation->start_time(); | |
| 290 controller->RemoveAnimation(animation->id()); | |
| 291 EndTest(); | |
| 292 } | |
| 293 | |
| 294 void UpdateAnimationState(LayerTreeHostImpl* impl_host, | |
| 295 bool has_unfinished_animation) override { | |
| 296 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 297 impl_host->animation_host()->GetTimelineById(timeline_id_); | |
| 298 scoped_refptr<AnimationPlayer> player_child_impl = | |
| 299 timeline_impl->GetPlayerById(player_child_id_); | |
| 300 | |
| 301 LayerAnimationController* controller = | |
| 302 player_child_impl->element_animations()->layer_animation_controller(); | |
| 303 Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); | |
| 304 if (!animation) | |
| 305 return; | |
| 306 | |
| 307 impl_start_time_ = animation->start_time(); | |
| 308 } | |
| 309 | |
| 310 void AfterTest() override { | |
| 311 EXPECT_EQ(impl_start_time_, main_start_time_); | |
| 312 EXPECT_LT(base::TimeTicks(), impl_start_time_); | |
| 313 } | |
| 314 | |
| 315 private: | |
| 316 base::TimeTicks main_start_time_; | |
| 317 base::TimeTicks impl_start_time_; | |
| 318 FakeContentLayerClient client_; | |
| 319 scoped_refptr<FakePictureLayer> picture_; | |
| 320 }; | |
| 321 | |
| 322 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 323 LayerTreeHostTimelinesTestSynchronizeAnimationStartTimes); | |
| 324 | |
| 325 // Ensures that notify animation finished is called. | |
| 326 // Evolved from LayerTreeHostAnimationTestAnimationFinishedEvents. | |
| 327 class LayerTreeHostTimelinesTestAnimationFinishedEvents | |
| 328 : public LayerTreeHostTimelinesTest { | |
| 329 public: | |
| 330 LayerTreeHostTimelinesTestAnimationFinishedEvents() {} | |
| 331 | |
| 332 void BeginTest() override { | |
| 333 AttachPlayersToTimeline(); | |
| 334 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 335 PostAddInstantAnimationToMainThreadPlayer(player_.get()); | |
| 336 } | |
| 337 | |
| 338 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
| 339 TargetProperty::Type target_property, | |
| 340 int group) override { | |
| 341 LayerAnimationController* controller = | |
| 342 player_->element_animations()->layer_animation_controller(); | |
| 343 Animation* animation = controller->GetAnimation(TargetProperty::OPACITY); | |
| 344 if (animation) | |
| 345 controller->RemoveAnimation(animation->id()); | |
| 346 EndTest(); | |
| 347 } | |
| 348 | |
| 349 void AfterTest() override {} | |
| 350 }; | |
| 351 | |
| 352 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 353 LayerTreeHostTimelinesTestAnimationFinishedEvents); | |
| 354 | |
| 355 // Ensures that when opacity is being animated, this value does not cause the | |
| 356 // subtree to be skipped. | |
| 357 // Evolved from LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity. | |
| 358 class LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity | |
| 359 : public LayerTreeHostTimelinesTest { | |
| 360 public: | |
| 361 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity() | |
| 362 : update_check_layer_( | |
| 363 FakePictureLayer::Create(layer_settings(), &client_)) {} | |
| 364 | |
| 365 void SetupTree() override { | |
| 366 update_check_layer_->SetOpacity(0.f); | |
| 367 layer_tree_host()->SetRootLayer(update_check_layer_); | |
| 368 client_.set_bounds(update_check_layer_->bounds()); | |
| 369 LayerTreeHostTimelinesTest::SetupTree(); | |
| 370 | |
| 371 AttachPlayersToTimeline(); | |
| 372 player_->AttachLayer(update_check_layer_->id()); | |
| 373 } | |
| 374 | |
| 375 void BeginTest() override { | |
| 376 PostAddAnimationToMainThreadPlayer(player_.get()); | |
| 377 } | |
| 378 | |
| 379 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 380 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 381 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 382 scoped_refptr<AnimationPlayer> player_impl = | |
| 383 timeline_impl->GetPlayerById(player_id_); | |
| 384 | |
| 385 LayerAnimationController* controller_impl = | |
| 386 player_impl->element_animations()->layer_animation_controller(); | |
| 387 Animation* animation_impl = | |
| 388 controller_impl->GetAnimation(TargetProperty::OPACITY); | |
| 389 controller_impl->RemoveAnimation(animation_impl->id()); | |
| 390 EndTest(); | |
| 391 } | |
| 392 | |
| 393 void AfterTest() override { | |
| 394 // Update() should have been called once, proving that the layer was not | |
| 395 // skipped. | |
| 396 EXPECT_EQ(1, update_check_layer_->update_count()); | |
| 397 | |
| 398 // clear update_check_layer_ so LayerTreeHost dies. | |
| 399 update_check_layer_ = NULL; | |
| 400 } | |
| 401 | |
| 402 private: | |
| 403 FakeContentLayerClient client_; | |
| 404 scoped_refptr<FakePictureLayer> update_check_layer_; | |
| 405 }; | |
| 406 | |
| 407 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 408 LayerTreeHostTimelinesTestDoNotSkipLayersWithAnimatedOpacity); | |
| 409 | |
| 410 // Layers added to tree with existing active animations should have the | |
| 411 // animation correctly recognized. | |
| 412 // Evolved from LayerTreeHostAnimationTestLayerAddedWithAnimation. | |
| 413 class LayerTreeHostTimelinesTestLayerAddedWithAnimation | |
| 414 : public LayerTreeHostTimelinesTest { | |
| 415 public: | |
| 416 LayerTreeHostTimelinesTestLayerAddedWithAnimation() {} | |
| 417 | |
| 418 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 419 | |
| 420 void DidCommit() override { | |
| 421 if (layer_tree_host()->source_frame_number() == 1) { | |
| 422 AttachPlayersToTimeline(); | |
| 423 | |
| 424 scoped_refptr<Layer> layer = Layer::Create(layer_settings()); | |
| 425 player_->AttachLayer(layer->id()); | |
| 426 player_->set_layer_animation_delegate(this); | |
| 427 | |
| 428 // Any valid AnimationCurve will do here. | |
| 429 scoped_ptr<AnimationCurve> curve(new FakeFloatAnimationCurve()); | |
| 430 scoped_ptr<Animation> animation( | |
| 431 Animation::Create(std::move(curve), 1, 1, TargetProperty::OPACITY)); | |
| 432 player_->AddAnimation(std::move(animation)); | |
| 433 | |
| 434 // We add the animation *before* attaching the layer to the tree. | |
| 435 layer_tree_host()->root_layer()->AddChild(layer); | |
| 436 } | |
| 437 } | |
| 438 | |
| 439 void AnimateLayers(LayerTreeHostImpl* impl_host, | |
| 440 base::TimeTicks monotonic_time) override { | |
| 441 EndTest(); | |
| 442 } | |
| 443 | |
| 444 void AfterTest() override {} | |
| 445 }; | |
| 446 | |
| 447 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 448 LayerTreeHostTimelinesTestLayerAddedWithAnimation); | |
| 449 | |
| 450 // Animations should not be started when frames are being skipped due to | |
| 451 // checkerboard. | |
| 452 // Evolved from LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations. | |
| 453 class LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations | |
| 454 : public LayerTreeHostTimelinesTest { | |
| 455 void SetupTree() override { | |
| 456 LayerTreeHostTimelinesTest::SetupTree(); | |
| 457 picture_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 458 picture_->SetBounds(gfx::Size(4, 4)); | |
| 459 client_.set_bounds(picture_->bounds()); | |
| 460 layer_tree_host()->root_layer()->AddChild(picture_); | |
| 461 | |
| 462 AttachPlayersToTimeline(); | |
| 463 player_child_->AttachLayer(picture_->id()); | |
| 464 player_child_->set_layer_animation_delegate(this); | |
| 465 } | |
| 466 | |
| 467 void InitializeSettings(LayerTreeSettings* settings) override { | |
| 468 // Make sure that drawing many times doesn't cause a checkerboarded | |
| 469 // animation to start so we avoid flake in this test. | |
| 470 settings->timeout_and_draw_when_animation_checkerboards = false; | |
| 471 LayerTreeHostTimelinesTest::InitializeSettings(settings); | |
| 472 } | |
| 473 | |
| 474 void BeginTest() override { | |
| 475 prevented_draw_ = 0; | |
| 476 started_times_ = 0; | |
| 477 | |
| 478 PostSetNeedsCommitToMainThread(); | |
| 479 } | |
| 480 | |
| 481 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 482 LayerTreeHostImpl::FrameData* frame_data, | |
| 483 DrawResult draw_result) override { | |
| 484 // Don't checkerboard when the first animation wants to start. | |
| 485 if (host_impl->active_tree()->source_frame_number() < 2) | |
| 486 return draw_result; | |
| 487 if (TestEnded()) | |
| 488 return draw_result; | |
| 489 // Act like there is checkerboard when the second animation wants to draw. | |
| 490 ++prevented_draw_; | |
| 491 if (prevented_draw_ > 2) | |
| 492 EndTest(); | |
| 493 return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; | |
| 494 } | |
| 495 | |
| 496 void DidCommitAndDrawFrame() override { | |
| 497 switch (layer_tree_host()->source_frame_number()) { | |
| 498 case 1: | |
| 499 // The animation is longer than 1 BeginFrame interval. | |
| 500 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 0.2f, 0.8f, | |
| 501 false); | |
| 502 break; | |
| 503 case 2: | |
| 504 // This second animation will not be drawn so it should not start. | |
| 505 AddAnimatedTransformToPlayer(player_child_.get(), 0.1, 5, 5); | |
| 506 break; | |
| 507 } | |
| 508 } | |
| 509 | |
| 510 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
| 511 TargetProperty::Type target_property, | |
| 512 int group) override { | |
| 513 if (TestEnded()) | |
| 514 return; | |
| 515 started_times_++; | |
| 516 } | |
| 517 | |
| 518 void AfterTest() override { | |
| 519 // Make sure we tried to draw the second animation but failed. | |
| 520 EXPECT_LT(0, prevented_draw_); | |
| 521 // The first animation should be started, but the second should not because | |
| 522 // of checkerboard. | |
| 523 EXPECT_EQ(1, started_times_); | |
| 524 } | |
| 525 | |
| 526 int prevented_draw_; | |
| 527 int started_times_; | |
| 528 FakeContentLayerClient client_; | |
| 529 scoped_refptr<FakePictureLayer> picture_; | |
| 530 }; | |
| 531 | |
| 532 MULTI_THREAD_TEST_F( | |
| 533 LayerTreeHostTimelinesTestCheckerboardDoesntStartAnimations); | |
| 534 | |
| 535 // Verifies that scroll offset animations are only accepted when impl-scrolling | |
| 536 // is supported, and that when scroll offset animations are accepted, | |
| 537 // scroll offset updates are sent back to the main thread. | |
| 538 // Evolved from LayerTreeHostAnimationTestScrollOffsetChangesArePropagated | |
| 539 class LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated | |
| 540 : public LayerTreeHostTimelinesTest { | |
| 541 public: | |
| 542 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated() {} | |
| 543 | |
| 544 void SetupTree() override { | |
| 545 LayerTreeHostTimelinesTest::SetupTree(); | |
| 546 | |
| 547 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 548 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); | |
| 549 scroll_layer_->SetBounds(gfx::Size(1000, 1000)); | |
| 550 client_.set_bounds(scroll_layer_->bounds()); | |
| 551 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20)); | |
| 552 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
| 553 | |
| 554 AttachPlayersToTimeline(); | |
| 555 player_child_->AttachLayer(scroll_layer_->id()); | |
| 556 } | |
| 557 | |
| 558 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 559 | |
| 560 void DidCommit() override { | |
| 561 switch (layer_tree_host()->source_frame_number()) { | |
| 562 case 1: { | |
| 563 scoped_ptr<ScrollOffsetAnimationCurve> curve( | |
| 564 ScrollOffsetAnimationCurve::Create( | |
| 565 gfx::ScrollOffset(500.f, 550.f), | |
| 566 EaseInOutTimingFunction::Create())); | |
| 567 scoped_ptr<Animation> animation(Animation::Create( | |
| 568 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); | |
| 569 animation->set_needs_synchronized_start_time(true); | |
| 570 bool impl_scrolling_supported = | |
| 571 layer_tree_host()->proxy()->SupportsImplScrolling(); | |
| 572 if (impl_scrolling_supported) | |
| 573 player_child_->AddAnimation(std::move(animation)); | |
| 574 else | |
| 575 EndTest(); | |
| 576 break; | |
| 577 } | |
| 578 default: | |
| 579 if (scroll_layer_->scroll_offset().x() > 10 && | |
| 580 scroll_layer_->scroll_offset().y() > 20) | |
| 581 EndTest(); | |
| 582 } | |
| 583 } | |
| 584 | |
| 585 void AfterTest() override {} | |
| 586 | |
| 587 private: | |
| 588 FakeContentLayerClient client_; | |
| 589 scoped_refptr<FakePictureLayer> scroll_layer_; | |
| 590 }; | |
| 591 | |
| 592 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 593 LayerTreeHostTimelinesTestScrollOffsetChangesArePropagated); | |
| 594 | |
| 595 // Verifies that when the main thread removes a scroll animation and sets a new | |
| 596 // scroll position, the active tree takes on exactly this new scroll position | |
| 597 // after activation, and the main thread doesn't receive a spurious scroll | |
| 598 // delta. | |
| 599 // Evolved from LayerTreeHostAnimationTestScrollOffsetAnimationRemoval | |
| 600 class LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval | |
| 601 : public LayerTreeHostTimelinesTest { | |
| 602 public: | |
| 603 LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval() | |
| 604 : final_postion_(50.0, 100.0) {} | |
| 605 | |
| 606 void SetupTree() override { | |
| 607 LayerTreeHostTimelinesTest::SetupTree(); | |
| 608 | |
| 609 scroll_layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 610 scroll_layer_->SetScrollClipLayerId(layer_tree_host()->root_layer()->id()); | |
| 611 scroll_layer_->SetBounds(gfx::Size(10000, 10000)); | |
| 612 client_.set_bounds(scroll_layer_->bounds()); | |
| 613 scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0)); | |
| 614 layer_tree_host()->root_layer()->AddChild(scroll_layer_); | |
| 615 | |
| 616 scoped_ptr<ScrollOffsetAnimationCurve> curve( | |
| 617 ScrollOffsetAnimationCurve::Create(gfx::ScrollOffset(6500.f, 7500.f), | |
| 618 EaseInOutTimingFunction::Create())); | |
| 619 scoped_ptr<Animation> animation(Animation::Create( | |
| 620 std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET)); | |
| 621 animation->set_needs_synchronized_start_time(true); | |
| 622 | |
| 623 AttachPlayersToTimeline(); | |
| 624 player_child_->AttachLayer(scroll_layer_->id()); | |
| 625 player_child_->AddAnimation(std::move(animation)); | |
| 626 } | |
| 627 | |
| 628 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 629 | |
| 630 void BeginMainFrame(const BeginFrameArgs& args) override { | |
| 631 switch (layer_tree_host()->source_frame_number()) { | |
| 632 case 0: | |
| 633 break; | |
| 634 case 1: { | |
| 635 Animation* animation = | |
| 636 player_child_->element_animations() | |
| 637 ->layer_animation_controller() | |
| 638 ->GetAnimation(TargetProperty::SCROLL_OFFSET); | |
| 639 player_child_->RemoveAnimation(animation->id()); | |
| 640 scroll_layer_->SetScrollOffset(final_postion_); | |
| 641 break; | |
| 642 } | |
| 643 default: | |
| 644 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); | |
| 645 } | |
| 646 } | |
| 647 | |
| 648 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
| 649 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
| 650 } | |
| 651 | |
| 652 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, | |
| 653 const BeginFrameArgs& args) override { | |
| 654 if (!host_impl->pending_tree()) | |
| 655 return; | |
| 656 | |
| 657 if (!host_impl->active_tree()->root_layer()) { | |
| 658 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 659 return; | |
| 660 } | |
| 661 | |
| 662 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 663 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 664 scoped_refptr<AnimationPlayer> player_impl = | |
| 665 timeline_impl->GetPlayerById(player_child_id_); | |
| 666 | |
| 667 LayerImpl* scroll_layer_impl = | |
| 668 host_impl->active_tree()->root_layer()->children()[0].get(); | |
| 669 Animation* animation = player_impl->element_animations() | |
| 670 ->layer_animation_controller() | |
| 671 ->GetAnimation(TargetProperty::SCROLL_OFFSET); | |
| 672 | |
| 673 if (!animation || animation->run_state() != Animation::RUNNING) { | |
| 674 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 675 return; | |
| 676 } | |
| 677 | |
| 678 // Block activation until the running animation has a chance to produce a | |
| 679 // scroll delta. | |
| 680 gfx::Vector2dF scroll_delta = ScrollDelta(scroll_layer_impl); | |
| 681 if (scroll_delta.x() < 1.f || scroll_delta.y() < 1.f) | |
| 682 return; | |
| 683 | |
| 684 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 685 } | |
| 686 | |
| 687 void WillActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 688 if (host_impl->pending_tree()->source_frame_number() != 1) | |
| 689 return; | |
| 690 LayerImpl* scroll_layer_impl = | |
| 691 host_impl->pending_tree()->root_layer()->children()[0].get(); | |
| 692 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); | |
| 693 } | |
| 694 | |
| 695 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 696 if (host_impl->active_tree()->source_frame_number() != 1) | |
| 697 return; | |
| 698 LayerImpl* scroll_layer_impl = | |
| 699 host_impl->active_tree()->root_layer()->children()[0].get(); | |
| 700 EXPECT_EQ(final_postion_, scroll_layer_impl->CurrentScrollOffset()); | |
| 701 EndTest(); | |
| 702 } | |
| 703 | |
| 704 void AfterTest() override { | |
| 705 EXPECT_EQ(final_postion_, scroll_layer_->scroll_offset()); | |
| 706 } | |
| 707 | |
| 708 private: | |
| 709 FakeContentLayerClient client_; | |
| 710 scoped_refptr<FakePictureLayer> scroll_layer_; | |
| 711 const gfx::ScrollOffset final_postion_; | |
| 712 }; | |
| 713 | |
| 714 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestScrollOffsetAnimationRemoval); | |
| 715 | |
| 716 // When animations are simultaneously added to an existing layer and to a new | |
| 717 // layer, they should start at the same time, even when there's already a | |
| 718 // running animation on the existing layer. | |
| 719 // Evolved from LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers. | |
| 720 class LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers | |
| 721 : public LayerTreeHostTimelinesTest { | |
| 722 public: | |
| 723 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers() | |
| 724 : frame_count_with_pending_tree_(0) {} | |
| 725 | |
| 726 void BeginTest() override { | |
| 727 AttachPlayersToTimeline(); | |
| 728 PostSetNeedsCommitToMainThread(); | |
| 729 } | |
| 730 | |
| 731 void DidCommit() override { | |
| 732 if (layer_tree_host()->source_frame_number() == 1) { | |
| 733 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 734 AddAnimatedTransformToPlayer(player_.get(), 4, 1, 1); | |
| 735 } else if (layer_tree_host()->source_frame_number() == 2) { | |
| 736 AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 0.5f, true); | |
| 737 | |
| 738 scoped_refptr<Layer> layer = Layer::Create(layer_settings()); | |
| 739 layer_tree_host()->root_layer()->AddChild(layer); | |
| 740 layer->SetBounds(gfx::Size(4, 4)); | |
| 741 | |
| 742 player_child_->AttachLayer(layer->id()); | |
| 743 player_child_->set_layer_animation_delegate(this); | |
| 744 AddOpacityTransitionToPlayer(player_child_.get(), 1, 0.f, 0.5f, true); | |
| 745 } | |
| 746 } | |
| 747 | |
| 748 void BeginCommitOnThread(LayerTreeHostImpl* host_impl) override { | |
| 749 host_impl->BlockNotifyReadyToActivateForTesting(true); | |
| 750 } | |
| 751 | |
| 752 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 753 // For the commit that added animations to new and existing layers, keep | |
| 754 // blocking activation. We want to verify that even with activation blocked, | |
| 755 // the animation on the layer that's already in the active tree won't get a | |
| 756 // head start. | |
| 757 if (host_impl->pending_tree()->source_frame_number() != 2) { | |
| 758 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 759 } | |
| 760 } | |
| 761 | |
| 762 void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, | |
| 763 const BeginFrameArgs& args) override { | |
| 764 if (!host_impl->pending_tree() || | |
| 765 host_impl->pending_tree()->source_frame_number() != 2) | |
| 766 return; | |
| 767 | |
| 768 frame_count_with_pending_tree_++; | |
| 769 if (frame_count_with_pending_tree_ == 2) { | |
| 770 host_impl->BlockNotifyReadyToActivateForTesting(false); | |
| 771 } | |
| 772 } | |
| 773 | |
| 774 void UpdateAnimationState(LayerTreeHostImpl* host_impl, | |
| 775 bool has_unfinished_animation) override { | |
| 776 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 777 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 778 scoped_refptr<AnimationPlayer> player_impl = | |
| 779 timeline_impl->GetPlayerById(player_id_); | |
| 780 scoped_refptr<AnimationPlayer> player_child_impl = | |
| 781 timeline_impl->GetPlayerById(player_child_id_); | |
| 782 | |
| 783 // wait for tree activation. | |
| 784 if (!player_impl->element_animations()) | |
| 785 return; | |
| 786 | |
| 787 LayerAnimationController* root_controller_impl = | |
| 788 player_impl->element_animations()->layer_animation_controller(); | |
| 789 Animation* root_animation = | |
| 790 root_controller_impl->GetAnimation(TargetProperty::OPACITY); | |
| 791 if (!root_animation || root_animation->run_state() != Animation::RUNNING) | |
| 792 return; | |
| 793 | |
| 794 LayerAnimationController* child_controller_impl = | |
| 795 player_child_impl->element_animations()->layer_animation_controller(); | |
| 796 Animation* child_animation = | |
| 797 child_controller_impl->GetAnimation(TargetProperty::OPACITY); | |
| 798 EXPECT_EQ(Animation::RUNNING, child_animation->run_state()); | |
| 799 EXPECT_EQ(root_animation->start_time(), child_animation->start_time()); | |
| 800 root_controller_impl->AbortAnimations(TargetProperty::OPACITY); | |
| 801 root_controller_impl->AbortAnimations(TargetProperty::TRANSFORM); | |
| 802 child_controller_impl->AbortAnimations(TargetProperty::OPACITY); | |
| 803 EndTest(); | |
| 804 } | |
| 805 | |
| 806 void AfterTest() override {} | |
| 807 | |
| 808 private: | |
| 809 int frame_count_with_pending_tree_; | |
| 810 }; | |
| 811 | |
| 812 // This test blocks activation which is not supported for single thread mode. | |
| 813 MULTI_THREAD_BLOCKNOTIFY_TEST_F( | |
| 814 LayerTreeHostTimelinesTestAnimationsAddedToNewAndExistingLayers); | |
| 815 | |
| 816 // Evolved from LayerTreeHostAnimationTestAddAnimationAfterAnimating. | |
| 817 class LayerTreeHostTimelinesTestAddAnimationAfterAnimating | |
| 818 : public LayerTreeHostTimelinesTest { | |
| 819 public: | |
| 820 void SetupTree() override { | |
| 821 LayerTreeHostTimelinesTest::SetupTree(); | |
| 822 content_ = Layer::Create(layer_settings()); | |
| 823 content_->SetBounds(gfx::Size(4, 4)); | |
| 824 layer_tree_host()->root_layer()->AddChild(content_); | |
| 825 | |
| 826 AttachPlayersToTimeline(); | |
| 827 | |
| 828 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 829 player_child_->AttachLayer(content_->id()); | |
| 830 } | |
| 831 | |
| 832 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 833 | |
| 834 void DidCommit() override { | |
| 835 switch (layer_tree_host()->source_frame_number()) { | |
| 836 case 1: | |
| 837 // First frame: add an animation to the root layer. | |
| 838 AddAnimatedTransformToPlayer(player_.get(), 0.1, 5, 5); | |
| 839 break; | |
| 840 case 2: | |
| 841 // Second frame: add an animation to the content layer. The root layer | |
| 842 // animation has caused us to animate already during this frame. | |
| 843 AddOpacityTransitionToPlayer(player_child_.get(), 0.1, 5, 5, false); | |
| 844 break; | |
| 845 } | |
| 846 } | |
| 847 | |
| 848 void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override { | |
| 849 // After both animations have started, verify that they have valid | |
| 850 // start times. | |
| 851 if (host_impl->active_tree()->source_frame_number() < 2) | |
| 852 return; | |
| 853 AnimationRegistrar::AnimationControllerMap controllers_copy = | |
| 854 host_impl->animation_host() | |
| 855 ->animation_registrar() | |
| 856 ->active_animation_controllers_for_testing(); | |
| 857 EXPECT_EQ(2u, controllers_copy.size()); | |
| 858 for (auto& it : controllers_copy) { | |
| 859 int id = it.first; | |
| 860 if (id == host_impl->RootLayer()->id()) { | |
| 861 Animation* anim = it.second->GetAnimation(TargetProperty::TRANSFORM); | |
| 862 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); | |
| 863 } else if (id == host_impl->RootLayer()->children()[0]->id()) { | |
| 864 Animation* anim = it.second->GetAnimation(TargetProperty::OPACITY); | |
| 865 EXPECT_GT((anim->start_time() - base::TimeTicks()).InSecondsF(), 0); | |
| 866 } | |
| 867 EndTest(); | |
| 868 } | |
| 869 } | |
| 870 | |
| 871 void AfterTest() override {} | |
| 872 | |
| 873 private: | |
| 874 scoped_refptr<Layer> content_; | |
| 875 }; | |
| 876 | |
| 877 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 878 LayerTreeHostTimelinesTestAddAnimationAfterAnimating); | |
| 879 | |
| 880 class LayerTreeHostTimelinesTestRemoveAnimation | |
| 881 : public LayerTreeHostTimelinesTest { | |
| 882 public: | |
| 883 void SetupTree() override { | |
| 884 LayerTreeHostTimelinesTest::SetupTree(); | |
| 885 layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 886 layer_->SetBounds(gfx::Size(4, 4)); | |
| 887 client_.set_bounds(layer_->bounds()); | |
| 888 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 889 | |
| 890 AttachPlayersToTimeline(); | |
| 891 | |
| 892 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 893 player_child_->AttachLayer(layer_->id()); | |
| 894 } | |
| 895 | |
| 896 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 897 | |
| 898 void DidCommit() override { | |
| 899 switch (layer_tree_host()->source_frame_number()) { | |
| 900 case 1: | |
| 901 AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5); | |
| 902 break; | |
| 903 case 2: | |
| 904 LayerAnimationController* controller = | |
| 905 player_child_->element_animations()->layer_animation_controller(); | |
| 906 Animation* animation = | |
| 907 controller->GetAnimation(TargetProperty::TRANSFORM); | |
| 908 player_child_->RemoveAnimation(animation->id()); | |
| 909 gfx::Transform transform; | |
| 910 transform.Translate(10.f, 10.f); | |
| 911 layer_->SetTransform(transform); | |
| 912 | |
| 913 // Do something that causes property trees to get rebuilt. | |
| 914 layer_->AddChild(Layer::Create(layer_settings())); | |
| 915 break; | |
| 916 } | |
| 917 } | |
| 918 | |
| 919 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 920 if (host_impl->active_tree()->source_frame_number() < 2) | |
| 921 return; | |
| 922 gfx::Transform expected_transform; | |
| 923 expected_transform.Translate(10.f, 10.f); | |
| 924 EXPECT_EQ( | |
| 925 expected_transform, | |
| 926 host_impl->active_tree()->root_layer()->children()[0]->DrawTransform()); | |
| 927 EndTest(); | |
| 928 } | |
| 929 | |
| 930 void AfterTest() override {} | |
| 931 | |
| 932 private: | |
| 933 scoped_refptr<Layer> layer_; | |
| 934 FakeContentLayerClient client_; | |
| 935 }; | |
| 936 | |
| 937 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestRemoveAnimation); | |
| 938 | |
| 939 class LayerTreeHostTimelinesTestAnimationFinishesDuringCommit | |
| 940 : public LayerTreeHostTimelinesTest { | |
| 941 public: | |
| 942 void SetupTree() override { | |
| 943 LayerTreeHostTimelinesTest::SetupTree(); | |
| 944 layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 945 layer_->SetBounds(gfx::Size(4, 4)); | |
| 946 client_.set_bounds(layer_->bounds()); | |
| 947 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 948 | |
| 949 AttachPlayersToTimeline(); | |
| 950 | |
| 951 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 952 player_child_->AttachLayer(layer_->id()); | |
| 953 } | |
| 954 | |
| 955 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 956 | |
| 957 void DidCommit() override { | |
| 958 if (layer_tree_host()->source_frame_number() == 1) | |
| 959 AddAnimatedTransformToPlayer(player_child_.get(), 0.04, 5, 5); | |
| 960 } | |
| 961 | |
| 962 void WillCommit() override { | |
| 963 if (layer_tree_host()->source_frame_number() == 2) { | |
| 964 // Block until the animation finishes on the compositor thread. Since | |
| 965 // animations have already been ticked on the main thread, when the commit | |
| 966 // happens the state on the main thread will be consistent with having a | |
| 967 // running animation but the state on the compositor thread will be | |
| 968 // consistent with having only a finished animation. | |
| 969 completion_.Wait(); | |
| 970 } | |
| 971 } | |
| 972 | |
| 973 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 974 switch (host_impl->sync_tree()->source_frame_number()) { | |
| 975 case 1: | |
| 976 PostSetNeedsCommitToMainThread(); | |
| 977 break; | |
| 978 case 2: | |
| 979 gfx::Transform expected_transform; | |
| 980 expected_transform.Translate(5.f, 5.f); | |
| 981 LayerImpl* layer_impl = | |
| 982 host_impl->sync_tree()->root_layer()->children()[0].get(); | |
| 983 EXPECT_EQ(expected_transform, layer_impl->DrawTransform()); | |
| 984 EndTest(); | |
| 985 break; | |
| 986 } | |
| 987 } | |
| 988 | |
| 989 void UpdateAnimationState(LayerTreeHostImpl* host_impl, | |
| 990 bool has_unfinished_animation) override { | |
| 991 if (host_impl->active_tree()->source_frame_number() == 1 && | |
| 992 !has_unfinished_animation) { | |
| 993 // The animation has finished, so allow the main thread to commit. | |
| 994 completion_.Signal(); | |
| 995 } | |
| 996 } | |
| 997 | |
| 998 void AfterTest() override {} | |
| 999 | |
| 1000 private: | |
| 1001 scoped_refptr<Layer> layer_; | |
| 1002 FakeContentLayerClient client_; | |
| 1003 CompletionEvent completion_; | |
| 1004 }; | |
| 1005 | |
| 1006 // An animation finishing during commit can only happen when we have a separate | |
| 1007 // compositor thread. | |
| 1008 MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestAnimationFinishesDuringCommit); | |
| 1009 | |
| 1010 // Check that SetTransformIsPotentiallyAnimatingChanged is called | |
| 1011 // if we destroy LayerAnimationController and ElementAnimations. | |
| 1012 class LayerTreeHostTimelinesTestSetPotentiallyAnimatingOnLacDestruction | |
| 1013 : public LayerTreeHostTimelinesTest { | |
| 1014 public: | |
| 1015 void SetupTree() override { | |
| 1016 prev_screen_space_transform_is_animating_ = true; | |
| 1017 screen_space_transform_animation_stopped_ = false; | |
| 1018 | |
| 1019 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1020 AttachPlayersToTimeline(); | |
| 1021 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 1022 AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5); | |
| 1023 } | |
| 1024 | |
| 1025 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1026 | |
| 1027 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1028 if (host_impl->pending_tree()->source_frame_number() <= 1) { | |
| 1029 EXPECT_TRUE(host_impl->pending_tree() | |
| 1030 ->root_layer() | |
| 1031 ->screen_space_transform_is_animating()); | |
| 1032 } else { | |
| 1033 EXPECT_FALSE(host_impl->pending_tree() | |
| 1034 ->root_layer() | |
| 1035 ->screen_space_transform_is_animating()); | |
| 1036 } | |
| 1037 } | |
| 1038 | |
| 1039 void DidCommit() override { PostSetNeedsCommitToMainThread(); } | |
| 1040 | |
| 1041 void UpdateLayerTreeHost() override { | |
| 1042 if (layer_tree_host()->source_frame_number() == 2) { | |
| 1043 // Destroy player. | |
| 1044 timeline_->DetachPlayer(player_.get()); | |
| 1045 player_ = nullptr; | |
| 1046 } | |
| 1047 } | |
| 1048 | |
| 1049 DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, | |
| 1050 LayerTreeHostImpl::FrameData* frame_data, | |
| 1051 DrawResult draw_result) override { | |
| 1052 const bool screen_space_transform_is_animating = | |
| 1053 host_impl->active_tree() | |
| 1054 ->root_layer() | |
| 1055 ->screen_space_transform_is_animating(); | |
| 1056 | |
| 1057 // Check that screen_space_transform_is_animating changes only once. | |
| 1058 if (screen_space_transform_is_animating && | |
| 1059 prev_screen_space_transform_is_animating_) | |
| 1060 EXPECT_FALSE(screen_space_transform_animation_stopped_); | |
| 1061 if (!screen_space_transform_is_animating && | |
| 1062 prev_screen_space_transform_is_animating_) { | |
| 1063 EXPECT_FALSE(screen_space_transform_animation_stopped_); | |
| 1064 screen_space_transform_animation_stopped_ = true; | |
| 1065 } | |
| 1066 if (!screen_space_transform_is_animating && | |
| 1067 !prev_screen_space_transform_is_animating_) | |
| 1068 EXPECT_TRUE(screen_space_transform_animation_stopped_); | |
| 1069 | |
| 1070 prev_screen_space_transform_is_animating_ = | |
| 1071 screen_space_transform_is_animating; | |
| 1072 | |
| 1073 return draw_result; | |
| 1074 } | |
| 1075 | |
| 1076 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1077 if (host_impl->active_tree()->source_frame_number() >= 2) | |
| 1078 EndTest(); | |
| 1079 } | |
| 1080 | |
| 1081 void AfterTest() override { | |
| 1082 EXPECT_TRUE(screen_space_transform_animation_stopped_); | |
| 1083 } | |
| 1084 | |
| 1085 bool prev_screen_space_transform_is_animating_; | |
| 1086 bool screen_space_transform_animation_stopped_; | |
| 1087 }; | |
| 1088 | |
| 1089 MULTI_THREAD_TEST_F( | |
| 1090 LayerTreeHostTimelinesTestSetPotentiallyAnimatingOnLacDestruction); | |
| 1091 | |
| 1092 // Check that we invalidate property trees on AnimationPlayer::SetNeedsCommit. | |
| 1093 class LayerTreeHostTimelinesTestRebuildPropertyTreesOnAnimationSetNeedsCommit | |
| 1094 : public LayerTreeHostTimelinesTest { | |
| 1095 public: | |
| 1096 void SetupTree() override { | |
| 1097 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1098 layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 1099 layer_->SetBounds(gfx::Size(4, 4)); | |
| 1100 client_.set_bounds(layer_->bounds()); | |
| 1101 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 1102 | |
| 1103 AttachPlayersToTimeline(); | |
| 1104 | |
| 1105 player_->AttachLayer(layer_tree_host()->root_layer()->id()); | |
| 1106 player_child_->AttachLayer(layer_->id()); | |
| 1107 } | |
| 1108 | |
| 1109 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1110 | |
| 1111 void DidCommit() override { | |
| 1112 if (layer_tree_host()->source_frame_number() == 1 || | |
| 1113 layer_tree_host()->source_frame_number() == 2) | |
| 1114 PostSetNeedsCommitToMainThread(); | |
| 1115 } | |
| 1116 | |
| 1117 void UpdateLayerTreeHost() override { | |
| 1118 if (layer_tree_host()->source_frame_number() == 1) { | |
| 1119 EXPECT_FALSE(layer_tree_host()->property_trees()->needs_rebuild); | |
| 1120 AddAnimatedTransformToPlayer(player_child_.get(), 1.0, 5, 5); | |
| 1121 } | |
| 1122 | |
| 1123 EXPECT_TRUE(layer_tree_host()->property_trees()->needs_rebuild); | |
| 1124 } | |
| 1125 | |
| 1126 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1127 if (host_impl->active_tree()->source_frame_number() >= 2) | |
| 1128 EndTest(); | |
| 1129 } | |
| 1130 | |
| 1131 void AfterTest() override {} | |
| 1132 | |
| 1133 private: | |
| 1134 scoped_refptr<Layer> layer_; | |
| 1135 FakeContentLayerClient client_; | |
| 1136 }; | |
| 1137 | |
| 1138 MULTI_THREAD_TEST_F( | |
| 1139 LayerTreeHostTimelinesTestRebuildPropertyTreesOnAnimationSetNeedsCommit); | |
| 1140 | |
| 1141 class LayerTreeHostTimelinesTestPendingTreeAnimatesFirstCommit | |
| 1142 : public LayerTreeHostTimelinesTest { | |
| 1143 public: | |
| 1144 void SetupTree() override { | |
| 1145 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1146 | |
| 1147 layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 1148 layer_->SetBounds(gfx::Size(2, 2)); | |
| 1149 client_.set_bounds(layer_->bounds()); | |
| 1150 // Transform the layer to 4,4 to start. | |
| 1151 gfx::Transform start_transform; | |
| 1152 start_transform.Translate(4.0, 4.0); | |
| 1153 layer_->SetTransform(start_transform); | |
| 1154 | |
| 1155 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 1156 player_->AttachLayer(layer_->id()); | |
| 1157 | |
| 1158 AttachPlayersToTimeline(); | |
| 1159 } | |
| 1160 | |
| 1161 void BeginTest() override { | |
| 1162 // Add a translate from 6,7 to 8,9. | |
| 1163 TransformOperations start; | |
| 1164 start.AppendTranslate(6.f, 7.f, 0.f); | |
| 1165 TransformOperations end; | |
| 1166 end.AppendTranslate(8.f, 9.f, 0.f); | |
| 1167 AddAnimatedTransformToPlayer(player_.get(), 4.0, start, end); | |
| 1168 | |
| 1169 PostSetNeedsCommitToMainThread(); | |
| 1170 } | |
| 1171 | |
| 1172 void WillPrepareTiles(LayerTreeHostImpl* host_impl) override { | |
| 1173 if (host_impl->sync_tree()->source_frame_number() != 0) | |
| 1174 return; | |
| 1175 | |
| 1176 // After checking this on the sync tree, we will activate, which will cause | |
| 1177 // PrepareTiles to happen again (which races with the test exiting). | |
| 1178 if (TestEnded()) | |
| 1179 return; | |
| 1180 | |
| 1181 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 1182 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 1183 scoped_refptr<AnimationPlayer> player_impl = | |
| 1184 timeline_impl->GetPlayerById(player_id_); | |
| 1185 | |
| 1186 LayerAnimationController* controller_impl = | |
| 1187 player_impl->element_animations()->layer_animation_controller(); | |
| 1188 | |
| 1189 LayerImpl* root = host_impl->sync_tree()->root_layer(); | |
| 1190 LayerImpl* child = root->children()[0].get(); | |
| 1191 Animation* animation = | |
| 1192 controller_impl->GetAnimation(TargetProperty::TRANSFORM); | |
| 1193 | |
| 1194 // The animation should be starting for the first frame. | |
| 1195 EXPECT_EQ(Animation::STARTING, animation->run_state()); | |
| 1196 | |
| 1197 // And the transform should be propogated to the sync tree layer, at its | |
| 1198 // starting state which is 6,7. | |
| 1199 gfx::Transform expected_transform; | |
| 1200 expected_transform.Translate(6.0, 7.0); | |
| 1201 EXPECT_EQ(expected_transform, child->DrawTransform()); | |
| 1202 // And the sync tree layer should know it is animating. | |
| 1203 EXPECT_TRUE(child->screen_space_transform_is_animating()); | |
| 1204 | |
| 1205 controller_impl->AbortAnimations(TargetProperty::TRANSFORM); | |
| 1206 EndTest(); | |
| 1207 } | |
| 1208 | |
| 1209 void AfterTest() override {} | |
| 1210 | |
| 1211 FakeContentLayerClient client_; | |
| 1212 scoped_refptr<Layer> layer_; | |
| 1213 }; | |
| 1214 | |
| 1215 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1216 LayerTreeHostTimelinesTestPendingTreeAnimatesFirstCommit); | |
| 1217 | |
| 1218 // When a layer with an animation is removed from the tree and later re-added, | |
| 1219 // the animation should resume. | |
| 1220 class LayerTreeHostTimelinesTestAnimatedLayerRemovedAndAdded | |
| 1221 : public LayerTreeHostTimelinesTest { | |
| 1222 public: | |
| 1223 void SetupTree() override { | |
| 1224 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1225 layer_ = Layer::Create(layer_settings()); | |
| 1226 layer_->SetBounds(gfx::Size(4, 4)); | |
| 1227 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 1228 | |
| 1229 layer_tree_host()->animation_host()->AddAnimationTimeline(timeline_.get()); | |
| 1230 timeline_->AttachPlayer(player_.get()); | |
| 1231 player_->AttachLayer(layer_->id()); | |
| 1232 DCHECK(player_->element_animations()); | |
| 1233 | |
| 1234 AddOpacityTransitionToPlayer(player_.get(), 10000.0, 0.1f, 0.9f, true); | |
| 1235 } | |
| 1236 | |
| 1237 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1238 | |
| 1239 void DidCommit() override { | |
| 1240 switch (layer_tree_host()->source_frame_number()) { | |
| 1241 case 0: | |
| 1242 EXPECT_TRUE(player_->element_animations() | |
| 1243 ->has_active_value_observer_for_testing()); | |
| 1244 EXPECT_FALSE(player_->element_animations() | |
| 1245 ->has_pending_value_observer_for_testing()); | |
| 1246 EXPECT_TRUE(layer_tree_host() | |
| 1247 ->animation_host() | |
| 1248 ->animation_registrar() | |
| 1249 ->needs_animate_layers()); | |
| 1250 break; | |
| 1251 case 1: | |
| 1252 layer_->RemoveFromParent(); | |
| 1253 EXPECT_FALSE(player_->element_animations() | |
| 1254 ->has_active_value_observer_for_testing()); | |
| 1255 EXPECT_FALSE(player_->element_animations() | |
| 1256 ->has_pending_value_observer_for_testing()); | |
| 1257 EXPECT_TRUE(layer_tree_host() | |
| 1258 ->animation_host() | |
| 1259 ->animation_registrar() | |
| 1260 ->needs_animate_layers()); | |
| 1261 break; | |
| 1262 case 2: | |
| 1263 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 1264 EXPECT_TRUE(player_->element_animations() | |
| 1265 ->has_active_value_observer_for_testing()); | |
| 1266 EXPECT_FALSE(player_->element_animations() | |
| 1267 ->has_pending_value_observer_for_testing()); | |
| 1268 EXPECT_TRUE(layer_tree_host() | |
| 1269 ->animation_host() | |
| 1270 ->animation_registrar() | |
| 1271 ->needs_animate_layers()); | |
| 1272 break; | |
| 1273 } | |
| 1274 } | |
| 1275 | |
| 1276 void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1277 scoped_refptr<AnimationTimeline> timeline_impl = | |
| 1278 host_impl->animation_host()->GetTimelineById(timeline_id_); | |
| 1279 scoped_refptr<AnimationPlayer> player_impl = | |
| 1280 timeline_impl->GetPlayerById(player_id_); | |
| 1281 | |
| 1282 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1283 case 0: | |
| 1284 EXPECT_TRUE(player_impl->element_animations() | |
| 1285 ->has_active_value_observer_for_testing()); | |
| 1286 EXPECT_TRUE(host_impl->animation_host() | |
| 1287 ->animation_registrar() | |
| 1288 ->needs_animate_layers()); | |
| 1289 break; | |
| 1290 case 1: | |
| 1291 EXPECT_FALSE(player_impl->element_animations() | |
| 1292 ->has_active_value_observer_for_testing()); | |
| 1293 EXPECT_TRUE(host_impl->animation_host() | |
| 1294 ->animation_registrar() | |
| 1295 ->needs_animate_layers()); | |
| 1296 break; | |
| 1297 case 2: | |
| 1298 EXPECT_TRUE(player_impl->element_animations() | |
| 1299 ->has_active_value_observer_for_testing()); | |
| 1300 EXPECT_TRUE(host_impl->animation_host() | |
| 1301 ->animation_registrar() | |
| 1302 ->needs_animate_layers()); | |
| 1303 EndTest(); | |
| 1304 break; | |
| 1305 } | |
| 1306 } | |
| 1307 | |
| 1308 void AfterTest() override {} | |
| 1309 | |
| 1310 private: | |
| 1311 scoped_refptr<Layer> layer_; | |
| 1312 }; | |
| 1313 | |
| 1314 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1315 LayerTreeHostTimelinesTestAnimatedLayerRemovedAndAdded); | |
| 1316 | |
| 1317 class LayerTreeHostTimelinesTestIsAnimating | |
| 1318 : public LayerTreeHostTimelinesTest { | |
| 1319 public: | |
| 1320 void SetupTree() override { | |
| 1321 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1322 layer_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 1323 layer_->SetBounds(gfx::Size(4, 4)); | |
| 1324 client_.set_bounds(layer_->bounds()); | |
| 1325 layer_tree_host()->root_layer()->AddChild(layer_); | |
| 1326 | |
| 1327 AttachPlayersToTimeline(); | |
| 1328 player_->AttachLayer(layer_->id()); | |
| 1329 } | |
| 1330 | |
| 1331 void BeginTest() override { PostSetNeedsCommitToMainThread(); } | |
| 1332 | |
| 1333 void DidCommit() override { | |
| 1334 switch (layer_tree_host()->source_frame_number()) { | |
| 1335 case 1: | |
| 1336 AddAnimatedTransformToPlayer(player_.get(), 1.0, 5, 5); | |
| 1337 break; | |
| 1338 case 2: | |
| 1339 LayerAnimationController* controller = | |
| 1340 player_->element_animations()->layer_animation_controller(); | |
| 1341 Animation* animation = | |
| 1342 controller->GetAnimation(TargetProperty::TRANSFORM); | |
| 1343 player_->RemoveAnimation(animation->id()); | |
| 1344 break; | |
| 1345 } | |
| 1346 } | |
| 1347 | |
| 1348 void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1349 LayerImpl* root = host_impl->sync_tree()->root_layer(); | |
| 1350 LayerImpl* child = root->children()[0].get(); | |
| 1351 switch (host_impl->sync_tree()->source_frame_number()) { | |
| 1352 case 0: | |
| 1353 // No animation yet. | |
| 1354 break; | |
| 1355 case 1: | |
| 1356 // Animation is started. | |
| 1357 EXPECT_TRUE(child->screen_space_transform_is_animating()); | |
| 1358 break; | |
| 1359 case 2: | |
| 1360 // The animation is removed/stopped. | |
| 1361 EXPECT_FALSE(child->screen_space_transform_is_animating()); | |
| 1362 EndTest(); | |
| 1363 break; | |
| 1364 default: | |
| 1365 NOTREACHED(); | |
| 1366 } | |
| 1367 } | |
| 1368 | |
| 1369 void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { | |
| 1370 LayerImpl* root = host_impl->active_tree()->root_layer(); | |
| 1371 LayerImpl* child = root->children()[0].get(); | |
| 1372 switch (host_impl->active_tree()->source_frame_number()) { | |
| 1373 case 0: | |
| 1374 // No animation yet. | |
| 1375 break; | |
| 1376 case 1: | |
| 1377 // Animation is started. | |
| 1378 EXPECT_TRUE(child->screen_space_transform_is_animating()); | |
| 1379 break; | |
| 1380 case 2: | |
| 1381 // The animation is removed/stopped. | |
| 1382 EXPECT_FALSE(child->screen_space_transform_is_animating()); | |
| 1383 EndTest(); | |
| 1384 break; | |
| 1385 default: | |
| 1386 NOTREACHED(); | |
| 1387 } | |
| 1388 } | |
| 1389 | |
| 1390 void AfterTest() override {} | |
| 1391 | |
| 1392 private: | |
| 1393 scoped_refptr<Layer> layer_; | |
| 1394 FakeContentLayerClient client_; | |
| 1395 }; | |
| 1396 | |
| 1397 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTimelinesTestIsAnimating); | |
| 1398 | |
| 1399 class LayerTreeHostTimelinesTestNotifyAnimationFinished | |
| 1400 : public LayerTreeHostTimelinesTest { | |
| 1401 public: | |
| 1402 LayerTreeHostTimelinesTestNotifyAnimationFinished() | |
| 1403 : called_animation_started_(false), called_animation_finished_(false) {} | |
| 1404 | |
| 1405 void SetupTree() override { | |
| 1406 LayerTreeHostTimelinesTest::SetupTree(); | |
| 1407 picture_ = FakePictureLayer::Create(layer_settings(), &client_); | |
| 1408 picture_->SetBounds(gfx::Size(4, 4)); | |
| 1409 client_.set_bounds(picture_->bounds()); | |
| 1410 layer_tree_host()->root_layer()->AddChild(picture_); | |
| 1411 | |
| 1412 AttachPlayersToTimeline(); | |
| 1413 player_->AttachLayer(picture_->id()); | |
| 1414 player_->set_layer_animation_delegate(this); | |
| 1415 } | |
| 1416 | |
| 1417 void BeginTest() override { | |
| 1418 PostAddLongAnimationToMainThreadPlayer(player_.get()); | |
| 1419 } | |
| 1420 | |
| 1421 void NotifyAnimationStarted(base::TimeTicks monotonic_time, | |
| 1422 TargetProperty::Type target_property, | |
| 1423 int group) override { | |
| 1424 called_animation_started_ = true; | |
| 1425 layer_tree_host()->AnimateLayers(base::TimeTicks::FromInternalValue( | |
| 1426 std::numeric_limits<int64_t>::max())); | |
| 1427 PostSetNeedsCommitToMainThread(); | |
| 1428 } | |
| 1429 | |
| 1430 void NotifyAnimationFinished(base::TimeTicks monotonic_time, | |
| 1431 TargetProperty::Type target_property, | |
| 1432 int group) override { | |
| 1433 called_animation_finished_ = true; | |
| 1434 EndTest(); | |
| 1435 } | |
| 1436 | |
| 1437 void AfterTest() override { | |
| 1438 EXPECT_TRUE(called_animation_started_); | |
| 1439 EXPECT_TRUE(called_animation_finished_); | |
| 1440 } | |
| 1441 | |
| 1442 private: | |
| 1443 bool called_animation_started_; | |
| 1444 bool called_animation_finished_; | |
| 1445 FakeContentLayerClient client_; | |
| 1446 scoped_refptr<FakePictureLayer> picture_; | |
| 1447 }; | |
| 1448 | |
| 1449 SINGLE_AND_MULTI_THREAD_TEST_F( | |
| 1450 LayerTreeHostTimelinesTestNotifyAnimationFinished); | |
| 1451 | |
| 1452 } // namespace | |
| 1453 } // namespace cc | |
| OLD | NEW |