| Index: ui/compositor/layer_animator.cc
|
| ===================================================================
|
| --- ui/compositor/layer_animator.cc (revision 157564)
|
| +++ ui/compositor/layer_animator.cc (working copy)
|
| @@ -38,6 +38,32 @@
|
|
|
| } // namespace
|
|
|
| +class LayerAnimator::DestroyedTracker
|
| + : public base::RefCounted<LayerAnimator::DestroyedTracker> {
|
| + public:
|
| + DestroyedTracker() : is_alive_(true) {}
|
| +
|
| + // 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:
|
| + friend class base::RefCounted<DestroyedTracker>;
|
| +
|
| + ~DestroyedTracker() {
|
| + DCHECK(!is_alive_);
|
| + }
|
| +
|
| + bool is_alive_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DestroyedTracker);
|
| +};
|
| +
|
| // static
|
| bool LayerAnimator::disable_animations_for_test_ = false;
|
| // static
|
| @@ -53,14 +79,15 @@
|
| 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();
|
| - ClearAnimationsInternal();
|
| - delegate_ = NULL;
|
| + ClearAnimations();
|
| + destroyed_tracker_->AnimatorDeleted();
|
| }
|
|
|
| // static
|
| @@ -159,11 +186,11 @@
|
| }
|
|
|
| void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
|
| + DCHECK(delegate);
|
| delegate_ = delegate;
|
| }
|
|
|
| void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| OnScheduled(animation);
|
| if (!StartSequenceImmediately(animation)) {
|
| // Attempt to preempt a running animation.
|
| @@ -192,7 +219,6 @@
|
| }
|
|
|
| void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| OnScheduled(animation);
|
| if (is_animating()) {
|
| animation_queue_.push_back(make_linked_ptr(animation));
|
| @@ -205,8 +231,6 @@
|
|
|
| void LayerAnimator::ScheduleTogether(
|
| const std::vector<LayerAnimationSequence*>& animations) {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| -
|
| // Collect all the affected properties.
|
| LayerAnimationElement::AnimatableProperties animated_properties;
|
| std::vector<LayerAnimationSequence*>::const_iterator iter;
|
| @@ -262,19 +286,20 @@
|
|
|
| void LayerAnimator::StopAnimatingProperty(
|
| LayerAnimationElement::AnimatableProperty property) {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| while (true) {
|
| RunningAnimation* running = GetRunningAnimation(property);
|
| if (!running)
|
| break;
|
| - FinishAnimation(running->sequence);
|
| + if (FinishAnimation(running->sequence) == DESTROYED)
|
| + return;
|
| }
|
| }
|
|
|
| void LayerAnimator::StopAnimating() {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| - while (is_animating())
|
| - FinishAnimation(running_animations_[0].sequence);
|
| + while (is_animating()) {
|
| + if (FinishAnimation(running_animations_[0].sequence) == DESTROYED)
|
| + return;
|
| + }
|
| }
|
|
|
| void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
|
| @@ -293,12 +318,9 @@
|
|
|
| // LayerAnimator protected -----------------------------------------------------
|
|
|
| -void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
|
| +bool LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
|
| base::TimeDelta delta) {
|
| - if (!delegate())
|
| - return;
|
| -
|
| - sequence->Progress(delta, delegate());
|
| + return sequence->Progress(delta, delegate());
|
| }
|
|
|
|
|
| @@ -315,7 +337,6 @@
|
|
|
| void LayerAnimator::Step(base::TimeTicks now) {
|
| TRACE_EVENT0("ui", "LayerAnimator::Step");
|
| - scoped_refptr<LayerAnimator> retain(this);
|
|
|
| last_step_time_ = now;
|
|
|
| @@ -323,6 +344,7 @@
|
| // and finishing them may indirectly affect the collection of running
|
| // animations.
|
| RunningAnimations running_animations_copy = running_animations_;
|
| + bool needs_redraw = false;
|
| for (size_t i = 0; i < running_animations_copy.size(); ++i) {
|
| if (!HasAnimation(running_animations_copy[i].sequence))
|
| continue;
|
| @@ -330,10 +352,22 @@
|
| 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
|
| - 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())
|
| + delegate()->ScheduleDrawForAnimation();
|
| }
|
|
|
| void LayerAnimator::SetStartTime(base::TimeTicks start_time) {
|
| @@ -383,17 +417,21 @@
|
| return to_return.release();
|
| }
|
|
|
| -void LayerAnimator::FinishAnimation(LayerAnimationSequence* sequence) {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| +LayerAnimator::DestroyedType LayerAnimator::FinishAnimation(
|
| + LayerAnimationSequence* sequence) {
|
| scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
|
| - if (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() {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| // Special case: if we've started a 0 duration animation, just finish it now
|
| // and get rid of it. We need to make a copy because Progress may indirectly
|
| // cause new animations to start running.
|
| @@ -403,8 +441,8 @@
|
| continue;
|
|
|
| if (running_animations_copy[i].sequence->duration() == base::TimeDelta()) {
|
| - ProgressAnimation(running_animations_copy[i].sequence,
|
| - running_animations_copy[i].sequence->duration());
|
| + running_animations_copy[i].sequence->Progress(
|
| + running_animations_copy[i].sequence->duration(), delegate());
|
| scoped_ptr<LayerAnimationSequence> removed(
|
| RemoveAnimation(running_animations_copy[i].sequence));
|
| }
|
| @@ -414,8 +452,23 @@
|
| }
|
|
|
| void LayerAnimator::ClearAnimations() {
|
| - scoped_refptr<LayerAnimator> retain(this);
|
| - ClearAnimationsInternal();
|
| + // Abort should never affect the set of running animations, but just in case
|
| + // clients are badly behaved, we will use a copy of the running animations.
|
| + RunningAnimations running_animations_copy = running_animations_;
|
| + for (size_t i = 0; i < running_animations_copy.size(); ++i) {
|
| + if (!HasAnimation(running_animations_copy[i].sequence))
|
| + continue;
|
| +
|
| + scoped_ptr<LayerAnimationSequence> removed(
|
| + RemoveAnimation(running_animations_copy[i].sequence));
|
| + if (removed.get())
|
| + removed->Abort();
|
| + }
|
| + // This *should* have cleared the list of running animations.
|
| + DCHECK(running_animations_.empty());
|
| + running_animations_.clear();
|
| + animation_queue_.clear();
|
| + UpdateAnimationState();
|
| }
|
|
|
| LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
|
| @@ -462,8 +515,8 @@
|
| if (abort)
|
| running_animations_copy[i].sequence->Abort();
|
| else
|
| - ProgressAnimation(running_animations_copy[i].sequence,
|
| - running_animations_copy[i].sequence->duration());
|
| + running_animations_copy[i].sequence->Progress(
|
| + running_animations_copy[i].sequence->duration(), delegate());
|
| }
|
| }
|
|
|
| @@ -484,7 +537,7 @@
|
| if (abort)
|
| sequences[i]->Abort();
|
| else
|
| - ProgressAnimation(sequences[i], sequences[i]->duration());
|
| + sequences[i]->Progress(sequences[i]->duration(), delegate());
|
| }
|
| }
|
| }
|
| @@ -496,7 +549,7 @@
|
| RemoveAllAnimationsWithACommonProperty(sequence, abort);
|
| LayerAnimationSequence* removed = RemoveAnimation(sequence);
|
| DCHECK(removed == NULL || removed == sequence);
|
| - ProgressAnimation(sequence, sequence->duration());
|
| + sequence->Progress(sequence->duration(), delegate());
|
| }
|
|
|
| void LayerAnimator::ImmediatelyAnimateToNewTarget(
|
| @@ -639,24 +692,4 @@
|
| return transition_duration_;
|
| }
|
|
|
| -void LayerAnimator::ClearAnimationsInternal() {
|
| - // Abort should never affect the set of running animations, but just in case
|
| - // clients are badly behaved, we will use a copy of the running animations.
|
| - RunningAnimations running_animations_copy = running_animations_;
|
| - for (size_t i = 0; i < running_animations_copy.size(); ++i) {
|
| - if (!HasAnimation(running_animations_copy[i].sequence))
|
| - continue;
|
| -
|
| - scoped_ptr<LayerAnimationSequence> removed(
|
| - RemoveAnimation(running_animations_copy[i].sequence));
|
| - if (removed.get())
|
| - removed->Abort();
|
| - }
|
| - // This *should* have cleared the list of running animations.
|
| - DCHECK(running_animations_.empty());
|
| - running_animations_.clear();
|
| - animation_queue_.clear();
|
| - UpdateAnimationState();
|
| -}
|
| -
|
| } // namespace ui
|
|
|