Implements RLZTrackerDelegate on iOS.
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blob54b1a717f7868d59ebc17c3bc7835d3ff8caa9c3
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),
31 scroll_offset_animation_was_interrupted_(false) {
34 LayerAnimationController::~LayerAnimationController() {
35 if (registrar_)
36 registrar_->UnregisterAnimationController(this);
39 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
40 int id) {
41 return make_scoped_refptr(new LayerAnimationController(id));
44 void LayerAnimationController::PauseAnimation(int animation_id,
45 base::TimeDelta time_offset) {
46 for (size_t i = 0; i < animations_.size(); ++i) {
47 if (animations_[i]->id() == animation_id) {
48 animations_[i]->SetRunState(Animation::PAUSED,
49 time_offset + animations_[i]->start_time());
54 struct HasAnimationId {
55 explicit HasAnimationId(int id) : id_(id) {}
56 bool operator()(Animation* animation) const {
57 return animation->id() == id_;
60 private:
61 int id_;
64 void LayerAnimationController::RemoveAnimation(int animation_id) {
65 auto animations_to_remove =
66 animations_.remove_if(HasAnimationId(animation_id));
67 for (auto it = animations_to_remove; it != animations_.end(); ++it) {
68 if ((*it)->target_property() == Animation::SCROLL_OFFSET) {
69 scroll_offset_animation_was_interrupted_ = true;
70 break;
73 animations_.erase(animations_to_remove, animations_.end());
74 UpdateActivation(NORMAL_ACTIVATION);
77 struct HasAnimationIdAndProperty {
78 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
79 : id_(id), target_property_(target_property) {}
80 bool operator()(Animation* animation) const {
81 return animation->id() == id_ &&
82 animation->target_property() == target_property_;
85 private:
86 int id_;
87 Animation::TargetProperty target_property_;
90 void LayerAnimationController::RemoveAnimation(
91 int animation_id,
92 Animation::TargetProperty target_property) {
93 auto animations_to_remove = animations_.remove_if(
94 HasAnimationIdAndProperty(animation_id, target_property));
95 if (target_property == Animation::SCROLL_OFFSET &&
96 animations_to_remove != animations_.end())
97 scroll_offset_animation_was_interrupted_ = true;
99 animations_.erase(animations_to_remove, animations_.end());
100 UpdateActivation(NORMAL_ACTIVATION);
103 void LayerAnimationController::AbortAnimations(
104 Animation::TargetProperty target_property) {
105 for (size_t i = 0; i < animations_.size(); ++i) {
106 if (animations_[i]->target_property() == target_property &&
107 !animations_[i]->is_finished())
108 animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_);
112 // Ensures that the list of active animations on the main thread and the impl
113 // thread are kept in sync.
114 void LayerAnimationController::PushAnimationUpdatesTo(
115 LayerAnimationController* controller_impl) {
116 DCHECK(this != controller_impl);
117 if (!has_any_animation() && !controller_impl->has_any_animation())
118 return;
119 PurgeAnimationsMarkedForDeletion();
120 PushNewAnimationsToImplThread(controller_impl);
122 // Remove finished impl side animations only after pushing,
123 // and only after the animations are deleted on the main thread
124 // this insures we will never push an animation twice.
125 RemoveAnimationsCompletedOnMainThread(controller_impl);
127 PushPropertiesToImplThread(controller_impl);
128 controller_impl->UpdateActivation(NORMAL_ACTIVATION);
129 UpdateActivation(NORMAL_ACTIVATION);
132 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
133 DCHECK(!monotonic_time.is_null());
134 if (!HasValueObserver())
135 return;
137 if (needs_to_start_animations_)
138 StartAnimations(monotonic_time);
139 TickAnimations(monotonic_time);
140 last_tick_time_ = monotonic_time;
143 void LayerAnimationController::AccumulatePropertyUpdates(
144 base::TimeTicks monotonic_time,
145 AnimationEventsVector* events) {
146 if (!events)
147 return;
149 for (size_t i = 0; i < animations_.size(); ++i) {
150 Animation* animation = animations_[i];
151 if (!animation->is_impl_only())
152 continue;
154 if (!animation->InEffect(monotonic_time))
155 continue;
157 base::TimeDelta trimmed =
158 animation->TrimTimeToCurrentIteration(monotonic_time);
159 switch (animation->target_property()) {
160 case Animation::OPACITY: {
161 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
162 animation->group(), Animation::OPACITY,
163 monotonic_time);
164 const FloatAnimationCurve* float_animation_curve =
165 animation->curve()->ToFloatAnimationCurve();
166 event.opacity = float_animation_curve->GetValue(trimmed);
167 event.is_impl_only = true;
168 events->push_back(event);
169 break;
172 case Animation::TRANSFORM: {
173 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
174 animation->group(), Animation::TRANSFORM,
175 monotonic_time);
176 const TransformAnimationCurve* transform_animation_curve =
177 animation->curve()->ToTransformAnimationCurve();
178 event.transform = transform_animation_curve->GetValue(trimmed);
179 event.is_impl_only = true;
180 events->push_back(event);
181 break;
184 case Animation::FILTER: {
185 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
186 animation->group(), 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::BACKGROUND_COLOR: {
197 break;
200 case Animation::SCROLL_OFFSET: {
201 // Impl-side changes to scroll offset are already sent back to the
202 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE
203 // isn't needed.
204 break;
210 void LayerAnimationController::UpdateState(bool start_ready_animations,
211 AnimationEventsVector* events) {
212 if (!HasActiveValueObserver())
213 return;
215 // Animate hasn't been called, this happens if an observer has been added
216 // between the Commit and Draw phases.
217 if (last_tick_time_ == base::TimeTicks())
218 return;
220 if (start_ready_animations)
221 PromoteStartedAnimations(last_tick_time_, events);
223 MarkFinishedAnimations(last_tick_time_);
224 MarkAnimationsForDeletion(last_tick_time_, events);
226 if (needs_to_start_animations_ && start_ready_animations) {
227 StartAnimations(last_tick_time_);
228 PromoteStartedAnimations(last_tick_time_, events);
231 AccumulatePropertyUpdates(last_tick_time_, events);
233 UpdateActivation(NORMAL_ACTIVATION);
236 struct AffectsNoObservers {
237 bool operator()(Animation* animation) const {
238 return !animation->affects_active_observers() &&
239 !animation->affects_pending_observers();
243 void LayerAnimationController::ActivateAnimations() {
244 for (size_t i = 0; i < animations_.size(); ++i) {
245 animations_[i]->set_affects_active_observers(
246 animations_[i]->affects_pending_observers());
248 animations_.erase(cc::remove_if(&animations_,
249 animations_.begin(),
250 animations_.end(),
251 AffectsNoObservers()),
252 animations_.end());
253 scroll_offset_animation_was_interrupted_ = false;
254 UpdateActivation(NORMAL_ACTIVATION);
257 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
258 animations_.push_back(animation.Pass());
259 needs_to_start_animations_ = true;
260 UpdateActivation(NORMAL_ACTIVATION);
263 Animation* LayerAnimationController::GetAnimation(
264 Animation::TargetProperty target_property) const {
265 for (size_t i = 0; i < animations_.size(); ++i) {
266 size_t index = animations_.size() - i - 1;
267 if (animations_[index]->target_property() == target_property)
268 return animations_[index];
270 return 0;
273 Animation* LayerAnimationController::GetAnimationById(int animation_id) const {
274 for (size_t i = 0; i < animations_.size(); ++i)
275 if (animations_[i]->id() == animation_id)
276 return animations_[i];
277 return nullptr;
280 bool LayerAnimationController::HasActiveAnimation() const {
281 for (size_t i = 0; i < animations_.size(); ++i) {
282 if (!animations_[i]->is_finished())
283 return true;
285 return false;
288 bool LayerAnimationController::IsAnimatingProperty(
289 Animation::TargetProperty target_property) const {
290 for (size_t i = 0; i < animations_.size(); ++i) {
291 if (!animations_[i]->is_finished() &&
292 animations_[i]->InEffect(last_tick_time_) &&
293 animations_[i]->target_property() == target_property)
294 return true;
296 return false;
299 void LayerAnimationController::SetAnimationRegistrar(
300 AnimationRegistrar* registrar) {
301 if (registrar_ == registrar)
302 return;
304 if (registrar_)
305 registrar_->UnregisterAnimationController(this);
307 registrar_ = registrar;
308 if (registrar_)
309 registrar_->RegisterAnimationController(this);
311 UpdateActivation(FORCE_ACTIVATION);
314 void LayerAnimationController::NotifyAnimationStarted(
315 const AnimationEvent& event) {
316 if (event.is_impl_only) {
317 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
318 OnAnimationStarted(event));
319 if (layer_animation_delegate_)
320 layer_animation_delegate_->NotifyAnimationStarted(
321 event.monotonic_time, event.target_property, event.group_id);
322 return;
325 for (size_t i = 0; i < animations_.size(); ++i) {
326 if (animations_[i]->group() == event.group_id &&
327 animations_[i]->target_property() == event.target_property &&
328 animations_[i]->needs_synchronized_start_time()) {
329 animations_[i]->set_needs_synchronized_start_time(false);
330 if (!animations_[i]->has_set_start_time())
331 animations_[i]->set_start_time(event.monotonic_time);
333 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
334 OnAnimationStarted(event));
335 if (layer_animation_delegate_)
336 layer_animation_delegate_->NotifyAnimationStarted(
337 event.monotonic_time, event.target_property, event.group_id);
339 return;
344 void LayerAnimationController::NotifyAnimationFinished(
345 const AnimationEvent& event) {
346 if (event.is_impl_only) {
347 if (layer_animation_delegate_)
348 layer_animation_delegate_->NotifyAnimationFinished(
349 event.monotonic_time, event.target_property, event.group_id);
350 return;
353 for (size_t i = 0; i < animations_.size(); ++i) {
354 if (animations_[i]->group() == event.group_id &&
355 animations_[i]->target_property() == event.target_property) {
356 animations_[i]->set_received_finished_event(true);
357 if (layer_animation_delegate_)
358 layer_animation_delegate_->NotifyAnimationFinished(
359 event.monotonic_time, event.target_property, event.group_id);
361 return;
366 void LayerAnimationController::NotifyAnimationAborted(
367 const AnimationEvent& event) {
368 for (size_t i = 0; i < animations_.size(); ++i) {
369 if (animations_[i]->group() == event.group_id &&
370 animations_[i]->target_property() == event.target_property) {
371 animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time);
376 void LayerAnimationController::NotifyAnimationPropertyUpdate(
377 const AnimationEvent& event) {
378 bool notify_active_observers = true;
379 bool notify_pending_observers = true;
380 switch (event.target_property) {
381 case Animation::OPACITY:
382 NotifyObserversOpacityAnimated(
383 event.opacity, notify_active_observers, notify_pending_observers);
384 break;
385 case Animation::TRANSFORM:
386 NotifyObserversTransformAnimated(
387 event.transform, notify_active_observers, notify_pending_observers);
388 break;
389 default:
390 NOTREACHED();
394 void LayerAnimationController::AddValueObserver(
395 LayerAnimationValueObserver* observer) {
396 if (!value_observers_.HasObserver(observer))
397 value_observers_.AddObserver(observer);
400 void LayerAnimationController::RemoveValueObserver(
401 LayerAnimationValueObserver* observer) {
402 value_observers_.RemoveObserver(observer);
405 void LayerAnimationController::AddEventObserver(
406 LayerAnimationEventObserver* observer) {
407 if (!event_observers_.HasObserver(observer))
408 event_observers_.AddObserver(observer);
411 void LayerAnimationController::RemoveEventObserver(
412 LayerAnimationEventObserver* observer) {
413 event_observers_.RemoveObserver(observer);
416 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
417 for (size_t i = 0; i < animations_.size(); ++i) {
418 if (!animations_[i]->is_finished() &&
419 animations_[i]->target_property() == Animation::FILTER &&
420 animations_[i]
421 ->curve()
422 ->ToFilterAnimationCurve()
423 ->HasFilterThatMovesPixels())
424 return true;
427 return false;
430 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
431 return IsAnimatingProperty(Animation::TRANSFORM);
434 bool LayerAnimationController::FilterAnimationBoundsForBox(
435 const gfx::BoxF& box, gfx::BoxF* bounds) const {
436 // TODO(avallee): Implement.
437 return false;
440 bool LayerAnimationController::TransformAnimationBoundsForBox(
441 const gfx::BoxF& box,
442 gfx::BoxF* bounds) const {
443 DCHECK(HasTransformAnimationThatInflatesBounds())
444 << "TransformAnimationBoundsForBox will give incorrect results if there "
445 << "are no transform animations affecting bounds, non-animated transform "
446 << "is not known";
448 // Compute bounds based on animations for which is_finished() is false.
449 // Do nothing if there are no such animations; in this case, it is assumed
450 // that callers will take care of computing bounds based on the owning layer's
451 // actual transform.
452 *bounds = gfx::BoxF();
453 for (size_t i = 0; i < animations_.size(); ++i) {
454 if (animations_[i]->is_finished() ||
455 animations_[i]->target_property() != Animation::TRANSFORM)
456 continue;
458 const TransformAnimationCurve* transform_animation_curve =
459 animations_[i]->curve()->ToTransformAnimationCurve();
460 gfx::BoxF animation_bounds;
461 bool success =
462 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
463 if (!success)
464 return false;
465 bounds->Union(animation_bounds);
468 return true;
471 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
472 for (size_t i = 0; i < animations_.size(); ++i) {
473 if (animations_[i]->is_finished() ||
474 animations_[i]->target_property() != Animation::TRANSFORM)
475 continue;
477 const TransformAnimationCurve* transform_animation_curve =
478 animations_[i]->curve()->ToTransformAnimationCurve();
479 if (transform_animation_curve->AffectsScale())
480 return true;
483 return false;
486 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
487 for (size_t i = 0; i < animations_.size(); ++i) {
488 if (animations_[i]->is_finished() ||
489 animations_[i]->target_property() != Animation::TRANSFORM)
490 continue;
492 const TransformAnimationCurve* transform_animation_curve =
493 animations_[i]->curve()->ToTransformAnimationCurve();
494 if (!transform_animation_curve->IsTranslation())
495 return false;
498 return true;
501 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
502 for (size_t i = 0; i < animations_.size(); ++i) {
503 if (animations_[i]->is_finished() ||
504 animations_[i]->target_property() != Animation::TRANSFORM)
505 continue;
507 const TransformAnimationCurve* transform_animation_curve =
508 animations_[i]->curve()->ToTransformAnimationCurve();
509 if (!transform_animation_curve->PreservesAxisAlignment())
510 return false;
513 return true;
516 bool LayerAnimationController::AnimationStartScale(float* start_scale) const {
517 *start_scale = 0.f;
518 for (size_t i = 0; i < animations_.size(); ++i) {
519 if (animations_[i]->is_finished() ||
520 animations_[i]->target_property() != Animation::TRANSFORM)
521 continue;
523 bool forward_direction = true;
524 switch (animations_[i]->direction()) {
525 case Animation::DIRECTION_NORMAL:
526 case Animation::DIRECTION_ALTERNATE:
527 forward_direction = animations_[i]->playback_rate() >= 0.0;
528 break;
529 case Animation::DIRECTION_REVERSE:
530 case Animation::DIRECTION_ALTERNATE_REVERSE:
531 forward_direction = animations_[i]->playback_rate() < 0.0;
532 break;
535 const TransformAnimationCurve* transform_animation_curve =
536 animations_[i]->curve()->ToTransformAnimationCurve();
537 float animation_start_scale = 0.f;
538 if (!transform_animation_curve->AnimationStartScale(forward_direction,
539 &animation_start_scale))
540 return false;
541 *start_scale = std::max(*start_scale, animation_start_scale);
543 return true;
546 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
547 *max_scale = 0.f;
548 for (size_t i = 0; i < animations_.size(); ++i) {
549 if (animations_[i]->is_finished() ||
550 animations_[i]->target_property() != Animation::TRANSFORM)
551 continue;
553 bool forward_direction = true;
554 switch (animations_[i]->direction()) {
555 case Animation::DIRECTION_NORMAL:
556 case Animation::DIRECTION_ALTERNATE:
557 forward_direction = animations_[i]->playback_rate() >= 0.0;
558 break;
559 case Animation::DIRECTION_REVERSE:
560 case Animation::DIRECTION_ALTERNATE_REVERSE:
561 forward_direction = animations_[i]->playback_rate() < 0.0;
562 break;
565 const TransformAnimationCurve* transform_animation_curve =
566 animations_[i]->curve()->ToTransformAnimationCurve();
567 float animation_scale = 0.f;
568 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
569 &animation_scale))
570 return false;
571 *max_scale = std::max(*max_scale, animation_scale);
574 return true;
577 void LayerAnimationController::PushNewAnimationsToImplThread(
578 LayerAnimationController* controller_impl) const {
579 // Any new animations owned by the main thread's controller are cloned and
580 // add to the impl thread's controller.
581 for (size_t i = 0; i < animations_.size(); ++i) {
582 // If the animation is already running on the impl thread, there is no
583 // need to copy it over.
584 if (controller_impl->GetAnimationById(animations_[i]->id()))
585 continue;
587 // Scroll animations always start at the current scroll offset.
588 if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
589 gfx::ScrollOffset current_scroll_offset;
590 if (controller_impl->value_provider_) {
591 current_scroll_offset =
592 controller_impl->value_provider_->ScrollOffsetForAnimation();
593 } else {
594 // The owning layer isn't yet in the active tree, so the main thread
595 // scroll offset will be up-to-date.
596 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
598 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
599 current_scroll_offset);
602 // The new animation should be set to run as soon as possible.
603 Animation::RunState initial_run_state =
604 Animation::WAITING_FOR_TARGET_AVAILABILITY;
605 scoped_ptr<Animation> to_add(
606 animations_[i]->CloneAndInitialize(initial_run_state));
607 DCHECK(!to_add->needs_synchronized_start_time());
608 to_add->set_affects_active_observers(false);
609 controller_impl->AddAnimation(to_add.Pass());
613 static bool IsCompleted(
614 Animation* animation,
615 const LayerAnimationController* main_thread_controller) {
616 if (animation->is_impl_only()) {
617 return (animation->run_state() == Animation::WAITING_FOR_DELETION);
618 } else {
619 return !main_thread_controller->GetAnimationById(animation->id());
623 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
624 return animation->run_state() == Animation::WAITING_FOR_DELETION &&
625 !animation->affects_pending_observers();
628 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
629 LayerAnimationController* controller_impl) const {
630 // Animations removed on the main thread should no longer affect pending
631 // observers, and should stop affecting active observers after the next call
632 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
633 // immediately.
634 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
635 for (size_t i = 0; i < animations.size(); ++i) {
636 if (IsCompleted(animations[i], this))
637 animations[i]->set_affects_pending_observers(false);
639 animations.erase(cc::remove_if(&animations,
640 animations.begin(),
641 animations.end(),
642 AffectsActiveOnlyAndIsWaitingForDeletion),
643 animations.end());
646 void LayerAnimationController::PushPropertiesToImplThread(
647 LayerAnimationController* controller_impl) {
648 for (size_t i = 0; i < animations_.size(); ++i) {
649 Animation* current_impl =
650 controller_impl->GetAnimationById(animations_[i]->id());
651 if (current_impl)
652 animations_[i]->PushPropertiesTo(current_impl);
654 controller_impl->scroll_offset_animation_was_interrupted_ =
655 scroll_offset_animation_was_interrupted_;
656 scroll_offset_animation_was_interrupted_ = false;
659 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
660 DCHECK(needs_to_start_animations_);
661 needs_to_start_animations_ = false;
662 // First collect running properties affecting each type of observer.
663 TargetProperties blocked_properties_for_active_observers;
664 TargetProperties blocked_properties_for_pending_observers;
665 std::vector<size_t> animations_waiting_for_target;
667 animations_waiting_for_target.reserve(animations_.size());
668 for (size_t i = 0; i < animations_.size(); ++i) {
669 if (animations_[i]->run_state() == Animation::STARTING ||
670 animations_[i]->run_state() == Animation::RUNNING) {
671 if (animations_[i]->affects_active_observers()) {
672 blocked_properties_for_active_observers.insert(
673 animations_[i]->target_property());
675 if (animations_[i]->affects_pending_observers()) {
676 blocked_properties_for_pending_observers.insert(
677 animations_[i]->target_property());
679 } else if (animations_[i]->run_state() ==
680 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
681 animations_waiting_for_target.push_back(i);
685 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
686 // Collect all properties for animations with the same group id (they
687 // should all also be in the list of animations).
688 size_t animation_index = animations_waiting_for_target[i];
689 Animation* animation_waiting_for_target = animations_[animation_index];
690 // Check for the run state again even though the animation was waiting
691 // for target because it might have changed the run state while handling
692 // previous animation in this loop (if they belong to same group).
693 if (animation_waiting_for_target->run_state() ==
694 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
695 TargetProperties enqueued_properties;
696 bool affects_active_observers =
697 animation_waiting_for_target->affects_active_observers();
698 bool affects_pending_observers =
699 animation_waiting_for_target->affects_pending_observers();
700 enqueued_properties.insert(
701 animation_waiting_for_target->target_property());
702 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
703 if (animation_waiting_for_target->group() == animations_[j]->group()) {
704 enqueued_properties.insert(animations_[j]->target_property());
705 affects_active_observers |=
706 animations_[j]->affects_active_observers();
707 affects_pending_observers |=
708 animations_[j]->affects_pending_observers();
712 // Check to see if intersection of the list of properties affected by
713 // the group and the list of currently blocked properties is null, taking
714 // into account the type(s) of observers affected by the group. In any
715 // case, the group's target properties need to be added to the lists of
716 // blocked properties.
717 bool null_intersection = true;
718 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
719 p_iter != enqueued_properties.end();
720 ++p_iter) {
721 if (affects_active_observers &&
722 !blocked_properties_for_active_observers.insert(*p_iter).second)
723 null_intersection = false;
724 if (affects_pending_observers &&
725 !blocked_properties_for_pending_observers.insert(*p_iter).second)
726 null_intersection = false;
729 // If the intersection is null, then we are free to start the animations
730 // in the group.
731 if (null_intersection) {
732 animation_waiting_for_target->SetRunState(Animation::STARTING,
733 monotonic_time);
734 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
735 if (animation_waiting_for_target->group() ==
736 animations_[j]->group()) {
737 animations_[j]->SetRunState(Animation::STARTING, monotonic_time);
740 } else {
741 needs_to_start_animations_ = true;
747 void LayerAnimationController::PromoteStartedAnimations(
748 base::TimeTicks monotonic_time,
749 AnimationEventsVector* events) {
750 for (size_t i = 0; i < animations_.size(); ++i) {
751 if (animations_[i]->run_state() == Animation::STARTING &&
752 animations_[i]->affects_active_observers()) {
753 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time);
754 if (!animations_[i]->has_set_start_time() &&
755 !animations_[i]->needs_synchronized_start_time())
756 animations_[i]->set_start_time(monotonic_time);
757 if (events) {
758 base::TimeTicks start_time;
759 if (animations_[i]->has_set_start_time())
760 start_time = animations_[i]->start_time();
761 else
762 start_time = monotonic_time;
763 AnimationEvent started_event(
764 AnimationEvent::STARTED, id_, animations_[i]->group(),
765 animations_[i]->target_property(), start_time);
766 started_event.is_impl_only = animations_[i]->is_impl_only();
767 if (started_event.is_impl_only)
768 NotifyAnimationStarted(started_event);
769 else
770 events->push_back(started_event);
776 void LayerAnimationController::MarkFinishedAnimations(
777 base::TimeTicks monotonic_time) {
778 for (size_t i = 0; i < animations_.size(); ++i) {
779 if (animations_[i]->IsFinishedAt(monotonic_time) &&
780 animations_[i]->run_state() != Animation::ABORTED &&
781 animations_[i]->run_state() != Animation::WAITING_FOR_DELETION)
782 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
786 void LayerAnimationController::MarkAnimationsForDeletion(
787 base::TimeTicks monotonic_time,
788 AnimationEventsVector* events) {
789 bool marked_animations_for_deletions = false;
790 std::vector<size_t> animations_with_same_group_id;
792 animations_with_same_group_id.reserve(animations_.size());
793 // Non-aborted animations are marked for deletion after a corresponding
794 // AnimationEvent::FINISHED event is sent or received. This means that if
795 // we don't have an events vector, we must ensure that non-aborted animations
796 // have received a finished event before marking them for deletion.
797 for (size_t i = 0; i < animations_.size(); i++) {
798 int group_id = animations_[i]->group();
799 if (animations_[i]->run_state() == Animation::ABORTED) {
800 if (events && !animations_[i]->is_impl_only()) {
801 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id,
802 animations_[i]->target_property(),
803 monotonic_time);
804 events->push_back(aborted_event);
806 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
807 monotonic_time);
808 marked_animations_for_deletions = true;
809 continue;
812 bool all_anims_with_same_id_are_finished = false;
814 // Since deleting an animation on the main thread leads to its deletion
815 // on the impl thread, we only mark a FINISHED main thread animation for
816 // deletion once it has received a FINISHED event from the impl thread.
817 bool animation_i_will_send_or_has_received_finish_event =
818 animations_[i]->is_controlling_instance() ||
819 animations_[i]->is_impl_only() ||
820 animations_[i]->received_finished_event();
821 // If an animation is finished, and not already marked for deletion,
822 // find out if all other animations in the same group are also finished.
823 if (animations_[i]->run_state() == Animation::FINISHED &&
824 animation_i_will_send_or_has_received_finish_event) {
825 // Clear the animations_with_same_group_id if it was added for
826 // the previous animation's iteration.
827 if (animations_with_same_group_id.size() > 0)
828 animations_with_same_group_id.clear();
829 all_anims_with_same_id_are_finished = true;
830 for (size_t j = 0; j < animations_.size(); ++j) {
831 bool animation_j_will_send_or_has_received_finish_event =
832 animations_[j]->is_controlling_instance() ||
833 animations_[j]->is_impl_only() ||
834 animations_[j]->received_finished_event();
835 if (group_id == animations_[j]->group()) {
836 if (!animations_[j]->is_finished() ||
837 (animations_[j]->run_state() == Animation::FINISHED &&
838 !animation_j_will_send_or_has_received_finish_event)) {
839 all_anims_with_same_id_are_finished = false;
840 break;
841 } else if (j >= i &&
842 animations_[j]->run_state() != Animation::ABORTED) {
843 // Mark down the animations which belong to the same group
844 // and is not yet aborted. If this current iteration finds that all
845 // animations with same ID are finished, then the marked
846 // animations below will be set to WAITING_FOR_DELETION in next
847 // iteration.
848 animations_with_same_group_id.push_back(j);
853 if (all_anims_with_same_id_are_finished) {
854 // We now need to remove all animations with the same group id as
855 // group_id (and send along animation finished notifications, if
856 // necessary).
857 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
858 size_t animation_index = animations_with_same_group_id[j];
859 if (events) {
860 AnimationEvent finished_event(
861 AnimationEvent::FINISHED, id_,
862 animations_[animation_index]->group(),
863 animations_[animation_index]->target_property(),
864 monotonic_time);
865 finished_event.is_impl_only =
866 animations_[animation_index]->is_impl_only();
867 if (finished_event.is_impl_only)
868 NotifyAnimationFinished(finished_event);
869 else
870 events->push_back(finished_event);
872 animations_[animation_index]->SetRunState(
873 Animation::WAITING_FOR_DELETION, monotonic_time);
875 marked_animations_for_deletions = true;
878 if (marked_animations_for_deletions)
879 NotifyObserversAnimationWaitingForDeletion();
882 static bool IsWaitingForDeletion(Animation* animation) {
883 return animation->run_state() == Animation::WAITING_FOR_DELETION;
886 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
887 animations_.erase(cc::remove_if(&animations_,
888 animations_.begin(),
889 animations_.end(),
890 IsWaitingForDeletion),
891 animations_.end());
894 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
895 for (size_t i = 0; i < animations_.size(); ++i) {
896 if (animations_[i]->run_state() == Animation::STARTING ||
897 animations_[i]->run_state() == Animation::RUNNING ||
898 animations_[i]->run_state() == Animation::PAUSED) {
899 if (!animations_[i]->InEffect(monotonic_time))
900 continue;
902 base::TimeDelta trimmed =
903 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
905 switch (animations_[i]->target_property()) {
906 case Animation::TRANSFORM: {
907 const TransformAnimationCurve* transform_animation_curve =
908 animations_[i]->curve()->ToTransformAnimationCurve();
909 const gfx::Transform transform =
910 transform_animation_curve->GetValue(trimmed);
911 NotifyObserversTransformAnimated(
912 transform,
913 animations_[i]->affects_active_observers(),
914 animations_[i]->affects_pending_observers());
915 break;
918 case Animation::OPACITY: {
919 const FloatAnimationCurve* float_animation_curve =
920 animations_[i]->curve()->ToFloatAnimationCurve();
921 const float opacity = std::max(
922 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
923 NotifyObserversOpacityAnimated(
924 opacity,
925 animations_[i]->affects_active_observers(),
926 animations_[i]->affects_pending_observers());
927 break;
930 case Animation::FILTER: {
931 const FilterAnimationCurve* filter_animation_curve =
932 animations_[i]->curve()->ToFilterAnimationCurve();
933 const FilterOperations filter =
934 filter_animation_curve->GetValue(trimmed);
935 NotifyObserversFilterAnimated(
936 filter,
937 animations_[i]->affects_active_observers(),
938 animations_[i]->affects_pending_observers());
939 break;
942 case Animation::BACKGROUND_COLOR: {
943 // Not yet implemented.
944 break;
947 case Animation::SCROLL_OFFSET: {
948 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
949 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
950 const gfx::ScrollOffset scroll_offset =
951 scroll_offset_animation_curve->GetValue(trimmed);
952 NotifyObserversScrollOffsetAnimated(
953 scroll_offset,
954 animations_[i]->affects_active_observers(),
955 animations_[i]->affects_pending_observers());
956 break;
963 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
964 bool force = type == FORCE_ACTIVATION;
965 if (registrar_) {
966 bool was_active = is_active_;
967 is_active_ = false;
968 for (size_t i = 0; i < animations_.size(); ++i) {
969 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) {
970 is_active_ = true;
971 break;
975 if (is_active_ && (!was_active || force))
976 registrar_->DidActivateAnimationController(this);
977 else if (!is_active_ && (was_active || force))
978 registrar_->DidDeactivateAnimationController(this);
982 void LayerAnimationController::NotifyObserversOpacityAnimated(
983 float opacity,
984 bool notify_active_observers,
985 bool notify_pending_observers) {
986 if (value_observers_.might_have_observers()) {
987 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
988 &value_observers_);
989 LayerAnimationValueObserver* obs;
990 while ((obs = it.GetNext()) != nullptr) {
991 if ((notify_active_observers && notify_pending_observers) ||
992 (notify_active_observers && obs->IsActive()) ||
993 (notify_pending_observers && !obs->IsActive()))
994 obs->OnOpacityAnimated(opacity);
999 void LayerAnimationController::NotifyObserversTransformAnimated(
1000 const gfx::Transform& transform,
1001 bool notify_active_observers,
1002 bool notify_pending_observers) {
1003 if (value_observers_.might_have_observers()) {
1004 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1005 &value_observers_);
1006 LayerAnimationValueObserver* obs;
1007 while ((obs = it.GetNext()) != nullptr) {
1008 if ((notify_active_observers && notify_pending_observers) ||
1009 (notify_active_observers && obs->IsActive()) ||
1010 (notify_pending_observers && !obs->IsActive()))
1011 obs->OnTransformAnimated(transform);
1016 void LayerAnimationController::NotifyObserversFilterAnimated(
1017 const FilterOperations& filters,
1018 bool notify_active_observers,
1019 bool notify_pending_observers) {
1020 if (value_observers_.might_have_observers()) {
1021 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1022 &value_observers_);
1023 LayerAnimationValueObserver* obs;
1024 while ((obs = it.GetNext()) != nullptr) {
1025 if ((notify_active_observers && notify_pending_observers) ||
1026 (notify_active_observers && obs->IsActive()) ||
1027 (notify_pending_observers && !obs->IsActive()))
1028 obs->OnFilterAnimated(filters);
1033 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1034 const gfx::ScrollOffset& scroll_offset,
1035 bool notify_active_observers,
1036 bool notify_pending_observers) {
1037 if (value_observers_.might_have_observers()) {
1038 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1039 &value_observers_);
1040 LayerAnimationValueObserver* obs;
1041 while ((obs = it.GetNext()) != nullptr) {
1042 if ((notify_active_observers && notify_pending_observers) ||
1043 (notify_active_observers && obs->IsActive()) ||
1044 (notify_pending_observers && !obs->IsActive()))
1045 obs->OnScrollOffsetAnimated(scroll_offset);
1050 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1051 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1052 value_observers_,
1053 OnAnimationWaitingForDeletion());
1056 bool LayerAnimationController::HasValueObserver() {
1057 if (value_observers_.might_have_observers()) {
1058 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1059 &value_observers_);
1060 return it.GetNext() != nullptr;
1062 return false;
1065 bool LayerAnimationController::HasActiveValueObserver() {
1066 if (value_observers_.might_have_observers()) {
1067 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1068 &value_observers_);
1069 LayerAnimationValueObserver* obs;
1070 while ((obs = it.GetNext()) != nullptr)
1071 if (obs->IsActive())
1072 return true;
1074 return false;
1077 } // namespace cc