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