08a0ee91f1854cf4fc5020b50d8996803a9f1c01
[platform/framework/web/crosswalk.git] / src / cc / animation / layer_animation_controller.cc
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
23 LayerAnimationController::LayerAnimationController(int id)
24     : registrar_(0),
25       id_(id),
26       is_active_(false),
27       value_provider_(NULL),
28       layer_animation_delegate_(NULL),
29       needs_to_start_animations_(false) {
30 }
31
32 LayerAnimationController::~LayerAnimationController() {
33   if (registrar_)
34     registrar_->UnregisterAnimationController(this);
35 }
36
37 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
38     int id) {
39   return make_scoped_refptr(new LayerAnimationController(id));
40 }
41
42 void LayerAnimationController::PauseAnimation(int animation_id,
43                                               base::TimeDelta time_offset) {
44   for (size_t i = 0; i < animations_.size(); ++i) {
45     if (animations_[i]->id() == animation_id) {
46       animations_[i]->SetRunState(Animation::Paused,
47                                   time_offset + animations_[i]->start_time());
48     }
49   }
50 }
51
52 struct HasAnimationId {
53   explicit HasAnimationId(int id) : id_(id) {}
54   bool operator()(Animation* animation) const {
55     return animation->id() == id_;
56   }
57
58  private:
59   int id_;
60 };
61
62 void LayerAnimationController::RemoveAnimation(int animation_id) {
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 {
72   HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
73       : id_(id), target_property_(target_property) {}
74   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
84 void LayerAnimationController::RemoveAnimation(
85     int animation_id,
86     Animation::TargetProperty target_property) {
87   animations_.erase(
88       cc::remove_if(&animations_,
89                     animations_.begin(),
90                     animations_.end(),
91                     HasAnimationIdAndProperty(animation_id, target_property)),
92       animations_.end());
93   UpdateActivation(NormalActivation);
94 }
95
96 void LayerAnimationController::AbortAnimations(
97     Animation::TargetProperty target_property) {
98   for (size_t i = 0; i < animations_.size(); ++i) {
99     if (animations_[i]->target_property() == target_property &&
100         !animations_[i]->is_finished())
101       animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
102   }
103 }
104
105 // Ensures that the list of active animations on the main thread and the impl
106 // thread are kept in sync.
107 void LayerAnimationController::PushAnimationUpdatesTo(
108     LayerAnimationController* controller_impl) {
109   DCHECK(this != controller_impl);
110   if (!has_any_animation() && !controller_impl->has_any_animation())
111     return;
112   PurgeAnimationsMarkedForDeletion();
113   PushNewAnimationsToImplThread(controller_impl);
114
115   // Remove finished impl side animations only after pushing,
116   // and only after the animations are deleted on the main thread
117   // this insures we will never push an animation twice.
118   RemoveAnimationsCompletedOnMainThread(controller_impl);
119
120   PushPropertiesToImplThread(controller_impl);
121   controller_impl->UpdateActivation(NormalActivation);
122   UpdateActivation(NormalActivation);
123 }
124
125 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
126   DCHECK(!monotonic_time.is_null());
127   if (!HasValueObserver())
128     return;
129
130   if (needs_to_start_animations_)
131     StartAnimations(monotonic_time);
132   TickAnimations(monotonic_time);
133   last_tick_time_ = monotonic_time;
134 }
135
136 void LayerAnimationController::AccumulatePropertyUpdates(
137     base::TimeTicks monotonic_time,
138     AnimationEventsVector* events) {
139   if (!events)
140     return;
141
142   for (size_t i = 0; i < animations_.size(); ++i) {
143     Animation* animation = animations_[i];
144     if (!animation->is_impl_only())
145       continue;
146
147     if (!animation->InEffect(monotonic_time))
148       continue;
149
150     double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
151     switch (animation->target_property()) {
152       case Animation::Opacity: {
153         AnimationEvent event(AnimationEvent::PropertyUpdate,
154                              id_,
155                              animation->group(),
156                              Animation::Opacity,
157                              monotonic_time);
158         const FloatAnimationCurve* float_animation_curve =
159             animation->curve()->ToFloatAnimationCurve();
160         event.opacity = float_animation_curve->GetValue(trimmed);
161         event.is_impl_only = true;
162         events->push_back(event);
163         break;
164       }
165
166       case Animation::Transform: {
167         AnimationEvent event(AnimationEvent::PropertyUpdate,
168                              id_,
169                              animation->group(),
170                              Animation::Transform,
171                              monotonic_time);
172         const TransformAnimationCurve* transform_animation_curve =
173             animation->curve()->ToTransformAnimationCurve();
174         event.transform = transform_animation_curve->GetValue(trimmed);
175         event.is_impl_only = true;
176         events->push_back(event);
177         break;
178       }
179
180       case Animation::Filter: {
181         AnimationEvent event(AnimationEvent::PropertyUpdate,
182                              id_,
183                              animation->group(),
184                              Animation::Filter,
185                              monotonic_time);
186         const FilterAnimationCurve* filter_animation_curve =
187             animation->curve()->ToFilterAnimationCurve();
188         event.filters = filter_animation_curve->GetValue(trimmed);
189         event.is_impl_only = true;
190         events->push_back(event);
191         break;
192       }
193
194       case Animation::BackgroundColor: { break; }
195
196       case Animation::ScrollOffset: {
197         // Impl-side changes to scroll offset are already sent back to the
198         // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
199         // isn't needed.
200         break;
201       }
202
203       case Animation::TargetPropertyEnumSize:
204         NOTREACHED();
205     }
206   }
207 }
208
209 void LayerAnimationController::UpdateState(bool start_ready_animations,
210                                            AnimationEventsVector* events) {
211   if (!HasActiveValueObserver())
212     return;
213
214   DCHECK(last_tick_time_ != base::TimeTicks());
215   if (start_ready_animations)
216     PromoteStartedAnimations(last_tick_time_, events);
217
218   MarkFinishedAnimations(last_tick_time_);
219   MarkAnimationsForDeletion(last_tick_time_, events);
220
221   if (needs_to_start_animations_ && start_ready_animations) {
222     StartAnimations(last_tick_time_);
223     PromoteStartedAnimations(last_tick_time_, events);
224   }
225
226   AccumulatePropertyUpdates(last_tick_time_, events);
227
228   UpdateActivation(NormalActivation);
229 }
230
231 struct AffectsNoObservers {
232   bool operator()(Animation* animation) const {
233     return !animation->affects_active_observers() &&
234            !animation->affects_pending_observers();
235   }
236 };
237
238 void LayerAnimationController::ActivateAnimations() {
239   for (size_t i = 0; i < animations_.size(); ++i) {
240     animations_[i]->set_affects_active_observers(
241         animations_[i]->affects_pending_observers());
242   }
243   animations_.erase(cc::remove_if(&animations_,
244                                   animations_.begin(),
245                                   animations_.end(),
246                                   AffectsNoObservers()),
247                     animations_.end());
248   UpdateActivation(NormalActivation);
249 }
250
251 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
252   animations_.push_back(animation.Pass());
253   needs_to_start_animations_ = true;
254   UpdateActivation(NormalActivation);
255 }
256
257 Animation* LayerAnimationController::GetAnimation(
258     int group_id,
259     Animation::TargetProperty target_property) const {
260   for (size_t i = 0; i < animations_.size(); ++i)
261     if (animations_[i]->group() == group_id &&
262         animations_[i]->target_property() == target_property)
263       return animations_[i];
264   return 0;
265 }
266
267 Animation* LayerAnimationController::GetAnimation(
268     Animation::TargetProperty target_property) const {
269   for (size_t i = 0; i < animations_.size(); ++i) {
270     size_t index = animations_.size() - i - 1;
271     if (animations_[index]->target_property() == target_property)
272       return animations_[index];
273   }
274   return 0;
275 }
276
277 bool LayerAnimationController::HasActiveAnimation() const {
278   for (size_t i = 0; i < animations_.size(); ++i) {
279     if (!animations_[i]->is_finished())
280       return true;
281   }
282   return false;
283 }
284
285 bool LayerAnimationController::IsAnimatingProperty(
286     Animation::TargetProperty target_property) const {
287   for (size_t i = 0; i < animations_.size(); ++i) {
288     if (!animations_[i]->is_finished() &&
289         animations_[i]->target_property() == target_property)
290       return true;
291   }
292   return false;
293 }
294
295 void LayerAnimationController::SetAnimationRegistrar(
296     AnimationRegistrar* registrar) {
297   if (registrar_ == registrar)
298     return;
299
300   if (registrar_)
301     registrar_->UnregisterAnimationController(this);
302
303   registrar_ = registrar;
304   if (registrar_)
305     registrar_->RegisterAnimationController(this);
306
307   UpdateActivation(ForceActivation);
308 }
309
310 void LayerAnimationController::NotifyAnimationStarted(
311     const AnimationEvent& event) {
312   if (event.is_impl_only) {
313     FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
314                       OnAnimationStarted(event));
315     if (layer_animation_delegate_)
316       layer_animation_delegate_->NotifyAnimationStarted(event.monotonic_time,
317                                                         event.target_property);
318     return;
319   }
320
321   for (size_t i = 0; i < animations_.size(); ++i) {
322     if (animations_[i]->group() == event.group_id &&
323         animations_[i]->target_property() == event.target_property &&
324         animations_[i]->needs_synchronized_start_time()) {
325       animations_[i]->set_needs_synchronized_start_time(false);
326       if (!animations_[i]->has_set_start_time())
327         animations_[i]->set_start_time(event.monotonic_time);
328
329       FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
330                         OnAnimationStarted(event));
331       if (layer_animation_delegate_)
332         layer_animation_delegate_->NotifyAnimationStarted(
333             event.monotonic_time, event.target_property);
334
335       return;
336     }
337   }
338 }
339
340 void LayerAnimationController::NotifyAnimationFinished(
341     const AnimationEvent& event) {
342   if (event.is_impl_only) {
343     if (layer_animation_delegate_)
344       layer_animation_delegate_->NotifyAnimationFinished(event.monotonic_time,
345                                                          event.target_property);
346     return;
347   }
348
349   for (size_t i = 0; i < animations_.size(); ++i) {
350     if (animations_[i]->group() == event.group_id &&
351         animations_[i]->target_property() == event.target_property) {
352       animations_[i]->set_received_finished_event(true);
353       if (layer_animation_delegate_)
354         layer_animation_delegate_->NotifyAnimationFinished(
355             event.monotonic_time, event.target_property);
356
357       return;
358     }
359   }
360 }
361
362 void LayerAnimationController::NotifyAnimationAborted(
363     const AnimationEvent& event) {
364   for (size_t i = 0; i < animations_.size(); ++i) {
365     if (animations_[i]->group() == event.group_id &&
366         animations_[i]->target_property() == event.target_property) {
367       animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
368     }
369   }
370 }
371
372 void LayerAnimationController::NotifyAnimationPropertyUpdate(
373     const AnimationEvent& event) {
374   bool notify_active_observers = true;
375   bool notify_pending_observers = true;
376   switch (event.target_property) {
377     case Animation::Opacity:
378       NotifyObserversOpacityAnimated(
379           event.opacity, notify_active_observers, notify_pending_observers);
380       break;
381     case Animation::Transform:
382       NotifyObserversTransformAnimated(
383           event.transform, notify_active_observers, notify_pending_observers);
384       break;
385     default:
386       NOTREACHED();
387   }
388 }
389
390 void LayerAnimationController::AddValueObserver(
391     LayerAnimationValueObserver* observer) {
392   if (!value_observers_.HasObserver(observer))
393     value_observers_.AddObserver(observer);
394 }
395
396 void LayerAnimationController::RemoveValueObserver(
397     LayerAnimationValueObserver* observer) {
398   value_observers_.RemoveObserver(observer);
399 }
400
401 void LayerAnimationController::AddEventObserver(
402     LayerAnimationEventObserver* observer) {
403   if (!event_observers_.HasObserver(observer))
404     event_observers_.AddObserver(observer);
405 }
406
407 void LayerAnimationController::RemoveEventObserver(
408     LayerAnimationEventObserver* observer) {
409   event_observers_.RemoveObserver(observer);
410 }
411
412 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
413   for (size_t i = 0; i < animations_.size(); ++i) {
414     if (!animations_[i]->is_finished() &&
415         animations_[i]->target_property() == Animation::Filter &&
416         animations_[i]
417             ->curve()
418             ->ToFilterAnimationCurve()
419             ->HasFilterThatMovesPixels())
420       return true;
421   }
422
423   return false;
424 }
425
426 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
427   return IsAnimatingProperty(Animation::Transform);
428 }
429
430 bool LayerAnimationController::FilterAnimationBoundsForBox(
431     const gfx::BoxF& box, gfx::BoxF* bounds) const {
432   // TODO(avallee): Implement.
433   return false;
434 }
435
436 bool LayerAnimationController::TransformAnimationBoundsForBox(
437     const gfx::BoxF& box,
438     gfx::BoxF* bounds) const {
439   DCHECK(HasTransformAnimationThatInflatesBounds())
440       << "TransformAnimationBoundsForBox will give incorrect results if there "
441       << "are no transform animations affecting bounds, non-animated transform "
442       << "is not known";
443
444   // Compute bounds based on animations for which is_finished() is false.
445   // Do nothing if there are no such animations; in this case, it is assumed
446   // that callers will take care of computing bounds based on the owning layer's
447   // actual transform.
448   *bounds = gfx::BoxF();
449   for (size_t i = 0; i < animations_.size(); ++i) {
450     if (animations_[i]->is_finished() ||
451         animations_[i]->target_property() != Animation::Transform)
452       continue;
453
454     const TransformAnimationCurve* transform_animation_curve =
455         animations_[i]->curve()->ToTransformAnimationCurve();
456     gfx::BoxF animation_bounds;
457     bool success =
458         transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
459     if (!success)
460       return false;
461     bounds->Union(animation_bounds);
462   }
463
464   return true;
465 }
466
467 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
468   for (size_t i = 0; i < animations_.size(); ++i) {
469     if (animations_[i]->is_finished() ||
470         animations_[i]->target_property() != Animation::Transform)
471       continue;
472
473     const TransformAnimationCurve* transform_animation_curve =
474         animations_[i]->curve()->ToTransformAnimationCurve();
475     if (transform_animation_curve->AffectsScale())
476       return true;
477   }
478
479   return false;
480 }
481
482 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
483   for (size_t i = 0; i < animations_.size(); ++i) {
484     if (animations_[i]->is_finished() ||
485         animations_[i]->target_property() != Animation::Transform)
486       continue;
487
488     const TransformAnimationCurve* transform_animation_curve =
489         animations_[i]->curve()->ToTransformAnimationCurve();
490     if (!transform_animation_curve->IsTranslation())
491       return false;
492   }
493
494   return true;
495 }
496
497 bool LayerAnimationController::MaximumScale(float* max_scale) const {
498   *max_scale = 0.f;
499   for (size_t i = 0; i < animations_.size(); ++i) {
500     if (animations_[i]->is_finished() ||
501         animations_[i]->target_property() != Animation::Transform)
502       continue;
503
504     const TransformAnimationCurve* transform_animation_curve =
505         animations_[i]->curve()->ToTransformAnimationCurve();
506     float animation_scale = 0.f;
507     if (!transform_animation_curve->MaximumScale(&animation_scale))
508       return false;
509     *max_scale = std::max(*max_scale, animation_scale);
510   }
511
512   return true;
513 }
514
515 void LayerAnimationController::PushNewAnimationsToImplThread(
516     LayerAnimationController* controller_impl) const {
517   // Any new animations owned by the main thread's controller are cloned and
518   // add to the impl thread's controller.
519   for (size_t i = 0; i < animations_.size(); ++i) {
520     // If the animation is already running on the impl thread, there is no
521     // need to copy it over.
522     if (controller_impl->GetAnimation(animations_[i]->group(),
523                                       animations_[i]->target_property()))
524       continue;
525
526     // If the animation is not running on the impl thread, it does not
527     // necessarily mean that it needs to be copied over and started; it may
528     // have already finished. In this case, the impl thread animation will
529     // have already notified that it has started and the main thread animation
530     // will no longer need
531     // a synchronized start time.
532     if (!animations_[i]->needs_synchronized_start_time())
533       continue;
534
535     // Scroll animations always start at the current scroll offset.
536     if (animations_[i]->target_property() == Animation::ScrollOffset) {
537       gfx::Vector2dF current_scroll_offset;
538       if (controller_impl->value_provider_) {
539         current_scroll_offset =
540             controller_impl->value_provider_->ScrollOffsetForAnimation();
541       } else {
542         // The owning layer isn't yet in the active tree, so the main thread
543         // scroll offset will be up-to-date.
544         current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
545       }
546       animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
547           current_scroll_offset);
548     }
549
550     // The new animation should be set to run as soon as possible.
551     Animation::RunState initial_run_state =
552         Animation::WaitingForTargetAvailability;
553     scoped_ptr<Animation> to_add(
554         animations_[i]->CloneAndInitialize(initial_run_state));
555     DCHECK(!to_add->needs_synchronized_start_time());
556     to_add->set_affects_active_observers(false);
557     controller_impl->AddAnimation(to_add.Pass());
558   }
559 }
560
561 static bool IsCompleted(
562     Animation* animation,
563     const LayerAnimationController* main_thread_controller) {
564   if (animation->is_impl_only()) {
565     return (animation->run_state() == Animation::WaitingForDeletion);
566   } else {
567     return !main_thread_controller->GetAnimation(animation->group(),
568                                                  animation->target_property());
569   }
570 }
571
572 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
573   return animation->run_state() == Animation::WaitingForDeletion &&
574          !animation->affects_pending_observers();
575 }
576
577 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
578     LayerAnimationController* controller_impl) const {
579   // Animations removed on the main thread should no longer affect pending
580   // observers, and should stop affecting active observers after the next call
581   // to ActivateAnimations. If already WaitingForDeletion, they can be removed
582   // immediately.
583   ScopedPtrVector<Animation>& animations = controller_impl->animations_;
584   for (size_t i = 0; i < animations.size(); ++i) {
585     if (IsCompleted(animations[i], this))
586       animations[i]->set_affects_pending_observers(false);
587   }
588   animations.erase(cc::remove_if(&animations,
589                                  animations.begin(),
590                                  animations.end(),
591                                  AffectsActiveOnlyAndIsWaitingForDeletion),
592                    animations.end());
593 }
594
595 void LayerAnimationController::PushPropertiesToImplThread(
596     LayerAnimationController* controller_impl) const {
597   for (size_t i = 0; i < animations_.size(); ++i) {
598     Animation* current_impl = controller_impl->GetAnimation(
599         animations_[i]->group(), animations_[i]->target_property());
600     if (current_impl)
601       animations_[i]->PushPropertiesTo(current_impl);
602   }
603 }
604
605 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
606   DCHECK(needs_to_start_animations_);
607   needs_to_start_animations_ = false;
608   // First collect running properties affecting each type of observer.
609   TargetProperties blocked_properties_for_active_observers;
610   TargetProperties blocked_properties_for_pending_observers;
611   std::vector<size_t> animations_waiting_for_target;
612
613   animations_waiting_for_target.reserve(animations_.size());
614   for (size_t i = 0; i < animations_.size(); ++i) {
615     if (animations_[i]->run_state() == Animation::Starting ||
616         animations_[i]->run_state() == Animation::Running) {
617       if (animations_[i]->affects_active_observers()) {
618         blocked_properties_for_active_observers.insert(
619             animations_[i]->target_property());
620       }
621       if (animations_[i]->affects_pending_observers()) {
622         blocked_properties_for_pending_observers.insert(
623             animations_[i]->target_property());
624       }
625     } else if (animations_[i]->run_state() ==
626                Animation::WaitingForTargetAvailability) {
627       animations_waiting_for_target.push_back(i);
628     }
629   }
630
631   for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
632       // Collect all properties for animations with the same group id (they
633       // should all also be in the list of animations).
634     size_t animation_index = animations_waiting_for_target[i];
635     Animation* animation_waiting_for_target = animations_[animation_index];
636     // Check for the run state again even though the animation was waiting
637     // for target because it might have changed the run state while handling
638     // previous animation in this loop (if they belong to same group).
639     if (animation_waiting_for_target->run_state() ==
640         Animation::WaitingForTargetAvailability) {
641       TargetProperties enqueued_properties;
642       bool affects_active_observers =
643           animation_waiting_for_target->affects_active_observers();
644       bool affects_pending_observers =
645           animation_waiting_for_target->affects_pending_observers();
646       enqueued_properties.insert(
647           animation_waiting_for_target->target_property());
648       for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
649         if (animation_waiting_for_target->group() == animations_[j]->group()) {
650           enqueued_properties.insert(animations_[j]->target_property());
651           affects_active_observers |=
652               animations_[j]->affects_active_observers();
653           affects_pending_observers |=
654               animations_[j]->affects_pending_observers();
655         }
656       }
657
658       // Check to see if intersection of the list of properties affected by
659       // the group and the list of currently blocked properties is null, taking
660       // into account the type(s) of observers affected by the group. In any
661       // case, the group's target properties need to be added to the lists of
662       // blocked properties.
663       bool null_intersection = true;
664       for (TargetProperties::iterator p_iter = enqueued_properties.begin();
665            p_iter != enqueued_properties.end();
666            ++p_iter) {
667         if (affects_active_observers &&
668             !blocked_properties_for_active_observers.insert(*p_iter).second)
669           null_intersection = false;
670         if (affects_pending_observers &&
671             !blocked_properties_for_pending_observers.insert(*p_iter).second)
672           null_intersection = false;
673       }
674
675       // If the intersection is null, then we are free to start the animations
676       // in the group.
677       if (null_intersection) {
678         animation_waiting_for_target->SetRunState(Animation::Starting,
679                                                   monotonic_time);
680         for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
681           if (animation_waiting_for_target->group() ==
682               animations_[j]->group()) {
683             animations_[j]->SetRunState(Animation::Starting, monotonic_time);
684           }
685         }
686       } else {
687         needs_to_start_animations_ = true;
688       }
689     }
690   }
691 }
692
693 void LayerAnimationController::PromoteStartedAnimations(
694     base::TimeTicks monotonic_time,
695     AnimationEventsVector* events) {
696   for (size_t i = 0; i < animations_.size(); ++i) {
697     if (animations_[i]->run_state() == Animation::Starting &&
698         animations_[i]->affects_active_observers()) {
699       animations_[i]->SetRunState(Animation::Running, monotonic_time);
700       if (!animations_[i]->has_set_start_time() &&
701           !animations_[i]->needs_synchronized_start_time())
702         animations_[i]->set_start_time(monotonic_time);
703       if (events) {
704         AnimationEvent started_event(AnimationEvent::Started,
705                                      id_,
706                                      animations_[i]->group(),
707                                      animations_[i]->target_property(),
708                                      monotonic_time);
709         started_event.is_impl_only = animations_[i]->is_impl_only();
710         if (started_event.is_impl_only)
711           NotifyAnimationStarted(started_event);
712         else
713           events->push_back(started_event);
714       }
715     }
716   }
717 }
718
719 void LayerAnimationController::MarkFinishedAnimations(
720     base::TimeTicks monotonic_time) {
721   for (size_t i = 0; i < animations_.size(); ++i) {
722     if (animations_[i]->IsFinishedAt(monotonic_time) &&
723         animations_[i]->run_state() != Animation::Aborted &&
724         animations_[i]->run_state() != Animation::WaitingForDeletion)
725       animations_[i]->SetRunState(Animation::Finished, monotonic_time);
726   }
727 }
728
729 void LayerAnimationController::MarkAnimationsForDeletion(
730     base::TimeTicks monotonic_time,
731     AnimationEventsVector* events) {
732   bool marked_animations_for_deletions = false;
733   std::vector<size_t> animations_with_same_group_id;
734
735   animations_with_same_group_id.reserve(animations_.size());
736   // Non-aborted animations are marked for deletion after a corresponding
737   // AnimationEvent::Finished event is sent or received. This means that if
738   // we don't have an events vector, we must ensure that non-aborted animations
739   // have received a finished event before marking them for deletion.
740   for (size_t i = 0; i < animations_.size(); i++) {
741     int group_id = animations_[i]->group();
742     if (animations_[i]->run_state() == Animation::Aborted) {
743       if (events && !animations_[i]->is_impl_only()) {
744         AnimationEvent aborted_event(AnimationEvent::Aborted,
745                                      id_,
746                                      group_id,
747                                      animations_[i]->target_property(),
748                                      monotonic_time);
749         events->push_back(aborted_event);
750       }
751       animations_[i]->SetRunState(Animation::WaitingForDeletion,
752                                   monotonic_time);
753       marked_animations_for_deletions = true;
754       continue;
755     }
756
757     bool all_anims_with_same_id_are_finished = false;
758
759     // Since deleting an animation on the main thread leads to its deletion
760     // on the impl thread, we only mark a Finished main thread animation for
761     // deletion once it has received a Finished event from the impl thread.
762     bool animation_i_will_send_or_has_received_finish_event =
763         events || animations_[i]->received_finished_event();
764     // If an animation is finished, and not already marked for deletion,
765     // find out if all other animations in the same group are also finished.
766     if (animations_[i]->run_state() == Animation::Finished &&
767         animation_i_will_send_or_has_received_finish_event) {
768       // Clear the animations_with_same_group_id if it was added for
769       // the previous animation's iteration.
770       if (animations_with_same_group_id.size() > 0)
771         animations_with_same_group_id.clear();
772       all_anims_with_same_id_are_finished = true;
773       for (size_t j = 0; j < animations_.size(); ++j) {
774         bool animation_j_will_send_or_has_received_finish_event =
775             events || animations_[j]->received_finished_event();
776         if (group_id == animations_[j]->group()) {
777           if (!animations_[j]->is_finished() ||
778               (animations_[j]->run_state() == Animation::Finished &&
779                !animation_j_will_send_or_has_received_finish_event)) {
780             all_anims_with_same_id_are_finished = false;
781             break;
782           } else if (j >= i &&
783                      animations_[j]->run_state() != Animation::Aborted) {
784             // Mark down the animations which belong to the same group
785             // and is not yet aborted. If this current iteration finds that all
786             // animations with same ID are finished, then the marked
787             // animations below will be set to WaitingForDeletion in next
788             // iteration.
789             animations_with_same_group_id.push_back(j);
790           }
791         }
792       }
793     }
794     if (all_anims_with_same_id_are_finished) {
795       // We now need to remove all animations with the same group id as
796       // group_id (and send along animation finished notifications, if
797       // necessary).
798       for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
799         size_t animation_index = animations_with_same_group_id[j];
800           if (events) {
801             AnimationEvent finished_event(
802                 AnimationEvent::Finished,
803                 id_,
804                 animations_[animation_index]->group(),
805                 animations_[animation_index]->target_property(),
806                 monotonic_time);
807             finished_event.is_impl_only =
808                 animations_[animation_index]->is_impl_only();
809             if (finished_event.is_impl_only)
810               NotifyAnimationFinished(finished_event);
811             else
812               events->push_back(finished_event);
813           }
814           animations_[animation_index]->SetRunState(
815               Animation::WaitingForDeletion, monotonic_time);
816       }
817       marked_animations_for_deletions = true;
818     }
819   }
820   if (marked_animations_for_deletions)
821     NotifyObserversAnimationWaitingForDeletion();
822 }
823
824 static bool IsWaitingForDeletion(Animation* animation) {
825   return animation->run_state() == Animation::WaitingForDeletion;
826 }
827
828 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
829   animations_.erase(cc::remove_if(&animations_,
830                                   animations_.begin(),
831                                   animations_.end(),
832                                   IsWaitingForDeletion),
833                     animations_.end());
834 }
835
836 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
837   for (size_t i = 0; i < animations_.size(); ++i) {
838     if (animations_[i]->run_state() == Animation::Starting ||
839         animations_[i]->run_state() == Animation::Running ||
840         animations_[i]->run_state() == Animation::Paused) {
841       if (!animations_[i]->InEffect(monotonic_time))
842         continue;
843
844       double trimmed =
845           animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
846
847       switch (animations_[i]->target_property()) {
848         case Animation::Transform: {
849           const TransformAnimationCurve* transform_animation_curve =
850               animations_[i]->curve()->ToTransformAnimationCurve();
851           const gfx::Transform transform =
852               transform_animation_curve->GetValue(trimmed);
853           NotifyObserversTransformAnimated(
854               transform,
855               animations_[i]->affects_active_observers(),
856               animations_[i]->affects_pending_observers());
857           break;
858         }
859
860         case Animation::Opacity: {
861           const FloatAnimationCurve* float_animation_curve =
862               animations_[i]->curve()->ToFloatAnimationCurve();
863           const float opacity = std::max(
864               std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
865           NotifyObserversOpacityAnimated(
866               opacity,
867               animations_[i]->affects_active_observers(),
868               animations_[i]->affects_pending_observers());
869           break;
870         }
871
872         case Animation::Filter: {
873           const FilterAnimationCurve* filter_animation_curve =
874               animations_[i]->curve()->ToFilterAnimationCurve();
875           const FilterOperations filter =
876               filter_animation_curve->GetValue(trimmed);
877           NotifyObserversFilterAnimated(
878               filter,
879               animations_[i]->affects_active_observers(),
880               animations_[i]->affects_pending_observers());
881           break;
882         }
883
884         case Animation::BackgroundColor: {
885           // Not yet implemented.
886           break;
887         }
888
889         case Animation::ScrollOffset: {
890           const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
891               animations_[i]->curve()->ToScrollOffsetAnimationCurve();
892           const gfx::Vector2dF scroll_offset =
893               scroll_offset_animation_curve->GetValue(trimmed);
894           NotifyObserversScrollOffsetAnimated(
895               scroll_offset,
896               animations_[i]->affects_active_observers(),
897               animations_[i]->affects_pending_observers());
898           break;
899         }
900
901         // Do nothing for sentinel value.
902         case Animation::TargetPropertyEnumSize:
903           NOTREACHED();
904       }
905     }
906   }
907 }
908
909 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
910   bool force = type == ForceActivation;
911   if (registrar_) {
912     bool was_active = is_active_;
913     is_active_ = false;
914     for (size_t i = 0; i < animations_.size(); ++i) {
915       if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
916         is_active_ = true;
917         break;
918       }
919     }
920
921     if (is_active_ && (!was_active || force))
922       registrar_->DidActivateAnimationController(this);
923     else if (!is_active_ && (was_active || force))
924       registrar_->DidDeactivateAnimationController(this);
925   }
926 }
927
928 void LayerAnimationController::NotifyObserversOpacityAnimated(
929     float opacity,
930     bool notify_active_observers,
931     bool notify_pending_observers) {
932   if (value_observers_.might_have_observers()) {
933     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
934         value_observers_);
935     LayerAnimationValueObserver* obs;
936     while ((obs = it.GetNext()) != NULL) {
937       if ((notify_active_observers && notify_pending_observers) ||
938           (notify_active_observers && obs->IsActive()) ||
939           (notify_pending_observers && !obs->IsActive()))
940         obs->OnOpacityAnimated(opacity);
941     }
942   }
943 }
944
945 void LayerAnimationController::NotifyObserversTransformAnimated(
946     const gfx::Transform& transform,
947     bool notify_active_observers,
948     bool notify_pending_observers) {
949   if (value_observers_.might_have_observers()) {
950     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
951         value_observers_);
952     LayerAnimationValueObserver* obs;
953     while ((obs = it.GetNext()) != NULL) {
954       if ((notify_active_observers && notify_pending_observers) ||
955           (notify_active_observers && obs->IsActive()) ||
956           (notify_pending_observers && !obs->IsActive()))
957         obs->OnTransformAnimated(transform);
958     }
959   }
960 }
961
962 void LayerAnimationController::NotifyObserversFilterAnimated(
963     const FilterOperations& filters,
964     bool notify_active_observers,
965     bool notify_pending_observers) {
966   if (value_observers_.might_have_observers()) {
967     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
968         value_observers_);
969     LayerAnimationValueObserver* obs;
970     while ((obs = it.GetNext()) != NULL) {
971       if ((notify_active_observers && notify_pending_observers) ||
972           (notify_active_observers && obs->IsActive()) ||
973           (notify_pending_observers && !obs->IsActive()))
974         obs->OnFilterAnimated(filters);
975     }
976   }
977 }
978
979 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
980     const gfx::Vector2dF& scroll_offset,
981     bool notify_active_observers,
982     bool notify_pending_observers) {
983   if (value_observers_.might_have_observers()) {
984     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
985         value_observers_);
986     LayerAnimationValueObserver* obs;
987     while ((obs = it.GetNext()) != NULL) {
988       if ((notify_active_observers && notify_pending_observers) ||
989           (notify_active_observers && obs->IsActive()) ||
990           (notify_pending_observers && !obs->IsActive()))
991         obs->OnScrollOffsetAnimated(scroll_offset);
992     }
993   }
994 }
995
996 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
997   FOR_EACH_OBSERVER(LayerAnimationValueObserver,
998                     value_observers_,
999                     OnAnimationWaitingForDeletion());
1000 }
1001
1002 bool LayerAnimationController::HasValueObserver() {
1003   if (value_observers_.might_have_observers()) {
1004     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1005         value_observers_);
1006     return it.GetNext() != NULL;
1007   }
1008   return false;
1009 }
1010
1011 bool LayerAnimationController::HasActiveValueObserver() {
1012   if (value_observers_.might_have_observers()) {
1013     ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1014         value_observers_);
1015     LayerAnimationValueObserver* obs;
1016     while ((obs = it.GetNext()) != NULL)
1017       if (obs->IsActive())
1018         return true;
1019   }
1020   return false;
1021 }
1022
1023 }  // namespace cc