Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "ui/compositor/layer_animator.h" | 5 #include "ui/compositor/layer_animator.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "ui/base/animation/animation_container.h" | 10 #include "ui/base/animation/animation_container.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 static const base::TimeDelta kDefaultTransitionDuration = | 23 static const base::TimeDelta kDefaultTransitionDuration = |
| 24 base::TimeDelta::FromMilliseconds(120); | 24 base::TimeDelta::FromMilliseconds(120); |
| 25 | 25 |
| 26 static const base::TimeDelta kTimerInterval = | 26 static const base::TimeDelta kTimerInterval = |
| 27 base::TimeDelta::FromMilliseconds(10); | 27 base::TimeDelta::FromMilliseconds(10); |
| 28 | 28 |
| 29 } // namespace | 29 } // namespace |
| 30 | 30 |
| 31 class LayerAnimator::DestroyedTracker | |
| 32 : public base::RefCounted<LayerAnimator::DestroyedTracker> { | |
| 33 public: | |
| 34 DestroyedTracker() : is_alive_(true) {} | |
| 35 virtual ~DestroyedTracker() { | |
| 36 DCHECK(!is_alive_); | |
| 37 } | |
| 38 | |
| 39 // Returns true if the animator is still alive. | |
| 40 bool is_alive() const { return is_alive_; } | |
| 41 | |
| 42 // Invoked when the animator is destroyed. | |
| 43 void AnimatorDeleted() { | |
| 44 DCHECK(is_alive_); | |
| 45 is_alive_ = false; | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 bool is_alive_; | |
| 50 | |
| 51 DISALLOW_COPY_AND_ASSIGN(DestroyedTracker); | |
| 52 }; | |
| 53 | |
| 31 // static | 54 // static |
| 32 bool LayerAnimator::disable_animations_for_test_ = false; | 55 bool LayerAnimator::disable_animations_for_test_ = false; |
| 33 // static | 56 // static |
| 34 bool LayerAnimator::slow_animation_mode_ = false; | 57 bool LayerAnimator::slow_animation_mode_ = false; |
| 35 // static | 58 // static |
| 36 int LayerAnimator::slow_animation_scale_factor_ = 4; | 59 int LayerAnimator::slow_animation_scale_factor_ = 4; |
| 37 | 60 |
| 38 // LayerAnimator public -------------------------------------------------------- | 61 // LayerAnimator public -------------------------------------------------------- |
| 39 | 62 |
| 40 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) | 63 LayerAnimator::LayerAnimator(base::TimeDelta transition_duration) |
| 41 : delegate_(NULL), | 64 : delegate_(NULL), |
| 42 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), | 65 preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET), |
| 43 transition_duration_(transition_duration), | 66 transition_duration_(transition_duration), |
| 44 tween_type_(Tween::LINEAR), | 67 tween_type_(Tween::LINEAR), |
| 45 is_started_(false), | 68 is_started_(false), |
| 46 disable_timer_for_test_(false) { | 69 disable_timer_for_test_(false), |
| 70 destroyed_tracker_(new DestroyedTracker) { | |
| 47 } | 71 } |
| 48 | 72 |
| 49 LayerAnimator::~LayerAnimator() { | 73 LayerAnimator::~LayerAnimator() { |
| 50 for (size_t i = 0; i < running_animations_.size(); ++i) | 74 for (size_t i = 0; i < running_animations_.size(); ++i) |
| 51 running_animations_[i].sequence->OnAnimatorDestroyed(); | 75 running_animations_[i].sequence->OnAnimatorDestroyed(); |
| 52 ClearAnimations(); | 76 ClearAnimations(); |
| 77 destroyed_tracker_->AnimatorDeleted(); | |
| 53 } | 78 } |
| 54 | 79 |
| 55 // static | 80 // static |
| 56 LayerAnimator* LayerAnimator::CreateDefaultAnimator() { | 81 LayerAnimator* LayerAnimator::CreateDefaultAnimator() { |
| 57 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0)); | 82 return new LayerAnimator(base::TimeDelta::FromMilliseconds(0)); |
| 58 } | 83 } |
| 59 | 84 |
| 60 // static | 85 // static |
| 61 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { | 86 LayerAnimator* LayerAnimator::CreateImplicitAnimator() { |
| 62 return new LayerAnimator(kDefaultTransitionDuration); | 87 return new LayerAnimator(kDefaultTransitionDuration); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 } | 270 } |
| 246 return false; | 271 return false; |
| 247 } | 272 } |
| 248 | 273 |
| 249 void LayerAnimator::StopAnimatingProperty( | 274 void LayerAnimator::StopAnimatingProperty( |
| 250 LayerAnimationElement::AnimatableProperty property) { | 275 LayerAnimationElement::AnimatableProperty property) { |
| 251 while (true) { | 276 while (true) { |
| 252 RunningAnimation* running = GetRunningAnimation(property); | 277 RunningAnimation* running = GetRunningAnimation(property); |
| 253 if (!running) | 278 if (!running) |
| 254 break; | 279 break; |
| 255 FinishAnimation(running->sequence); | 280 if (FinishAnimation(running->sequence) == DESTROYED) |
| 281 return; | |
| 256 } | 282 } |
| 257 } | 283 } |
| 258 | 284 |
| 259 void LayerAnimator::StopAnimating() { | 285 void LayerAnimator::StopAnimating() { |
| 260 while (is_animating()) | 286 while (is_animating()) { |
| 261 FinishAnimation(running_animations_[0].sequence); | 287 if (FinishAnimation(running_animations_[0].sequence) == DESTROYED) |
| 288 return; | |
| 289 } | |
| 262 } | 290 } |
| 263 | 291 |
| 264 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) { | 292 void LayerAnimator::AddObserver(LayerAnimationObserver* observer) { |
| 265 if (!observers_.HasObserver(observer)) | 293 if (!observers_.HasObserver(observer)) |
| 266 observers_.AddObserver(observer); | 294 observers_.AddObserver(observer); |
| 267 } | 295 } |
| 268 | 296 |
| 269 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { | 297 void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) { |
| 270 observers_.RemoveObserver(observer); | 298 observers_.RemoveObserver(observer); |
| 271 // Remove the observer from all sequences as well. | 299 // Remove the observer from all sequences as well. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 // animations. | 331 // animations. |
| 304 RunningAnimations running_animations_copy = running_animations_; | 332 RunningAnimations running_animations_copy = running_animations_; |
| 305 bool needs_redraw = false; | 333 bool needs_redraw = false; |
| 306 for (size_t i = 0; i < running_animations_copy.size(); ++i) { | 334 for (size_t i = 0; i < running_animations_copy.size(); ++i) { |
| 307 if (!HasAnimation(running_animations_copy[i].sequence)) | 335 if (!HasAnimation(running_animations_copy[i].sequence)) |
| 308 continue; | 336 continue; |
| 309 | 337 |
| 310 base::TimeDelta delta = now - running_animations_copy[i].start_time; | 338 base::TimeDelta delta = now - running_animations_copy[i].start_time; |
| 311 if (delta >= running_animations_copy[i].sequence->duration() && | 339 if (delta >= running_animations_copy[i].sequence->duration() && |
| 312 !running_animations_copy[i].sequence->is_cyclic()) { | 340 !running_animations_copy[i].sequence->is_cyclic()) { |
| 313 FinishAnimation(running_animations_copy[i].sequence); | 341 if (FinishAnimation(running_animations_copy[i].sequence) == DESTROYED) |
| 314 } else if (ProgressAnimation(running_animations_copy[i].sequence, delta)) | 342 return; |
| 315 needs_redraw = true; | 343 needs_redraw = true; |
| 344 } else { | |
| 345 scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_); | |
| 346 const bool progress_result = | |
| 347 ProgressAnimation(running_animations_copy[i].sequence, delta); | |
| 348 if (!tracker->is_alive()) | |
| 349 return; | |
| 350 if (progress_result) | |
| 351 needs_redraw = true; | |
| 352 } | |
| 316 } | 353 } |
| 317 | 354 |
| 318 if (needs_redraw && delegate()) | 355 if (needs_redraw && delegate()) |
| 319 delegate()->ScheduleDrawForAnimation(); | 356 delegate()->ScheduleDrawForAnimation(); |
| 320 } | 357 } |
| 321 | 358 |
| 322 void LayerAnimator::SetStartTime(base::TimeTicks start_time) { | 359 void LayerAnimator::SetStartTime(base::TimeTicks start_time) { |
| 323 // Do nothing. | 360 // Do nothing. |
| 324 } | 361 } |
| 325 | 362 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 if ((*queue_iter) == sequence) { | 402 if ((*queue_iter) == sequence) { |
| 366 to_return = *queue_iter; | 403 to_return = *queue_iter; |
| 367 animation_queue_.erase(queue_iter); | 404 animation_queue_.erase(queue_iter); |
| 368 break; | 405 break; |
| 369 } | 406 } |
| 370 } | 407 } |
| 371 | 408 |
| 372 return to_return.release(); | 409 return to_return.release(); |
| 373 } | 410 } |
| 374 | 411 |
| 375 void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) { | 412 LayerAnimator::DestroyedType LayerAnimator::FinishAnimation( |
| 413 LayerAnimationSequence* sequence) { | |
| 376 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); | 414 scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence)); |
| 377 sequence->Progress(sequence->duration(), delegate()); | 415 { |
| 416 scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_); | |
| 417 sequence->Progress(sequence->duration(), delegate()); | |
| 418 if (!tracker->is_alive()) | |
| 419 return DESTROYED; | |
| 420 } | |
| 378 ProcessQueue(); | 421 ProcessQueue(); |
| 379 UpdateAnimationState(); | 422 UpdateAnimationState(); |
| 423 return NOT_DESTROYED; | |
| 380 } | 424 } |
| 381 | 425 |
| 382 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { | 426 void LayerAnimator::FinishAnyAnimationWithZeroDuration() { |
| 383 // Special case: if we've started a 0 duration animation, just finish it now | 427 // Special case: if we've started a 0 duration animation, just finish it now |
| 384 // and get rid of it. We need to make a copy because Progress may indirectly | 428 // and get rid of it. We need to make a copy because Progress may indirectly |
| 385 // cause new animations to start running. | 429 // cause new animations to start running. |
| 386 RunningAnimations running_animations_copy = running_animations_; | 430 RunningAnimations running_animations_copy = running_animations_; |
| 387 for (size_t i = 0; i < running_animations_copy.size(); ++i) { | 431 for (size_t i = 0; i < running_animations_copy.size(); ++i) { |
| 388 if (!HasAnimation(running_animations_copy[i].sequence)) | 432 if (!HasAnimation(running_animations_copy[i].sequence)) |
| 389 continue; | 433 continue; |
| 390 | 434 |
| 391 if (running_animations_copy[i].sequence->duration() == base::TimeDelta()) { | 435 if (running_animations_copy[i].sequence->duration() == base::TimeDelta()) { |
| 392 running_animations_copy[i].sequence->Progress( | 436 running_animations_copy[i].sequence->Progress( |
| 393 running_animations_copy[i].sequence->duration(), delegate()); | 437 running_animations_copy[i].sequence->duration(), delegate()); |
|
Ian Vollick
2012/09/06 00:57:35
Seems like there's a chance we could delete 'this'
| |
| 394 scoped_ptr<LayerAnimationSequence> removed( | 438 scoped_ptr<LayerAnimationSequence> removed( |
| 395 RemoveAnimation(running_animations_copy[i].sequence)); | 439 RemoveAnimation(running_animations_copy[i].sequence)); |
| 396 } | 440 } |
| 397 } | 441 } |
| 398 ProcessQueue(); | 442 ProcessQueue(); |
| 399 UpdateAnimationState(); | 443 UpdateAnimationState(); |
| 400 } | 444 } |
| 401 | 445 |
| 402 void LayerAnimator::ClearAnimations() { | 446 void LayerAnimator::ClearAnimations() { |
| 403 // Abort should never affect the set of running animations, but just in case | 447 // Abort should never affect the set of running animations, but just in case |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 continue; | 501 continue; |
| 458 | 502 |
| 459 if (running_animations_copy[i].sequence->HasCommonProperty( | 503 if (running_animations_copy[i].sequence->HasCommonProperty( |
| 460 sequence->properties())) { | 504 sequence->properties())) { |
| 461 scoped_ptr<LayerAnimationSequence> removed( | 505 scoped_ptr<LayerAnimationSequence> removed( |
| 462 RemoveAnimation(running_animations_copy[i].sequence)); | 506 RemoveAnimation(running_animations_copy[i].sequence)); |
| 463 if (abort) | 507 if (abort) |
| 464 running_animations_copy[i].sequence->Abort(); | 508 running_animations_copy[i].sequence->Abort(); |
| 465 else | 509 else |
| 466 running_animations_copy[i].sequence->Progress( | 510 running_animations_copy[i].sequence->Progress( |
| 467 running_animations_copy[i].sequence->duration(), delegate()); | 511 running_animations_copy[i].sequence->duration(), delegate()); |
|
Ian Vollick
2012/09/06 00:57:35
This seems like another place we can bail early if
| |
| 468 } | 512 } |
| 469 } | 513 } |
| 470 | 514 |
| 471 // Same for the queued animations that haven't been started. Again, we'll | 515 // Same for the queued animations that haven't been started. Again, we'll |
| 472 // need to operate on a copy. | 516 // need to operate on a copy. |
| 473 std::vector<LayerAnimationSequence*> sequences; | 517 std::vector<LayerAnimationSequence*> sequences; |
| 474 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); | 518 for (AnimationQueue::iterator queue_iter = animation_queue_.begin(); |
| 475 queue_iter != animation_queue_.end(); ++queue_iter) | 519 queue_iter != animation_queue_.end(); ++queue_iter) |
| 476 sequences.push_back((*queue_iter).get()); | 520 sequences.push_back((*queue_iter).get()); |
| 477 | 521 |
| 478 for (size_t i = 0; i < sequences.size(); ++i) { | 522 for (size_t i = 0; i < sequences.size(); ++i) { |
| 479 if (!HasAnimation(sequences[i])) | 523 if (!HasAnimation(sequences[i])) |
| 480 continue; | 524 continue; |
| 481 | 525 |
| 482 if (sequences[i]->HasCommonProperty(sequence->properties())) { | 526 if (sequences[i]->HasCommonProperty(sequence->properties())) { |
| 483 scoped_ptr<LayerAnimationSequence> removed( | 527 scoped_ptr<LayerAnimationSequence> removed( |
| 484 RemoveAnimation(sequences[i])); | 528 RemoveAnimation(sequences[i])); |
| 485 if (abort) | 529 if (abort) |
| 486 sequences[i]->Abort(); | 530 sequences[i]->Abort(); |
| 487 else | 531 else |
| 488 sequences[i]->Progress(sequences[i]->duration(), delegate()); | 532 sequences[i]->Progress(sequences[i]->duration(), delegate()); |
|
Ian Vollick
2012/09/06 00:57:35
Same here.
| |
| 489 } | 533 } |
| 490 } | 534 } |
| 491 } | 535 } |
| 492 | 536 |
| 493 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { | 537 void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) { |
| 494 // Ensure that sequence is disposed of when this function completes. | 538 // Ensure that sequence is disposed of when this function completes. |
| 495 scoped_ptr<LayerAnimationSequence> to_dispose(sequence); | 539 scoped_ptr<LayerAnimationSequence> to_dispose(sequence); |
| 496 const bool abort = false; | 540 const bool abort = false; |
| 497 RemoveAllAnimationsWithACommonProperty(sequence, abort); | 541 RemoveAllAnimationsWithACommonProperty(sequence, abort); |
| 498 LayerAnimationSequence* removed = RemoveAnimation(sequence); | 542 LayerAnimationSequence* removed = RemoveAnimation(sequence); |
| 499 DCHECK(removed == NULL || removed == sequence); | 543 DCHECK(removed == NULL || removed == sequence); |
| 500 sequence->Progress(sequence->duration(), delegate()); | 544 sequence->Progress(sequence->duration(), delegate()); |
|
Ian Vollick
2012/09/06 00:57:35
Same here.
| |
| 501 } | 545 } |
| 502 | 546 |
| 503 void LayerAnimator::ImmediatelyAnimateToNewTarget( | 547 void LayerAnimator::ImmediatelyAnimateToNewTarget( |
| 504 LayerAnimationSequence* sequence) { | 548 LayerAnimationSequence* sequence) { |
| 505 const bool abort = true; | 549 const bool abort = true; |
| 506 RemoveAllAnimationsWithACommonProperty(sequence, abort); | 550 RemoveAllAnimationsWithACommonProperty(sequence, abort); |
| 507 AddToQueueIfNotPresent(sequence); | 551 AddToQueueIfNotPresent(sequence); |
| 508 StartSequenceImmediately(sequence); | 552 StartSequenceImmediately(sequence); |
| 509 } | 553 } |
| 510 | 554 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 } | 671 } |
| 628 } | 672 } |
| 629 sequence->OnScheduled(); | 673 sequence->OnScheduled(); |
| 630 } | 674 } |
| 631 | 675 |
| 632 base::TimeDelta LayerAnimator::GetTransitionDuration() const { | 676 base::TimeDelta LayerAnimator::GetTransitionDuration() const { |
| 633 return transition_duration_; | 677 return transition_duration_; |
| 634 } | 678 } |
| 635 | 679 |
| 636 } // namespace ui | 680 } // namespace ui |
| OLD | NEW |