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