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"
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"
24 LayerAnimationController::LayerAnimationController(int id
)
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() {
36 registrar_
->UnregisterAnimationController(this);
39 scoped_refptr
<LayerAnimationController
> LayerAnimationController::Create(
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_
;
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;
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_
;
87 Animation::TargetProperty target_property_
;
90 void LayerAnimationController::RemoveAnimation(
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())
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())
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
) {
149 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
150 Animation
* animation
= animations_
[i
];
151 if (!animation
->is_impl_only())
154 if (!animation
->InEffect(monotonic_time
))
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
,
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
);
172 case Animation::TRANSFORM
: {
173 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
174 animation
->group(), Animation::TRANSFORM
,
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
);
184 case Animation::FILTER
: {
185 AnimationEvent
event(AnimationEvent::PROPERTY_UPDATE
, id_
,
186 animation
->group(), Animation::FILTER
,
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
);
196 case Animation::BACKGROUND_COLOR
: {
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
210 void LayerAnimationController::UpdateState(bool start_ready_animations
,
211 AnimationEventsVector
* events
) {
212 if (!HasActiveValueObserver())
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())
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_
,
251 AffectsNoObservers()),
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
];
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
];
280 bool LayerAnimationController::HasActiveAnimation() const {
281 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
282 if (!animations_
[i
]->is_finished())
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
)
299 void LayerAnimationController::SetAnimationRegistrar(
300 AnimationRegistrar
* registrar
) {
301 if (registrar_
== registrar
)
305 registrar_
->UnregisterAnimationController(this);
307 registrar_
= 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
);
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
);
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
);
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
);
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
);
385 case Animation::TRANSFORM
:
386 NotifyObserversTransformAnimated(
387 event
.transform
, notify_active_observers
, notify_pending_observers
);
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
&&
422 ->ToFilterAnimationCurve()
423 ->HasFilterThatMovesPixels())
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.
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 "
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
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
)
458 const TransformAnimationCurve
* transform_animation_curve
=
459 animations_
[i
]->curve()->ToTransformAnimationCurve();
460 gfx::BoxF animation_bounds
;
462 transform_animation_curve
->AnimatedBoundsForBox(box
, &animation_bounds
);
465 bounds
->Union(animation_bounds
);
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
)
477 const TransformAnimationCurve
* transform_animation_curve
=
478 animations_
[i
]->curve()->ToTransformAnimationCurve();
479 if (transform_animation_curve
->AffectsScale())
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
)
492 const TransformAnimationCurve
* transform_animation_curve
=
493 animations_
[i
]->curve()->ToTransformAnimationCurve();
494 if (!transform_animation_curve
->IsTranslation())
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
)
507 const TransformAnimationCurve
* transform_animation_curve
=
508 animations_
[i
]->curve()->ToTransformAnimationCurve();
509 if (!transform_animation_curve
->PreservesAxisAlignment())
516 bool LayerAnimationController::AnimationStartScale(float* start_scale
) const {
518 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
519 if (animations_
[i
]->is_finished() ||
520 animations_
[i
]->target_property() != Animation::TRANSFORM
)
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;
529 case Animation::DIRECTION_REVERSE
:
530 case Animation::DIRECTION_ALTERNATE_REVERSE
:
531 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
))
541 *start_scale
= std::max(*start_scale
, animation_start_scale
);
546 bool LayerAnimationController::MaximumTargetScale(float* max_scale
) const {
548 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
549 if (animations_
[i
]->is_finished() ||
550 animations_
[i
]->target_property() != Animation::TRANSFORM
)
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;
559 case Animation::DIRECTION_REVERSE
:
560 case Animation::DIRECTION_ALTERNATE_REVERSE
:
561 forward_direction
= animations_
[i
]->playback_rate() < 0.0;
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
,
571 *max_scale
= std::max(*max_scale
, animation_scale
);
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()))
587 // If the animation is not running on the impl thread, it does not
588 // necessarily mean that it needs to be copied over and started; it may
589 // have already finished. In this case, the impl thread animation will
590 // have already notified that it has started and the main thread animation
591 // will no longer need
592 // a synchronized start time.
593 if (!animations_
[i
]->needs_synchronized_start_time())
596 // Scroll animations always start at the current scroll offset.
597 if (animations_
[i
]->target_property() == Animation::SCROLL_OFFSET
) {
598 gfx::ScrollOffset current_scroll_offset
;
599 if (controller_impl
->value_provider_
) {
600 current_scroll_offset
=
601 controller_impl
->value_provider_
->ScrollOffsetForAnimation();
603 // The owning layer isn't yet in the active tree, so the main thread
604 // scroll offset will be up-to-date.
605 current_scroll_offset
= value_provider_
->ScrollOffsetForAnimation();
607 animations_
[i
]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
608 current_scroll_offset
);
611 // The new animation should be set to run as soon as possible.
612 Animation::RunState initial_run_state
=
613 Animation::WAITING_FOR_TARGET_AVAILABILITY
;
614 scoped_ptr
<Animation
> to_add(
615 animations_
[i
]->CloneAndInitialize(initial_run_state
));
616 DCHECK(!to_add
->needs_synchronized_start_time());
617 to_add
->set_affects_active_observers(false);
618 controller_impl
->AddAnimation(to_add
.Pass());
622 static bool IsCompleted(
623 Animation
* animation
,
624 const LayerAnimationController
* main_thread_controller
) {
625 if (animation
->is_impl_only()) {
626 return (animation
->run_state() == Animation::WAITING_FOR_DELETION
);
628 return !main_thread_controller
->GetAnimationById(animation
->id());
632 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation
* animation
) {
633 return animation
->run_state() == Animation::WAITING_FOR_DELETION
&&
634 !animation
->affects_pending_observers();
637 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
638 LayerAnimationController
* controller_impl
) const {
639 // Animations removed on the main thread should no longer affect pending
640 // observers, and should stop affecting active observers after the next call
641 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed
643 ScopedPtrVector
<Animation
>& animations
= controller_impl
->animations_
;
644 for (size_t i
= 0; i
< animations
.size(); ++i
) {
645 if (IsCompleted(animations
[i
], this))
646 animations
[i
]->set_affects_pending_observers(false);
648 animations
.erase(cc::remove_if(&animations
,
651 AffectsActiveOnlyAndIsWaitingForDeletion
),
655 void LayerAnimationController::PushPropertiesToImplThread(
656 LayerAnimationController
* controller_impl
) {
657 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
658 Animation
* current_impl
=
659 controller_impl
->GetAnimationById(animations_
[i
]->id());
661 animations_
[i
]->PushPropertiesTo(current_impl
);
663 controller_impl
->scroll_offset_animation_was_interrupted_
=
664 scroll_offset_animation_was_interrupted_
;
665 scroll_offset_animation_was_interrupted_
= false;
668 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time
) {
669 DCHECK(needs_to_start_animations_
);
670 needs_to_start_animations_
= false;
671 // First collect running properties affecting each type of observer.
672 TargetProperties blocked_properties_for_active_observers
;
673 TargetProperties blocked_properties_for_pending_observers
;
674 std::vector
<size_t> animations_waiting_for_target
;
676 animations_waiting_for_target
.reserve(animations_
.size());
677 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
678 if (animations_
[i
]->run_state() == Animation::STARTING
||
679 animations_
[i
]->run_state() == Animation::RUNNING
) {
680 if (animations_
[i
]->affects_active_observers()) {
681 blocked_properties_for_active_observers
.insert(
682 animations_
[i
]->target_property());
684 if (animations_
[i
]->affects_pending_observers()) {
685 blocked_properties_for_pending_observers
.insert(
686 animations_
[i
]->target_property());
688 } else if (animations_
[i
]->run_state() ==
689 Animation::WAITING_FOR_TARGET_AVAILABILITY
) {
690 animations_waiting_for_target
.push_back(i
);
694 for (size_t i
= 0; i
< animations_waiting_for_target
.size(); ++i
) {
695 // Collect all properties for animations with the same group id (they
696 // should all also be in the list of animations).
697 size_t animation_index
= animations_waiting_for_target
[i
];
698 Animation
* animation_waiting_for_target
= animations_
[animation_index
];
699 // Check for the run state again even though the animation was waiting
700 // for target because it might have changed the run state while handling
701 // previous animation in this loop (if they belong to same group).
702 if (animation_waiting_for_target
->run_state() ==
703 Animation::WAITING_FOR_TARGET_AVAILABILITY
) {
704 TargetProperties enqueued_properties
;
705 bool affects_active_observers
=
706 animation_waiting_for_target
->affects_active_observers();
707 bool affects_pending_observers
=
708 animation_waiting_for_target
->affects_pending_observers();
709 enqueued_properties
.insert(
710 animation_waiting_for_target
->target_property());
711 for (size_t j
= animation_index
+ 1; j
< animations_
.size(); ++j
) {
712 if (animation_waiting_for_target
->group() == animations_
[j
]->group()) {
713 enqueued_properties
.insert(animations_
[j
]->target_property());
714 affects_active_observers
|=
715 animations_
[j
]->affects_active_observers();
716 affects_pending_observers
|=
717 animations_
[j
]->affects_pending_observers();
721 // Check to see if intersection of the list of properties affected by
722 // the group and the list of currently blocked properties is null, taking
723 // into account the type(s) of observers affected by the group. In any
724 // case, the group's target properties need to be added to the lists of
725 // blocked properties.
726 bool null_intersection
= true;
727 for (TargetProperties::iterator p_iter
= enqueued_properties
.begin();
728 p_iter
!= enqueued_properties
.end();
730 if (affects_active_observers
&&
731 !blocked_properties_for_active_observers
.insert(*p_iter
).second
)
732 null_intersection
= false;
733 if (affects_pending_observers
&&
734 !blocked_properties_for_pending_observers
.insert(*p_iter
).second
)
735 null_intersection
= false;
738 // If the intersection is null, then we are free to start the animations
740 if (null_intersection
) {
741 animation_waiting_for_target
->SetRunState(Animation::STARTING
,
743 for (size_t j
= animation_index
+ 1; j
< animations_
.size(); ++j
) {
744 if (animation_waiting_for_target
->group() ==
745 animations_
[j
]->group()) {
746 animations_
[j
]->SetRunState(Animation::STARTING
, monotonic_time
);
750 needs_to_start_animations_
= true;
756 void LayerAnimationController::PromoteStartedAnimations(
757 base::TimeTicks monotonic_time
,
758 AnimationEventsVector
* events
) {
759 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
760 if (animations_
[i
]->run_state() == Animation::STARTING
&&
761 animations_
[i
]->affects_active_observers()) {
762 animations_
[i
]->SetRunState(Animation::RUNNING
, monotonic_time
);
763 if (!animations_
[i
]->has_set_start_time() &&
764 !animations_
[i
]->needs_synchronized_start_time())
765 animations_
[i
]->set_start_time(monotonic_time
);
767 AnimationEvent
started_event(
768 AnimationEvent::STARTED
, id_
, animations_
[i
]->group(),
769 animations_
[i
]->target_property(), monotonic_time
);
770 started_event
.is_impl_only
= animations_
[i
]->is_impl_only();
771 if (started_event
.is_impl_only
)
772 NotifyAnimationStarted(started_event
);
774 events
->push_back(started_event
);
780 void LayerAnimationController::MarkFinishedAnimations(
781 base::TimeTicks monotonic_time
) {
782 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
783 if (animations_
[i
]->IsFinishedAt(monotonic_time
) &&
784 animations_
[i
]->run_state() != Animation::ABORTED
&&
785 animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
)
786 animations_
[i
]->SetRunState(Animation::FINISHED
, monotonic_time
);
790 void LayerAnimationController::MarkAnimationsForDeletion(
791 base::TimeTicks monotonic_time
,
792 AnimationEventsVector
* events
) {
793 bool marked_animations_for_deletions
= false;
794 std::vector
<size_t> animations_with_same_group_id
;
796 animations_with_same_group_id
.reserve(animations_
.size());
797 // Non-aborted animations are marked for deletion after a corresponding
798 // AnimationEvent::FINISHED event is sent or received. This means that if
799 // we don't have an events vector, we must ensure that non-aborted animations
800 // have received a finished event before marking them for deletion.
801 for (size_t i
= 0; i
< animations_
.size(); i
++) {
802 int group_id
= animations_
[i
]->group();
803 if (animations_
[i
]->run_state() == Animation::ABORTED
) {
804 if (events
&& !animations_
[i
]->is_impl_only()) {
805 AnimationEvent
aborted_event(AnimationEvent::ABORTED
, id_
, group_id
,
806 animations_
[i
]->target_property(),
808 events
->push_back(aborted_event
);
810 animations_
[i
]->SetRunState(Animation::WAITING_FOR_DELETION
,
812 marked_animations_for_deletions
= true;
816 bool all_anims_with_same_id_are_finished
= false;
818 // Since deleting an animation on the main thread leads to its deletion
819 // on the impl thread, we only mark a FINISHED main thread animation for
820 // deletion once it has received a FINISHED event from the impl thread.
821 bool animation_i_will_send_or_has_received_finish_event
=
822 events
|| animations_
[i
]->received_finished_event();
823 // If an animation is finished, and not already marked for deletion,
824 // find out if all other animations in the same group are also finished.
825 if (animations_
[i
]->run_state() == Animation::FINISHED
&&
826 animation_i_will_send_or_has_received_finish_event
) {
827 // Clear the animations_with_same_group_id if it was added for
828 // the previous animation's iteration.
829 if (animations_with_same_group_id
.size() > 0)
830 animations_with_same_group_id
.clear();
831 all_anims_with_same_id_are_finished
= true;
832 for (size_t j
= 0; j
< animations_
.size(); ++j
) {
833 bool animation_j_will_send_or_has_received_finish_event
=
834 events
|| 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;
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
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
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
];
860 AnimationEvent
finished_event(
861 AnimationEvent::FINISHED
, id_
,
862 animations_
[animation_index
]->group(),
863 animations_
[animation_index
]->target_property(),
865 finished_event
.is_impl_only
=
866 animations_
[animation_index
]->is_impl_only();
867 if (finished_event
.is_impl_only
)
868 NotifyAnimationFinished(finished_event
);
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_
,
890 IsWaitingForDeletion
),
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
))
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(
913 animations_
[i
]->affects_active_observers(),
914 animations_
[i
]->affects_pending_observers());
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(
925 animations_
[i
]->affects_active_observers(),
926 animations_
[i
]->affects_pending_observers());
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(
937 animations_
[i
]->affects_active_observers(),
938 animations_
[i
]->affects_pending_observers());
942 case Animation::BACKGROUND_COLOR
: {
943 // Not yet implemented.
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(
954 animations_
[i
]->affects_active_observers(),
955 animations_
[i
]->affects_pending_observers());
963 void LayerAnimationController::UpdateActivation(UpdateActivationType type
) {
964 bool force
= type
== FORCE_ACTIVATION
;
966 bool was_active
= is_active_
;
968 for (size_t i
= 0; i
< animations_
.size(); ++i
) {
969 if (animations_
[i
]->run_state() != Animation::WAITING_FOR_DELETION
) {
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(
984 bool notify_active_observers
,
985 bool notify_pending_observers
) {
986 if (value_observers_
.might_have_observers()) {
987 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
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
,
1053 OnAnimationWaitingForDeletion());
1056 bool LayerAnimationController::HasValueObserver() {
1057 if (value_observers_
.might_have_observers()) {
1058 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1060 return it
.GetNext() != nullptr;
1065 bool LayerAnimationController::HasActiveValueObserver() {
1066 if (value_observers_
.might_have_observers()) {
1067 ObserverListBase
<LayerAnimationValueObserver
>::Iterator
it(
1069 LayerAnimationValueObserver
* obs
;
1070 while ((obs
= it
.GetNext()) != nullptr)
1071 if (obs
->IsActive())