Support HTTP/2 drafts 14 and 15 simultaneously.
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blobf621ad318c4d5470442b842be7fee9ab4eee0333
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"
7 #include <algorithm>
8 #include <vector>
10 #include "cc/animation/animation.h"
11 #include "cc/animation/animation_delegate.h"
12 #include "cc/animation/animation_registrar.h"
13 #include "cc/animation/keyframed_animation_curve.h"
14 #include "cc/animation/layer_animation_value_observer.h"
15 #include "cc/animation/layer_animation_value_provider.h"
16 #include "cc/animation/scroll_offset_animation_curve.h"
17 #include "cc/base/scoped_ptr_algorithm.h"
18 #include "cc/output/filter_operations.h"
19 #include "ui/gfx/geometry/box_f.h"
20 #include "ui/gfx/transform.h"
22 namespace cc {
24 LayerAnimationController::LayerAnimationController(int id)
25 : registrar_(0),
26 id_(id),
27 is_active_(false),
28 value_provider_(nullptr),
29 layer_animation_delegate_(nullptr),
30 needs_to_start_animations_(false) {
33 LayerAnimationController::~LayerAnimationController() {
34 if (registrar_)
35 registrar_->UnregisterAnimationController(this);
38 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
39 int id) {
40 return make_scoped_refptr(new LayerAnimationController(id));
43 void LayerAnimationController::PauseAnimation(int animation_id,
44 base::TimeDelta time_offset) {
45 for (size_t i = 0; i < animations_.size(); ++i) {
46 if (animations_[i]->id() == animation_id) {
47 animations_[i]->SetRunState(Animation::Paused,
48 time_offset + animations_[i]->start_time());
53 struct HasAnimationId {
54 explicit HasAnimationId(int id) : id_(id) {}
55 bool operator()(Animation* animation) const {
56 return animation->id() == id_;
59 private:
60 int id_;
63 void LayerAnimationController::RemoveAnimation(int animation_id) {
64 animations_.erase(cc::remove_if(&animations_,
65 animations_.begin(),
66 animations_.end(),
67 HasAnimationId(animation_id)),
68 animations_.end());
69 UpdateActivation(NormalActivation);
72 struct HasAnimationIdAndProperty {
73 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
74 : id_(id), target_property_(target_property) {}
75 bool operator()(Animation* animation) const {
76 return animation->id() == id_ &&
77 animation->target_property() == target_property_;
80 private:
81 int id_;
82 Animation::TargetProperty target_property_;
85 void LayerAnimationController::RemoveAnimation(
86 int animation_id,
87 Animation::TargetProperty target_property) {
88 animations_.erase(
89 cc::remove_if(&animations_,
90 animations_.begin(),
91 animations_.end(),
92 HasAnimationIdAndProperty(animation_id, target_property)),
93 animations_.end());
94 UpdateActivation(NormalActivation);
97 void LayerAnimationController::AbortAnimations(
98 Animation::TargetProperty target_property) {
99 for (size_t i = 0; i < animations_.size(); ++i) {
100 if (animations_[i]->target_property() == target_property &&
101 !animations_[i]->is_finished())
102 animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
106 // Ensures that the list of active animations on the main thread and the impl
107 // thread are kept in sync.
108 void LayerAnimationController::PushAnimationUpdatesTo(
109 LayerAnimationController* controller_impl) {
110 DCHECK(this != controller_impl);
111 if (!has_any_animation() && !controller_impl->has_any_animation())
112 return;
113 PurgeAnimationsMarkedForDeletion();
114 PushNewAnimationsToImplThread(controller_impl);
116 // Remove finished impl side animations only after pushing,
117 // and only after the animations are deleted on the main thread
118 // this insures we will never push an animation twice.
119 RemoveAnimationsCompletedOnMainThread(controller_impl);
121 PushPropertiesToImplThread(controller_impl);
122 controller_impl->UpdateActivation(NormalActivation);
123 UpdateActivation(NormalActivation);
126 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
127 DCHECK(!monotonic_time.is_null());
128 if (!HasValueObserver())
129 return;
131 if (needs_to_start_animations_)
132 StartAnimations(monotonic_time);
133 TickAnimations(monotonic_time);
134 last_tick_time_ = monotonic_time;
137 void LayerAnimationController::AccumulatePropertyUpdates(
138 base::TimeTicks monotonic_time,
139 AnimationEventsVector* events) {
140 if (!events)
141 return;
143 for (size_t i = 0; i < animations_.size(); ++i) {
144 Animation* animation = animations_[i];
145 if (!animation->is_impl_only())
146 continue;
148 if (!animation->InEffect(monotonic_time))
149 continue;
151 double trimmed =
152 animation->TrimTimeToCurrentIteration(monotonic_time).InSecondsF();
153 switch (animation->target_property()) {
154 case Animation::Opacity: {
155 AnimationEvent event(AnimationEvent::PropertyUpdate,
156 id_,
157 animation->group(),
158 Animation::Opacity,
159 monotonic_time);
160 const FloatAnimationCurve* float_animation_curve =
161 animation->curve()->ToFloatAnimationCurve();
162 event.opacity = float_animation_curve->GetValue(trimmed);
163 event.is_impl_only = true;
164 events->push_back(event);
165 break;
168 case Animation::Transform: {
169 AnimationEvent event(AnimationEvent::PropertyUpdate,
170 id_,
171 animation->group(),
172 Animation::Transform,
173 monotonic_time);
174 const TransformAnimationCurve* transform_animation_curve =
175 animation->curve()->ToTransformAnimationCurve();
176 event.transform = transform_animation_curve->GetValue(trimmed);
177 event.is_impl_only = true;
178 events->push_back(event);
179 break;
182 case Animation::Filter: {
183 AnimationEvent event(AnimationEvent::PropertyUpdate,
184 id_,
185 animation->group(),
186 Animation::Filter,
187 monotonic_time);
188 const FilterAnimationCurve* filter_animation_curve =
189 animation->curve()->ToFilterAnimationCurve();
190 event.filters = filter_animation_curve->GetValue(trimmed);
191 event.is_impl_only = true;
192 events->push_back(event);
193 break;
196 case Animation::BackgroundColor: { break; }
198 case Animation::ScrollOffset: {
199 // Impl-side changes to scroll offset are already sent back to the
200 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
201 // isn't needed.
202 break;
205 case Animation::TargetPropertyEnumSize:
206 NOTREACHED();
211 void LayerAnimationController::UpdateState(bool start_ready_animations,
212 AnimationEventsVector* events) {
213 if (!HasActiveValueObserver())
214 return;
216 // Animate hasn't been called, this happens if an observer has been added
217 // between the Commit and Draw phases.
218 if (last_tick_time_ == base::TimeTicks())
219 return;
221 if (start_ready_animations)
222 PromoteStartedAnimations(last_tick_time_, events);
224 MarkFinishedAnimations(last_tick_time_);
225 MarkAnimationsForDeletion(last_tick_time_, events);
227 if (needs_to_start_animations_ && start_ready_animations) {
228 StartAnimations(last_tick_time_);
229 PromoteStartedAnimations(last_tick_time_, events);
232 AccumulatePropertyUpdates(last_tick_time_, events);
234 UpdateActivation(NormalActivation);
237 struct AffectsNoObservers {
238 bool operator()(Animation* animation) const {
239 return !animation->affects_active_observers() &&
240 !animation->affects_pending_observers();
244 void LayerAnimationController::ActivateAnimations() {
245 for (size_t i = 0; i < animations_.size(); ++i) {
246 animations_[i]->set_affects_active_observers(
247 animations_[i]->affects_pending_observers());
249 animations_.erase(cc::remove_if(&animations_,
250 animations_.begin(),
251 animations_.end(),
252 AffectsNoObservers()),
253 animations_.end());
254 UpdateActivation(NormalActivation);
257 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
258 animations_.push_back(animation.Pass());
259 needs_to_start_animations_ = true;
260 UpdateActivation(NormalActivation);
263 Animation* LayerAnimationController::GetAnimation(
264 int group_id,
265 Animation::TargetProperty target_property) const {
266 for (size_t i = 0; i < animations_.size(); ++i)
267 if (animations_[i]->group() == group_id &&
268 animations_[i]->target_property() == target_property)
269 return animations_[i];
270 return 0;
273 Animation* LayerAnimationController::GetAnimation(
274 Animation::TargetProperty target_property) const {
275 for (size_t i = 0; i < animations_.size(); ++i) {
276 size_t index = animations_.size() - i - 1;
277 if (animations_[index]->target_property() == target_property)
278 return animations_[index];
280 return 0;
283 bool LayerAnimationController::HasActiveAnimation() const {
284 for (size_t i = 0; i < animations_.size(); ++i) {
285 if (!animations_[i]->is_finished())
286 return true;
288 return false;
291 bool LayerAnimationController::IsAnimatingProperty(
292 Animation::TargetProperty target_property) const {
293 for (size_t i = 0; i < animations_.size(); ++i) {
294 if (!animations_[i]->is_finished() &&
295 animations_[i]->InEffect(last_tick_time_) &&
296 animations_[i]->target_property() == target_property)
297 return true;
299 return false;
302 void LayerAnimationController::SetAnimationRegistrar(
303 AnimationRegistrar* registrar) {
304 if (registrar_ == registrar)
305 return;
307 if (registrar_)
308 registrar_->UnregisterAnimationController(this);
310 registrar_ = registrar;
311 if (registrar_)
312 registrar_->RegisterAnimationController(this);
314 UpdateActivation(ForceActivation);
317 void LayerAnimationController::NotifyAnimationStarted(
318 const AnimationEvent& event) {
319 if (event.is_impl_only) {
320 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
321 OnAnimationStarted(event));
322 if (layer_animation_delegate_)
323 layer_animation_delegate_->NotifyAnimationStarted(
324 event.monotonic_time, event.target_property, event.group_id);
325 return;
328 for (size_t i = 0; i < animations_.size(); ++i) {
329 if (animations_[i]->group() == event.group_id &&
330 animations_[i]->target_property() == event.target_property &&
331 animations_[i]->needs_synchronized_start_time()) {
332 animations_[i]->set_needs_synchronized_start_time(false);
333 if (!animations_[i]->has_set_start_time())
334 animations_[i]->set_start_time(event.monotonic_time);
336 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
337 OnAnimationStarted(event));
338 if (layer_animation_delegate_)
339 layer_animation_delegate_->NotifyAnimationStarted(
340 event.monotonic_time, event.target_property, event.group_id);
342 return;
347 void LayerAnimationController::NotifyAnimationFinished(
348 const AnimationEvent& event) {
349 if (event.is_impl_only) {
350 if (layer_animation_delegate_)
351 layer_animation_delegate_->NotifyAnimationFinished(
352 event.monotonic_time, event.target_property, event.group_id);
353 return;
356 for (size_t i = 0; i < animations_.size(); ++i) {
357 if (animations_[i]->group() == event.group_id &&
358 animations_[i]->target_property() == event.target_property) {
359 animations_[i]->set_received_finished_event(true);
360 if (layer_animation_delegate_)
361 layer_animation_delegate_->NotifyAnimationFinished(
362 event.monotonic_time, event.target_property, event.group_id);
364 return;
369 void LayerAnimationController::NotifyAnimationAborted(
370 const AnimationEvent& event) {
371 for (size_t i = 0; i < animations_.size(); ++i) {
372 if (animations_[i]->group() == event.group_id &&
373 animations_[i]->target_property() == event.target_property) {
374 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
379 void LayerAnimationController::NotifyAnimationPropertyUpdate(
380 const AnimationEvent& event) {
381 bool notify_active_observers = true;
382 bool notify_pending_observers = true;
383 switch (event.target_property) {
384 case Animation::Opacity:
385 NotifyObserversOpacityAnimated(
386 event.opacity, notify_active_observers, notify_pending_observers);
387 break;
388 case Animation::Transform:
389 NotifyObserversTransformAnimated(
390 event.transform, notify_active_observers, notify_pending_observers);
391 break;
392 default:
393 NOTREACHED();
397 void LayerAnimationController::AddValueObserver(
398 LayerAnimationValueObserver* observer) {
399 if (!value_observers_.HasObserver(observer))
400 value_observers_.AddObserver(observer);
403 void LayerAnimationController::RemoveValueObserver(
404 LayerAnimationValueObserver* observer) {
405 value_observers_.RemoveObserver(observer);
408 void LayerAnimationController::AddEventObserver(
409 LayerAnimationEventObserver* observer) {
410 if (!event_observers_.HasObserver(observer))
411 event_observers_.AddObserver(observer);
414 void LayerAnimationController::RemoveEventObserver(
415 LayerAnimationEventObserver* observer) {
416 event_observers_.RemoveObserver(observer);
419 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
420 for (size_t i = 0; i < animations_.size(); ++i) {
421 if (!animations_[i]->is_finished() &&
422 animations_[i]->target_property() == Animation::Filter &&
423 animations_[i]
424 ->curve()
425 ->ToFilterAnimationCurve()
426 ->HasFilterThatMovesPixels())
427 return true;
430 return false;
433 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
434 return IsAnimatingProperty(Animation::Transform);
437 bool LayerAnimationController::FilterAnimationBoundsForBox(
438 const gfx::BoxF& box, gfx::BoxF* bounds) const {
439 // TODO(avallee): Implement.
440 return false;
443 bool LayerAnimationController::TransformAnimationBoundsForBox(
444 const gfx::BoxF& box,
445 gfx::BoxF* bounds) const {
446 DCHECK(HasTransformAnimationThatInflatesBounds())
447 << "TransformAnimationBoundsForBox will give incorrect results if there "
448 << "are no transform animations affecting bounds, non-animated transform "
449 << "is not known";
451 // Compute bounds based on animations for which is_finished() is false.
452 // Do nothing if there are no such animations; in this case, it is assumed
453 // that callers will take care of computing bounds based on the owning layer's
454 // actual transform.
455 *bounds = gfx::BoxF();
456 for (size_t i = 0; i < animations_.size(); ++i) {
457 if (animations_[i]->is_finished() ||
458 animations_[i]->target_property() != Animation::Transform)
459 continue;
461 const TransformAnimationCurve* transform_animation_curve =
462 animations_[i]->curve()->ToTransformAnimationCurve();
463 gfx::BoxF animation_bounds;
464 bool success =
465 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
466 if (!success)
467 return false;
468 bounds->Union(animation_bounds);
471 return true;
474 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
475 for (size_t i = 0; i < animations_.size(); ++i) {
476 if (animations_[i]->is_finished() ||
477 animations_[i]->target_property() != Animation::Transform)
478 continue;
480 const TransformAnimationCurve* transform_animation_curve =
481 animations_[i]->curve()->ToTransformAnimationCurve();
482 if (transform_animation_curve->AffectsScale())
483 return true;
486 return false;
489 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
490 for (size_t i = 0; i < animations_.size(); ++i) {
491 if (animations_[i]->is_finished() ||
492 animations_[i]->target_property() != Animation::Transform)
493 continue;
495 const TransformAnimationCurve* transform_animation_curve =
496 animations_[i]->curve()->ToTransformAnimationCurve();
497 if (!transform_animation_curve->IsTranslation())
498 return false;
501 return true;
504 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
505 *max_scale = 0.f;
506 for (size_t i = 0; i < animations_.size(); ++i) {
507 if (animations_[i]->is_finished() ||
508 animations_[i]->target_property() != Animation::Transform)
509 continue;
511 bool forward_direction = true;
512 switch (animations_[i]->direction()) {
513 case Animation::Normal:
514 case Animation::Alternate:
515 forward_direction = animations_[i]->playback_rate() >= 0.0;
516 break;
517 case Animation::Reverse:
518 case Animation::AlternateReverse:
519 forward_direction = animations_[i]->playback_rate() < 0.0;
520 break;
523 const TransformAnimationCurve* transform_animation_curve =
524 animations_[i]->curve()->ToTransformAnimationCurve();
525 float animation_scale = 0.f;
526 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
527 &animation_scale))
528 return false;
529 *max_scale = std::max(*max_scale, animation_scale);
532 return true;
535 void LayerAnimationController::PushNewAnimationsToImplThread(
536 LayerAnimationController* controller_impl) const {
537 // Any new animations owned by the main thread's controller are cloned and
538 // add to the impl thread's controller.
539 for (size_t i = 0; i < animations_.size(); ++i) {
540 // If the animation is already running on the impl thread, there is no
541 // need to copy it over.
542 if (controller_impl->GetAnimation(animations_[i]->group(),
543 animations_[i]->target_property()))
544 continue;
546 // If the animation is not running on the impl thread, it does not
547 // necessarily mean that it needs to be copied over and started; it may
548 // have already finished. In this case, the impl thread animation will
549 // have already notified that it has started and the main thread animation
550 // will no longer need
551 // a synchronized start time.
552 if (!animations_[i]->needs_synchronized_start_time())
553 continue;
555 // Scroll animations always start at the current scroll offset.
556 if (animations_[i]->target_property() == Animation::ScrollOffset) {
557 gfx::ScrollOffset current_scroll_offset;
558 if (controller_impl->value_provider_) {
559 current_scroll_offset =
560 controller_impl->value_provider_->ScrollOffsetForAnimation();
561 } else {
562 // The owning layer isn't yet in the active tree, so the main thread
563 // scroll offset will be up-to-date.
564 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
566 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
567 current_scroll_offset);
570 // The new animation should be set to run as soon as possible.
571 Animation::RunState initial_run_state =
572 Animation::WaitingForTargetAvailability;
573 scoped_ptr<Animation> to_add(
574 animations_[i]->CloneAndInitialize(initial_run_state));
575 DCHECK(!to_add->needs_synchronized_start_time());
576 to_add->set_affects_active_observers(false);
577 controller_impl->AddAnimation(to_add.Pass());
581 static bool IsCompleted(
582 Animation* animation,
583 const LayerAnimationController* main_thread_controller) {
584 if (animation->is_impl_only()) {
585 return (animation->run_state() == Animation::WaitingForDeletion);
586 } else {
587 return !main_thread_controller->GetAnimation(animation->group(),
588 animation->target_property());
592 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
593 return animation->run_state() == Animation::WaitingForDeletion &&
594 !animation->affects_pending_observers();
597 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
598 LayerAnimationController* controller_impl) const {
599 // Animations removed on the main thread should no longer affect pending
600 // observers, and should stop affecting active observers after the next call
601 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
602 // immediately.
603 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
604 for (size_t i = 0; i < animations.size(); ++i) {
605 if (IsCompleted(animations[i], this))
606 animations[i]->set_affects_pending_observers(false);
608 animations.erase(cc::remove_if(&animations,
609 animations.begin(),
610 animations.end(),
611 AffectsActiveOnlyAndIsWaitingForDeletion),
612 animations.end());
615 void LayerAnimationController::PushPropertiesToImplThread(
616 LayerAnimationController* controller_impl) const {
617 for (size_t i = 0; i < animations_.size(); ++i) {
618 Animation* current_impl = controller_impl->GetAnimation(
619 animations_[i]->group(), animations_[i]->target_property());
620 if (current_impl)
621 animations_[i]->PushPropertiesTo(current_impl);
625 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
626 DCHECK(needs_to_start_animations_);
627 needs_to_start_animations_ = false;
628 // First collect running properties affecting each type of observer.
629 TargetProperties blocked_properties_for_active_observers;
630 TargetProperties blocked_properties_for_pending_observers;
631 std::vector<size_t> animations_waiting_for_target;
633 animations_waiting_for_target.reserve(animations_.size());
634 for (size_t i = 0; i < animations_.size(); ++i) {
635 if (animations_[i]->run_state() == Animation::Starting ||
636 animations_[i]->run_state() == Animation::Running) {
637 if (animations_[i]->affects_active_observers()) {
638 blocked_properties_for_active_observers.insert(
639 animations_[i]->target_property());
641 if (animations_[i]->affects_pending_observers()) {
642 blocked_properties_for_pending_observers.insert(
643 animations_[i]->target_property());
645 } else if (animations_[i]->run_state() ==
646 Animation::WaitingForTargetAvailability) {
647 animations_waiting_for_target.push_back(i);
651 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
652 // Collect all properties for animations with the same group id (they
653 // should all also be in the list of animations).
654 size_t animation_index = animations_waiting_for_target[i];
655 Animation* animation_waiting_for_target = animations_[animation_index];
656 // Check for the run state again even though the animation was waiting
657 // for target because it might have changed the run state while handling
658 // previous animation in this loop (if they belong to same group).
659 if (animation_waiting_for_target->run_state() ==
660 Animation::WaitingForTargetAvailability) {
661 TargetProperties enqueued_properties;
662 bool affects_active_observers =
663 animation_waiting_for_target->affects_active_observers();
664 bool affects_pending_observers =
665 animation_waiting_for_target->affects_pending_observers();
666 enqueued_properties.insert(
667 animation_waiting_for_target->target_property());
668 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
669 if (animation_waiting_for_target->group() == animations_[j]->group()) {
670 enqueued_properties.insert(animations_[j]->target_property());
671 affects_active_observers |=
672 animations_[j]->affects_active_observers();
673 affects_pending_observers |=
674 animations_[j]->affects_pending_observers();
678 // Check to see if intersection of the list of properties affected by
679 // the group and the list of currently blocked properties is null, taking
680 // into account the type(s) of observers affected by the group. In any
681 // case, the group's target properties need to be added to the lists of
682 // blocked properties.
683 bool null_intersection = true;
684 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
685 p_iter != enqueued_properties.end();
686 ++p_iter) {
687 if (affects_active_observers &&
688 !blocked_properties_for_active_observers.insert(*p_iter).second)
689 null_intersection = false;
690 if (affects_pending_observers &&
691 !blocked_properties_for_pending_observers.insert(*p_iter).second)
692 null_intersection = false;
695 // If the intersection is null, then we are free to start the animations
696 // in the group.
697 if (null_intersection) {
698 animation_waiting_for_target->SetRunState(Animation::Starting,
699 monotonic_time);
700 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
701 if (animation_waiting_for_target->group() ==
702 animations_[j]->group()) {
703 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
706 } else {
707 needs_to_start_animations_ = true;
713 void LayerAnimationController::PromoteStartedAnimations(
714 base::TimeTicks monotonic_time,
715 AnimationEventsVector* events) {
716 for (size_t i = 0; i < animations_.size(); ++i) {
717 if (animations_[i]->run_state() == Animation::Starting &&
718 animations_[i]->affects_active_observers()) {
719 animations_[i]->SetRunState(Animation::Running, monotonic_time);
720 if (!animations_[i]->has_set_start_time() &&
721 !animations_[i]->needs_synchronized_start_time())
722 animations_[i]->set_start_time(monotonic_time);
723 if (events) {
724 AnimationEvent started_event(AnimationEvent::Started,
725 id_,
726 animations_[i]->group(),
727 animations_[i]->target_property(),
728 monotonic_time);
729 started_event.is_impl_only = animations_[i]->is_impl_only();
730 if (started_event.is_impl_only)
731 NotifyAnimationStarted(started_event);
732 else
733 events->push_back(started_event);
739 void LayerAnimationController::MarkFinishedAnimations(
740 base::TimeTicks monotonic_time) {
741 for (size_t i = 0; i < animations_.size(); ++i) {
742 if (animations_[i]->IsFinishedAt(monotonic_time) &&
743 animations_[i]->run_state() != Animation::Aborted &&
744 animations_[i]->run_state() != Animation::WaitingForDeletion)
745 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
749 void LayerAnimationController::MarkAnimationsForDeletion(
750 base::TimeTicks monotonic_time,
751 AnimationEventsVector* events) {
752 bool marked_animations_for_deletions = false;
753 std::vector<size_t> animations_with_same_group_id;
755 animations_with_same_group_id.reserve(animations_.size());
756 // Non-aborted animations are marked for deletion after a corresponding
757 // AnimationEvent::Finished event is sent or received. This means that if
758 // we don't have an events vector, we must ensure that non-aborted animations
759 // have received a finished event before marking them for deletion.
760 for (size_t i = 0; i < animations_.size(); i++) {
761 int group_id = animations_[i]->group();
762 if (animations_[i]->run_state() == Animation::Aborted) {
763 if (events && !animations_[i]->is_impl_only()) {
764 AnimationEvent aborted_event(AnimationEvent::Aborted,
765 id_,
766 group_id,
767 animations_[i]->target_property(),
768 monotonic_time);
769 events->push_back(aborted_event);
771 animations_[i]->SetRunState(Animation::WaitingForDeletion,
772 monotonic_time);
773 marked_animations_for_deletions = true;
774 continue;
777 bool all_anims_with_same_id_are_finished = false;
779 // Since deleting an animation on the main thread leads to its deletion
780 // on the impl thread, we only mark a Finished main thread animation for
781 // deletion once it has received a Finished event from the impl thread.
782 bool animation_i_will_send_or_has_received_finish_event =
783 events || animations_[i]->received_finished_event();
784 // If an animation is finished, and not already marked for deletion,
785 // find out if all other animations in the same group are also finished.
786 if (animations_[i]->run_state() == Animation::Finished &&
787 animation_i_will_send_or_has_received_finish_event) {
788 // Clear the animations_with_same_group_id if it was added for
789 // the previous animation's iteration.
790 if (animations_with_same_group_id.size() > 0)
791 animations_with_same_group_id.clear();
792 all_anims_with_same_id_are_finished = true;
793 for (size_t j = 0; j < animations_.size(); ++j) {
794 bool animation_j_will_send_or_has_received_finish_event =
795 events || animations_[j]->received_finished_event();
796 if (group_id == animations_[j]->group()) {
797 if (!animations_[j]->is_finished() ||
798 (animations_[j]->run_state() == Animation::Finished &&
799 !animation_j_will_send_or_has_received_finish_event)) {
800 all_anims_with_same_id_are_finished = false;
801 break;
802 } else if (j >= i &&
803 animations_[j]->run_state() != Animation::Aborted) {
804 // Mark down the animations which belong to the same group
805 // and is not yet aborted. If this current iteration finds that all
806 // animations with same ID are finished, then the marked
807 // animations below will be set to WaitingForDeletion in next
808 // iteration.
809 animations_with_same_group_id.push_back(j);
814 if (all_anims_with_same_id_are_finished) {
815 // We now need to remove all animations with the same group id as
816 // group_id (and send along animation finished notifications, if
817 // necessary).
818 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
819 size_t animation_index = animations_with_same_group_id[j];
820 if (events) {
821 AnimationEvent finished_event(
822 AnimationEvent::Finished,
823 id_,
824 animations_[animation_index]->group(),
825 animations_[animation_index]->target_property(),
826 monotonic_time);
827 finished_event.is_impl_only =
828 animations_[animation_index]->is_impl_only();
829 if (finished_event.is_impl_only)
830 NotifyAnimationFinished(finished_event);
831 else
832 events->push_back(finished_event);
834 animations_[animation_index]->SetRunState(
835 Animation::WaitingForDeletion, monotonic_time);
837 marked_animations_for_deletions = true;
840 if (marked_animations_for_deletions)
841 NotifyObserversAnimationWaitingForDeletion();
844 static bool IsWaitingForDeletion(Animation* animation) {
845 return animation->run_state() == Animation::WaitingForDeletion;
848 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
849 animations_.erase(cc::remove_if(&animations_,
850 animations_.begin(),
851 animations_.end(),
852 IsWaitingForDeletion),
853 animations_.end());
856 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
857 for (size_t i = 0; i < animations_.size(); ++i) {
858 if (animations_[i]->run_state() == Animation::Starting ||
859 animations_[i]->run_state() == Animation::Running ||
860 animations_[i]->run_state() == Animation::Paused) {
861 if (!animations_[i]->InEffect(monotonic_time))
862 continue;
864 double trimmed = animations_[i]
865 ->TrimTimeToCurrentIteration(monotonic_time)
866 .InSecondsF();
868 switch (animations_[i]->target_property()) {
869 case Animation::Transform: {
870 const TransformAnimationCurve* transform_animation_curve =
871 animations_[i]->curve()->ToTransformAnimationCurve();
872 const gfx::Transform transform =
873 transform_animation_curve->GetValue(trimmed);
874 NotifyObserversTransformAnimated(
875 transform,
876 animations_[i]->affects_active_observers(),
877 animations_[i]->affects_pending_observers());
878 break;
881 case Animation::Opacity: {
882 const FloatAnimationCurve* float_animation_curve =
883 animations_[i]->curve()->ToFloatAnimationCurve();
884 const float opacity = std::max(
885 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
886 NotifyObserversOpacityAnimated(
887 opacity,
888 animations_[i]->affects_active_observers(),
889 animations_[i]->affects_pending_observers());
890 break;
893 case Animation::Filter: {
894 const FilterAnimationCurve* filter_animation_curve =
895 animations_[i]->curve()->ToFilterAnimationCurve();
896 const FilterOperations filter =
897 filter_animation_curve->GetValue(trimmed);
898 NotifyObserversFilterAnimated(
899 filter,
900 animations_[i]->affects_active_observers(),
901 animations_[i]->affects_pending_observers());
902 break;
905 case Animation::BackgroundColor: {
906 // Not yet implemented.
907 break;
910 case Animation::ScrollOffset: {
911 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
912 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
913 const gfx::ScrollOffset scroll_offset =
914 scroll_offset_animation_curve->GetValue(trimmed);
915 NotifyObserversScrollOffsetAnimated(
916 scroll_offset,
917 animations_[i]->affects_active_observers(),
918 animations_[i]->affects_pending_observers());
919 break;
922 // Do nothing for sentinel value.
923 case Animation::TargetPropertyEnumSize:
924 NOTREACHED();
930 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
931 bool force = type == ForceActivation;
932 if (registrar_) {
933 bool was_active = is_active_;
934 is_active_ = false;
935 for (size_t i = 0; i < animations_.size(); ++i) {
936 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
937 is_active_ = true;
938 break;
942 if (is_active_ && (!was_active || force))
943 registrar_->DidActivateAnimationController(this);
944 else if (!is_active_ && (was_active || force))
945 registrar_->DidDeactivateAnimationController(this);
949 void LayerAnimationController::NotifyObserversOpacityAnimated(
950 float opacity,
951 bool notify_active_observers,
952 bool notify_pending_observers) {
953 if (value_observers_.might_have_observers()) {
954 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
955 value_observers_);
956 LayerAnimationValueObserver* obs;
957 while ((obs = it.GetNext()) != nullptr) {
958 if ((notify_active_observers && notify_pending_observers) ||
959 (notify_active_observers && obs->IsActive()) ||
960 (notify_pending_observers && !obs->IsActive()))
961 obs->OnOpacityAnimated(opacity);
966 void LayerAnimationController::NotifyObserversTransformAnimated(
967 const gfx::Transform& transform,
968 bool notify_active_observers,
969 bool notify_pending_observers) {
970 if (value_observers_.might_have_observers()) {
971 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
972 value_observers_);
973 LayerAnimationValueObserver* obs;
974 while ((obs = it.GetNext()) != nullptr) {
975 if ((notify_active_observers && notify_pending_observers) ||
976 (notify_active_observers && obs->IsActive()) ||
977 (notify_pending_observers && !obs->IsActive()))
978 obs->OnTransformAnimated(transform);
983 void LayerAnimationController::NotifyObserversFilterAnimated(
984 const FilterOperations& filters,
985 bool notify_active_observers,
986 bool notify_pending_observers) {
987 if (value_observers_.might_have_observers()) {
988 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
989 value_observers_);
990 LayerAnimationValueObserver* obs;
991 while ((obs = it.GetNext()) != nullptr) {
992 if ((notify_active_observers && notify_pending_observers) ||
993 (notify_active_observers && obs->IsActive()) ||
994 (notify_pending_observers && !obs->IsActive()))
995 obs->OnFilterAnimated(filters);
1000 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1001 const gfx::ScrollOffset& scroll_offset,
1002 bool notify_active_observers,
1003 bool notify_pending_observers) {
1004 if (value_observers_.might_have_observers()) {
1005 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1006 value_observers_);
1007 LayerAnimationValueObserver* obs;
1008 while ((obs = it.GetNext()) != nullptr) {
1009 if ((notify_active_observers && notify_pending_observers) ||
1010 (notify_active_observers && obs->IsActive()) ||
1011 (notify_pending_observers && !obs->IsActive()))
1012 obs->OnScrollOffsetAnimated(scroll_offset);
1017 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1018 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1019 value_observers_,
1020 OnAnimationWaitingForDeletion());
1023 bool LayerAnimationController::HasValueObserver() {
1024 if (value_observers_.might_have_observers()) {
1025 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1026 value_observers_);
1027 return it.GetNext() != nullptr;
1029 return false;
1032 bool LayerAnimationController::HasActiveValueObserver() {
1033 if (value_observers_.might_have_observers()) {
1034 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1035 value_observers_);
1036 LayerAnimationValueObserver* obs;
1037 while ((obs = it.GetNext()) != nullptr)
1038 if (obs->IsActive())
1039 return true;
1041 return false;
1044 } // namespace cc