layer_animator.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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
3// found in the LICENSE file.
4
5#include "ui/compositor/layer_animator.h"
6
7#include "base/debug/trace_event.h"
8#include "base/logging.h"
9#include "base/memory/scoped_ptr.h"
10#include "cc/animation/animation_id_provider.h"
11#include "ui/base/animation/animation_container.h"
12#include "ui/compositor/compositor.h"
13#include "ui/compositor/layer.h"
14#include "ui/compositor/layer_animation_delegate.h"
15#include "ui/compositor/layer_animation_observer.h"
16#include "ui/compositor/layer_animation_sequence.h"
17
18#define SAFE_INVOKE_VOID(function, running_anim, ...) \
19    if (running_anim.is_sequence_alive()) \
20      function(running_anim.sequence(), ##__VA_ARGS__)
21#define SAFE_INVOKE_BOOL(function, running_anim) \
22    ((running_anim.is_sequence_alive()) \
23        ? function(running_anim.sequence()) \
24        : false)
25#define SAFE_INVOKE_PTR(function, running_anim) \
26    ((running_anim.is_sequence_alive()) \
27        ? function(running_anim.sequence()) \
28        : NULL)
29
30namespace ui {
31
32class LayerAnimator;
33
34namespace {
35
36const int kDefaultTransitionDurationMs = 120;
37const int kTimerIntervalMs = 10;
38
39// Returns the AnimationContainer we're added to.
40ui::AnimationContainer* GetAnimationContainer() {
41  static ui::AnimationContainer* container = NULL;
42  if (!container) {
43    container = new AnimationContainer();
44    container->AddRef();
45  }
46  return container;
47}
48
49}  // namespace
50
51// LayerAnimator public --------------------------------------------------------
52
53LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
54    : delegate_(NULL),
55      preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
56      transition_duration_(transition_duration),
57      tween_type_(Tween::LINEAR),
58      is_started_(false),
59      disable_timer_for_test_(false),
60      adding_animations_(false) {
61}
62
63LayerAnimator::~LayerAnimator() {
64  for (size_t i = 0; i < running_animations_.size(); ++i) {
65    if (running_animations_[i].is_sequence_alive())
66      running_animations_[i].sequence()->OnAnimatorDestroyed();
67  }
68  ClearAnimationsInternal();
69  delegate_ = NULL;
70}
71
72// static
73LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
74  return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
75}
76
77// static
78LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
79  return new LayerAnimator(
80      base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
81}
82
83// This macro provides the implementation for the setter and getter (well,
84// the getter of the target value) for an animated property. For example,
85// it is used for the implementations of SetTransform and GetTargetTransform.
86// It is worth noting that SetFoo avoids invoking the usual animation machinery
87// if the transition duration is zero -- in this case we just set the property
88// on the layer animation delegate immediately.
89#define ANIMATED_PROPERTY(type, property, name, member_type, member)  \
90void LayerAnimator::Set##name(type value) {                           \
91  base::TimeDelta duration = GetTransitionDuration();                 \
92  if (duration == base::TimeDelta() && delegate() &&                  \
93      (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) {              \
94    StopAnimatingProperty(LayerAnimationElement::property);           \
95    delegate()->Set##name##FromAnimation(value);                      \
96    return;                                                           \
97  }                                                                   \
98  scoped_ptr<LayerAnimationElement> element(                          \
99      LayerAnimationElement::Create##name##Element(value, duration)); \
100  element->set_tween_type(tween_type_);                               \
101  StartAnimation(new LayerAnimationSequence(element.release()));      \
102}                                                                     \
103                                                                      \
104member_type LayerAnimator::GetTarget##name() const {                  \
105  LayerAnimationElement::TargetValue target(delegate());              \
106  GetTargetValue(&target);                                            \
107  return target.member;                                               \
108}
109
110ANIMATED_PROPERTY(
111    const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform);
112ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds);
113ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity);
114ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
115ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
116ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
117ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
118
119void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
120  delegate_ = delegate;
121}
122
123void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
124  scoped_refptr<LayerAnimator> retain(this);
125  OnScheduled(animation);
126  if (!StartSequenceImmediately(animation)) {
127    // Attempt to preempt a running animation.
128    switch (preemption_strategy_) {
129      case IMMEDIATELY_SET_NEW_TARGET:
130        ImmediatelySetNewTarget(animation);
131        break;
132      case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
133        ImmediatelyAnimateToNewTarget(animation);
134        break;
135      case ENQUEUE_NEW_ANIMATION:
136        EnqueueNewAnimation(animation);
137        break;
138      case REPLACE_QUEUED_ANIMATIONS:
139        ReplaceQueuedAnimations(animation);
140        break;
141      case BLEND_WITH_CURRENT_ANIMATION: {
142        // TODO(vollick) Add support for blended sequences and use them here.
143        NOTIMPLEMENTED();
144        break;
145      }
146    }
147  }
148  FinishAnyAnimationWithZeroDuration();
149  UpdateAnimationState();
150}
151
152void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
153  scoped_refptr<LayerAnimator> retain(this);
154  OnScheduled(animation);
155  if (is_animating()) {
156    animation_queue_.push_back(make_linked_ptr(animation));
157    ProcessQueue();
158  } else {
159    StartSequenceImmediately(animation);
160  }
161  UpdateAnimationState();
162}
163
164void LayerAnimator::StartTogether(
165    const std::vector<LayerAnimationSequence*>& animations) {
166  scoped_refptr<LayerAnimator> retain(this);
167  if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
168    std::vector<LayerAnimationSequence*>::const_iterator iter;
169    for (iter = animations.begin(); iter != animations.end(); ++iter) {
170      StartAnimation(*iter);
171    }
172    return;
173  }
174
175  adding_animations_ = true;
176  if (!is_animating()) {
177    if (GetAnimationContainer()->is_running())
178      last_step_time_ = GetAnimationContainer()->last_tick_time();
179    else
180      last_step_time_ = base::TimeTicks::Now();
181  }
182
183  // Collect all the affected properties.
184  LayerAnimationElement::AnimatableProperties animated_properties;
185  std::vector<LayerAnimationSequence*>::const_iterator iter;
186  for (iter = animations.begin(); iter != animations.end(); ++iter) {
187    animated_properties.insert((*iter)->properties().begin(),
188                               (*iter)->properties().end());
189  }
190
191  // Starting a zero duration pause that affects all the animated properties
192  // will prevent any of the sequences from animating until there are no
193  // running animations that affect any of these properties, as well as
194  // handle preemption strategy.
195  StartAnimation(new LayerAnimationSequence(
196      LayerAnimationElement::CreatePauseElement(animated_properties,
197                                                base::TimeDelta())));
198
199  bool wait_for_group_start = false;
200  for (iter = animations.begin(); iter != animations.end(); ++iter)
201    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
202
203  int group_id = cc::AnimationIdProvider::NextGroupId();
204
205  // These animations (provided they don't animate any common properties) will
206  // now animate together if trivially scheduled.
207  for (iter = animations.begin(); iter != animations.end(); ++iter) {
208    (*iter)->set_animation_group_id(group_id);
209    (*iter)->set_waiting_for_group_start(wait_for_group_start);
210    ScheduleAnimation(*iter);
211  }
212
213  adding_animations_ = false;
214  UpdateAnimationState();
215}
216
217
218void LayerAnimator::ScheduleTogether(
219    const std::vector<LayerAnimationSequence*>& animations) {
220  scoped_refptr<LayerAnimator> retain(this);
221
222  // Collect all the affected properties.
223  LayerAnimationElement::AnimatableProperties animated_properties;
224  std::vector<LayerAnimationSequence*>::const_iterator iter;
225  for (iter = animations.begin(); iter != animations.end(); ++iter) {
226    animated_properties.insert((*iter)->properties().begin(),
227                               (*iter)->properties().end());
228  }
229
230  // Scheduling a zero duration pause that affects all the animated properties
231  // will prevent any of the sequences from animating until there are no
232  // running animations that affect any of these properties.
233  ScheduleAnimation(new LayerAnimationSequence(
234      LayerAnimationElement::CreatePauseElement(animated_properties,
235                                                base::TimeDelta())));
236
237  bool wait_for_group_start = false;
238  for (iter = animations.begin(); iter != animations.end(); ++iter)
239    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
240
241  int group_id = cc::AnimationIdProvider::NextGroupId();
242
243  // These animations (provided they don't animate any common properties) will
244  // now animate together if trivially scheduled.
245  for (iter = animations.begin(); iter != animations.end(); ++iter) {
246    (*iter)->set_animation_group_id(group_id);
247    (*iter)->set_waiting_for_group_start(wait_for_group_start);
248    ScheduleAnimation(*iter);
249  }
250
251  UpdateAnimationState();
252}
253
254void LayerAnimator::SchedulePauseForProperties(
255    base::TimeDelta duration,
256    LayerAnimationElement::AnimatableProperty property,
257    ...) {
258  ui::LayerAnimationElement::AnimatableProperties properties_to_pause;
259  va_list marker;
260  va_start(marker, property);
261  for (int p = static_cast<int>(property); p != -1; p = va_arg(marker, int)) {
262    properties_to_pause.insert(
263        static_cast<LayerAnimationElement::AnimatableProperty>(p));
264  }
265  va_end(marker);
266  ScheduleAnimation(new ui::LayerAnimationSequence(
267                        ui::LayerAnimationElement::CreatePauseElement(
268                            properties_to_pause, duration)));
269}
270
271bool LayerAnimator::IsAnimatingProperty(
272    LayerAnimationElement::AnimatableProperty property) const {
273  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
274       queue_iter != animation_queue_.end(); ++queue_iter) {
275    if ((*queue_iter)->properties().find(property) !=
276        (*queue_iter)->properties().end()) {
277      return true;
278    }
279  }
280  return false;
281}
282
283void LayerAnimator::StopAnimatingProperty(
284    LayerAnimationElement::AnimatableProperty property) {
285  scoped_refptr<LayerAnimator> retain(this);
286  while (true) {
287    // GetRunningAnimation purges deleted animations before searching, so we are
288    // guaranteed to find a live animation if any is returned at all.
289    RunningAnimation* running = GetRunningAnimation(property);
290    if (!running)
291      break;
292    // As was mentioned above, this sequence must be alive.
293    DCHECK(running->is_sequence_alive());
294    FinishAnimation(running->sequence(), false);
295  }
296}
297
298void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
299  if (!observers_.HasObserver(observer))
300    observers_.AddObserver(observer);
301}
302
303void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
304  observers_.RemoveObserver(observer);
305  // Remove the observer from all sequences as well.
306  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
307       queue_iter != animation_queue_.end(); ++queue_iter) {
308    (*queue_iter)->RemoveObserver(observer);
309  }
310}
311
312void LayerAnimator::OnThreadedAnimationStarted(
313    const cc::AnimationEvent& event) {
314  LayerAnimationElement::AnimatableProperty property =
315    LayerAnimationElement::ToAnimatableProperty(event.target_property);
316
317  RunningAnimation* running = GetRunningAnimation(property);
318  if (!running)
319    return;
320  DCHECK(running->is_sequence_alive());
321
322  if (running->sequence()->animation_group_id() != event.group_id)
323    return;
324
325  running->sequence()->OnThreadedAnimationStarted(event);
326  if (!running->sequence()->waiting_for_group_start())
327    return;
328
329  base::TimeTicks start_time = base::TimeTicks::FromInternalValue(
330      event.monotonic_time * base::Time::kMicrosecondsPerSecond);
331
332  running->sequence()->set_waiting_for_group_start(false);
333
334  // The call to GetRunningAnimation made above already purged deleted
335  // animations, so we are guaranteed that all the animations we iterate
336  // over now are alive.
337  for (RunningAnimations::iterator iter = running_animations_.begin();
338       iter != running_animations_.end(); ++iter) {
339    // Ensure that each sequence is only Started once, regardless of the
340    // number of sequences in the group that have threaded first elements.
341    if (((*iter).sequence()->animation_group_id() == event.group_id) &&
342        !(*iter).sequence()->IsFirstElementThreaded() &&
343        (*iter).sequence()->waiting_for_group_start()) {
344      (*iter).sequence()->set_start_time(start_time);
345      (*iter).sequence()->set_waiting_for_group_start(false);
346      (*iter).sequence()->Start(delegate());
347    }
348  }
349}
350
351// LayerAnimator protected -----------------------------------------------------
352
353void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
354                                      base::TimeTicks now) {
355  if (!delegate() || sequence->waiting_for_group_start())
356    return;
357
358  sequence->Progress(now, delegate());
359}
360
361void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
362  if (!delegate())
363    return;
364
365  sequence->ProgressToEnd(delegate());
366}
367
368bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
369  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
370       queue_iter != animation_queue_.end(); ++queue_iter) {
371    if ((*queue_iter).get() == sequence)
372      return true;
373  }
374  return false;
375}
376
377// LayerAnimator private -------------------------------------------------------
378
379void LayerAnimator::Step(base::TimeTicks now) {
380  TRACE_EVENT0("ui", "LayerAnimator::Step");
381  scoped_refptr<LayerAnimator> retain(this);
382
383  last_step_time_ = now;
384
385  PurgeDeletedAnimations();
386
387  // We need to make a copy of the running animations because progressing them
388  // and finishing them may indirectly affect the collection of running
389  // animations.
390  RunningAnimations running_animations_copy = running_animations_;
391  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
392    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
393      continue;
394
395    if (running_animations_copy[i].sequence()->IsFinished(now)) {
396      SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
397    } else {
398      SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
399    }
400  }
401}
402
403void LayerAnimator::SetStartTime(base::TimeTicks start_time) {
404  // Do nothing.
405}
406
407base::TimeDelta LayerAnimator::GetTimerInterval() const {
408  return base::TimeDelta::FromMilliseconds(kTimerIntervalMs);
409}
410
411void LayerAnimator::StopAnimatingInternal(bool abort) {
412  scoped_refptr<LayerAnimator> retain(this);
413  while (is_animating()) {
414    // We're going to attempt to finish the first running animation. Let's
415    // ensure that it's valid.
416    PurgeDeletedAnimations();
417
418    // If we've purged all running animations, attempt to start one up.
419    if (running_animations_.empty())
420      ProcessQueue();
421
422    DCHECK(!running_animations_.empty());
423
424    // Still no luck, let's just bail and clear all animations.
425    if (running_animations_.empty()) {
426      ClearAnimationsInternal();
427      break;
428    }
429
430    SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
431  }
432}
433
434void LayerAnimator::UpdateAnimationState() {
435  if (disable_timer_for_test_)
436    return;
437
438  const bool should_start = is_animating();
439  if (should_start && !is_started_)
440    GetAnimationContainer()->Start(this);
441  else if (!should_start && is_started_)
442    GetAnimationContainer()->Stop(this);
443
444  is_started_ = should_start;
445}
446
447LayerAnimationSequence* LayerAnimator::RemoveAnimation(
448    LayerAnimationSequence* sequence) {
449  linked_ptr<LayerAnimationSequence> to_return;
450
451  bool is_running = false;
452
453  // First remove from running animations
454  for (RunningAnimations::iterator iter = running_animations_.begin();
455       iter != running_animations_.end(); ++iter) {
456    if ((*iter).sequence() == sequence) {
457      running_animations_.erase(iter);
458      is_running = true;
459      break;
460    }
461  }
462
463  // Then remove from the queue
464  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
465       queue_iter != animation_queue_.end(); ++queue_iter) {
466    if ((*queue_iter) == sequence) {
467      to_return = *queue_iter;
468      animation_queue_.erase(queue_iter);
469      break;
470    }
471  }
472
473  if (!to_return.get() ||
474      !to_return->waiting_for_group_start() ||
475      !to_return->IsFirstElementThreaded())
476    return to_return.release();
477
478  // The removed sequence may have been responsible for making other sequences
479  // wait for a group start. If no other sequences in the group have a
480  // threaded first element, the group no longer needs the additional wait.
481  bool is_wait_still_needed = false;
482  int group_id = to_return->animation_group_id();
483  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
484       queue_iter != animation_queue_.end(); ++queue_iter) {
485    if (((*queue_iter)->animation_group_id() == group_id) &&
486        (*queue_iter)->IsFirstElementThreaded()) {
487      is_wait_still_needed = true;
488      break;
489    }
490  }
491
492  if (is_wait_still_needed)
493    return to_return.release();
494
495  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
496       queue_iter != animation_queue_.end(); ++queue_iter) {
497    if ((*queue_iter)->animation_group_id() == group_id &&
498        (*queue_iter)->waiting_for_group_start()) {
499      (*queue_iter)->set_waiting_for_group_start(false);
500      if (is_running) {
501        (*queue_iter)->set_start_time(last_step_time_);
502        (*queue_iter)->Start(delegate());
503      }
504    }
505  }
506  return to_return.release();
507}
508
509void LayerAnimator::FinishAnimation(
510    LayerAnimationSequence* sequence, bool abort) {
511  scoped_refptr<LayerAnimator> retain(this);
512  scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
513  if (abort)
514    sequence->Abort(delegate());
515  else
516    ProgressAnimationToEnd(sequence);
517  ProcessQueue();
518  UpdateAnimationState();
519}
520
521void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
522  scoped_refptr<LayerAnimator> retain(this);
523  // Special case: if we've started a 0 duration animation, just finish it now
524  // and get rid of it. We need to make a copy because Progress may indirectly
525  // cause new animations to start running.
526  RunningAnimations running_animations_copy = running_animations_;
527  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
528    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
529      continue;
530
531    if (running_animations_copy[i].sequence()->IsFinished(
532          running_animations_copy[i].sequence()->start_time())) {
533      SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
534      scoped_ptr<LayerAnimationSequence> removed(
535          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
536    }
537  }
538  ProcessQueue();
539  UpdateAnimationState();
540}
541
542void LayerAnimator::ClearAnimations() {
543  scoped_refptr<LayerAnimator> retain(this);
544  ClearAnimationsInternal();
545}
546
547LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
548    LayerAnimationElement::AnimatableProperty property) {
549  PurgeDeletedAnimations();
550  for (RunningAnimations::iterator iter = running_animations_.begin();
551       iter != running_animations_.end(); ++iter) {
552    if ((*iter).sequence()->properties().find(property) !=
553        (*iter).sequence()->properties().end())
554      return &(*iter);
555  }
556  return NULL;
557}
558
559void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
560  // If we don't have the animation in the queue yet, add it.
561  bool found_sequence = false;
562  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
563       queue_iter != animation_queue_.end(); ++queue_iter) {
564    if ((*queue_iter) == animation) {
565      found_sequence = true;
566      break;
567    }
568  }
569
570  if (!found_sequence)
571    animation_queue_.push_front(make_linked_ptr(animation));
572}
573
574void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
575    LayerAnimationSequence* sequence, bool abort) {
576  // For all the running animations, if they animate the same property,
577  // progress them to the end and remove them. Note, Aborting or Progressing
578  // animations may affect the collection of running animations, so we need to
579  // operate on a copy.
580  RunningAnimations running_animations_copy = running_animations_;
581  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
582    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
583      continue;
584
585    if (running_animations_copy[i].sequence()->HasConflictingProperty(
586            sequence->properties())) {
587      scoped_ptr<LayerAnimationSequence> removed(
588          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
589      if (abort)
590        running_animations_copy[i].sequence()->Abort(delegate());
591      else
592        SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
593    }
594  }
595
596  // Same for the queued animations that haven't been started. Again, we'll
597  // need to operate on a copy.
598  std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
599  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
600       queue_iter != animation_queue_.end(); ++queue_iter)
601    sequences.push_back((*queue_iter)->AsWeakPtr());
602
603  for (size_t i = 0; i < sequences.size(); ++i) {
604    if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
605      continue;
606
607    if (sequences[i]->HasConflictingProperty(sequence->properties())) {
608      scoped_ptr<LayerAnimationSequence> removed(
609          RemoveAnimation(sequences[i].get()));
610      if (abort)
611        sequences[i]->Abort(delegate());
612      else
613        ProgressAnimationToEnd(sequences[i].get());
614    }
615  }
616}
617
618void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
619  // Need to detect if our sequence gets destroyed.
620  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
621      sequence->AsWeakPtr();
622
623  const bool abort = false;
624  RemoveAllAnimationsWithACommonProperty(sequence, abort);
625  if (!weak_sequence_ptr.get())
626    return;
627
628  LayerAnimationSequence* removed = RemoveAnimation(sequence);
629  DCHECK(removed == NULL || removed == sequence);
630  if (!weak_sequence_ptr.get())
631    return;
632
633  ProgressAnimationToEnd(sequence);
634  if (!weak_sequence_ptr.get())
635    return;
636
637  delete sequence;
638}
639
640void LayerAnimator::ImmediatelyAnimateToNewTarget(
641    LayerAnimationSequence* sequence) {
642  // Need to detect if our sequence gets destroyed.
643  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
644      sequence->AsWeakPtr();
645
646  const bool abort = true;
647  RemoveAllAnimationsWithACommonProperty(sequence, abort);
648  if (!weak_sequence_ptr.get())
649    return;
650
651  AddToQueueIfNotPresent(sequence);
652  if (!weak_sequence_ptr.get())
653    return;
654
655  StartSequenceImmediately(sequence);
656}
657
658void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
659  // It is assumed that if there was no conflicting animation, we would
660  // not have been called. No need to check for a collision; just
661  // add to the queue.
662  animation_queue_.push_back(make_linked_ptr(sequence));
663  ProcessQueue();
664}
665
666void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
667  // Need to detect if our sequence gets destroyed.
668  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
669      sequence->AsWeakPtr();
670
671  // Remove all animations that aren't running. Note: at each iteration i is
672  // incremented or an element is removed from the queue, so
673  // animation_queue_.size() - i is always decreasing and we are always making
674  // progress towards the loop terminating.
675  for (size_t i = 0; i < animation_queue_.size();) {
676    if (!weak_sequence_ptr.get())
677      break;
678
679    PurgeDeletedAnimations();
680
681    bool is_running = false;
682    for (RunningAnimations::const_iterator iter = running_animations_.begin();
683         iter != running_animations_.end(); ++iter) {
684      if ((*iter).sequence() == animation_queue_[i].get()) {
685        is_running = true;
686        break;
687      }
688    }
689
690    if (!is_running)
691      delete RemoveAnimation(animation_queue_[i].get());
692    else
693      ++i;
694  }
695  animation_queue_.push_back(make_linked_ptr(sequence));
696  ProcessQueue();
697}
698
699void LayerAnimator::ProcessQueue() {
700  bool started_sequence = false;
701  do {
702    started_sequence = false;
703    // Build a list of all currently animated properties.
704    LayerAnimationElement::AnimatableProperties animated;
705    for (RunningAnimations::const_iterator iter = running_animations_.begin();
706         iter != running_animations_.end(); ++iter) {
707      if (!(*iter).is_sequence_alive())
708        continue;
709      animated.insert((*iter).sequence()->properties().begin(),
710                      (*iter).sequence()->properties().end());
711    }
712
713    // Try to find an animation that doesn't conflict with an animated
714    // property or a property that will be animated before it. Note: starting
715    // the animation may indirectly cause more animations to be started, so we
716    // need to operate on a copy.
717    std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
718    for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
719         queue_iter != animation_queue_.end(); ++queue_iter)
720      sequences.push_back((*queue_iter)->AsWeakPtr());
721
722    for (size_t i = 0; i < sequences.size(); ++i) {
723      if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
724        continue;
725
726      if (!sequences[i]->HasConflictingProperty(animated)) {
727        StartSequenceImmediately(sequences[i].get());
728        started_sequence = true;
729        break;
730      }
731
732      // Animation couldn't be started. Add its properties to the collection so
733      // that we don't start a conflicting animation. For example, if our queue
734      // has the elements { {T,B}, {B} } (that is, an element that animates both
735      // the transform and the bounds followed by an element that animates the
736      // bounds), and we're currently animating the transform, we can't start
737      // the first element because it animates the transform, too. We cannot
738      // start the second element, either, because the first element animates
739      // bounds too, and needs to go first.
740      animated.insert(sequences[i]->properties().begin(),
741                      sequences[i]->properties().end());
742    }
743
744    // If we started a sequence, try again. We may be able to start several.
745  } while (started_sequence);
746}
747
748bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
749  PurgeDeletedAnimations();
750
751  // Ensure that no one is animating one of the sequence's properties already.
752  for (RunningAnimations::const_iterator iter = running_animations_.begin();
753       iter != running_animations_.end(); ++iter) {
754    if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
755      return false;
756  }
757
758  // All clear, actually start the sequence. Note: base::TimeTicks::Now has
759  // a resolution that can be as bad as 15ms. If this causes glitches in the
760  // animations, this can be switched to HighResNow() (animation uses Now()
761  // internally).
762  // All LayerAnimators share the same AnimationContainer. Use the
763  // last_tick_time() from there to ensure animations started during the same
764  // event complete at the same time.
765  base::TimeTicks start_time;
766  if (is_animating() || adding_animations_)
767    start_time = last_step_time_;
768  else if (GetAnimationContainer()->is_running())
769    start_time = GetAnimationContainer()->last_tick_time();
770  else
771    start_time = base::TimeTicks::Now();
772
773  if (!sequence->animation_group_id())
774    sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
775  if (!sequence->waiting_for_group_start() ||
776      sequence->IsFirstElementThreaded()) {
777    sequence->set_start_time(start_time);
778    sequence->Start(delegate());
779  }
780  running_animations_.push_back(
781      RunningAnimation(sequence->AsWeakPtr()));
782
783  // Need to keep a reference to the animation.
784  AddToQueueIfNotPresent(sequence);
785
786  // Ensure that animations get stepped at their start time.
787  Step(start_time);
788
789  return true;
790}
791
792void LayerAnimator::GetTargetValue(
793    LayerAnimationElement::TargetValue* target) const {
794  for (AnimationQueue::const_iterator iter = animation_queue_.begin();
795       iter != animation_queue_.end(); ++iter) {
796    (*iter)->GetTargetValue(target);
797  }
798}
799
800void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
801  if (observers_.might_have_observers()) {
802    ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
803    LayerAnimationObserver* obs;
804    while ((obs = it.GetNext()) != NULL) {
805      sequence->AddObserver(obs);
806    }
807  }
808  sequence->OnScheduled();
809}
810
811base::TimeDelta LayerAnimator::GetTransitionDuration() const {
812  return transition_duration_;
813}
814
815void LayerAnimator::ClearAnimationsInternal() {
816  PurgeDeletedAnimations();
817
818  // Abort should never affect the set of running animations, but just in case
819  // clients are badly behaved, we will use a copy of the running animations.
820  RunningAnimations running_animations_copy = running_animations_;
821  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
822    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
823      continue;
824
825    scoped_ptr<LayerAnimationSequence> removed(
826        RemoveAnimation(running_animations_copy[i].sequence()));
827    if (removed.get())
828      removed->Abort(delegate());
829  }
830  // This *should* have cleared the list of running animations.
831  DCHECK(running_animations_.empty());
832  running_animations_.clear();
833  animation_queue_.clear();
834  UpdateAnimationState();
835}
836
837void LayerAnimator::PurgeDeletedAnimations() {
838  for (size_t i = 0; i < running_animations_.size();) {
839    if (!running_animations_[i].is_sequence_alive())
840      running_animations_.erase(running_animations_.begin() + i);
841    else
842      i++;
843  }
844}
845
846LayerAnimator::RunningAnimation::RunningAnimation(
847    const base::WeakPtr<LayerAnimationSequence>& sequence)
848    : sequence_(sequence) {
849}
850
851LayerAnimator::RunningAnimation::~RunningAnimation() { }
852
853}  // namespace ui
854