| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/layer_tree_host.h" | 5 #include "cc/trees/layer_tree_host.h" |
| 6 | 6 |
| 7 #include "cc/animation/animation_curve.h" | 7 #include "cc/animation/animation_curve.h" |
| 8 #include "cc/animation/layer_animation_controller.h" | 8 #include "cc/animation/layer_animation_controller.h" |
| 9 #include "cc/animation/scroll_offset_animation_curve.h" | 9 #include "cc/animation/scroll_offset_animation_curve.h" |
| 10 #include "cc/animation/timing_function.h" | 10 #include "cc/animation/timing_function.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 } | 216 } |
| 217 | 217 |
| 218 void AfterTest() override {} | 218 void AfterTest() override {} |
| 219 | 219 |
| 220 private: | 220 private: |
| 221 bool started_animating_; | 221 bool started_animating_; |
| 222 }; | 222 }; |
| 223 | 223 |
| 224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); | 224 SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestAnimationsGetDeleted); |
| 225 | 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. | 226 // Ensure that an animation's timing function is respected. |
| 456 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction | 227 class LayerTreeHostAnimationTestAddAnimationWithTimingFunction |
| 457 : public LayerTreeHostAnimationTest { | 228 : public LayerTreeHostAnimationTest { |
| 458 public: | 229 public: |
| 459 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} | 230 LayerTreeHostAnimationTestAddAnimationWithTimingFunction() {} |
| 460 | 231 |
| 461 void SetupTree() override { | 232 void SetupTree() override { |
| 462 LayerTreeHostAnimationTest::SetupTree(); | 233 LayerTreeHostAnimationTest::SetupTree(); |
| 463 content_ = FakeContentLayer::Create(&client_); | 234 content_ = FakeContentLayer::Create(&client_); |
| 464 content_->SetBounds(gfx::Size(4, 4)); | 235 content_->SetBounds(gfx::Size(4, 4)); |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 private: | 1037 private: |
| 1267 scoped_refptr<Layer> content_; | 1038 scoped_refptr<Layer> content_; |
| 1268 int num_swap_buffers_; | 1039 int num_swap_buffers_; |
| 1269 }; | 1040 }; |
| 1270 | 1041 |
| 1271 SINGLE_AND_MULTI_THREAD_TEST_F( | 1042 SINGLE_AND_MULTI_THREAD_TEST_F( |
| 1272 LayerTreeHostAnimationTestAddAnimationAfterAnimating); | 1043 LayerTreeHostAnimationTestAddAnimationAfterAnimating); |
| 1273 | 1044 |
| 1274 } // namespace | 1045 } // namespace |
| 1275 } // namespace cc | 1046 } // namespace cc |
| OLD | NEW |