| Index: ui/compositor/layer_animator.cc
|
| diff --git a/ui/compositor/layer_animator.cc b/ui/compositor/layer_animator.cc
|
| index fbb298ad88797ee6a661e5ce17696e36519614ad..7c12d33a84b61d7fcb02bc03874496f7e0909f87 100644
|
| --- a/ui/compositor/layer_animator.cc
|
| +++ b/ui/compositor/layer_animator.cc
|
| @@ -28,6 +28,29 @@ static const base::TimeDelta kTimerInterval =
|
|
|
| } // namespace
|
|
|
| +class LayerAnimator::DestroyedTracker
|
| + : public base::RefCounted<LayerAnimator::DestroyedTracker> {
|
| + public:
|
| + DestroyedTracker() : is_alive_(true) {}
|
| + virtual ~DestroyedTracker() {
|
| + DCHECK(!is_alive_);
|
| + }
|
| +
|
| + // Returns true if the animator is still alive.
|
| + bool is_alive() const { return is_alive_; }
|
| +
|
| + // Invoked when the animator is destroyed.
|
| + void AnimatorDeleted() {
|
| + DCHECK(is_alive_);
|
| + is_alive_ = false;
|
| + }
|
| +
|
| + private:
|
| + bool is_alive_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DestroyedTracker);
|
| +};
|
| +
|
| // static
|
| bool LayerAnimator::disable_animations_for_test_ = false;
|
| // static
|
| @@ -43,13 +66,15 @@ LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
|
| transition_duration_(transition_duration),
|
| tween_type_(Tween::LINEAR),
|
| is_started_(false),
|
| - disable_timer_for_test_(false) {
|
| + disable_timer_for_test_(false),
|
| + destroyed_tracker_(new DestroyedTracker) {
|
| }
|
|
|
| LayerAnimator::~LayerAnimator() {
|
| for (size_t i = 0; i < running_animations_.size(); ++i)
|
| running_animations_[i].sequence->OnAnimatorDestroyed();
|
| ClearAnimations();
|
| + destroyed_tracker_->AnimatorDeleted();
|
| }
|
|
|
| // static
|
| @@ -252,13 +277,16 @@ void LayerAnimator::StopAnimatingProperty(
|
| RunningAnimation* running = GetRunningAnimation(property);
|
| if (!running)
|
| break;
|
| - FinishAnimation(running->sequence);
|
| + if (FinishAnimation(running->sequence) == DESTROYED)
|
| + return;
|
| }
|
| }
|
|
|
| void LayerAnimator::StopAnimating() {
|
| - while (is_animating())
|
| - FinishAnimation(running_animations_[0].sequence);
|
| + while (is_animating()) {
|
| + if (FinishAnimation(running_animations_[0].sequence) == DESTROYED)
|
| + return;
|
| + }
|
| }
|
|
|
| void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
|
| @@ -310,9 +338,18 @@ void LayerAnimator::Step(base::TimeTicks now) {
|
| base::TimeDelta delta = now - running_animations_copy[i].start_time;
|
| if (delta >= running_animations_copy[i].sequence->duration() &&
|
| !running_animations_copy[i].sequence->is_cyclic()) {
|
| - FinishAnimation(running_animations_copy[i].sequence);
|
| - } else if (ProgressAnimation(running_animations_copy[i].sequence, delta))
|
| + if (FinishAnimation(running_animations_copy[i].sequence) == DESTROYED)
|
| + return;
|
| needs_redraw = true;
|
| + } else {
|
| + scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_);
|
| + const bool progress_result =
|
| + ProgressAnimation(running_animations_copy[i].sequence, delta);
|
| + if (!tracker->is_alive())
|
| + return;
|
| + if (progress_result)
|
| + needs_redraw = true;
|
| + }
|
| }
|
|
|
| if (needs_redraw && delegate())
|
| @@ -372,11 +409,18 @@ LayerAnimationSequence* LayerAnimator::RemoveAnimation(
|
| return to_return.release();
|
| }
|
|
|
| -void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
|
| +LayerAnimator::DestroyedType LayerAnimator::FinishAnimation(
|
| + LayerAnimationSequence* sequence) {
|
| scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
|
| - sequence->Progress(sequence->duration(), delegate());
|
| + {
|
| + scoped_refptr<DestroyedTracker> tracker(destroyed_tracker_);
|
| + sequence->Progress(sequence->duration(), delegate());
|
| + if (!tracker->is_alive())
|
| + return DESTROYED;
|
| + }
|
| ProcessQueue();
|
| UpdateAnimationState();
|
| + return NOT_DESTROYED;
|
| }
|
|
|
| void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
|
|
|