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