1. With introduction of compressed formats, e.g. ETC1, the number of
[chromium-blink-merge.git] / cc / animation / layer_animation_controller.cc
blob67c37bcbbc09300c1e2bd066e90e990221ee0a72
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() +
50 animations_[i]->time_offset());
55 struct HasAnimationId {
56 explicit HasAnimationId(int id) : id_(id) {}
57 bool operator()(Animation* animation) const {
58 return animation->id() == id_;
61 private:
62 int id_;
65 void LayerAnimationController::RemoveAnimation(int animation_id) {
66 auto animations_to_remove =
67 animations_.remove_if(HasAnimationId(animation_id));
68 for (auto it = animations_to_remove; it != animations_.end(); ++it) {
69 if ((*it)->target_property() == Animation::SCROLL_OFFSET) {
70 scroll_offset_animation_was_interrupted_ = true;
71 break;
74 animations_.erase(animations_to_remove, animations_.end());
75 UpdateActivation(NORMAL_ACTIVATION);
78 struct HasAnimationIdAndProperty {
79 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
80 : id_(id), target_property_(target_property) {}
81 bool operator()(Animation* animation) const {
82 return animation->id() == id_ &&
83 animation->target_property() == target_property_;
86 private:
87 int id_;
88 Animation::TargetProperty target_property_;
91 void LayerAnimationController::RemoveAnimation(
92 int animation_id,
93 Animation::TargetProperty target_property) {
94 auto animations_to_remove = animations_.remove_if(
95 HasAnimationIdAndProperty(animation_id, target_property));
96 if (target_property == Animation::SCROLL_OFFSET &&
97 animations_to_remove != animations_.end())
98 scroll_offset_animation_was_interrupted_ = true;
100 animations_.erase(animations_to_remove, animations_.end());
101 UpdateActivation(NORMAL_ACTIVATION);
104 void LayerAnimationController::AbortAnimations(
105 Animation::TargetProperty target_property) {
106 for (size_t i = 0; i < animations_.size(); ++i) {
107 if (animations_[i]->target_property() == target_property &&
108 !animations_[i]->is_finished())
109 animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_);
113 // Ensures that the list of active animations on the main thread and the impl
114 // thread are kept in sync.
115 void LayerAnimationController::PushAnimationUpdatesTo(
116 LayerAnimationController* controller_impl) {
117 DCHECK(this != controller_impl);
118 if (!has_any_animation() && !controller_impl->has_any_animation())
119 return;
120 PurgeAnimationsMarkedForDeletion();
121 PushNewAnimationsToImplThread(controller_impl);
123 // Remove finished impl side animations only after pushing,
124 // and only after the animations are deleted on the main thread
125 // this insures we will never push an animation twice.
126 RemoveAnimationsCompletedOnMainThread(controller_impl);
128 PushPropertiesToImplThread(controller_impl);
129 controller_impl->UpdateActivation(NORMAL_ACTIVATION);
130 UpdateActivation(NORMAL_ACTIVATION);
133 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
134 DCHECK(!monotonic_time.is_null());
135 if (!HasValueObserver())
136 return;
138 if (needs_to_start_animations_)
139 StartAnimations(monotonic_time);
140 TickAnimations(monotonic_time);
141 last_tick_time_ = monotonic_time;
144 void LayerAnimationController::AccumulatePropertyUpdates(
145 base::TimeTicks monotonic_time,
146 AnimationEventsVector* events) {
147 if (!events)
148 return;
150 for (size_t i = 0; i < animations_.size(); ++i) {
151 Animation* animation = animations_[i];
152 if (!animation->is_impl_only())
153 continue;
155 if (!animation->InEffect(monotonic_time))
156 continue;
158 base::TimeDelta trimmed =
159 animation->TrimTimeToCurrentIteration(monotonic_time);
160 switch (animation->target_property()) {
161 case Animation::OPACITY: {
162 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
163 animation->group(), 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::PROPERTY_UPDATE, id_,
175 animation->group(), Animation::TRANSFORM,
176 monotonic_time);
177 const TransformAnimationCurve* transform_animation_curve =
178 animation->curve()->ToTransformAnimationCurve();
179 event.transform = transform_animation_curve->GetValue(trimmed);
180 event.is_impl_only = true;
181 events->push_back(event);
182 break;
185 case Animation::FILTER: {
186 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_,
187 animation->group(), Animation::FILTER,
188 monotonic_time);
189 const FilterAnimationCurve* filter_animation_curve =
190 animation->curve()->ToFilterAnimationCurve();
191 event.filters = filter_animation_curve->GetValue(trimmed);
192 event.is_impl_only = true;
193 events->push_back(event);
194 break;
197 case Animation::BACKGROUND_COLOR: {
198 break;
201 case Animation::SCROLL_OFFSET: {
202 // Impl-side changes to scroll offset are already sent back to the
203 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE
204 // isn't needed.
205 break;
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(NORMAL_ACTIVATION);
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 scroll_offset_animation_was_interrupted_ = false;
255 UpdateActivation(NORMAL_ACTIVATION);
258 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
259 animations_.push_back(animation.Pass());
260 needs_to_start_animations_ = true;
261 UpdateActivation(NORMAL_ACTIVATION);
264 Animation* LayerAnimationController::GetAnimation(
265 Animation::TargetProperty target_property) const {
266 for (size_t i = 0; i < animations_.size(); ++i) {
267 size_t index = animations_.size() - i - 1;
268 if (animations_[index]->target_property() == target_property)
269 return animations_[index];
271 return 0;
274 Animation* LayerAnimationController::GetAnimationById(int animation_id) const {
275 for (size_t i = 0; i < animations_.size(); ++i)
276 if (animations_[i]->id() == animation_id)
277 return animations_[i];
278 return nullptr;
281 bool LayerAnimationController::HasActiveAnimation() const {
282 for (size_t i = 0; i < animations_.size(); ++i) {
283 if (!animations_[i]->is_finished())
284 return true;
286 return false;
289 bool LayerAnimationController::IsPotentiallyAnimatingProperty(
290 Animation::TargetProperty target_property,
291 ObserverType observer_type) const {
292 for (size_t i = 0; i < animations_.size(); ++i) {
293 if (!animations_[i]->is_finished() &&
294 animations_[i]->target_property() == target_property) {
295 if ((observer_type == ObserverType::ACTIVE &&
296 animations_[i]->affects_active_observers()) ||
297 (observer_type == ObserverType::PENDING &&
298 animations_[i]->affects_pending_observers()))
299 return true;
302 return false;
305 bool LayerAnimationController::IsCurrentlyAnimatingProperty(
306 Animation::TargetProperty target_property,
307 ObserverType observer_type) const {
308 for (size_t i = 0; i < animations_.size(); ++i) {
309 if (!animations_[i]->is_finished() &&
310 animations_[i]->InEffect(last_tick_time_) &&
311 animations_[i]->target_property() == target_property) {
312 if ((observer_type == ObserverType::ACTIVE &&
313 animations_[i]->affects_active_observers()) ||
314 (observer_type == ObserverType::PENDING &&
315 animations_[i]->affects_pending_observers()))
316 return true;
319 return false;
322 void LayerAnimationController::SetAnimationRegistrar(
323 AnimationRegistrar* registrar) {
324 if (registrar_ == registrar)
325 return;
327 if (registrar_)
328 registrar_->UnregisterAnimationController(this);
330 registrar_ = registrar;
331 if (registrar_)
332 registrar_->RegisterAnimationController(this);
334 UpdateActivation(FORCE_ACTIVATION);
337 void LayerAnimationController::NotifyAnimationStarted(
338 const AnimationEvent& event) {
339 if (event.is_impl_only) {
340 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
341 OnAnimationStarted(event));
342 if (layer_animation_delegate_)
343 layer_animation_delegate_->NotifyAnimationStarted(
344 event.monotonic_time, event.target_property, event.group_id);
345 return;
348 for (size_t i = 0; i < animations_.size(); ++i) {
349 if (animations_[i]->group() == event.group_id &&
350 animations_[i]->target_property() == event.target_property &&
351 animations_[i]->needs_synchronized_start_time()) {
352 animations_[i]->set_needs_synchronized_start_time(false);
353 if (!animations_[i]->has_set_start_time())
354 animations_[i]->set_start_time(event.monotonic_time);
356 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
357 OnAnimationStarted(event));
358 if (layer_animation_delegate_)
359 layer_animation_delegate_->NotifyAnimationStarted(
360 event.monotonic_time, event.target_property, event.group_id);
362 return;
367 void LayerAnimationController::NotifyAnimationFinished(
368 const AnimationEvent& event) {
369 if (event.is_impl_only) {
370 if (layer_animation_delegate_)
371 layer_animation_delegate_->NotifyAnimationFinished(
372 event.monotonic_time, event.target_property, event.group_id);
373 return;
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]->set_received_finished_event(true);
380 if (layer_animation_delegate_)
381 layer_animation_delegate_->NotifyAnimationFinished(
382 event.monotonic_time, event.target_property, event.group_id);
384 return;
389 void LayerAnimationController::NotifyAnimationAborted(
390 const AnimationEvent& event) {
391 for (size_t i = 0; i < animations_.size(); ++i) {
392 if (animations_[i]->group() == event.group_id &&
393 animations_[i]->target_property() == event.target_property) {
394 animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time);
399 void LayerAnimationController::NotifyAnimationPropertyUpdate(
400 const AnimationEvent& event) {
401 bool notify_active_observers = true;
402 bool notify_pending_observers = true;
403 switch (event.target_property) {
404 case Animation::OPACITY:
405 NotifyObserversOpacityAnimated(
406 event.opacity, notify_active_observers, notify_pending_observers);
407 break;
408 case Animation::TRANSFORM:
409 NotifyObserversTransformAnimated(
410 event.transform, notify_active_observers, notify_pending_observers);
411 break;
412 default:
413 NOTREACHED();
417 void LayerAnimationController::AddValueObserver(
418 LayerAnimationValueObserver* observer) {
419 if (!value_observers_.HasObserver(observer))
420 value_observers_.AddObserver(observer);
423 void LayerAnimationController::RemoveValueObserver(
424 LayerAnimationValueObserver* observer) {
425 value_observers_.RemoveObserver(observer);
428 void LayerAnimationController::AddEventObserver(
429 LayerAnimationEventObserver* observer) {
430 if (!event_observers_.HasObserver(observer))
431 event_observers_.AddObserver(observer);
434 void LayerAnimationController::RemoveEventObserver(
435 LayerAnimationEventObserver* observer) {
436 event_observers_.RemoveObserver(observer);
439 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
440 for (size_t i = 0; i < animations_.size(); ++i) {
441 if (!animations_[i]->is_finished() &&
442 animations_[i]->target_property() == Animation::FILTER &&
443 animations_[i]
444 ->curve()
445 ->ToFilterAnimationCurve()
446 ->HasFilterThatMovesPixels())
447 return true;
450 return false;
453 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
454 return IsCurrentlyAnimatingProperty(Animation::TRANSFORM,
455 ObserverType::ACTIVE) ||
456 IsCurrentlyAnimatingProperty(Animation::TRANSFORM,
457 ObserverType::PENDING);
460 bool LayerAnimationController::FilterAnimationBoundsForBox(
461 const gfx::BoxF& box, gfx::BoxF* bounds) const {
462 // TODO(avallee): Implement.
463 return false;
466 bool LayerAnimationController::TransformAnimationBoundsForBox(
467 const gfx::BoxF& box,
468 gfx::BoxF* bounds) const {
469 DCHECK(HasTransformAnimationThatInflatesBounds())
470 << "TransformAnimationBoundsForBox will give incorrect results if there "
471 << "are no transform animations affecting bounds, non-animated transform "
472 << "is not known";
474 // Compute bounds based on animations for which is_finished() is false.
475 // Do nothing if there are no such animations; in this case, it is assumed
476 // that callers will take care of computing bounds based on the owning layer's
477 // actual transform.
478 *bounds = gfx::BoxF();
479 for (size_t i = 0; i < animations_.size(); ++i) {
480 if (animations_[i]->is_finished() ||
481 animations_[i]->target_property() != Animation::TRANSFORM)
482 continue;
484 const TransformAnimationCurve* transform_animation_curve =
485 animations_[i]->curve()->ToTransformAnimationCurve();
486 gfx::BoxF animation_bounds;
487 bool success =
488 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
489 if (!success)
490 return false;
491 bounds->Union(animation_bounds);
494 return true;
497 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
498 for (size_t i = 0; i < animations_.size(); ++i) {
499 if (animations_[i]->is_finished() ||
500 animations_[i]->target_property() != Animation::TRANSFORM)
501 continue;
503 const TransformAnimationCurve* transform_animation_curve =
504 animations_[i]->curve()->ToTransformAnimationCurve();
505 if (transform_animation_curve->AffectsScale())
506 return true;
509 return false;
512 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
513 for (size_t i = 0; i < animations_.size(); ++i) {
514 if (animations_[i]->is_finished() ||
515 animations_[i]->target_property() != Animation::TRANSFORM)
516 continue;
518 const TransformAnimationCurve* transform_animation_curve =
519 animations_[i]->curve()->ToTransformAnimationCurve();
520 if (!transform_animation_curve->IsTranslation())
521 return false;
524 return true;
527 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const {
528 for (size_t i = 0; i < animations_.size(); ++i) {
529 if (animations_[i]->is_finished() ||
530 animations_[i]->target_property() != Animation::TRANSFORM)
531 continue;
533 const TransformAnimationCurve* transform_animation_curve =
534 animations_[i]->curve()->ToTransformAnimationCurve();
535 if (!transform_animation_curve->PreservesAxisAlignment())
536 return false;
539 return true;
542 bool LayerAnimationController::AnimationStartScale(float* start_scale) const {
543 *start_scale = 0.f;
544 for (size_t i = 0; i < animations_.size(); ++i) {
545 if (animations_[i]->is_finished() ||
546 animations_[i]->target_property() != Animation::TRANSFORM)
547 continue;
549 bool forward_direction = true;
550 switch (animations_[i]->direction()) {
551 case Animation::DIRECTION_NORMAL:
552 case Animation::DIRECTION_ALTERNATE:
553 forward_direction = animations_[i]->playback_rate() >= 0.0;
554 break;
555 case Animation::DIRECTION_REVERSE:
556 case Animation::DIRECTION_ALTERNATE_REVERSE:
557 forward_direction = animations_[i]->playback_rate() < 0.0;
558 break;
561 const TransformAnimationCurve* transform_animation_curve =
562 animations_[i]->curve()->ToTransformAnimationCurve();
563 float animation_start_scale = 0.f;
564 if (!transform_animation_curve->AnimationStartScale(forward_direction,
565 &animation_start_scale))
566 return false;
567 *start_scale = std::max(*start_scale, animation_start_scale);
569 return true;
572 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
573 *max_scale = 0.f;
574 for (size_t i = 0; i < animations_.size(); ++i) {
575 if (animations_[i]->is_finished() ||
576 animations_[i]->target_property() != Animation::TRANSFORM)
577 continue;
579 bool forward_direction = true;
580 switch (animations_[i]->direction()) {
581 case Animation::DIRECTION_NORMAL:
582 case Animation::DIRECTION_ALTERNATE:
583 forward_direction = animations_[i]->playback_rate() >= 0.0;
584 break;
585 case Animation::DIRECTION_REVERSE:
586 case Animation::DIRECTION_ALTERNATE_REVERSE:
587 forward_direction = animations_[i]->playback_rate() < 0.0;
588 break;
591 const TransformAnimationCurve* transform_animation_curve =
592 animations_[i]->curve()->ToTransformAnimationCurve();
593 float animation_scale = 0.f;
594 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
595 &animation_scale))
596 return false;
597 *max_scale = std::max(*max_scale, animation_scale);
600 return true;
603 void LayerAnimationController::PushNewAnimationsToImplThread(
604 LayerAnimationController* controller_impl) const {
605 // Any new animations owned by the main thread's controller are cloned and
606 // add to the impl thread's controller.
607 for (size_t i = 0; i < animations_.size(); ++i) {
608 // If the animation is already running on the impl thread, there is no
609 // need to copy it over.
610 if (controller_impl->GetAnimationById(animations_[i]->id()))
611 continue;
613 // Scroll animations always start at the current scroll offset.
614 if (animations_[i]->target_property() == Animation::SCROLL_OFFSET) {
615 gfx::ScrollOffset current_scroll_offset;
616 if (controller_impl->value_provider_) {
617 current_scroll_offset =
618 controller_impl->value_provider_->ScrollOffsetForAnimation();
619 } else {
620 // The owning layer isn't yet in the active tree, so the main thread
621 // scroll offset will be up-to-date.
622 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
624 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
625 current_scroll_offset);
628 // The new animation should be set to run as soon as possible.
629 Animation::RunState initial_run_state =
630 Animation::WAITING_FOR_TARGET_AVAILABILITY;
631 scoped_ptr<Animation> to_add(
632 animations_[i]->CloneAndInitialize(initial_run_state));
633 DCHECK(!to_add->needs_synchronized_start_time());
634 to_add->set_affects_active_observers(false);
635 controller_impl->AddAnimation(to_add.Pass());
639 static bool IsCompleted(
640 Animation* animation,
641 const LayerAnimationController* main_thread_controller) {
642 if (animation->is_impl_only()) {
643 return (animation->run_state() == Animation::WAITING_FOR_DELETION);
644 } else {
645 return !main_thread_controller->GetAnimationById(animation->id());
649 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
650 return animation->run_state() == Animation::WAITING_FOR_DELETION &&
651 !animation->affects_pending_observers();
654 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
655 LayerAnimationController* controller_impl) const {
656 // Animations removed on the main thread should no longer affect pending
657 // observers, and should stop affecting active observers after the next call
658 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
659 // immediately.
660 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
661 for (size_t i = 0; i < animations.size(); ++i) {
662 if (IsCompleted(animations[i], this))
663 animations[i]->set_affects_pending_observers(false);
665 animations.erase(cc::remove_if(&animations,
666 animations.begin(),
667 animations.end(),
668 AffectsActiveOnlyAndIsWaitingForDeletion),
669 animations.end());
672 void LayerAnimationController::PushPropertiesToImplThread(
673 LayerAnimationController* controller_impl) {
674 for (size_t i = 0; i < animations_.size(); ++i) {
675 Animation* current_impl =
676 controller_impl->GetAnimationById(animations_[i]->id());
677 if (current_impl)
678 animations_[i]->PushPropertiesTo(current_impl);
680 controller_impl->scroll_offset_animation_was_interrupted_ =
681 scroll_offset_animation_was_interrupted_;
682 scroll_offset_animation_was_interrupted_ = false;
685 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
686 DCHECK(needs_to_start_animations_);
687 needs_to_start_animations_ = false;
688 // First collect running properties affecting each type of observer.
689 TargetProperties blocked_properties_for_active_observers;
690 TargetProperties blocked_properties_for_pending_observers;
691 std::vector<size_t> animations_waiting_for_target;
693 animations_waiting_for_target.reserve(animations_.size());
694 for (size_t i = 0; i < animations_.size(); ++i) {
695 if (animations_[i]->run_state() == Animation::STARTING ||
696 animations_[i]->run_state() == Animation::RUNNING) {
697 if (animations_[i]->affects_active_observers()) {
698 blocked_properties_for_active_observers.insert(
699 animations_[i]->target_property());
701 if (animations_[i]->affects_pending_observers()) {
702 blocked_properties_for_pending_observers.insert(
703 animations_[i]->target_property());
705 } else if (animations_[i]->run_state() ==
706 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
707 animations_waiting_for_target.push_back(i);
711 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
712 // Collect all properties for animations with the same group id (they
713 // should all also be in the list of animations).
714 size_t animation_index = animations_waiting_for_target[i];
715 Animation* animation_waiting_for_target = animations_[animation_index];
716 // Check for the run state again even though the animation was waiting
717 // for target because it might have changed the run state while handling
718 // previous animation in this loop (if they belong to same group).
719 if (animation_waiting_for_target->run_state() ==
720 Animation::WAITING_FOR_TARGET_AVAILABILITY) {
721 TargetProperties enqueued_properties;
722 bool affects_active_observers =
723 animation_waiting_for_target->affects_active_observers();
724 bool affects_pending_observers =
725 animation_waiting_for_target->affects_pending_observers();
726 enqueued_properties.insert(
727 animation_waiting_for_target->target_property());
728 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
729 if (animation_waiting_for_target->group() == animations_[j]->group()) {
730 enqueued_properties.insert(animations_[j]->target_property());
731 affects_active_observers |=
732 animations_[j]->affects_active_observers();
733 affects_pending_observers |=
734 animations_[j]->affects_pending_observers();
738 // Check to see if intersection of the list of properties affected by
739 // the group and the list of currently blocked properties is null, taking
740 // into account the type(s) of observers affected by the group. In any
741 // case, the group's target properties need to be added to the lists of
742 // blocked properties.
743 bool null_intersection = true;
744 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
745 p_iter != enqueued_properties.end();
746 ++p_iter) {
747 if (affects_active_observers &&
748 !blocked_properties_for_active_observers.insert(*p_iter).second)
749 null_intersection = false;
750 if (affects_pending_observers &&
751 !blocked_properties_for_pending_observers.insert(*p_iter).second)
752 null_intersection = false;
755 // If the intersection is null, then we are free to start the animations
756 // in the group.
757 if (null_intersection) {
758 animation_waiting_for_target->SetRunState(Animation::STARTING,
759 monotonic_time);
760 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
761 if (animation_waiting_for_target->group() ==
762 animations_[j]->group()) {
763 animations_[j]->SetRunState(Animation::STARTING, monotonic_time);
766 } else {
767 needs_to_start_animations_ = true;
773 void LayerAnimationController::PromoteStartedAnimations(
774 base::TimeTicks monotonic_time,
775 AnimationEventsVector* events) {
776 for (size_t i = 0; i < animations_.size(); ++i) {
777 if (animations_[i]->run_state() == Animation::STARTING &&
778 animations_[i]->affects_active_observers()) {
779 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time);
780 if (!animations_[i]->has_set_start_time() &&
781 !animations_[i]->needs_synchronized_start_time())
782 animations_[i]->set_start_time(monotonic_time);
783 if (events) {
784 base::TimeTicks start_time;
785 if (animations_[i]->has_set_start_time())
786 start_time = animations_[i]->start_time();
787 else
788 start_time = monotonic_time;
789 AnimationEvent started_event(
790 AnimationEvent::STARTED, id_, animations_[i]->group(),
791 animations_[i]->target_property(), start_time);
792 started_event.is_impl_only = animations_[i]->is_impl_only();
793 if (started_event.is_impl_only)
794 NotifyAnimationStarted(started_event);
795 else
796 events->push_back(started_event);
802 void LayerAnimationController::MarkFinishedAnimations(
803 base::TimeTicks monotonic_time) {
804 for (size_t i = 0; i < animations_.size(); ++i) {
805 if (animations_[i]->IsFinishedAt(monotonic_time) &&
806 animations_[i]->run_state() != Animation::ABORTED &&
807 animations_[i]->run_state() != Animation::WAITING_FOR_DELETION)
808 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time);
812 void LayerAnimationController::MarkAnimationsForDeletion(
813 base::TimeTicks monotonic_time,
814 AnimationEventsVector* events) {
815 bool marked_animations_for_deletions = false;
816 std::vector<size_t> animations_with_same_group_id;
818 animations_with_same_group_id.reserve(animations_.size());
819 // Non-aborted animations are marked for deletion after a corresponding
820 // AnimationEvent::FINISHED event is sent or received. This means that if
821 // we don't have an events vector, we must ensure that non-aborted animations
822 // have received a finished event before marking them for deletion.
823 for (size_t i = 0; i < animations_.size(); i++) {
824 int group_id = animations_[i]->group();
825 if (animations_[i]->run_state() == Animation::ABORTED) {
826 if (events && !animations_[i]->is_impl_only()) {
827 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id,
828 animations_[i]->target_property(),
829 monotonic_time);
830 events->push_back(aborted_event);
832 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION,
833 monotonic_time);
834 marked_animations_for_deletions = true;
835 continue;
838 bool all_anims_with_same_id_are_finished = false;
840 // Since deleting an animation on the main thread leads to its deletion
841 // on the impl thread, we only mark a FINISHED main thread animation for
842 // deletion once it has received a FINISHED event from the impl thread.
843 bool animation_i_will_send_or_has_received_finish_event =
844 animations_[i]->is_controlling_instance() ||
845 animations_[i]->is_impl_only() ||
846 animations_[i]->received_finished_event();
847 // If an animation is finished, and not already marked for deletion,
848 // find out if all other animations in the same group are also finished.
849 if (animations_[i]->run_state() == Animation::FINISHED &&
850 animation_i_will_send_or_has_received_finish_event) {
851 // Clear the animations_with_same_group_id if it was added for
852 // the previous animation's iteration.
853 if (animations_with_same_group_id.size() > 0)
854 animations_with_same_group_id.clear();
855 all_anims_with_same_id_are_finished = true;
856 for (size_t j = 0; j < animations_.size(); ++j) {
857 bool animation_j_will_send_or_has_received_finish_event =
858 animations_[j]->is_controlling_instance() ||
859 animations_[j]->is_impl_only() ||
860 animations_[j]->received_finished_event();
861 if (group_id == animations_[j]->group()) {
862 if (!animations_[j]->is_finished() ||
863 (animations_[j]->run_state() == Animation::FINISHED &&
864 !animation_j_will_send_or_has_received_finish_event)) {
865 all_anims_with_same_id_are_finished = false;
866 break;
867 } else if (j >= i &&
868 animations_[j]->run_state() != Animation::ABORTED) {
869 // Mark down the animations which belong to the same group
870 // and is not yet aborted. If this current iteration finds that all
871 // animations with same ID are finished, then the marked
872 // animations below will be set to WAITING_FOR_DELETION in next
873 // iteration.
874 animations_with_same_group_id.push_back(j);
879 if (all_anims_with_same_id_are_finished) {
880 // We now need to remove all animations with the same group id as
881 // group_id (and send along animation finished notifications, if
882 // necessary).
883 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
884 size_t animation_index = animations_with_same_group_id[j];
885 if (events) {
886 AnimationEvent finished_event(
887 AnimationEvent::FINISHED, id_,
888 animations_[animation_index]->group(),
889 animations_[animation_index]->target_property(),
890 monotonic_time);
891 finished_event.is_impl_only =
892 animations_[animation_index]->is_impl_only();
893 if (finished_event.is_impl_only)
894 NotifyAnimationFinished(finished_event);
895 else
896 events->push_back(finished_event);
898 animations_[animation_index]->SetRunState(
899 Animation::WAITING_FOR_DELETION, monotonic_time);
901 marked_animations_for_deletions = true;
904 if (marked_animations_for_deletions)
905 NotifyObserversAnimationWaitingForDeletion();
908 static bool IsWaitingForDeletion(Animation* animation) {
909 return animation->run_state() == Animation::WAITING_FOR_DELETION;
912 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
913 animations_.erase(cc::remove_if(&animations_,
914 animations_.begin(),
915 animations_.end(),
916 IsWaitingForDeletion),
917 animations_.end());
920 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
921 for (size_t i = 0; i < animations_.size(); ++i) {
922 if (animations_[i]->run_state() == Animation::STARTING ||
923 animations_[i]->run_state() == Animation::RUNNING ||
924 animations_[i]->run_state() == Animation::PAUSED) {
925 if (!animations_[i]->InEffect(monotonic_time))
926 continue;
928 base::TimeDelta trimmed =
929 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
931 switch (animations_[i]->target_property()) {
932 case Animation::TRANSFORM: {
933 const TransformAnimationCurve* transform_animation_curve =
934 animations_[i]->curve()->ToTransformAnimationCurve();
935 const gfx::Transform transform =
936 transform_animation_curve->GetValue(trimmed);
937 NotifyObserversTransformAnimated(
938 transform,
939 animations_[i]->affects_active_observers(),
940 animations_[i]->affects_pending_observers());
941 break;
944 case Animation::OPACITY: {
945 const FloatAnimationCurve* float_animation_curve =
946 animations_[i]->curve()->ToFloatAnimationCurve();
947 const float opacity = std::max(
948 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
949 NotifyObserversOpacityAnimated(
950 opacity,
951 animations_[i]->affects_active_observers(),
952 animations_[i]->affects_pending_observers());
953 break;
956 case Animation::FILTER: {
957 const FilterAnimationCurve* filter_animation_curve =
958 animations_[i]->curve()->ToFilterAnimationCurve();
959 const FilterOperations filter =
960 filter_animation_curve->GetValue(trimmed);
961 NotifyObserversFilterAnimated(
962 filter,
963 animations_[i]->affects_active_observers(),
964 animations_[i]->affects_pending_observers());
965 break;
968 case Animation::BACKGROUND_COLOR: {
969 // Not yet implemented.
970 break;
973 case Animation::SCROLL_OFFSET: {
974 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
975 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
976 const gfx::ScrollOffset scroll_offset =
977 scroll_offset_animation_curve->GetValue(trimmed);
978 NotifyObserversScrollOffsetAnimated(
979 scroll_offset,
980 animations_[i]->affects_active_observers(),
981 animations_[i]->affects_pending_observers());
982 break;
989 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
990 bool force = type == FORCE_ACTIVATION;
991 if (registrar_) {
992 bool was_active = is_active_;
993 is_active_ = false;
994 for (size_t i = 0; i < animations_.size(); ++i) {
995 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) {
996 is_active_ = true;
997 break;
1001 if (is_active_ && (!was_active || force))
1002 registrar_->DidActivateAnimationController(this);
1003 else if (!is_active_ && (was_active || force))
1004 registrar_->DidDeactivateAnimationController(this);
1008 void LayerAnimationController::NotifyObserversOpacityAnimated(
1009 float opacity,
1010 bool notify_active_observers,
1011 bool notify_pending_observers) {
1012 if (value_observers_.might_have_observers()) {
1013 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1014 &value_observers_);
1015 LayerAnimationValueObserver* obs;
1016 while ((obs = it.GetNext()) != nullptr) {
1017 if ((notify_active_observers && notify_pending_observers) ||
1018 (notify_active_observers && obs->IsActive()) ||
1019 (notify_pending_observers && !obs->IsActive()))
1020 obs->OnOpacityAnimated(opacity);
1025 void LayerAnimationController::NotifyObserversTransformAnimated(
1026 const gfx::Transform& transform,
1027 bool notify_active_observers,
1028 bool notify_pending_observers) {
1029 if (value_observers_.might_have_observers()) {
1030 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1031 &value_observers_);
1032 LayerAnimationValueObserver* obs;
1033 while ((obs = it.GetNext()) != nullptr) {
1034 if ((notify_active_observers && notify_pending_observers) ||
1035 (notify_active_observers && obs->IsActive()) ||
1036 (notify_pending_observers && !obs->IsActive()))
1037 obs->OnTransformAnimated(transform);
1042 void LayerAnimationController::NotifyObserversFilterAnimated(
1043 const FilterOperations& filters,
1044 bool notify_active_observers,
1045 bool notify_pending_observers) {
1046 if (value_observers_.might_have_observers()) {
1047 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1048 &value_observers_);
1049 LayerAnimationValueObserver* obs;
1050 while ((obs = it.GetNext()) != nullptr) {
1051 if ((notify_active_observers && notify_pending_observers) ||
1052 (notify_active_observers && obs->IsActive()) ||
1053 (notify_pending_observers && !obs->IsActive()))
1054 obs->OnFilterAnimated(filters);
1059 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
1060 const gfx::ScrollOffset& scroll_offset,
1061 bool notify_active_observers,
1062 bool notify_pending_observers) {
1063 if (value_observers_.might_have_observers()) {
1064 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1065 &value_observers_);
1066 LayerAnimationValueObserver* obs;
1067 while ((obs = it.GetNext()) != nullptr) {
1068 if ((notify_active_observers && notify_pending_observers) ||
1069 (notify_active_observers && obs->IsActive()) ||
1070 (notify_pending_observers && !obs->IsActive()))
1071 obs->OnScrollOffsetAnimated(scroll_offset);
1076 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1077 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1078 value_observers_,
1079 OnAnimationWaitingForDeletion());
1082 bool LayerAnimationController::HasValueObserver() {
1083 if (value_observers_.might_have_observers()) {
1084 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1085 &value_observers_);
1086 return it.GetNext() != nullptr;
1088 return false;
1091 bool LayerAnimationController::HasActiveValueObserver() {
1092 if (value_observers_.might_have_observers()) {
1093 base::ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1094 &value_observers_);
1095 LayerAnimationValueObserver* obs;
1096 while ((obs = it.GetNext()) != nullptr)
1097 if (obs->IsActive())
1098 return true;
1100 return false;
1103 } // namespace cc