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.
5 #include "cc/animation/layer_animation_controller.h"
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"
23 LayerAnimationController::LayerAnimationController(int id)
27 value_provider_(NULL),
28 layer_animation_delegate_(NULL),
29 needs_to_start_animations_(false) {
32 LayerAnimationController::~LayerAnimationController() {
34 registrar_->UnregisterAnimationController(this);
37 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
39 return make_scoped_refptr(new LayerAnimationController(id));
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());
52 struct HasAnimationId {
53 explicit HasAnimationId(int id) : id_(id) {}
54 bool operator()(Animation* animation) const {
55 return animation->id() == id_;
62 void LayerAnimationController::RemoveAnimation(int animation_id) {
63 animations_.erase(cc::remove_if(&animations_,
66 HasAnimationId(animation_id)),
68 UpdateActivation(NormalActivation);
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_;
81 Animation::TargetProperty target_property_;
84 void LayerAnimationController::RemoveAnimation(
86 Animation::TargetProperty target_property) {
88 cc::remove_if(&animations_,
91 HasAnimationIdAndProperty(animation_id, target_property)),
93 UpdateActivation(NormalActivation);
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_);
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())
112 PurgeAnimationsMarkedForDeletion();
113 PushNewAnimationsToImplThread(controller_impl);
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);
120 PushPropertiesToImplThread(controller_impl);
121 controller_impl->UpdateActivation(NormalActivation);
122 UpdateActivation(NormalActivation);
125 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
126 DCHECK(!monotonic_time.is_null());
127 if (!HasValueObserver())
130 if (needs_to_start_animations_)
131 StartAnimations(monotonic_time);
132 TickAnimations(monotonic_time);
133 last_tick_time_ = monotonic_time;
136 void LayerAnimationController::AccumulatePropertyUpdates(
137 base::TimeTicks monotonic_time,
138 AnimationEventsVector* events) {
142 for (size_t i = 0; i < animations_.size(); ++i) {
143 Animation* animation = animations_[i];
144 if (!animation->is_impl_only())
147 double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
148 switch (animation->target_property()) {
149 case Animation::Opacity: {
150 AnimationEvent event(AnimationEvent::PropertyUpdate,
155 const FloatAnimationCurve* float_animation_curve =
156 animation->curve()->ToFloatAnimationCurve();
157 event.opacity = float_animation_curve->GetValue(trimmed);
158 event.is_impl_only = true;
159 events->push_back(event);
163 case Animation::Transform: {
164 AnimationEvent event(AnimationEvent::PropertyUpdate,
167 Animation::Transform,
169 const TransformAnimationCurve* transform_animation_curve =
170 animation->curve()->ToTransformAnimationCurve();
171 event.transform = transform_animation_curve->GetValue(trimmed);
172 event.is_impl_only = true;
173 events->push_back(event);
177 case Animation::Filter: {
178 AnimationEvent event(AnimationEvent::PropertyUpdate,
183 const FilterAnimationCurve* filter_animation_curve =
184 animation->curve()->ToFilterAnimationCurve();
185 event.filters = filter_animation_curve->GetValue(trimmed);
186 event.is_impl_only = true;
187 events->push_back(event);
191 case Animation::BackgroundColor: { break; }
193 case Animation::ScrollOffset: {
194 // Impl-side changes to scroll offset are already sent back to the
195 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
200 case Animation::TargetPropertyEnumSize:
206 void LayerAnimationController::UpdateState(bool start_ready_animations,
207 AnimationEventsVector* events) {
208 if (!HasActiveValueObserver())
211 DCHECK(last_tick_time_ != base::TimeTicks());
212 if (start_ready_animations)
213 PromoteStartedAnimations(last_tick_time_, events);
215 MarkFinishedAnimations(last_tick_time_);
216 MarkAnimationsForDeletion(last_tick_time_, events);
218 if (needs_to_start_animations_ && start_ready_animations) {
219 StartAnimations(last_tick_time_);
220 PromoteStartedAnimations(last_tick_time_, events);
223 AccumulatePropertyUpdates(last_tick_time_, events);
225 UpdateActivation(NormalActivation);
228 struct AffectsNoObservers {
229 bool operator()(Animation* animation) const {
230 return !animation->affects_active_observers() &&
231 !animation->affects_pending_observers();
235 void LayerAnimationController::ActivateAnimations() {
236 for (size_t i = 0; i < animations_.size(); ++i) {
237 animations_[i]->set_affects_active_observers(
238 animations_[i]->affects_pending_observers());
240 animations_.erase(cc::remove_if(&animations_,
243 AffectsNoObservers()),
245 UpdateActivation(NormalActivation);
248 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
249 animations_.push_back(animation.Pass());
250 needs_to_start_animations_ = true;
251 UpdateActivation(NormalActivation);
254 Animation* LayerAnimationController::GetAnimation(
256 Animation::TargetProperty target_property) const {
257 for (size_t i = 0; i < animations_.size(); ++i)
258 if (animations_[i]->group() == group_id &&
259 animations_[i]->target_property() == target_property)
260 return animations_[i];
264 Animation* LayerAnimationController::GetAnimation(
265 Animation::TargetProperty target_property) const {
266 for (size_t i = 0; i < animations_.size(); ++i) {
267 size_t index = animations_.size() - i - 1;
268 if (animations_[index]->target_property() == target_property)
269 return animations_[index];
274 bool LayerAnimationController::HasActiveAnimation() const {
275 for (size_t i = 0; i < animations_.size(); ++i) {
276 if (!animations_[i]->is_finished())
282 bool LayerAnimationController::IsAnimatingProperty(
283 Animation::TargetProperty target_property) const {
284 for (size_t i = 0; i < animations_.size(); ++i) {
285 if (!animations_[i]->is_finished() &&
286 animations_[i]->target_property() == target_property)
292 void LayerAnimationController::SetAnimationRegistrar(
293 AnimationRegistrar* registrar) {
294 if (registrar_ == registrar)
298 registrar_->UnregisterAnimationController(this);
300 registrar_ = registrar;
302 registrar_->RegisterAnimationController(this);
304 UpdateActivation(ForceActivation);
307 void LayerAnimationController::NotifyAnimationStarted(
308 const AnimationEvent& event) {
309 if (event.is_impl_only) {
310 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
311 OnAnimationStarted(event));
312 if (layer_animation_delegate_)
313 layer_animation_delegate_->NotifyAnimationStarted(event.monotonic_time,
314 event.target_property);
318 for (size_t i = 0; i < animations_.size(); ++i) {
319 if (animations_[i]->group() == event.group_id &&
320 animations_[i]->target_property() == event.target_property &&
321 animations_[i]->needs_synchronized_start_time()) {
322 animations_[i]->set_needs_synchronized_start_time(false);
323 if (!animations_[i]->has_set_start_time())
324 animations_[i]->set_start_time(event.monotonic_time);
326 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
327 OnAnimationStarted(event));
328 if (layer_animation_delegate_)
329 layer_animation_delegate_->NotifyAnimationStarted(
330 event.monotonic_time, event.target_property);
337 void LayerAnimationController::NotifyAnimationFinished(
338 const AnimationEvent& event) {
339 if (event.is_impl_only) {
340 if (layer_animation_delegate_)
341 layer_animation_delegate_->NotifyAnimationFinished(event.monotonic_time,
342 event.target_property);
346 for (size_t i = 0; i < animations_.size(); ++i) {
347 if (animations_[i]->group() == event.group_id &&
348 animations_[i]->target_property() == event.target_property) {
349 animations_[i]->set_received_finished_event(true);
350 if (layer_animation_delegate_)
351 layer_animation_delegate_->NotifyAnimationFinished(
352 event.monotonic_time, event.target_property);
359 void LayerAnimationController::NotifyAnimationAborted(
360 const AnimationEvent& event) {
361 for (size_t i = 0; i < animations_.size(); ++i) {
362 if (animations_[i]->group() == event.group_id &&
363 animations_[i]->target_property() == event.target_property) {
364 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
369 void LayerAnimationController::NotifyAnimationPropertyUpdate(
370 const AnimationEvent& event) {
371 bool notify_active_observers = true;
372 bool notify_pending_observers = true;
373 switch (event.target_property) {
374 case Animation::Opacity:
375 NotifyObserversOpacityAnimated(
376 event.opacity, notify_active_observers, notify_pending_observers);
378 case Animation::Transform:
379 NotifyObserversTransformAnimated(
380 event.transform, notify_active_observers, notify_pending_observers);
387 void LayerAnimationController::AddValueObserver(
388 LayerAnimationValueObserver* observer) {
389 if (!value_observers_.HasObserver(observer))
390 value_observers_.AddObserver(observer);
393 void LayerAnimationController::RemoveValueObserver(
394 LayerAnimationValueObserver* observer) {
395 value_observers_.RemoveObserver(observer);
398 void LayerAnimationController::AddEventObserver(
399 LayerAnimationEventObserver* observer) {
400 if (!event_observers_.HasObserver(observer))
401 event_observers_.AddObserver(observer);
404 void LayerAnimationController::RemoveEventObserver(
405 LayerAnimationEventObserver* observer) {
406 event_observers_.RemoveObserver(observer);
409 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
410 for (size_t i = 0; i < animations_.size(); ++i) {
411 if (!animations_[i]->is_finished() &&
412 animations_[i]->target_property() == Animation::Filter &&
415 ->ToFilterAnimationCurve()
416 ->HasFilterThatMovesPixels())
423 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
424 return IsAnimatingProperty(Animation::Transform);
427 bool LayerAnimationController::FilterAnimationBoundsForBox(
428 const gfx::BoxF& box, gfx::BoxF* bounds) const {
429 // TODO(avallee): Implement.
433 bool LayerAnimationController::TransformAnimationBoundsForBox(
434 const gfx::BoxF& box,
435 gfx::BoxF* bounds) const {
436 DCHECK(HasTransformAnimationThatInflatesBounds())
437 << "TransformAnimationBoundsForBox will give incorrect results if there "
438 << "are no transform animations affecting bounds, non-animated transform "
441 // Compute bounds based on animations for which is_finished() is false.
442 // Do nothing if there are no such animations; in this case, it is assumed
443 // that callers will take care of computing bounds based on the owning layer's
445 *bounds = gfx::BoxF();
446 for (size_t i = 0; i < animations_.size(); ++i) {
447 if (animations_[i]->is_finished() ||
448 animations_[i]->target_property() != Animation::Transform)
451 const TransformAnimationCurve* transform_animation_curve =
452 animations_[i]->curve()->ToTransformAnimationCurve();
453 gfx::BoxF animation_bounds;
455 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
458 bounds->Union(animation_bounds);
464 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
465 for (size_t i = 0; i < animations_.size(); ++i) {
466 if (animations_[i]->is_finished() ||
467 animations_[i]->target_property() != Animation::Transform)
470 const TransformAnimationCurve* transform_animation_curve =
471 animations_[i]->curve()->ToTransformAnimationCurve();
472 if (transform_animation_curve->AffectsScale())
479 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
480 for (size_t i = 0; i < animations_.size(); ++i) {
481 if (animations_[i]->is_finished() ||
482 animations_[i]->target_property() != Animation::Transform)
485 const TransformAnimationCurve* transform_animation_curve =
486 animations_[i]->curve()->ToTransformAnimationCurve();
487 if (!transform_animation_curve->IsTranslation())
494 bool LayerAnimationController::MaximumScale(float* max_scale) const {
496 for (size_t i = 0; i < animations_.size(); ++i) {
497 if (animations_[i]->is_finished() ||
498 animations_[i]->target_property() != Animation::Transform)
501 const TransformAnimationCurve* transform_animation_curve =
502 animations_[i]->curve()->ToTransformAnimationCurve();
503 float animation_scale = 0.f;
504 if (!transform_animation_curve->MaximumScale(&animation_scale))
506 *max_scale = std::max(*max_scale, animation_scale);
512 void LayerAnimationController::PushNewAnimationsToImplThread(
513 LayerAnimationController* controller_impl) const {
514 // Any new animations owned by the main thread's controller are cloned and
515 // add to the impl thread's controller.
516 for (size_t i = 0; i < animations_.size(); ++i) {
517 // If the animation is already running on the impl thread, there is no
518 // need to copy it over.
519 if (controller_impl->GetAnimation(animations_[i]->group(),
520 animations_[i]->target_property()))
523 // If the animation is not running on the impl thread, it does not
524 // necessarily mean that it needs to be copied over and started; it may
525 // have already finished. In this case, the impl thread animation will
526 // have already notified that it has started and the main thread animation
527 // will no longer need
528 // a synchronized start time.
529 if (!animations_[i]->needs_synchronized_start_time())
532 // Scroll animations always start at the current scroll offset.
533 if (animations_[i]->target_property() == Animation::ScrollOffset) {
534 gfx::Vector2dF current_scroll_offset;
535 if (controller_impl->value_provider_) {
536 current_scroll_offset =
537 controller_impl->value_provider_->ScrollOffsetForAnimation();
539 // The owning layer isn't yet in the active tree, so the main thread
540 // scroll offset will be up-to-date.
541 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
543 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
544 current_scroll_offset);
547 // The new animation should be set to run as soon as possible.
548 Animation::RunState initial_run_state =
549 Animation::WaitingForTargetAvailability;
550 scoped_ptr<Animation> to_add(
551 animations_[i]->CloneAndInitialize(initial_run_state));
552 DCHECK(!to_add->needs_synchronized_start_time());
553 to_add->set_affects_active_observers(false);
554 controller_impl->AddAnimation(to_add.Pass());
558 static bool IsCompleted(
559 Animation* animation,
560 const LayerAnimationController* main_thread_controller) {
561 if (animation->is_impl_only()) {
562 return (animation->run_state() == Animation::WaitingForDeletion);
564 return !main_thread_controller->GetAnimation(animation->group(),
565 animation->target_property());
569 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
570 return animation->run_state() == Animation::WaitingForDeletion &&
571 !animation->affects_pending_observers();
574 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
575 LayerAnimationController* controller_impl) const {
576 // Animations removed on the main thread should no longer affect pending
577 // observers, and should stop affecting active observers after the next call
578 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
580 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
581 for (size_t i = 0; i < animations.size(); ++i) {
582 if (IsCompleted(animations[i], this))
583 animations[i]->set_affects_pending_observers(false);
585 animations.erase(cc::remove_if(&animations,
588 AffectsActiveOnlyAndIsWaitingForDeletion),
592 void LayerAnimationController::PushPropertiesToImplThread(
593 LayerAnimationController* controller_impl) const {
594 for (size_t i = 0; i < animations_.size(); ++i) {
595 Animation* current_impl = controller_impl->GetAnimation(
596 animations_[i]->group(), animations_[i]->target_property());
598 animations_[i]->PushPropertiesTo(current_impl);
602 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
603 DCHECK(needs_to_start_animations_);
604 needs_to_start_animations_ = false;
605 // First collect running properties affecting each type of observer.
606 TargetProperties blocked_properties_for_active_observers;
607 TargetProperties blocked_properties_for_pending_observers;
608 std::vector<size_t> animations_waiting_for_target;
610 animations_waiting_for_target.reserve(animations_.size());
611 for (size_t i = 0; i < animations_.size(); ++i) {
612 if (animations_[i]->run_state() == Animation::Starting ||
613 animations_[i]->run_state() == Animation::Running) {
614 if (animations_[i]->affects_active_observers()) {
615 blocked_properties_for_active_observers.insert(
616 animations_[i]->target_property());
618 if (animations_[i]->affects_pending_observers()) {
619 blocked_properties_for_pending_observers.insert(
620 animations_[i]->target_property());
622 } else if (animations_[i]->run_state() ==
623 Animation::WaitingForTargetAvailability) {
624 animations_waiting_for_target.push_back(i);
628 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
629 // Collect all properties for animations with the same group id (they
630 // should all also be in the list of animations).
631 size_t animation_index = animations_waiting_for_target[i];
632 Animation* animation_waiting_for_target = animations_[animation_index];
633 // Check for the run state again even though the animation was waiting
634 // for target because it might have changed the run state while handling
635 // previous animation in this loop (if they belong to same group).
636 if (animation_waiting_for_target->run_state() ==
637 Animation::WaitingForTargetAvailability) {
638 TargetProperties enqueued_properties;
639 bool affects_active_observers =
640 animation_waiting_for_target->affects_active_observers();
641 bool affects_pending_observers =
642 animation_waiting_for_target->affects_pending_observers();
643 enqueued_properties.insert(
644 animation_waiting_for_target->target_property());
645 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
646 if (animation_waiting_for_target->group() == animations_[j]->group()) {
647 enqueued_properties.insert(animations_[j]->target_property());
648 affects_active_observers |=
649 animations_[j]->affects_active_observers();
650 affects_pending_observers |=
651 animations_[j]->affects_pending_observers();
655 // Check to see if intersection of the list of properties affected by
656 // the group and the list of currently blocked properties is null, taking
657 // into account the type(s) of observers affected by the group. In any
658 // case, the group's target properties need to be added to the lists of
659 // blocked properties.
660 bool null_intersection = true;
661 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
662 p_iter != enqueued_properties.end();
664 if (affects_active_observers &&
665 !blocked_properties_for_active_observers.insert(*p_iter).second)
666 null_intersection = false;
667 if (affects_pending_observers &&
668 !blocked_properties_for_pending_observers.insert(*p_iter).second)
669 null_intersection = false;
672 // If the intersection is null, then we are free to start the animations
674 if (null_intersection) {
675 animation_waiting_for_target->SetRunState(Animation::Starting,
677 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
678 if (animation_waiting_for_target->group() ==
679 animations_[j]->group()) {
680 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
684 needs_to_start_animations_ = true;
690 void LayerAnimationController::PromoteStartedAnimations(
691 base::TimeTicks monotonic_time,
692 AnimationEventsVector* events) {
693 for (size_t i = 0; i < animations_.size(); ++i) {
694 if (animations_[i]->run_state() == Animation::Starting &&
695 animations_[i]->affects_active_observers()) {
696 animations_[i]->SetRunState(Animation::Running, monotonic_time);
697 if (!animations_[i]->has_set_start_time() &&
698 !animations_[i]->needs_synchronized_start_time())
699 animations_[i]->set_start_time(monotonic_time);
701 AnimationEvent started_event(AnimationEvent::Started,
703 animations_[i]->group(),
704 animations_[i]->target_property(),
706 started_event.is_impl_only = animations_[i]->is_impl_only();
707 if (started_event.is_impl_only)
708 NotifyAnimationStarted(started_event);
710 events->push_back(started_event);
716 void LayerAnimationController::MarkFinishedAnimations(
717 base::TimeTicks monotonic_time) {
718 for (size_t i = 0; i < animations_.size(); ++i) {
719 if (animations_[i]->IsFinishedAt(monotonic_time) &&
720 animations_[i]->run_state() != Animation::Aborted &&
721 animations_[i]->run_state() != Animation::WaitingForDeletion)
722 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
726 void LayerAnimationController::MarkAnimationsForDeletion(
727 base::TimeTicks monotonic_time,
728 AnimationEventsVector* events) {
729 bool marked_animations_for_deletions = false;
730 std::vector<size_t> animations_with_same_group_id;
732 animations_with_same_group_id.reserve(animations_.size());
733 // Non-aborted animations are marked for deletion after a corresponding
734 // AnimationEvent::Finished event is sent or received. This means that if
735 // we don't have an events vector, we must ensure that non-aborted animations
736 // have received a finished event before marking them for deletion.
737 for (size_t i = 0; i < animations_.size(); i++) {
738 int group_id = animations_[i]->group();
739 if (animations_[i]->run_state() == Animation::Aborted) {
740 if (events && !animations_[i]->is_impl_only()) {
741 AnimationEvent aborted_event(AnimationEvent::Aborted,
744 animations_[i]->target_property(),
746 events->push_back(aborted_event);
748 animations_[i]->SetRunState(Animation::WaitingForDeletion,
750 marked_animations_for_deletions = true;
754 bool all_anims_with_same_id_are_finished = false;
756 // Since deleting an animation on the main thread leads to its deletion
757 // on the impl thread, we only mark a Finished main thread animation for
758 // deletion once it has received a Finished event from the impl thread.
759 bool animation_i_will_send_or_has_received_finish_event =
760 events || animations_[i]->received_finished_event();
761 // If an animation is finished, and not already marked for deletion,
762 // find out if all other animations in the same group are also finished.
763 if (animations_[i]->run_state() == Animation::Finished &&
764 animation_i_will_send_or_has_received_finish_event) {
765 // Clear the animations_with_same_group_id if it was added for
766 // the previous animation's iteration.
767 if (animations_with_same_group_id.size() > 0)
768 animations_with_same_group_id.clear();
769 all_anims_with_same_id_are_finished = true;
770 for (size_t j = 0; j < animations_.size(); ++j) {
771 bool animation_j_will_send_or_has_received_finish_event =
772 events || animations_[j]->received_finished_event();
773 if (group_id == animations_[j]->group()) {
774 if (!animations_[j]->is_finished() ||
775 (animations_[j]->run_state() == Animation::Finished &&
776 !animation_j_will_send_or_has_received_finish_event)) {
777 all_anims_with_same_id_are_finished = false;
780 animations_[j]->run_state() != Animation::Aborted) {
781 // Mark down the animations which belong to the same group
782 // and is not yet aborted. If this current iteration finds that all
783 // animations with same ID are finished, then the marked
784 // animations below will be set to WaitingForDeletion in next
786 animations_with_same_group_id.push_back(j);
791 if (all_anims_with_same_id_are_finished) {
792 // We now need to remove all animations with the same group id as
793 // group_id (and send along animation finished notifications, if
795 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
796 size_t animation_index = animations_with_same_group_id[j];
798 AnimationEvent finished_event(
799 AnimationEvent::Finished,
801 animations_[animation_index]->group(),
802 animations_[animation_index]->target_property(),
804 finished_event.is_impl_only =
805 animations_[animation_index]->is_impl_only();
806 if (finished_event.is_impl_only)
807 NotifyAnimationFinished(finished_event);
809 events->push_back(finished_event);
811 animations_[animation_index]->SetRunState(
812 Animation::WaitingForDeletion, monotonic_time);
814 marked_animations_for_deletions = true;
817 if (marked_animations_for_deletions)
818 NotifyObserversAnimationWaitingForDeletion();
821 static bool IsWaitingForDeletion(Animation* animation) {
822 return animation->run_state() == Animation::WaitingForDeletion;
825 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
826 animations_.erase(cc::remove_if(&animations_,
829 IsWaitingForDeletion),
833 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
834 for (size_t i = 0; i < animations_.size(); ++i) {
835 if (animations_[i]->run_state() == Animation::Starting ||
836 animations_[i]->run_state() == Animation::Running ||
837 animations_[i]->run_state() == Animation::Paused) {
839 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
841 switch (animations_[i]->target_property()) {
842 case Animation::Transform: {
843 const TransformAnimationCurve* transform_animation_curve =
844 animations_[i]->curve()->ToTransformAnimationCurve();
845 const gfx::Transform transform =
846 transform_animation_curve->GetValue(trimmed);
847 NotifyObserversTransformAnimated(
849 animations_[i]->affects_active_observers(),
850 animations_[i]->affects_pending_observers());
854 case Animation::Opacity: {
855 const FloatAnimationCurve* float_animation_curve =
856 animations_[i]->curve()->ToFloatAnimationCurve();
857 const float opacity = std::max(
858 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
859 NotifyObserversOpacityAnimated(
861 animations_[i]->affects_active_observers(),
862 animations_[i]->affects_pending_observers());
866 case Animation::Filter: {
867 const FilterAnimationCurve* filter_animation_curve =
868 animations_[i]->curve()->ToFilterAnimationCurve();
869 const FilterOperations filter =
870 filter_animation_curve->GetValue(trimmed);
871 NotifyObserversFilterAnimated(
873 animations_[i]->affects_active_observers(),
874 animations_[i]->affects_pending_observers());
878 case Animation::BackgroundColor: {
879 // Not yet implemented.
883 case Animation::ScrollOffset: {
884 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
885 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
886 const gfx::Vector2dF scroll_offset =
887 scroll_offset_animation_curve->GetValue(trimmed);
888 NotifyObserversScrollOffsetAnimated(
890 animations_[i]->affects_active_observers(),
891 animations_[i]->affects_pending_observers());
895 // Do nothing for sentinel value.
896 case Animation::TargetPropertyEnumSize:
903 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
904 bool force = type == ForceActivation;
906 bool was_active = is_active_;
908 for (size_t i = 0; i < animations_.size(); ++i) {
909 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
915 if (is_active_ && (!was_active || force))
916 registrar_->DidActivateAnimationController(this);
917 else if (!is_active_ && (was_active || force))
918 registrar_->DidDeactivateAnimationController(this);
922 void LayerAnimationController::NotifyObserversOpacityAnimated(
924 bool notify_active_observers,
925 bool notify_pending_observers) {
926 if (value_observers_.might_have_observers()) {
927 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
929 LayerAnimationValueObserver* obs;
930 while ((obs = it.GetNext()) != NULL) {
931 if ((notify_active_observers && notify_pending_observers) ||
932 (notify_active_observers && obs->IsActive()) ||
933 (notify_pending_observers && !obs->IsActive()))
934 obs->OnOpacityAnimated(opacity);
939 void LayerAnimationController::NotifyObserversTransformAnimated(
940 const gfx::Transform& transform,
941 bool notify_active_observers,
942 bool notify_pending_observers) {
943 if (value_observers_.might_have_observers()) {
944 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
946 LayerAnimationValueObserver* obs;
947 while ((obs = it.GetNext()) != NULL) {
948 if ((notify_active_observers && notify_pending_observers) ||
949 (notify_active_observers && obs->IsActive()) ||
950 (notify_pending_observers && !obs->IsActive()))
951 obs->OnTransformAnimated(transform);
956 void LayerAnimationController::NotifyObserversFilterAnimated(
957 const FilterOperations& filters,
958 bool notify_active_observers,
959 bool notify_pending_observers) {
960 if (value_observers_.might_have_observers()) {
961 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
963 LayerAnimationValueObserver* obs;
964 while ((obs = it.GetNext()) != NULL) {
965 if ((notify_active_observers && notify_pending_observers) ||
966 (notify_active_observers && obs->IsActive()) ||
967 (notify_pending_observers && !obs->IsActive()))
968 obs->OnFilterAnimated(filters);
973 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
974 const gfx::Vector2dF& scroll_offset,
975 bool notify_active_observers,
976 bool notify_pending_observers) {
977 if (value_observers_.might_have_observers()) {
978 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
980 LayerAnimationValueObserver* obs;
981 while ((obs = it.GetNext()) != NULL) {
982 if ((notify_active_observers && notify_pending_observers) ||
983 (notify_active_observers && obs->IsActive()) ||
984 (notify_pending_observers && !obs->IsActive()))
985 obs->OnScrollOffsetAnimated(scroll_offset);
990 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
991 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
993 OnAnimationWaitingForDeletion());
996 bool LayerAnimationController::HasValueObserver() {
997 if (value_observers_.might_have_observers()) {
998 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1000 return it.GetNext() != NULL;
1005 bool LayerAnimationController::HasActiveValueObserver() {
1006 if (value_observers_.might_have_observers()) {
1007 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1009 LayerAnimationValueObserver* obs;
1010 while ((obs = it.GetNext()) != NULL)
1011 if (obs->IsActive())