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