Suppress UBSan's false positives for virtual base classes.
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blobd7367e6622e552796e49a90866bc9688888b727f
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 auto animations_to_remove =
65 animations_.remove_if(HasAnimationId(animation_id));
66 for (auto it = animations_to_remove; it != animations_.end(); ++it) {
67 if ((*it)->target_property() == Animation::ScrollOffset) {
68 NotifyObserversScrollOffsetAnimationRemoved();
69 break;
72 animations_.erase(animations_to_remove, animations_.end());
73 UpdateActivation(NormalActivation);
76 struct HasAnimationIdAndProperty {
77 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
78 : id_(id), target_property_(target_property) {}
79 bool operator()(Animation* animation) const {
80 return animation->id() == id_ &&
81 animation->target_property() == target_property_;
84 private:
85 int id_;
86 Animation::TargetProperty target_property_;
89 void LayerAnimationController::RemoveAnimation(
90 int animation_id,
91 Animation::TargetProperty target_property) {
92 auto animations_to_remove = animations_.remove_if(
93 HasAnimationIdAndProperty(animation_id, target_property));
94 if (target_property == Animation::ScrollOffset &&
95 animations_to_remove != animations_.end())
96 NotifyObserversScrollOffsetAnimationRemoved();
98 animations_.erase(animations_to_remove, animations_.end());
99 UpdateActivation(NormalActivation);
102 void LayerAnimationController::AbortAnimations(
103 Animation::TargetProperty target_property) {
104 for (size_t i = 0; i < animations_.size(); ++i) {
105 if (animations_[i]->target_property() == target_property &&
106 !animations_[i]->is_finished())
107 animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
111 // Ensures that the list of active animations on the main thread and the impl
112 // thread are kept in sync.
113 void LayerAnimationController::PushAnimationUpdatesTo(
114 LayerAnimationController* controller_impl) {
115 DCHECK(this != controller_impl);
116 if (!has_any_animation() && !controller_impl->has_any_animation())
117 return;
118 PurgeAnimationsMarkedForDeletion();
119 PushNewAnimationsToImplThread(controller_impl);
121 // Remove finished impl side animations only after pushing,
122 // and only after the animations are deleted on the main thread
123 // this insures we will never push an animation twice.
124 RemoveAnimationsCompletedOnMainThread(controller_impl);
126 PushPropertiesToImplThread(controller_impl);
127 controller_impl->UpdateActivation(NormalActivation);
128 UpdateActivation(NormalActivation);
131 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
132 DCHECK(!monotonic_time.is_null());
133 if (!HasValueObserver())
134 return;
136 if (needs_to_start_animations_)
137 StartAnimations(monotonic_time);
138 TickAnimations(monotonic_time);
139 last_tick_time_ = monotonic_time;
142 void LayerAnimationController::AccumulatePropertyUpdates(
143 base::TimeTicks monotonic_time,
144 AnimationEventsVector* events) {
145 if (!events)
146 return;
148 for (size_t i = 0; i < animations_.size(); ++i) {
149 Animation* animation = animations_[i];
150 if (!animation->is_impl_only())
151 continue;
153 if (!animation->InEffect(monotonic_time))
154 continue;
156 base::TimeDelta trimmed =
157 animation->TrimTimeToCurrentIteration(monotonic_time);
158 switch (animation->target_property()) {
159 case Animation::Opacity: {
160 AnimationEvent event(AnimationEvent::PropertyUpdate,
161 id_,
162 animation->group(),
163 Animation::Opacity,
164 monotonic_time);
165 const FloatAnimationCurve* float_animation_curve =
166 animation->curve()->ToFloatAnimationCurve();
167 event.opacity = float_animation_curve->GetValue(trimmed);
168 event.is_impl_only = true;
169 events->push_back(event);
170 break;
173 case Animation::Transform: {
174 AnimationEvent event(AnimationEvent::PropertyUpdate,
175 id_,
176 animation->group(),
177 Animation::Transform,
178 monotonic_time);
179 const TransformAnimationCurve* transform_animation_curve =
180 animation->curve()->ToTransformAnimationCurve();
181 event.transform = transform_animation_curve->GetValue(trimmed);
182 event.is_impl_only = true;
183 events->push_back(event);
184 break;
187 case Animation::Filter: {
188 AnimationEvent event(AnimationEvent::PropertyUpdate,
189 id_,
190 animation->group(),
191 Animation::Filter,
192 monotonic_time);
193 const FilterAnimationCurve* filter_animation_curve =
194 animation->curve()->ToFilterAnimationCurve();
195 event.filters = filter_animation_curve->GetValue(trimmed);
196 event.is_impl_only = true;
197 events->push_back(event);
198 break;
201 case Animation::BackgroundColor: { break; }
203 case Animation::ScrollOffset: {
204 // Impl-side changes to scroll offset are already sent back to the
205 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
206 // isn't needed.
207 break;
210 case Animation::TargetPropertyEnumSize:
211 NOTREACHED();
216 void LayerAnimationController::UpdateState(bool start_ready_animations,
217 AnimationEventsVector* events) {
218 if (!HasActiveValueObserver())
219 return;
221 // Animate hasn't been called, this happens if an observer has been added
222 // between the Commit and Draw phases.
223 if (last_tick_time_ == base::TimeTicks())
224 return;
226 if (start_ready_animations)
227 PromoteStartedAnimations(last_tick_time_, events);
229 MarkFinishedAnimations(last_tick_time_);
230 MarkAnimationsForDeletion(last_tick_time_, events);
232 if (needs_to_start_animations_ && start_ready_animations) {
233 StartAnimations(last_tick_time_);
234 PromoteStartedAnimations(last_tick_time_, events);
237 AccumulatePropertyUpdates(last_tick_time_, events);
239 UpdateActivation(NormalActivation);
242 struct AffectsNoObservers {
243 bool operator()(Animation* animation) const {
244 return !animation->affects_active_observers() &&
245 !animation->affects_pending_observers();
249 void LayerAnimationController::ActivateAnimations() {
250 for (size_t i = 0; i < animations_.size(); ++i) {
251 animations_[i]->set_affects_active_observers(
252 animations_[i]->affects_pending_observers());
254 animations_.erase(cc::remove_if(&animations_,
255 animations_.begin(),
256 animations_.end(),
257 AffectsNoObservers()),
258 animations_.end());
259 UpdateActivation(NormalActivation);
262 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
263 animations_.push_back(animation.Pass());
264 needs_to_start_animations_ = true;
265 UpdateActivation(NormalActivation);
268 Animation* LayerAnimationController::GetAnimation(
269 int group_id,
270 Animation::TargetProperty target_property) const {
271 for (size_t i = 0; i < animations_.size(); ++i)
272 if (animations_[i]->group() == group_id &&
273 animations_[i]->target_property() == target_property)
274 return animations_[i];
275 return 0;
278 Animation* LayerAnimationController::GetAnimation(
279 Animation::TargetProperty target_property) const {
280 for (size_t i = 0; i < animations_.size(); ++i) {
281 size_t index = animations_.size() - i - 1;
282 if (animations_[index]->target_property() == target_property)
283 return animations_[index];
285 return 0;
288 bool LayerAnimationController::HasActiveAnimation() const {
289 for (size_t i = 0; i < animations_.size(); ++i) {
290 if (!animations_[i]->is_finished())
291 return true;
293 return false;
296 bool LayerAnimationController::IsAnimatingProperty(
297 Animation::TargetProperty target_property) const {
298 for (size_t i = 0; i < animations_.size(); ++i) {
299 if (!animations_[i]->is_finished() &&
300 animations_[i]->InEffect(last_tick_time_) &&
301 animations_[i]->target_property() == target_property)
302 return true;
304 return false;
307 void LayerAnimationController::SetAnimationRegistrar(
308 AnimationRegistrar* registrar) {
309 if (registrar_ == registrar)
310 return;
312 if (registrar_)
313 registrar_->UnregisterAnimationController(this);
315 registrar_ = registrar;
316 if (registrar_)
317 registrar_->RegisterAnimationController(this);
319 UpdateActivation(ForceActivation);
322 void LayerAnimationController::NotifyAnimationStarted(
323 const AnimationEvent& event) {
324 if (event.is_impl_only) {
325 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
326 OnAnimationStarted(event));
327 if (layer_animation_delegate_)
328 layer_animation_delegate_->NotifyAnimationStarted(
329 event.monotonic_time, event.target_property, event.group_id);
330 return;
333 for (size_t i = 0; i < animations_.size(); ++i) {
334 if (animations_[i]->group() == event.group_id &&
335 animations_[i]->target_property() == event.target_property &&
336 animations_[i]->needs_synchronized_start_time()) {
337 animations_[i]->set_needs_synchronized_start_time(false);
338 if (!animations_[i]->has_set_start_time())
339 animations_[i]->set_start_time(event.monotonic_time);
341 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
342 OnAnimationStarted(event));
343 if (layer_animation_delegate_)
344 layer_animation_delegate_->NotifyAnimationStarted(
345 event.monotonic_time, event.target_property, event.group_id);
347 return;
352 void LayerAnimationController::NotifyAnimationFinished(
353 const AnimationEvent& event) {
354 if (event.is_impl_only) {
355 if (layer_animation_delegate_)
356 layer_animation_delegate_->NotifyAnimationFinished(
357 event.monotonic_time, event.target_property, event.group_id);
358 return;
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]->set_received_finished_event(true);
365 if (layer_animation_delegate_)
366 layer_animation_delegate_->NotifyAnimationFinished(
367 event.monotonic_time, event.target_property, event.group_id);
369 return;
374 void LayerAnimationController::NotifyAnimationAborted(
375 const AnimationEvent& event) {
376 for (size_t i = 0; i < animations_.size(); ++i) {
377 if (animations_[i]->group() == event.group_id &&
378 animations_[i]->target_property() == event.target_property) {
379 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
384 void LayerAnimationController::NotifyAnimationPropertyUpdate(
385 const AnimationEvent& event) {
386 bool notify_active_observers = true;
387 bool notify_pending_observers = true;
388 switch (event.target_property) {
389 case Animation::Opacity:
390 NotifyObserversOpacityAnimated(
391 event.opacity, notify_active_observers, notify_pending_observers);
392 break;
393 case Animation::Transform:
394 NotifyObserversTransformAnimated(
395 event.transform, notify_active_observers, notify_pending_observers);
396 break;
397 default:
398 NOTREACHED();
402 void LayerAnimationController::AddValueObserver(
403 LayerAnimationValueObserver* observer) {
404 if (!value_observers_.HasObserver(observer))
405 value_observers_.AddObserver(observer);
408 void LayerAnimationController::RemoveValueObserver(
409 LayerAnimationValueObserver* observer) {
410 value_observers_.RemoveObserver(observer);
413 void LayerAnimationController::AddEventObserver(
414 LayerAnimationEventObserver* observer) {
415 if (!event_observers_.HasObserver(observer))
416 event_observers_.AddObserver(observer);
419 void LayerAnimationController::RemoveEventObserver(
420 LayerAnimationEventObserver* observer) {
421 event_observers_.RemoveObserver(observer);
424 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
425 for (size_t i = 0; i < animations_.size(); ++i) {
426 if (!animations_[i]->is_finished() &&
427 animations_[i]->target_property() == Animation::Filter &&
428 animations_[i]
429 ->curve()
430 ->ToFilterAnimationCurve()
431 ->HasFilterThatMovesPixels())
432 return true;
435 return false;
438 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
439 return IsAnimatingProperty(Animation::Transform);
442 bool LayerAnimationController::FilterAnimationBoundsForBox(
443 const gfx::BoxF& box, gfx::BoxF* bounds) const {
444 // TODO(avallee): Implement.
445 return false;
448 bool LayerAnimationController::TransformAnimationBoundsForBox(
449 const gfx::BoxF& box,
450 gfx::BoxF* bounds) const {
451 DCHECK(HasTransformAnimationThatInflatesBounds())
452 << "TransformAnimationBoundsForBox will give incorrect results if there "
453 << "are no transform animations affecting bounds, non-animated transform "
454 << "is not known";
456 // Compute bounds based on animations for which is_finished() is false.
457 // Do nothing if there are no such animations; in this case, it is assumed
458 // that callers will take care of computing bounds based on the owning layer's
459 // actual transform.
460 *bounds = gfx::BoxF();
461 for (size_t i = 0; i < animations_.size(); ++i) {
462 if (animations_[i]->is_finished() ||
463 animations_[i]->target_property() != Animation::Transform)
464 continue;
466 const TransformAnimationCurve* transform_animation_curve =
467 animations_[i]->curve()->ToTransformAnimationCurve();
468 gfx::BoxF animation_bounds;
469 bool success =
470 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
471 if (!success)
472 return false;
473 bounds->Union(animation_bounds);
476 return true;
479 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
480 for (size_t i = 0; i < animations_.size(); ++i) {
481 if (animations_[i]->is_finished() ||
482 animations_[i]->target_property() != Animation::Transform)
483 continue;
485 const TransformAnimationCurve* transform_animation_curve =
486 animations_[i]->curve()->ToTransformAnimationCurve();
487 if (transform_animation_curve->AffectsScale())
488 return true;
491 return false;
494 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
495 for (size_t i = 0; i < animations_.size(); ++i) {
496 if (animations_[i]->is_finished() ||
497 animations_[i]->target_property() != Animation::Transform)
498 continue;
500 const TransformAnimationCurve* transform_animation_curve =
501 animations_[i]->curve()->ToTransformAnimationCurve();
502 if (!transform_animation_curve->IsTranslation())
503 return false;
506 return true;
509 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
510 for (size_t i = 0; i < animations_.size(); ++i) {
511 if (animations_[i]->is_finished() ||
512 animations_[i]->target_property() != Animation::Transform)
513 continue;
515 const TransformAnimationCurve* transform_animation_curve =
516 animations_[i]->curve()->ToTransformAnimationCurve();
517 if (!transform_animation_curve->PreservesAxisAlignment())
518 return false;
521 return true;
524 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
525 *max_scale = 0.f;
526 for (size_t i = 0; i < animations_.size(); ++i) {
527 if (animations_[i]->is_finished() ||
528 animations_[i]->target_property() != Animation::Transform)
529 continue;
531 bool forward_direction = true;
532 switch (animations_[i]->direction()) {
533 case Animation::Normal:
534 case Animation::Alternate:
535 forward_direction = animations_[i]->playback_rate() >= 0.0;
536 break;
537 case Animation::Reverse:
538 case Animation::AlternateReverse:
539 forward_direction = animations_[i]->playback_rate() < 0.0;
540 break;
543 const TransformAnimationCurve* transform_animation_curve =
544 animations_[i]->curve()->ToTransformAnimationCurve();
545 float animation_scale = 0.f;
546 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
547 &animation_scale))
548 return false;
549 *max_scale = std::max(*max_scale, animation_scale);
552 return true;
555 void LayerAnimationController::PushNewAnimationsToImplThread(
556 LayerAnimationController* controller_impl) const {
557 // Any new animations owned by the main thread's controller are cloned and
558 // add to the impl thread's controller.
559 for (size_t i = 0; i < animations_.size(); ++i) {
560 // If the animation is already running on the impl thread, there is no
561 // need to copy it over.
562 if (controller_impl->GetAnimation(animations_[i]->group(),
563 animations_[i]->target_property()))
564 continue;
566 // If the animation is not running on the impl thread, it does not
567 // necessarily mean that it needs to be copied over and started; it may
568 // have already finished. In this case, the impl thread animation will
569 // have already notified that it has started and the main thread animation
570 // will no longer need
571 // a synchronized start time.
572 if (!animations_[i]->needs_synchronized_start_time())
573 continue;
575 // Scroll animations always start at the current scroll offset.
576 if (animations_[i]->target_property() == Animation::ScrollOffset) {
577 gfx::ScrollOffset current_scroll_offset;
578 if (controller_impl->value_provider_) {
579 current_scroll_offset =
580 controller_impl->value_provider_->ScrollOffsetForAnimation();
581 } else {
582 // The owning layer isn't yet in the active tree, so the main thread
583 // scroll offset will be up-to-date.
584 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
586 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
587 current_scroll_offset);
590 // The new animation should be set to run as soon as possible.
591 Animation::RunState initial_run_state =
592 Animation::WaitingForTargetAvailability;
593 scoped_ptr<Animation> to_add(
594 animations_[i]->CloneAndInitialize(initial_run_state));
595 DCHECK(!to_add->needs_synchronized_start_time());
596 to_add->set_affects_active_observers(false);
597 controller_impl->AddAnimation(to_add.Pass());
601 static bool IsCompleted(
602 Animation* animation,
603 const LayerAnimationController* main_thread_controller) {
604 if (animation->is_impl_only()) {
605 return (animation->run_state() == Animation::WaitingForDeletion);
606 } else {
607 return !main_thread_controller->GetAnimation(animation->group(),
608 animation->target_property());
612 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
613 return animation->run_state() == Animation::WaitingForDeletion &&
614 !animation->affects_pending_observers();
617 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
618 LayerAnimationController* controller_impl) const {
619 // Animations removed on the main thread should no longer affect pending
620 // observers, and should stop affecting active observers after the next call
621 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
622 // immediately.
623 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
624 for (size_t i = 0; i < animations.size(); ++i) {
625 if (IsCompleted(animations[i], this))
626 animations[i]->set_affects_pending_observers(false);
628 animations.erase(cc::remove_if(&animations,
629 animations.begin(),
630 animations.end(),
631 AffectsActiveOnlyAndIsWaitingForDeletion),
632 animations.end());
635 void LayerAnimationController::PushPropertiesToImplThread(
636 LayerAnimationController* controller_impl) const {
637 for (size_t i = 0; i < animations_.size(); ++i) {
638 Animation* current_impl = controller_impl->GetAnimation(
639 animations_[i]->group(), animations_[i]->target_property());
640 if (current_impl)
641 animations_[i]->PushPropertiesTo(current_impl);
645 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
646 DCHECK(needs_to_start_animations_);
647 needs_to_start_animations_ = false;
648 // First collect running properties affecting each type of observer.
649 TargetProperties blocked_properties_for_active_observers;
650 TargetProperties blocked_properties_for_pending_observers;
651 std::vector<size_t> animations_waiting_for_target;
653 animations_waiting_for_target.reserve(animations_.size());
654 for (size_t i = 0; i < animations_.size(); ++i) {
655 if (animations_[i]->run_state() == Animation::Starting ||
656 animations_[i]->run_state() == Animation::Running) {
657 if (animations_[i]->affects_active_observers()) {
658 blocked_properties_for_active_observers.insert(
659 animations_[i]->target_property());
661 if (animations_[i]->affects_pending_observers()) {
662 blocked_properties_for_pending_observers.insert(
663 animations_[i]->target_property());
665 } else if (animations_[i]->run_state() ==
666 Animation::WaitingForTargetAvailability) {
667 animations_waiting_for_target.push_back(i);
671 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
672 // Collect all properties for animations with the same group id (they
673 // should all also be in the list of animations).
674 size_t animation_index = animations_waiting_for_target[i];
675 Animation* animation_waiting_for_target = animations_[animation_index];
676 // Check for the run state again even though the animation was waiting
677 // for target because it might have changed the run state while handling
678 // previous animation in this loop (if they belong to same group).
679 if (animation_waiting_for_target->run_state() ==
680 Animation::WaitingForTargetAvailability) {
681 TargetProperties enqueued_properties;
682 bool affects_active_observers =
683 animation_waiting_for_target->affects_active_observers();
684 bool affects_pending_observers =
685 animation_waiting_for_target->affects_pending_observers();
686 enqueued_properties.insert(
687 animation_waiting_for_target->target_property());
688 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
689 if (animation_waiting_for_target->group() == animations_[j]->group()) {
690 enqueued_properties.insert(animations_[j]->target_property());
691 affects_active_observers |=
692 animations_[j]->affects_active_observers();
693 affects_pending_observers |=
694 animations_[j]->affects_pending_observers();
698 // Check to see if intersection of the list of properties affected by
699 // the group and the list of currently blocked properties is null, taking
700 // into account the type(s) of observers affected by the group. In any
701 // case, the group's target properties need to be added to the lists of
702 // blocked properties.
703 bool null_intersection = true;
704 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
705 p_iter != enqueued_properties.end();
706 ++p_iter) {
707 if (affects_active_observers &&
708 !blocked_properties_for_active_observers.insert(*p_iter).second)
709 null_intersection = false;
710 if (affects_pending_observers &&
711 !blocked_properties_for_pending_observers.insert(*p_iter).second)
712 null_intersection = false;
715 // If the intersection is null, then we are free to start the animations
716 // in the group.
717 if (null_intersection) {
718 animation_waiting_for_target->SetRunState(Animation::Starting,
719 monotonic_time);
720 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
721 if (animation_waiting_for_target->group() ==
722 animations_[j]->group()) {
723 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
726 } else {
727 needs_to_start_animations_ = true;
733 void LayerAnimationController::PromoteStartedAnimations(
734 base::TimeTicks monotonic_time,
735 AnimationEventsVector* events) {
736 for (size_t i = 0; i < animations_.size(); ++i) {
737 if (animations_[i]->run_state() == Animation::Starting &&
738 animations_[i]->affects_active_observers()) {
739 animations_[i]->SetRunState(Animation::Running, monotonic_time);
740 if (!animations_[i]->has_set_start_time() &&
741 !animations_[i]->needs_synchronized_start_time())
742 animations_[i]->set_start_time(monotonic_time);
743 if (events) {
744 AnimationEvent started_event(AnimationEvent::Started,
745 id_,
746 animations_[i]->group(),
747 animations_[i]->target_property(),
748 monotonic_time);
749 started_event.is_impl_only = animations_[i]->is_impl_only();
750 if (started_event.is_impl_only)
751 NotifyAnimationStarted(started_event);
752 else
753 events->push_back(started_event);
759 void LayerAnimationController::MarkFinishedAnimations(
760 base::TimeTicks monotonic_time) {
761 for (size_t i = 0; i < animations_.size(); ++i) {
762 if (animations_[i]->IsFinishedAt(monotonic_time) &&
763 animations_[i]->run_state() != Animation::Aborted &&
764 animations_[i]->run_state() != Animation::WaitingForDeletion)
765 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
769 void LayerAnimationController::MarkAnimationsForDeletion(
770 base::TimeTicks monotonic_time,
771 AnimationEventsVector* events) {
772 bool marked_animations_for_deletions = false;
773 std::vector<size_t> animations_with_same_group_id;
775 animations_with_same_group_id.reserve(animations_.size());
776 // Non-aborted animations are marked for deletion after a corresponding
777 // AnimationEvent::Finished event is sent or received. This means that if
778 // we don't have an events vector, we must ensure that non-aborted animations
779 // have received a finished event before marking them for deletion.
780 for (size_t i = 0; i < animations_.size(); i++) {
781 int group_id = animations_[i]->group();
782 if (animations_[i]->run_state() == Animation::Aborted) {
783 if (events && !animations_[i]->is_impl_only()) {
784 AnimationEvent aborted_event(AnimationEvent::Aborted,
785 id_,
786 group_id,
787 animations_[i]->target_property(),
788 monotonic_time);
789 events->push_back(aborted_event);
791 animations_[i]->SetRunState(Animation::WaitingForDeletion,
792 monotonic_time);
793 marked_animations_for_deletions = true;
794 continue;
797 bool all_anims_with_same_id_are_finished = false;
799 // Since deleting an animation on the main thread leads to its deletion
800 // on the impl thread, we only mark a Finished main thread animation for
801 // deletion once it has received a Finished event from the impl thread.
802 bool animation_i_will_send_or_has_received_finish_event =
803 events || animations_[i]->received_finished_event();
804 // If an animation is finished, and not already marked for deletion,
805 // find out if all other animations in the same group are also finished.
806 if (animations_[i]->run_state() == Animation::Finished &&
807 animation_i_will_send_or_has_received_finish_event) {
808 // Clear the animations_with_same_group_id if it was added for
809 // the previous animation's iteration.
810 if (animations_with_same_group_id.size() > 0)
811 animations_with_same_group_id.clear();
812 all_anims_with_same_id_are_finished = true;
813 for (size_t j = 0; j < animations_.size(); ++j) {
814 bool animation_j_will_send_or_has_received_finish_event =
815 events || animations_[j]->received_finished_event();
816 if (group_id == animations_[j]->group()) {
817 if (!animations_[j]->is_finished() ||
818 (animations_[j]->run_state() == Animation::Finished &&
819 !animation_j_will_send_or_has_received_finish_event)) {
820 all_anims_with_same_id_are_finished = false;
821 break;
822 } else if (j >= i &&
823 animations_[j]->run_state() != Animation::Aborted) {
824 // Mark down the animations which belong to the same group
825 // and is not yet aborted. If this current iteration finds that all
826 // animations with same ID are finished, then the marked
827 // animations below will be set to WaitingForDeletion in next
828 // iteration.
829 animations_with_same_group_id.push_back(j);
834 if (all_anims_with_same_id_are_finished) {
835 // We now need to remove all animations with the same group id as
836 // group_id (and send along animation finished notifications, if
837 // necessary).
838 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
839 size_t animation_index = animations_with_same_group_id[j];
840 if (events) {
841 AnimationEvent finished_event(
842 AnimationEvent::Finished,
843 id_,
844 animations_[animation_index]->group(),
845 animations_[animation_index]->target_property(),
846 monotonic_time);
847 finished_event.is_impl_only =
848 animations_[animation_index]->is_impl_only();
849 if (finished_event.is_impl_only)
850 NotifyAnimationFinished(finished_event);
851 else
852 events->push_back(finished_event);
854 animations_[animation_index]->SetRunState(
855 Animation::WaitingForDeletion, monotonic_time);
857 marked_animations_for_deletions = true;
860 if (marked_animations_for_deletions)
861 NotifyObserversAnimationWaitingForDeletion();
864 static bool IsWaitingForDeletion(Animation* animation) {
865 return animation->run_state() == Animation::WaitingForDeletion;
868 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
869 animations_.erase(cc::remove_if(&animations_,
870 animations_.begin(),
871 animations_.end(),
872 IsWaitingForDeletion),
873 animations_.end());
876 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
877 for (size_t i = 0; i < animations_.size(); ++i) {
878 if (animations_[i]->run_state() == Animation::Starting ||
879 animations_[i]->run_state() == Animation::Running ||
880 animations_[i]->run_state() == Animation::Paused) {
881 if (!animations_[i]->InEffect(monotonic_time))
882 continue;
884 base::TimeDelta trimmed =
885 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
887 switch (animations_[i]->target_property()) {
888 case Animation::Transform: {
889 const TransformAnimationCurve* transform_animation_curve =
890 animations_[i]->curve()->ToTransformAnimationCurve();
891 const gfx::Transform transform =
892 transform_animation_curve->GetValue(trimmed);
893 NotifyObserversTransformAnimated(
894 transform,
895 animations_[i]->affects_active_observers(),
896 animations_[i]->affects_pending_observers());
897 break;
900 case Animation::Opacity: {
901 const FloatAnimationCurve* float_animation_curve =
902 animations_[i]->curve()->ToFloatAnimationCurve();
903 const float opacity = std::max(
904 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
905 NotifyObserversOpacityAnimated(
906 opacity,
907 animations_[i]->affects_active_observers(),
908 animations_[i]->affects_pending_observers());
909 break;
912 case Animation::Filter: {
913 const FilterAnimationCurve* filter_animation_curve =
914 animations_[i]->curve()->ToFilterAnimationCurve();
915 const FilterOperations filter =
916 filter_animation_curve->GetValue(trimmed);
917 NotifyObserversFilterAnimated(
918 filter,
919 animations_[i]->affects_active_observers(),
920 animations_[i]->affects_pending_observers());
921 break;
924 case Animation::BackgroundColor: {
925 // Not yet implemented.
926 break;
929 case Animation::ScrollOffset: {
930 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
931 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
932 const gfx::ScrollOffset scroll_offset =
933 scroll_offset_animation_curve->GetValue(trimmed);
934 NotifyObserversScrollOffsetAnimated(
935 scroll_offset,
936 animations_[i]->affects_active_observers(),
937 animations_[i]->affects_pending_observers());
938 break;
941 // Do nothing for sentinel value.
942 case Animation::TargetPropertyEnumSize:
943 NOTREACHED();
949 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
950 bool force = type == ForceActivation;
951 if (registrar_) {
952 bool was_active = is_active_;
953 is_active_ = false;
954 for (size_t i = 0; i < animations_.size(); ++i) {
955 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
956 is_active_ = true;
957 break;
961 if (is_active_ && (!was_active || force))
962 registrar_->DidActivateAnimationController(this);
963 else if (!is_active_ && (was_active || force))
964 registrar_->DidDeactivateAnimationController(this);
968 void LayerAnimationController::NotifyObserversOpacityAnimated(
969 float opacity,
970 bool notify_active_observers,
971 bool notify_pending_observers) {
972 if (value_observers_.might_have_observers()) {
973 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
974 value_observers_);
975 LayerAnimationValueObserver* obs;
976 while ((obs = it.GetNext()) != nullptr) {
977 if ((notify_active_observers && notify_pending_observers) ||
978 (notify_active_observers && obs->IsActive()) ||
979 (notify_pending_observers && !obs->IsActive()))
980 obs->OnOpacityAnimated(opacity);
985 void LayerAnimationController::NotifyObserversTransformAnimated(
986 const gfx::Transform& transform,
987 bool notify_active_observers,
988 bool notify_pending_observers) {
989 if (value_observers_.might_have_observers()) {
990 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
991 value_observers_);
992 LayerAnimationValueObserver* obs;
993 while ((obs = it.GetNext()) != nullptr) {
994 if ((notify_active_observers && notify_pending_observers) ||
995 (notify_active_observers && obs->IsActive()) ||
996 (notify_pending_observers && !obs->IsActive()))
997 obs->OnTransformAnimated(transform);
1002 void LayerAnimationController::NotifyObserversFilterAnimated(
1003 const FilterOperations& filters,
1004 bool notify_active_observers,
1005 bool notify_pending_observers) {
1006 if (value_observers_.might_have_observers()) {
1007 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1008 value_observers_);
1009 LayerAnimationValueObserver* obs;
1010 while ((obs = it.GetNext()) != nullptr) {
1011 if ((notify_active_observers && notify_pending_observers) ||
1012 (notify_active_observers && obs->IsActive()) ||
1013 (notify_pending_observers && !obs->IsActive()))
1014 obs->OnFilterAnimated(filters);
1019 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1020 const gfx::ScrollOffset& scroll_offset,
1021 bool notify_active_observers,
1022 bool notify_pending_observers) {
1023 if (value_observers_.might_have_observers()) {
1024 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1025 value_observers_);
1026 LayerAnimationValueObserver* obs;
1027 while ((obs = it.GetNext()) != nullptr) {
1028 if ((notify_active_observers && notify_pending_observers) ||
1029 (notify_active_observers && obs->IsActive()) ||
1030 (notify_pending_observers && !obs->IsActive()))
1031 obs->OnScrollOffsetAnimated(scroll_offset);
1036 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1037 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1038 value_observers_,
1039 OnAnimationWaitingForDeletion());
1042 void LayerAnimationController::NotifyObserversScrollOffsetAnimationRemoved() {
1043 FOR_EACH_OBSERVER(LayerAnimationValueObserver, value_observers_,
1044 OnScrollOffsetAnimationRemoved());
1047 bool LayerAnimationController::HasValueObserver() {
1048 if (value_observers_.might_have_observers()) {
1049 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1050 value_observers_);
1051 return it.GetNext() != nullptr;
1053 return false;
1056 bool LayerAnimationController::HasActiveValueObserver() {
1057 if (value_observers_.might_have_observers()) {
1058 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1059 value_observers_);
1060 LayerAnimationValueObserver* obs;
1061 while ((obs = it.GetNext()) != nullptr)
1062 if (obs->IsActive())
1063 return true;
1065 return false;
1068 } // namespace cc