• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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 "cc/animation/layer_animation_controller.h"
6 
7 #include <algorithm>
8 
9 #include "cc/animation/animation.h"
10 #include "cc/animation/animation_delegate.h"
11 #include "cc/animation/animation_registrar.h"
12 #include "cc/animation/keyframed_animation_curve.h"
13 #include "cc/animation/layer_animation_value_observer.h"
14 #include "cc/animation/layer_animation_value_provider.h"
15 #include "cc/animation/scroll_offset_animation_curve.h"
16 #include "cc/base/scoped_ptr_algorithm.h"
17 #include "cc/output/filter_operations.h"
18 #include "ui/gfx/box_f.h"
19 #include "ui/gfx/transform.h"
20 
21 namespace cc {
22 
LayerAnimationController(int id)23 LayerAnimationController::LayerAnimationController(int id)
24     : registrar_(0),
25       id_(id),
26       is_active_(false),
27       last_tick_time_(0),
28       value_provider_(NULL),
29       layer_animation_delegate_(NULL) {}
30 
~LayerAnimationController()31 LayerAnimationController::~LayerAnimationController() {
32   if (registrar_)
33     registrar_->UnregisterAnimationController(this);
34 }
35 
Create(int id)36 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
37     int id) {
38   return make_scoped_refptr(new LayerAnimationController(id));
39 }
40 
PauseAnimation(int animation_id,double time_offset)41 void LayerAnimationController::PauseAnimation(int animation_id,
42                                               double time_offset) {
43   for (size_t i = 0; i < active_animations_.size(); ++i) {
44     if (active_animations_[i]->id() == animation_id) {
45       active_animations_[i]->SetRunState(
46           Animation::Paused, time_offset + active_animations_[i]->start_time());
47     }
48   }
49 }
50 
51 struct HasAnimationId {
HasAnimationIdcc::HasAnimationId52   explicit HasAnimationId(int id) : id_(id) {}
operator ()cc::HasAnimationId53   bool operator()(Animation* animation) const {
54     return animation->id() == id_;
55   }
56 
57  private:
58   int id_;
59 };
60 
RemoveAnimation(int animation_id)61 void LayerAnimationController::RemoveAnimation(int animation_id) {
62   ScopedPtrVector<Animation>& animations = active_animations_;
63   animations.erase(cc::remove_if(&animations,
64                                  animations.begin(),
65                                  animations.end(),
66                                  HasAnimationId(animation_id)),
67                    animations.end());
68   UpdateActivation(NormalActivation);
69 }
70 
71 struct HasAnimationIdAndProperty {
HasAnimationIdAndPropertycc::HasAnimationIdAndProperty72   HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
73       : id_(id), target_property_(target_property) {}
operator ()cc::HasAnimationIdAndProperty74   bool operator()(Animation* animation) const {
75     return animation->id() == id_ &&
76         animation->target_property() == target_property_;
77   }
78 
79  private:
80   int id_;
81   Animation::TargetProperty target_property_;
82 };
83 
RemoveAnimation(int animation_id,Animation::TargetProperty target_property)84 void LayerAnimationController::RemoveAnimation(
85     int animation_id,
86     Animation::TargetProperty target_property) {
87   ScopedPtrVector<Animation>& animations = active_animations_;
88   animations.erase(
89       cc::remove_if(&animations,
90                     animations.begin(),
91                     animations.end(),
92                     HasAnimationIdAndProperty(animation_id, target_property)),
93       animations.end());
94   UpdateActivation(NormalActivation);
95 }
96 
AbortAnimations(Animation::TargetProperty target_property)97 void LayerAnimationController::AbortAnimations(
98     Animation::TargetProperty target_property) {
99   for (size_t i = 0; i < active_animations_.size(); ++i) {
100     if (active_animations_[i]->target_property() == target_property &&
101         !active_animations_[i]->is_finished())
102       active_animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
103   }
104 }
105 
106 // Ensures that the list of active animations on the main thread and the impl
107 // thread are kept in sync.
PushAnimationUpdatesTo(LayerAnimationController * controller_impl)108 void LayerAnimationController::PushAnimationUpdatesTo(
109     LayerAnimationController* controller_impl) {
110   DCHECK(this != controller_impl);
111   if (!has_any_animation() && !controller_impl->has_any_animation())
112     return;
113   PurgeAnimationsMarkedForDeletion();
114   PushNewAnimationsToImplThread(controller_impl);
115 
116   // Remove finished impl side animations only after pushing,
117   // and only after the animations are deleted on the main thread
118   // this insures we will never push an animation twice.
119   RemoveAnimationsCompletedOnMainThread(controller_impl);
120 
121   PushPropertiesToImplThread(controller_impl);
122   controller_impl->UpdateActivation(NormalActivation);
123   UpdateActivation(NormalActivation);
124 }
125 
Animate(double monotonic_time)126 void LayerAnimationController::Animate(double monotonic_time) {
127   DCHECK(monotonic_time);
128   if (!HasValueObserver())
129     return;
130 
131   StartAnimations(monotonic_time);
132   TickAnimations(monotonic_time);
133   last_tick_time_ = monotonic_time;
134 }
135 
AccumulatePropertyUpdates(double monotonic_time,AnimationEventsVector * events)136 void LayerAnimationController::AccumulatePropertyUpdates(
137     double monotonic_time,
138     AnimationEventsVector* events) {
139   if (!events)
140     return;
141 
142   for (size_t i = 0; i < active_animations_.size(); ++i) {
143     Animation* animation = active_animations_[i];
144     if (!animation->is_impl_only())
145       continue;
146 
147     double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
148     switch (animation->target_property()) {
149       case Animation::Opacity: {
150         AnimationEvent event(AnimationEvent::PropertyUpdate,
151                              id_,
152                              animation->group(),
153                              Animation::Opacity,
154                              monotonic_time);
155         event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
156             trimmed);
157         event.is_impl_only = true;
158         events->push_back(event);
159         break;
160       }
161 
162       case Animation::Transform: {
163         AnimationEvent event(AnimationEvent::PropertyUpdate,
164                              id_,
165                              animation->group(),
166                              Animation::Transform,
167                              monotonic_time);
168         event.transform =
169             animation->curve()->ToTransformAnimationCurve()->GetValue(trimmed);
170         event.is_impl_only = true;
171         events->push_back(event);
172         break;
173       }
174 
175       case Animation::Filter: {
176         AnimationEvent event(AnimationEvent::PropertyUpdate,
177                              id_,
178                              animation->group(),
179                              Animation::Filter,
180                              monotonic_time);
181         event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue(
182             trimmed);
183         event.is_impl_only = true;
184         events->push_back(event);
185         break;
186       }
187 
188       case Animation::BackgroundColor: { break; }
189 
190       case Animation::ScrollOffset: {
191         // Impl-side changes to scroll offset are already sent back to the
192         // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
193         // isn't needed.
194         break;
195       }
196 
197       case Animation::TargetPropertyEnumSize:
198         NOTREACHED();
199     }
200   }
201 }
202 
UpdateState(bool start_ready_animations,AnimationEventsVector * events)203 void LayerAnimationController::UpdateState(bool start_ready_animations,
204                                            AnimationEventsVector* events) {
205   if (!HasActiveValueObserver())
206     return;
207 
208   if (start_ready_animations)
209     PromoteStartedAnimations(last_tick_time_, events);
210 
211   MarkFinishedAnimations(last_tick_time_);
212   MarkAnimationsForDeletion(last_tick_time_, events);
213 
214   if (start_ready_animations) {
215     StartAnimations(last_tick_time_);
216     PromoteStartedAnimations(last_tick_time_, events);
217   }
218 
219   AccumulatePropertyUpdates(last_tick_time_, events);
220 
221   UpdateActivation(NormalActivation);
222 }
223 
AddAnimation(scoped_ptr<Animation> animation)224 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
225   active_animations_.push_back(animation.Pass());
226   UpdateActivation(NormalActivation);
227 }
228 
GetAnimation(int group_id,Animation::TargetProperty target_property) const229 Animation* LayerAnimationController::GetAnimation(
230     int group_id,
231     Animation::TargetProperty target_property) const {
232   for (size_t i = 0; i < active_animations_.size(); ++i)
233     if (active_animations_[i]->group() == group_id &&
234         active_animations_[i]->target_property() == target_property)
235       return active_animations_[i];
236   return 0;
237 }
238 
GetAnimation(Animation::TargetProperty target_property) const239 Animation* LayerAnimationController::GetAnimation(
240     Animation::TargetProperty target_property) const {
241   for (size_t i = 0; i < active_animations_.size(); ++i) {
242     size_t index = active_animations_.size() - i - 1;
243     if (active_animations_[index]->target_property() == target_property)
244       return active_animations_[index];
245   }
246   return 0;
247 }
248 
HasActiveAnimation() const249 bool LayerAnimationController::HasActiveAnimation() const {
250   for (size_t i = 0; i < active_animations_.size(); ++i) {
251     if (!active_animations_[i]->is_finished())
252       return true;
253   }
254   return false;
255 }
256 
IsAnimatingProperty(Animation::TargetProperty target_property) const257 bool LayerAnimationController::IsAnimatingProperty(
258     Animation::TargetProperty target_property) const {
259   for (size_t i = 0; i < active_animations_.size(); ++i) {
260     if (!active_animations_[i]->is_finished() &&
261         active_animations_[i]->target_property() == target_property)
262       return true;
263   }
264   return false;
265 }
266 
SetAnimationRegistrar(AnimationRegistrar * registrar)267 void LayerAnimationController::SetAnimationRegistrar(
268     AnimationRegistrar* registrar) {
269   if (registrar_ == registrar)
270     return;
271 
272   if (registrar_)
273     registrar_->UnregisterAnimationController(this);
274 
275   registrar_ = registrar;
276   if (registrar_)
277     registrar_->RegisterAnimationController(this);
278 
279   UpdateActivation(ForceActivation);
280 }
281 
NotifyAnimationStarted(const AnimationEvent & event,double wall_clock_time)282 void LayerAnimationController::NotifyAnimationStarted(
283     const AnimationEvent& event,
284     double wall_clock_time) {
285   base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue(
286       event.monotonic_time * base::Time::kMicrosecondsPerSecond);
287   if (event.is_impl_only) {
288     FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
289                       OnAnimationStarted(event));
290     if (layer_animation_delegate_)
291       layer_animation_delegate_->NotifyAnimationStarted(
292           wall_clock_time, monotonic_time, event.target_property);
293 
294     return;
295   }
296 
297   for (size_t i = 0; i < active_animations_.size(); ++i) {
298     if (active_animations_[i]->group() == event.group_id &&
299         active_animations_[i]->target_property() == event.target_property &&
300         active_animations_[i]->needs_synchronized_start_time()) {
301       active_animations_[i]->set_needs_synchronized_start_time(false);
302       active_animations_[i]->set_start_time(event.monotonic_time);
303 
304       FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
305                         OnAnimationStarted(event));
306       if (layer_animation_delegate_)
307         layer_animation_delegate_->NotifyAnimationStarted(
308             wall_clock_time, monotonic_time, event.target_property);
309 
310       return;
311     }
312   }
313 }
314 
NotifyAnimationFinished(const AnimationEvent & event,double wall_clock_time)315 void LayerAnimationController::NotifyAnimationFinished(
316     const AnimationEvent& event,
317     double wall_clock_time) {
318   base::TimeTicks monotonic_time = base::TimeTicks::FromInternalValue(
319       event.monotonic_time * base::Time::kMicrosecondsPerSecond);
320   if (event.is_impl_only) {
321     if (layer_animation_delegate_)
322       layer_animation_delegate_->NotifyAnimationFinished(
323           wall_clock_time, monotonic_time, event.target_property);
324     return;
325   }
326 
327   for (size_t i = 0; i < active_animations_.size(); ++i) {
328     if (active_animations_[i]->group() == event.group_id &&
329         active_animations_[i]->target_property() == event.target_property) {
330       active_animations_[i]->set_received_finished_event(true);
331       if (layer_animation_delegate_)
332         layer_animation_delegate_->NotifyAnimationFinished(
333             wall_clock_time, monotonic_time, event.target_property);
334 
335       return;
336     }
337   }
338 }
339 
NotifyAnimationAborted(const AnimationEvent & event)340 void LayerAnimationController::NotifyAnimationAborted(
341     const AnimationEvent& event) {
342   for (size_t i = 0; i < active_animations_.size(); ++i) {
343     if (active_animations_[i]->group() == event.group_id &&
344         active_animations_[i]->target_property() == event.target_property) {
345       active_animations_[i]->SetRunState(Animation::Aborted,
346                                          event.monotonic_time);
347     }
348   }
349 }
350 
NotifyAnimationPropertyUpdate(const AnimationEvent & event)351 void LayerAnimationController::NotifyAnimationPropertyUpdate(
352     const AnimationEvent& event) {
353   switch (event.target_property) {
354     case Animation::Opacity:
355       NotifyObserversOpacityAnimated(event.opacity);
356       break;
357     case Animation::Transform:
358       NotifyObserversTransformAnimated(event.transform);
359       break;
360     default:
361       NOTREACHED();
362   }
363 }
364 
AddValueObserver(LayerAnimationValueObserver * observer)365 void LayerAnimationController::AddValueObserver(
366     LayerAnimationValueObserver* observer) {
367   if (!value_observers_.HasObserver(observer))
368     value_observers_.AddObserver(observer);
369 }
370 
RemoveValueObserver(LayerAnimationValueObserver * observer)371 void LayerAnimationController::RemoveValueObserver(
372     LayerAnimationValueObserver* observer) {
373   value_observers_.RemoveObserver(observer);
374 }
375 
AddEventObserver(LayerAnimationEventObserver * observer)376 void LayerAnimationController::AddEventObserver(
377     LayerAnimationEventObserver* observer) {
378   if (!event_observers_.HasObserver(observer))
379     event_observers_.AddObserver(observer);
380 }
381 
RemoveEventObserver(LayerAnimationEventObserver * observer)382 void LayerAnimationController::RemoveEventObserver(
383     LayerAnimationEventObserver* observer) {
384   event_observers_.RemoveObserver(observer);
385 }
386 
AnimatedBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds)387 bool LayerAnimationController::AnimatedBoundsForBox(const gfx::BoxF& box,
388                                                     gfx::BoxF* bounds) {
389   // Compute bounds based on animations for which is_finished() is false.
390   // Do nothing if there are no such animations; in this case, it is assumed
391   // that callers will take care of computing bounds based on the owning layer's
392   // actual transform.
393   *bounds = gfx::BoxF();
394   for (size_t i = 0; i < active_animations_.size(); ++i) {
395     if (active_animations_[i]->is_finished() ||
396         active_animations_[i]->target_property() != Animation::Transform)
397       continue;
398 
399     const TransformAnimationCurve* transform_animation_curve =
400         active_animations_[i]->curve()->ToTransformAnimationCurve();
401     gfx::BoxF animation_bounds;
402     bool success =
403         transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
404     if (!success)
405       return false;
406     bounds->Union(animation_bounds);
407   }
408 
409   return true;
410 }
411 
PushNewAnimationsToImplThread(LayerAnimationController * controller_impl) const412 void LayerAnimationController::PushNewAnimationsToImplThread(
413     LayerAnimationController* controller_impl) const {
414   // Any new animations owned by the main thread's controller are cloned and
415   // add to the impl thread's controller.
416   for (size_t i = 0; i < active_animations_.size(); ++i) {
417     // If the animation is already running on the impl thread, there is no
418     // need to copy it over.
419     if (controller_impl->GetAnimation(active_animations_[i]->group(),
420                                       active_animations_[i]->target_property()))
421       continue;
422 
423     // If the animation is not running on the impl thread, it does not
424     // necessarily mean that it needs to be copied over and started; it may
425     // have already finished. In this case, the impl thread animation will
426     // have already notified that it has started and the main thread animation
427     // will no longer need
428     // a synchronized start time.
429     if (!active_animations_[i]->needs_synchronized_start_time())
430       continue;
431 
432     // Scroll animations always start at the current scroll offset.
433     if (active_animations_[i]->target_property() == Animation::ScrollOffset) {
434       gfx::Vector2dF current_scroll_offset;
435       if (controller_impl->value_provider_) {
436         current_scroll_offset =
437             controller_impl->value_provider_->ScrollOffsetForAnimation();
438       } else {
439         // The owning layer isn't yet in the active tree, so the main thread
440         // scroll offset will be up-to-date.
441         current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
442       }
443       active_animations_[i]->curve()->ToScrollOffsetAnimationCurve()
444           ->SetInitialValue(current_scroll_offset);
445     }
446 
447     // The new animation should be set to run as soon as possible.
448     Animation::RunState initial_run_state =
449         Animation::WaitingForTargetAvailability;
450     double start_time = 0;
451     scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize(
452         initial_run_state, start_time));
453     DCHECK(!to_add->needs_synchronized_start_time());
454     controller_impl->AddAnimation(to_add.Pass());
455   }
456 }
457 
458 struct IsCompleted {
IsCompletedcc::IsCompleted459   explicit IsCompleted(const LayerAnimationController& main_thread_controller)
460       : main_thread_controller_(main_thread_controller) {}
operator ()cc::IsCompleted461   bool operator()(Animation* animation) const {
462     if (animation->is_impl_only()) {
463       return (animation->run_state() == Animation::WaitingForDeletion);
464     } else {
465       return !main_thread_controller_.GetAnimation(
466           animation->group(),
467           animation->target_property());
468     }
469   }
470 
471  private:
472   const LayerAnimationController& main_thread_controller_;
473 };
474 
RemoveAnimationsCompletedOnMainThread(LayerAnimationController * controller_impl) const475 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
476     LayerAnimationController* controller_impl) const {
477   // Delete all impl thread animations for which there is no corresponding
478   // main thread animation. Each iteration,
479   // controller->active_animations_.size() is decremented or i is incremented
480   // guaranteeing progress towards loop termination.
481   ScopedPtrVector<Animation>& animations =
482       controller_impl->active_animations_;
483   animations.erase(cc::remove_if(&animations,
484                                  animations.begin(),
485                                  animations.end(),
486                                  IsCompleted(*this)),
487                    animations.end());
488 }
489 
PushPropertiesToImplThread(LayerAnimationController * controller_impl) const490 void LayerAnimationController::PushPropertiesToImplThread(
491     LayerAnimationController* controller_impl) const {
492   for (size_t i = 0; i < active_animations_.size(); ++i) {
493     Animation* current_impl =
494         controller_impl->GetAnimation(
495             active_animations_[i]->group(),
496             active_animations_[i]->target_property());
497     if (current_impl)
498       active_animations_[i]->PushPropertiesTo(current_impl);
499   }
500 }
501 
StartAnimations(double monotonic_time)502 void LayerAnimationController::StartAnimations(double monotonic_time) {
503   // First collect running properties.
504   TargetProperties blocked_properties;
505   for (size_t i = 0; i < active_animations_.size(); ++i) {
506     if (active_animations_[i]->run_state() == Animation::Starting ||
507         active_animations_[i]->run_state() == Animation::Running)
508       blocked_properties.insert(active_animations_[i]->target_property());
509   }
510 
511   for (size_t i = 0; i < active_animations_.size(); ++i) {
512     if (active_animations_[i]->run_state() ==
513         Animation::WaitingForTargetAvailability) {
514       // Collect all properties for animations with the same group id (they
515       // should all also be in the list of animations).
516       TargetProperties enqueued_properties;
517       enqueued_properties.insert(active_animations_[i]->target_property());
518       for (size_t j = i + 1; j < active_animations_.size(); ++j) {
519         if (active_animations_[i]->group() == active_animations_[j]->group())
520           enqueued_properties.insert(active_animations_[j]->target_property());
521       }
522 
523       // Check to see if intersection of the list of properties affected by
524       // the group and the list of currently blocked properties is null. In
525       // any case, the group's target properties need to be added to the list
526       // of blocked properties.
527       bool null_intersection = true;
528       for (TargetProperties::iterator p_iter = enqueued_properties.begin();
529            p_iter != enqueued_properties.end();
530            ++p_iter) {
531         if (!blocked_properties.insert(*p_iter).second)
532           null_intersection = false;
533       }
534 
535       // If the intersection is null, then we are free to start the animations
536       // in the group.
537       if (null_intersection) {
538         active_animations_[i]->SetRunState(
539             Animation::Starting, monotonic_time);
540         for (size_t j = i + 1; j < active_animations_.size(); ++j) {
541           if (active_animations_[i]->group() ==
542               active_animations_[j]->group()) {
543             active_animations_[j]->SetRunState(
544                 Animation::Starting, monotonic_time);
545           }
546         }
547       }
548     }
549   }
550 }
551 
PromoteStartedAnimations(double monotonic_time,AnimationEventsVector * events)552 void LayerAnimationController::PromoteStartedAnimations(
553     double monotonic_time,
554     AnimationEventsVector* events) {
555   for (size_t i = 0; i < active_animations_.size(); ++i) {
556     if (active_animations_[i]->run_state() == Animation::Starting) {
557       active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
558       if (!active_animations_[i]->has_set_start_time())
559         active_animations_[i]->set_start_time(monotonic_time);
560       if (events) {
561         AnimationEvent started_event(
562             AnimationEvent::Started,
563             id_,
564             active_animations_[i]->group(),
565             active_animations_[i]->target_property(),
566             monotonic_time);
567         started_event.is_impl_only = active_animations_[i]->is_impl_only();
568         events->push_back(started_event);
569       }
570     }
571   }
572 }
573 
MarkFinishedAnimations(double monotonic_time)574 void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) {
575   for (size_t i = 0; i < active_animations_.size(); ++i) {
576     if (active_animations_[i]->IsFinishedAt(monotonic_time) &&
577         active_animations_[i]->run_state() != Animation::Aborted &&
578         active_animations_[i]->run_state() != Animation::WaitingForDeletion)
579       active_animations_[i]->SetRunState(Animation::Finished, monotonic_time);
580   }
581 }
582 
MarkAnimationsForDeletion(double monotonic_time,AnimationEventsVector * events)583 void LayerAnimationController::MarkAnimationsForDeletion(
584     double monotonic_time, AnimationEventsVector* events) {
585   bool marked_animations_for_deletions = false;
586 
587   // Non-aborted animations are marked for deletion after a corresponding
588   // AnimationEvent::Finished event is sent or received. This means that if
589   // we don't have an events vector, we must ensure that non-aborted animations
590   // have received a finished event before marking them for deletion.
591   for (size_t i = 0; i < active_animations_.size(); i++) {
592     int group_id = active_animations_[i]->group();
593     if (active_animations_[i]->run_state() == Animation::Aborted) {
594       if (events && !active_animations_[i]->is_impl_only()) {
595         AnimationEvent aborted_event(
596             AnimationEvent::Aborted,
597             id_,
598             group_id,
599             active_animations_[i]->target_property(),
600             monotonic_time);
601         events->push_back(aborted_event);
602       }
603       active_animations_[i]->SetRunState(Animation::WaitingForDeletion,
604                                          monotonic_time);
605       marked_animations_for_deletions = true;
606       continue;
607     }
608 
609     bool all_anims_with_same_id_are_finished = false;
610 
611     // Since deleting an animation on the main thread leads to its deletion
612     // on the impl thread, we only mark a Finished main thread animation for
613     // deletion once it has received a Finished event from the impl thread.
614     bool animation_i_will_send_or_has_received_finish_event =
615         events || active_animations_[i]->received_finished_event();
616     // If an animation is finished, and not already marked for deletion,
617     // find out if all other animations in the same group are also finished.
618     if (active_animations_[i]->run_state() == Animation::Finished &&
619         animation_i_will_send_or_has_received_finish_event) {
620       all_anims_with_same_id_are_finished = true;
621       for (size_t j = 0; j < active_animations_.size(); ++j) {
622         bool animation_j_will_send_or_has_received_finish_event =
623             events || active_animations_[j]->received_finished_event();
624         if (group_id == active_animations_[j]->group() &&
625             (!active_animations_[j]->is_finished() ||
626              (active_animations_[j]->run_state() == Animation::Finished &&
627               !animation_j_will_send_or_has_received_finish_event))) {
628           all_anims_with_same_id_are_finished = false;
629           break;
630         }
631       }
632     }
633     if (all_anims_with_same_id_are_finished) {
634       // We now need to remove all animations with the same group id as
635       // group_id (and send along animation finished notifications, if
636       // necessary).
637       for (size_t j = i; j < active_animations_.size(); j++) {
638         if (active_animations_[j]->group() == group_id &&
639             active_animations_[j]->run_state() != Animation::Aborted) {
640           if (events) {
641             AnimationEvent finished_event(
642                 AnimationEvent::Finished,
643                 id_,
644                 active_animations_[j]->group(),
645                 active_animations_[j]->target_property(),
646                 monotonic_time);
647             finished_event.is_impl_only = active_animations_[j]->is_impl_only();
648             events->push_back(finished_event);
649           }
650           active_animations_[j]->SetRunState(Animation::WaitingForDeletion,
651                                              monotonic_time);
652         }
653       }
654       marked_animations_for_deletions = true;
655     }
656   }
657   if (marked_animations_for_deletions)
658     NotifyObserversAnimationWaitingForDeletion();
659 }
660 
IsWaitingForDeletion(Animation * animation)661 static bool IsWaitingForDeletion(Animation* animation) {
662   return animation->run_state() == Animation::WaitingForDeletion;
663 }
664 
PurgeAnimationsMarkedForDeletion()665 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
666   ScopedPtrVector<Animation>& animations = active_animations_;
667   animations.erase(cc::remove_if(&animations,
668                                  animations.begin(),
669                                  animations.end(),
670                                  IsWaitingForDeletion),
671                    animations.end());
672 }
673 
TickAnimations(double monotonic_time)674 void LayerAnimationController::TickAnimations(double monotonic_time) {
675   for (size_t i = 0; i < active_animations_.size(); ++i) {
676     if (active_animations_[i]->run_state() == Animation::Starting ||
677         active_animations_[i]->run_state() == Animation::Running ||
678         active_animations_[i]->run_state() == Animation::Paused) {
679       double trimmed =
680           active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
681 
682       switch (active_animations_[i]->target_property()) {
683         case Animation::Transform: {
684           const TransformAnimationCurve* transform_animation_curve =
685               active_animations_[i]->curve()->ToTransformAnimationCurve();
686           const gfx::Transform transform =
687               transform_animation_curve->GetValue(trimmed);
688           NotifyObserversTransformAnimated(transform);
689           break;
690         }
691 
692         case Animation::Opacity: {
693           const FloatAnimationCurve* float_animation_curve =
694               active_animations_[i]->curve()->ToFloatAnimationCurve();
695           const float opacity = float_animation_curve->GetValue(trimmed);
696           NotifyObserversOpacityAnimated(opacity);
697           break;
698         }
699 
700         case Animation::Filter: {
701           const FilterAnimationCurve* filter_animation_curve =
702               active_animations_[i]->curve()->ToFilterAnimationCurve();
703           const FilterOperations filter =
704               filter_animation_curve->GetValue(trimmed);
705           NotifyObserversFilterAnimated(filter);
706           break;
707         }
708 
709         case Animation::BackgroundColor: {
710           // Not yet implemented.
711           break;
712         }
713 
714         case Animation::ScrollOffset: {
715           const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
716               active_animations_[i]->curve()->ToScrollOffsetAnimationCurve();
717           const gfx::Vector2dF scroll_offset =
718               scroll_offset_animation_curve->GetValue(trimmed);
719           NotifyObserversScrollOffsetAnimated(scroll_offset);
720           break;
721         }
722 
723         // Do nothing for sentinel value.
724         case Animation::TargetPropertyEnumSize:
725           NOTREACHED();
726       }
727     }
728   }
729 }
730 
UpdateActivation(UpdateActivationType type)731 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
732   bool force = type == ForceActivation;
733   if (registrar_) {
734     bool was_active = is_active_;
735     is_active_ = false;
736     for (size_t i = 0; i < active_animations_.size(); ++i) {
737       if (active_animations_[i]->run_state() != Animation::WaitingForDeletion) {
738         is_active_ = true;
739         break;
740       }
741     }
742 
743     if (is_active_ && (!was_active || force))
744       registrar_->DidActivateAnimationController(this);
745     else if (!is_active_ && (was_active || force))
746       registrar_->DidDeactivateAnimationController(this);
747   }
748 }
749 
NotifyObserversOpacityAnimated(float opacity)750 void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) {
751   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
752                     value_observers_,
753                     OnOpacityAnimated(opacity));
754 }
755 
NotifyObserversTransformAnimated(const gfx::Transform & transform)756 void LayerAnimationController::NotifyObserversTransformAnimated(
757     const gfx::Transform& transform) {
758   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
759                     value_observers_,
760                     OnTransformAnimated(transform));
761 }
762 
NotifyObserversFilterAnimated(const FilterOperations & filters)763 void LayerAnimationController::NotifyObserversFilterAnimated(
764     const FilterOperations& filters) {
765   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
766                     value_observers_,
767                     OnFilterAnimated(filters));
768 }
769 
NotifyObserversScrollOffsetAnimated(gfx::Vector2dF scroll_offset)770 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
771     gfx::Vector2dF scroll_offset) {
772   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
773                     value_observers_,
774                     OnScrollOffsetAnimated(scroll_offset));
775 }
776 
NotifyObserversAnimationWaitingForDeletion()777 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
778   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
779                     value_observers_,
780                     OnAnimationWaitingForDeletion());
781 }
782 
HasValueObserver()783 bool LayerAnimationController::HasValueObserver() {
784   if (value_observers_.might_have_observers()) {
785     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
786         value_observers_);
787     return it.GetNext() != NULL;
788   }
789   return false;
790 }
791 
HasActiveValueObserver()792 bool LayerAnimationController::HasActiveValueObserver() {
793   if (value_observers_.might_have_observers()) {
794     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
795         value_observers_);
796     LayerAnimationValueObserver* obs;
797     while ((obs = it.GetNext()) != NULL)
798       if (obs->IsActive())
799         return true;
800   }
801   return false;
802 }
803 
804 }  // namespace cc
805