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.
4
5 #include "cc/animation/layer_animation_controller.h"
6
7 #include <algorithm>
8 #include <vector>
9
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/box_f.h"
20 #include "ui/gfx/transform.h"
21
22 namespace cc {
23
LayerAnimationController(int id)24 LayerAnimationController::LayerAnimationController(int id)
25 : registrar_(0),
26 id_(id),
27 is_active_(false),
28 value_provider_(NULL),
29 layer_animation_delegate_(NULL),
30 needs_to_start_animations_(false) {
31 }
32
~LayerAnimationController()33 LayerAnimationController::~LayerAnimationController() {
34 if (registrar_)
35 registrar_->UnregisterAnimationController(this);
36 }
37
Create(int id)38 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
39 int id) {
40 return make_scoped_refptr(new LayerAnimationController(id));
41 }
42
PauseAnimation(int animation_id,base::TimeDelta time_offset)43 void LayerAnimationController::PauseAnimation(int animation_id,
44 base::TimeDelta time_offset) {
45 for (size_t i = 0; i < animations_.size(); ++i) {
46 if (animations_[i]->id() == animation_id) {
47 animations_[i]->SetRunState(Animation::Paused,
48 time_offset + animations_[i]->start_time());
49 }
50 }
51 }
52
53 struct HasAnimationId {
HasAnimationIdcc::HasAnimationId54 explicit HasAnimationId(int id) : id_(id) {}
operator ()cc::HasAnimationId55 bool operator()(Animation* animation) const {
56 return animation->id() == id_;
57 }
58
59 private:
60 int id_;
61 };
62
RemoveAnimation(int animation_id)63 void LayerAnimationController::RemoveAnimation(int animation_id) {
64 animations_.erase(cc::remove_if(&animations_,
65 animations_.begin(),
66 animations_.end(),
67 HasAnimationId(animation_id)),
68 animations_.end());
69 UpdateActivation(NormalActivation);
70 }
71
72 struct HasAnimationIdAndProperty {
HasAnimationIdAndPropertycc::HasAnimationIdAndProperty73 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
74 : id_(id), target_property_(target_property) {}
operator ()cc::HasAnimationIdAndProperty75 bool operator()(Animation* animation) const {
76 return animation->id() == id_ &&
77 animation->target_property() == target_property_;
78 }
79
80 private:
81 int id_;
82 Animation::TargetProperty target_property_;
83 };
84
RemoveAnimation(int animation_id,Animation::TargetProperty target_property)85 void LayerAnimationController::RemoveAnimation(
86 int animation_id,
87 Animation::TargetProperty target_property) {
88 animations_.erase(
89 cc::remove_if(&animations_,
90 animations_.begin(),
91 animations_.end(),
92 HasAnimationIdAndProperty(animation_id, target_property)),
93 animations_.end());
94 UpdateActivation(NormalActivation);
95 }
96
AbortAnimations(Animation::TargetProperty target_property)97 void LayerAnimationController::AbortAnimations(
98 Animation::TargetProperty target_property) {
99 for (size_t i = 0; i < animations_.size(); ++i) {
100 if (animations_[i]->target_property() == target_property &&
101 !animations_[i]->is_finished())
102 animations_[i]->SetRunState(Animation::Aborted, last_tick_time_);
103 }
104 }
105
106 // Ensures that the list of active animations on the main thread and the impl
107 // thread are kept in sync.
PushAnimationUpdatesTo(LayerAnimationController * controller_impl)108 void LayerAnimationController::PushAnimationUpdatesTo(
109 LayerAnimationController* controller_impl) {
110 DCHECK(this != controller_impl);
111 if (!has_any_animation() && !controller_impl->has_any_animation())
112 return;
113 PurgeAnimationsMarkedForDeletion();
114 PushNewAnimationsToImplThread(controller_impl);
115
116 // Remove finished impl side animations only after pushing,
117 // and only after the animations are deleted on the main thread
118 // this insures we will never push an animation twice.
119 RemoveAnimationsCompletedOnMainThread(controller_impl);
120
121 PushPropertiesToImplThread(controller_impl);
122 controller_impl->UpdateActivation(NormalActivation);
123 UpdateActivation(NormalActivation);
124 }
125
Animate(base::TimeTicks monotonic_time)126 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) {
127 DCHECK(!monotonic_time.is_null());
128 if (!HasValueObserver())
129 return;
130
131 if (needs_to_start_animations_)
132 StartAnimations(monotonic_time);
133 TickAnimations(monotonic_time);
134 last_tick_time_ = monotonic_time;
135 }
136
AccumulatePropertyUpdates(base::TimeTicks monotonic_time,AnimationEventsVector * events)137 void LayerAnimationController::AccumulatePropertyUpdates(
138 base::TimeTicks monotonic_time,
139 AnimationEventsVector* events) {
140 if (!events)
141 return;
142
143 for (size_t i = 0; i < animations_.size(); ++i) {
144 Animation* animation = animations_[i];
145 if (!animation->is_impl_only())
146 continue;
147
148 if (!animation->InEffect(monotonic_time))
149 continue;
150
151 double trimmed = animation->TrimTimeToCurrentIteration(monotonic_time);
152 switch (animation->target_property()) {
153 case Animation::Opacity: {
154 AnimationEvent event(AnimationEvent::PropertyUpdate,
155 id_,
156 animation->group(),
157 Animation::Opacity,
158 monotonic_time);
159 const FloatAnimationCurve* float_animation_curve =
160 animation->curve()->ToFloatAnimationCurve();
161 event.opacity = float_animation_curve->GetValue(trimmed);
162 event.is_impl_only = true;
163 events->push_back(event);
164 break;
165 }
166
167 case Animation::Transform: {
168 AnimationEvent event(AnimationEvent::PropertyUpdate,
169 id_,
170 animation->group(),
171 Animation::Transform,
172 monotonic_time);
173 const TransformAnimationCurve* transform_animation_curve =
174 animation->curve()->ToTransformAnimationCurve();
175 event.transform = transform_animation_curve->GetValue(trimmed);
176 event.is_impl_only = true;
177 events->push_back(event);
178 break;
179 }
180
181 case Animation::Filter: {
182 AnimationEvent event(AnimationEvent::PropertyUpdate,
183 id_,
184 animation->group(),
185 Animation::Filter,
186 monotonic_time);
187 const FilterAnimationCurve* filter_animation_curve =
188 animation->curve()->ToFilterAnimationCurve();
189 event.filters = filter_animation_curve->GetValue(trimmed);
190 event.is_impl_only = true;
191 events->push_back(event);
192 break;
193 }
194
195 case Animation::BackgroundColor: { break; }
196
197 case Animation::ScrollOffset: {
198 // Impl-side changes to scroll offset are already sent back to the
199 // main thread (e.g. for user-driven scrolling), so a PropertyUpdate
200 // isn't needed.
201 break;
202 }
203
204 case Animation::TargetPropertyEnumSize:
205 NOTREACHED();
206 }
207 }
208 }
209
UpdateState(bool start_ready_animations,AnimationEventsVector * events)210 void LayerAnimationController::UpdateState(bool start_ready_animations,
211 AnimationEventsVector* events) {
212 if (!HasActiveValueObserver())
213 return;
214
215 DCHECK(last_tick_time_ != base::TimeTicks());
216 if (start_ready_animations)
217 PromoteStartedAnimations(last_tick_time_, events);
218
219 MarkFinishedAnimations(last_tick_time_);
220 MarkAnimationsForDeletion(last_tick_time_, events);
221
222 if (needs_to_start_animations_ && start_ready_animations) {
223 StartAnimations(last_tick_time_);
224 PromoteStartedAnimations(last_tick_time_, events);
225 }
226
227 AccumulatePropertyUpdates(last_tick_time_, events);
228
229 UpdateActivation(NormalActivation);
230 }
231
232 struct AffectsNoObservers {
operator ()cc::AffectsNoObservers233 bool operator()(Animation* animation) const {
234 return !animation->affects_active_observers() &&
235 !animation->affects_pending_observers();
236 }
237 };
238
ActivateAnimations()239 void LayerAnimationController::ActivateAnimations() {
240 for (size_t i = 0; i < animations_.size(); ++i) {
241 animations_[i]->set_affects_active_observers(
242 animations_[i]->affects_pending_observers());
243 }
244 animations_.erase(cc::remove_if(&animations_,
245 animations_.begin(),
246 animations_.end(),
247 AffectsNoObservers()),
248 animations_.end());
249 UpdateActivation(NormalActivation);
250 }
251
AddAnimation(scoped_ptr<Animation> animation)252 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
253 animations_.push_back(animation.Pass());
254 needs_to_start_animations_ = true;
255 UpdateActivation(NormalActivation);
256 }
257
GetAnimation(int group_id,Animation::TargetProperty target_property) const258 Animation* LayerAnimationController::GetAnimation(
259 int group_id,
260 Animation::TargetProperty target_property) const {
261 for (size_t i = 0; i < animations_.size(); ++i)
262 if (animations_[i]->group() == group_id &&
263 animations_[i]->target_property() == target_property)
264 return animations_[i];
265 return 0;
266 }
267
GetAnimation(Animation::TargetProperty target_property) const268 Animation* LayerAnimationController::GetAnimation(
269 Animation::TargetProperty target_property) const {
270 for (size_t i = 0; i < animations_.size(); ++i) {
271 size_t index = animations_.size() - i - 1;
272 if (animations_[index]->target_property() == target_property)
273 return animations_[index];
274 }
275 return 0;
276 }
277
HasActiveAnimation() const278 bool LayerAnimationController::HasActiveAnimation() const {
279 for (size_t i = 0; i < animations_.size(); ++i) {
280 if (!animations_[i]->is_finished())
281 return true;
282 }
283 return false;
284 }
285
IsAnimatingProperty(Animation::TargetProperty target_property) const286 bool LayerAnimationController::IsAnimatingProperty(
287 Animation::TargetProperty target_property) const {
288 for (size_t i = 0; i < animations_.size(); ++i) {
289 if (!animations_[i]->is_finished() &&
290 animations_[i]->InEffect(last_tick_time_) &&
291 animations_[i]->target_property() == target_property)
292 return true;
293 }
294 return false;
295 }
296
SetAnimationRegistrar(AnimationRegistrar * registrar)297 void LayerAnimationController::SetAnimationRegistrar(
298 AnimationRegistrar* registrar) {
299 if (registrar_ == registrar)
300 return;
301
302 if (registrar_)
303 registrar_->UnregisterAnimationController(this);
304
305 registrar_ = registrar;
306 if (registrar_)
307 registrar_->RegisterAnimationController(this);
308
309 UpdateActivation(ForceActivation);
310 }
311
NotifyAnimationStarted(const AnimationEvent & event)312 void LayerAnimationController::NotifyAnimationStarted(
313 const AnimationEvent& event) {
314 if (event.is_impl_only) {
315 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
316 OnAnimationStarted(event));
317 if (layer_animation_delegate_)
318 layer_animation_delegate_->NotifyAnimationStarted(event.monotonic_time,
319 event.target_property);
320 return;
321 }
322
323 for (size_t i = 0; i < animations_.size(); ++i) {
324 if (animations_[i]->group() == event.group_id &&
325 animations_[i]->target_property() == event.target_property &&
326 animations_[i]->needs_synchronized_start_time()) {
327 animations_[i]->set_needs_synchronized_start_time(false);
328 if (!animations_[i]->has_set_start_time())
329 animations_[i]->set_start_time(event.monotonic_time);
330
331 FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
332 OnAnimationStarted(event));
333 if (layer_animation_delegate_)
334 layer_animation_delegate_->NotifyAnimationStarted(
335 event.monotonic_time, event.target_property);
336
337 return;
338 }
339 }
340 }
341
NotifyAnimationFinished(const AnimationEvent & event)342 void LayerAnimationController::NotifyAnimationFinished(
343 const AnimationEvent& event) {
344 if (event.is_impl_only) {
345 if (layer_animation_delegate_)
346 layer_animation_delegate_->NotifyAnimationFinished(event.monotonic_time,
347 event.target_property);
348 return;
349 }
350
351 for (size_t i = 0; i < animations_.size(); ++i) {
352 if (animations_[i]->group() == event.group_id &&
353 animations_[i]->target_property() == event.target_property) {
354 animations_[i]->set_received_finished_event(true);
355 if (layer_animation_delegate_)
356 layer_animation_delegate_->NotifyAnimationFinished(
357 event.monotonic_time, event.target_property);
358
359 return;
360 }
361 }
362 }
363
NotifyAnimationAborted(const AnimationEvent & event)364 void LayerAnimationController::NotifyAnimationAborted(
365 const AnimationEvent& event) {
366 for (size_t i = 0; i < animations_.size(); ++i) {
367 if (animations_[i]->group() == event.group_id &&
368 animations_[i]->target_property() == event.target_property) {
369 animations_[i]->SetRunState(Animation::Aborted, event.monotonic_time);
370 }
371 }
372 }
373
NotifyAnimationPropertyUpdate(const AnimationEvent & event)374 void LayerAnimationController::NotifyAnimationPropertyUpdate(
375 const AnimationEvent& event) {
376 bool notify_active_observers = true;
377 bool notify_pending_observers = true;
378 switch (event.target_property) {
379 case Animation::Opacity:
380 NotifyObserversOpacityAnimated(
381 event.opacity, notify_active_observers, notify_pending_observers);
382 break;
383 case Animation::Transform:
384 NotifyObserversTransformAnimated(
385 event.transform, notify_active_observers, notify_pending_observers);
386 break;
387 default:
388 NOTREACHED();
389 }
390 }
391
AddValueObserver(LayerAnimationValueObserver * observer)392 void LayerAnimationController::AddValueObserver(
393 LayerAnimationValueObserver* observer) {
394 if (!value_observers_.HasObserver(observer))
395 value_observers_.AddObserver(observer);
396 }
397
RemoveValueObserver(LayerAnimationValueObserver * observer)398 void LayerAnimationController::RemoveValueObserver(
399 LayerAnimationValueObserver* observer) {
400 value_observers_.RemoveObserver(observer);
401 }
402
AddEventObserver(LayerAnimationEventObserver * observer)403 void LayerAnimationController::AddEventObserver(
404 LayerAnimationEventObserver* observer) {
405 if (!event_observers_.HasObserver(observer))
406 event_observers_.AddObserver(observer);
407 }
408
RemoveEventObserver(LayerAnimationEventObserver * observer)409 void LayerAnimationController::RemoveEventObserver(
410 LayerAnimationEventObserver* observer) {
411 event_observers_.RemoveObserver(observer);
412 }
413
HasFilterAnimationThatInflatesBounds() const414 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const {
415 for (size_t i = 0; i < animations_.size(); ++i) {
416 if (!animations_[i]->is_finished() &&
417 animations_[i]->target_property() == Animation::Filter &&
418 animations_[i]
419 ->curve()
420 ->ToFilterAnimationCurve()
421 ->HasFilterThatMovesPixels())
422 return true;
423 }
424
425 return false;
426 }
427
HasTransformAnimationThatInflatesBounds() const428 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const {
429 return IsAnimatingProperty(Animation::Transform);
430 }
431
FilterAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const432 bool LayerAnimationController::FilterAnimationBoundsForBox(
433 const gfx::BoxF& box, gfx::BoxF* bounds) const {
434 // TODO(avallee): Implement.
435 return false;
436 }
437
TransformAnimationBoundsForBox(const gfx::BoxF & box,gfx::BoxF * bounds) const438 bool LayerAnimationController::TransformAnimationBoundsForBox(
439 const gfx::BoxF& box,
440 gfx::BoxF* bounds) const {
441 DCHECK(HasTransformAnimationThatInflatesBounds())
442 << "TransformAnimationBoundsForBox will give incorrect results if there "
443 << "are no transform animations affecting bounds, non-animated transform "
444 << "is not known";
445
446 // Compute bounds based on animations for which is_finished() is false.
447 // Do nothing if there are no such animations; in this case, it is assumed
448 // that callers will take care of computing bounds based on the owning layer's
449 // actual transform.
450 *bounds = gfx::BoxF();
451 for (size_t i = 0; i < animations_.size(); ++i) {
452 if (animations_[i]->is_finished() ||
453 animations_[i]->target_property() != Animation::Transform)
454 continue;
455
456 const TransformAnimationCurve* transform_animation_curve =
457 animations_[i]->curve()->ToTransformAnimationCurve();
458 gfx::BoxF animation_bounds;
459 bool success =
460 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
461 if (!success)
462 return false;
463 bounds->Union(animation_bounds);
464 }
465
466 return true;
467 }
468
HasAnimationThatAffectsScale() const469 bool LayerAnimationController::HasAnimationThatAffectsScale() const {
470 for (size_t i = 0; i < animations_.size(); ++i) {
471 if (animations_[i]->is_finished() ||
472 animations_[i]->target_property() != Animation::Transform)
473 continue;
474
475 const TransformAnimationCurve* transform_animation_curve =
476 animations_[i]->curve()->ToTransformAnimationCurve();
477 if (transform_animation_curve->AffectsScale())
478 return true;
479 }
480
481 return false;
482 }
483
HasOnlyTranslationTransforms() const484 bool LayerAnimationController::HasOnlyTranslationTransforms() const {
485 for (size_t i = 0; i < animations_.size(); ++i) {
486 if (animations_[i]->is_finished() ||
487 animations_[i]->target_property() != Animation::Transform)
488 continue;
489
490 const TransformAnimationCurve* transform_animation_curve =
491 animations_[i]->curve()->ToTransformAnimationCurve();
492 if (!transform_animation_curve->IsTranslation())
493 return false;
494 }
495
496 return true;
497 }
498
MaximumTargetScale(float * max_scale) const499 bool LayerAnimationController::MaximumTargetScale(float* max_scale) const {
500 *max_scale = 0.f;
501 for (size_t i = 0; i < animations_.size(); ++i) {
502 if (animations_[i]->is_finished() ||
503 animations_[i]->target_property() != Animation::Transform)
504 continue;
505
506 bool forward_direction = true;
507 switch (animations_[i]->direction()) {
508 case Animation::Normal:
509 case Animation::Alternate:
510 forward_direction = animations_[i]->playback_rate() >= 0.0;
511 break;
512 case Animation::Reverse:
513 case Animation::AlternateReverse:
514 forward_direction = animations_[i]->playback_rate() < 0.0;
515 break;
516 }
517
518 const TransformAnimationCurve* transform_animation_curve =
519 animations_[i]->curve()->ToTransformAnimationCurve();
520 float animation_scale = 0.f;
521 if (!transform_animation_curve->MaximumTargetScale(forward_direction,
522 &animation_scale))
523 return false;
524 *max_scale = std::max(*max_scale, animation_scale);
525 }
526
527 return true;
528 }
529
PushNewAnimationsToImplThread(LayerAnimationController * controller_impl) const530 void LayerAnimationController::PushNewAnimationsToImplThread(
531 LayerAnimationController* controller_impl) const {
532 // Any new animations owned by the main thread's controller are cloned and
533 // add to the impl thread's controller.
534 for (size_t i = 0; i < animations_.size(); ++i) {
535 // If the animation is already running on the impl thread, there is no
536 // need to copy it over.
537 if (controller_impl->GetAnimation(animations_[i]->group(),
538 animations_[i]->target_property()))
539 continue;
540
541 // If the animation is not running on the impl thread, it does not
542 // necessarily mean that it needs to be copied over and started; it may
543 // have already finished. In this case, the impl thread animation will
544 // have already notified that it has started and the main thread animation
545 // will no longer need
546 // a synchronized start time.
547 if (!animations_[i]->needs_synchronized_start_time())
548 continue;
549
550 // Scroll animations always start at the current scroll offset.
551 if (animations_[i]->target_property() == Animation::ScrollOffset) {
552 gfx::Vector2dF current_scroll_offset;
553 if (controller_impl->value_provider_) {
554 current_scroll_offset =
555 controller_impl->value_provider_->ScrollOffsetForAnimation();
556 } else {
557 // The owning layer isn't yet in the active tree, so the main thread
558 // scroll offset will be up-to-date.
559 current_scroll_offset = value_provider_->ScrollOffsetForAnimation();
560 }
561 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue(
562 current_scroll_offset);
563 }
564
565 // The new animation should be set to run as soon as possible.
566 Animation::RunState initial_run_state =
567 Animation::WaitingForTargetAvailability;
568 scoped_ptr<Animation> to_add(
569 animations_[i]->CloneAndInitialize(initial_run_state));
570 DCHECK(!to_add->needs_synchronized_start_time());
571 to_add->set_affects_active_observers(false);
572 controller_impl->AddAnimation(to_add.Pass());
573 }
574 }
575
IsCompleted(Animation * animation,const LayerAnimationController * main_thread_controller)576 static bool IsCompleted(
577 Animation* animation,
578 const LayerAnimationController* main_thread_controller) {
579 if (animation->is_impl_only()) {
580 return (animation->run_state() == Animation::WaitingForDeletion);
581 } else {
582 return !main_thread_controller->GetAnimation(animation->group(),
583 animation->target_property());
584 }
585 }
586
AffectsActiveOnlyAndIsWaitingForDeletion(Animation * animation)587 static bool AffectsActiveOnlyAndIsWaitingForDeletion(Animation* animation) {
588 return animation->run_state() == Animation::WaitingForDeletion &&
589 !animation->affects_pending_observers();
590 }
591
RemoveAnimationsCompletedOnMainThread(LayerAnimationController * controller_impl) const592 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
593 LayerAnimationController* controller_impl) const {
594 // Animations removed on the main thread should no longer affect pending
595 // observers, and should stop affecting active observers after the next call
596 // to ActivateAnimations. If already WaitingForDeletion, they can be removed
597 // immediately.
598 ScopedPtrVector<Animation>& animations = controller_impl->animations_;
599 for (size_t i = 0; i < animations.size(); ++i) {
600 if (IsCompleted(animations[i], this))
601 animations[i]->set_affects_pending_observers(false);
602 }
603 animations.erase(cc::remove_if(&animations,
604 animations.begin(),
605 animations.end(),
606 AffectsActiveOnlyAndIsWaitingForDeletion),
607 animations.end());
608 }
609
PushPropertiesToImplThread(LayerAnimationController * controller_impl) const610 void LayerAnimationController::PushPropertiesToImplThread(
611 LayerAnimationController* controller_impl) const {
612 for (size_t i = 0; i < animations_.size(); ++i) {
613 Animation* current_impl = controller_impl->GetAnimation(
614 animations_[i]->group(), animations_[i]->target_property());
615 if (current_impl)
616 animations_[i]->PushPropertiesTo(current_impl);
617 }
618 }
619
StartAnimations(base::TimeTicks monotonic_time)620 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) {
621 DCHECK(needs_to_start_animations_);
622 needs_to_start_animations_ = false;
623 // First collect running properties affecting each type of observer.
624 TargetProperties blocked_properties_for_active_observers;
625 TargetProperties blocked_properties_for_pending_observers;
626 std::vector<size_t> animations_waiting_for_target;
627
628 animations_waiting_for_target.reserve(animations_.size());
629 for (size_t i = 0; i < animations_.size(); ++i) {
630 if (animations_[i]->run_state() == Animation::Starting ||
631 animations_[i]->run_state() == Animation::Running) {
632 if (animations_[i]->affects_active_observers()) {
633 blocked_properties_for_active_observers.insert(
634 animations_[i]->target_property());
635 }
636 if (animations_[i]->affects_pending_observers()) {
637 blocked_properties_for_pending_observers.insert(
638 animations_[i]->target_property());
639 }
640 } else if (animations_[i]->run_state() ==
641 Animation::WaitingForTargetAvailability) {
642 animations_waiting_for_target.push_back(i);
643 }
644 }
645
646 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) {
647 // Collect all properties for animations with the same group id (they
648 // should all also be in the list of animations).
649 size_t animation_index = animations_waiting_for_target[i];
650 Animation* animation_waiting_for_target = animations_[animation_index];
651 // Check for the run state again even though the animation was waiting
652 // for target because it might have changed the run state while handling
653 // previous animation in this loop (if they belong to same group).
654 if (animation_waiting_for_target->run_state() ==
655 Animation::WaitingForTargetAvailability) {
656 TargetProperties enqueued_properties;
657 bool affects_active_observers =
658 animation_waiting_for_target->affects_active_observers();
659 bool affects_pending_observers =
660 animation_waiting_for_target->affects_pending_observers();
661 enqueued_properties.insert(
662 animation_waiting_for_target->target_property());
663 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
664 if (animation_waiting_for_target->group() == animations_[j]->group()) {
665 enqueued_properties.insert(animations_[j]->target_property());
666 affects_active_observers |=
667 animations_[j]->affects_active_observers();
668 affects_pending_observers |=
669 animations_[j]->affects_pending_observers();
670 }
671 }
672
673 // Check to see if intersection of the list of properties affected by
674 // the group and the list of currently blocked properties is null, taking
675 // into account the type(s) of observers affected by the group. In any
676 // case, the group's target properties need to be added to the lists of
677 // blocked properties.
678 bool null_intersection = true;
679 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
680 p_iter != enqueued_properties.end();
681 ++p_iter) {
682 if (affects_active_observers &&
683 !blocked_properties_for_active_observers.insert(*p_iter).second)
684 null_intersection = false;
685 if (affects_pending_observers &&
686 !blocked_properties_for_pending_observers.insert(*p_iter).second)
687 null_intersection = false;
688 }
689
690 // If the intersection is null, then we are free to start the animations
691 // in the group.
692 if (null_intersection) {
693 animation_waiting_for_target->SetRunState(Animation::Starting,
694 monotonic_time);
695 for (size_t j = animation_index + 1; j < animations_.size(); ++j) {
696 if (animation_waiting_for_target->group() ==
697 animations_[j]->group()) {
698 animations_[j]->SetRunState(Animation::Starting, monotonic_time);
699 }
700 }
701 } else {
702 needs_to_start_animations_ = true;
703 }
704 }
705 }
706 }
707
PromoteStartedAnimations(base::TimeTicks monotonic_time,AnimationEventsVector * events)708 void LayerAnimationController::PromoteStartedAnimations(
709 base::TimeTicks monotonic_time,
710 AnimationEventsVector* events) {
711 for (size_t i = 0; i < animations_.size(); ++i) {
712 if (animations_[i]->run_state() == Animation::Starting &&
713 animations_[i]->affects_active_observers()) {
714 animations_[i]->SetRunState(Animation::Running, monotonic_time);
715 if (!animations_[i]->has_set_start_time() &&
716 !animations_[i]->needs_synchronized_start_time())
717 animations_[i]->set_start_time(monotonic_time);
718 if (events) {
719 AnimationEvent started_event(AnimationEvent::Started,
720 id_,
721 animations_[i]->group(),
722 animations_[i]->target_property(),
723 monotonic_time);
724 started_event.is_impl_only = animations_[i]->is_impl_only();
725 if (started_event.is_impl_only)
726 NotifyAnimationStarted(started_event);
727 else
728 events->push_back(started_event);
729 }
730 }
731 }
732 }
733
MarkFinishedAnimations(base::TimeTicks monotonic_time)734 void LayerAnimationController::MarkFinishedAnimations(
735 base::TimeTicks monotonic_time) {
736 for (size_t i = 0; i < animations_.size(); ++i) {
737 if (animations_[i]->IsFinishedAt(monotonic_time) &&
738 animations_[i]->run_state() != Animation::Aborted &&
739 animations_[i]->run_state() != Animation::WaitingForDeletion)
740 animations_[i]->SetRunState(Animation::Finished, monotonic_time);
741 }
742 }
743
MarkAnimationsForDeletion(base::TimeTicks monotonic_time,AnimationEventsVector * events)744 void LayerAnimationController::MarkAnimationsForDeletion(
745 base::TimeTicks monotonic_time,
746 AnimationEventsVector* events) {
747 bool marked_animations_for_deletions = false;
748 std::vector<size_t> animations_with_same_group_id;
749
750 animations_with_same_group_id.reserve(animations_.size());
751 // Non-aborted animations are marked for deletion after a corresponding
752 // AnimationEvent::Finished event is sent or received. This means that if
753 // we don't have an events vector, we must ensure that non-aborted animations
754 // have received a finished event before marking them for deletion.
755 for (size_t i = 0; i < animations_.size(); i++) {
756 int group_id = animations_[i]->group();
757 if (animations_[i]->run_state() == Animation::Aborted) {
758 if (events && !animations_[i]->is_impl_only()) {
759 AnimationEvent aborted_event(AnimationEvent::Aborted,
760 id_,
761 group_id,
762 animations_[i]->target_property(),
763 monotonic_time);
764 events->push_back(aborted_event);
765 }
766 animations_[i]->SetRunState(Animation::WaitingForDeletion,
767 monotonic_time);
768 marked_animations_for_deletions = true;
769 continue;
770 }
771
772 bool all_anims_with_same_id_are_finished = false;
773
774 // Since deleting an animation on the main thread leads to its deletion
775 // on the impl thread, we only mark a Finished main thread animation for
776 // deletion once it has received a Finished event from the impl thread.
777 bool animation_i_will_send_or_has_received_finish_event =
778 events || animations_[i]->received_finished_event();
779 // If an animation is finished, and not already marked for deletion,
780 // find out if all other animations in the same group are also finished.
781 if (animations_[i]->run_state() == Animation::Finished &&
782 animation_i_will_send_or_has_received_finish_event) {
783 // Clear the animations_with_same_group_id if it was added for
784 // the previous animation's iteration.
785 if (animations_with_same_group_id.size() > 0)
786 animations_with_same_group_id.clear();
787 all_anims_with_same_id_are_finished = true;
788 for (size_t j = 0; j < animations_.size(); ++j) {
789 bool animation_j_will_send_or_has_received_finish_event =
790 events || animations_[j]->received_finished_event();
791 if (group_id == animations_[j]->group()) {
792 if (!animations_[j]->is_finished() ||
793 (animations_[j]->run_state() == Animation::Finished &&
794 !animation_j_will_send_or_has_received_finish_event)) {
795 all_anims_with_same_id_are_finished = false;
796 break;
797 } else if (j >= i &&
798 animations_[j]->run_state() != Animation::Aborted) {
799 // Mark down the animations which belong to the same group
800 // and is not yet aborted. If this current iteration finds that all
801 // animations with same ID are finished, then the marked
802 // animations below will be set to WaitingForDeletion in next
803 // iteration.
804 animations_with_same_group_id.push_back(j);
805 }
806 }
807 }
808 }
809 if (all_anims_with_same_id_are_finished) {
810 // We now need to remove all animations with the same group id as
811 // group_id (and send along animation finished notifications, if
812 // necessary).
813 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) {
814 size_t animation_index = animations_with_same_group_id[j];
815 if (events) {
816 AnimationEvent finished_event(
817 AnimationEvent::Finished,
818 id_,
819 animations_[animation_index]->group(),
820 animations_[animation_index]->target_property(),
821 monotonic_time);
822 finished_event.is_impl_only =
823 animations_[animation_index]->is_impl_only();
824 if (finished_event.is_impl_only)
825 NotifyAnimationFinished(finished_event);
826 else
827 events->push_back(finished_event);
828 }
829 animations_[animation_index]->SetRunState(
830 Animation::WaitingForDeletion, monotonic_time);
831 }
832 marked_animations_for_deletions = true;
833 }
834 }
835 if (marked_animations_for_deletions)
836 NotifyObserversAnimationWaitingForDeletion();
837 }
838
IsWaitingForDeletion(Animation * animation)839 static bool IsWaitingForDeletion(Animation* animation) {
840 return animation->run_state() == Animation::WaitingForDeletion;
841 }
842
PurgeAnimationsMarkedForDeletion()843 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
844 animations_.erase(cc::remove_if(&animations_,
845 animations_.begin(),
846 animations_.end(),
847 IsWaitingForDeletion),
848 animations_.end());
849 }
850
TickAnimations(base::TimeTicks monotonic_time)851 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) {
852 for (size_t i = 0; i < animations_.size(); ++i) {
853 if (animations_[i]->run_state() == Animation::Starting ||
854 animations_[i]->run_state() == Animation::Running ||
855 animations_[i]->run_state() == Animation::Paused) {
856 if (!animations_[i]->InEffect(monotonic_time))
857 continue;
858
859 double trimmed =
860 animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
861
862 switch (animations_[i]->target_property()) {
863 case Animation::Transform: {
864 const TransformAnimationCurve* transform_animation_curve =
865 animations_[i]->curve()->ToTransformAnimationCurve();
866 const gfx::Transform transform =
867 transform_animation_curve->GetValue(trimmed);
868 NotifyObserversTransformAnimated(
869 transform,
870 animations_[i]->affects_active_observers(),
871 animations_[i]->affects_pending_observers());
872 break;
873 }
874
875 case Animation::Opacity: {
876 const FloatAnimationCurve* float_animation_curve =
877 animations_[i]->curve()->ToFloatAnimationCurve();
878 const float opacity = std::max(
879 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f);
880 NotifyObserversOpacityAnimated(
881 opacity,
882 animations_[i]->affects_active_observers(),
883 animations_[i]->affects_pending_observers());
884 break;
885 }
886
887 case Animation::Filter: {
888 const FilterAnimationCurve* filter_animation_curve =
889 animations_[i]->curve()->ToFilterAnimationCurve();
890 const FilterOperations filter =
891 filter_animation_curve->GetValue(trimmed);
892 NotifyObserversFilterAnimated(
893 filter,
894 animations_[i]->affects_active_observers(),
895 animations_[i]->affects_pending_observers());
896 break;
897 }
898
899 case Animation::BackgroundColor: {
900 // Not yet implemented.
901 break;
902 }
903
904 case Animation::ScrollOffset: {
905 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
906 animations_[i]->curve()->ToScrollOffsetAnimationCurve();
907 const gfx::Vector2dF scroll_offset =
908 scroll_offset_animation_curve->GetValue(trimmed);
909 NotifyObserversScrollOffsetAnimated(
910 scroll_offset,
911 animations_[i]->affects_active_observers(),
912 animations_[i]->affects_pending_observers());
913 break;
914 }
915
916 // Do nothing for sentinel value.
917 case Animation::TargetPropertyEnumSize:
918 NOTREACHED();
919 }
920 }
921 }
922 }
923
UpdateActivation(UpdateActivationType type)924 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
925 bool force = type == ForceActivation;
926 if (registrar_) {
927 bool was_active = is_active_;
928 is_active_ = false;
929 for (size_t i = 0; i < animations_.size(); ++i) {
930 if (animations_[i]->run_state() != Animation::WaitingForDeletion) {
931 is_active_ = true;
932 break;
933 }
934 }
935
936 if (is_active_ && (!was_active || force))
937 registrar_->DidActivateAnimationController(this);
938 else if (!is_active_ && (was_active || force))
939 registrar_->DidDeactivateAnimationController(this);
940 }
941 }
942
NotifyObserversOpacityAnimated(float opacity,bool notify_active_observers,bool notify_pending_observers)943 void LayerAnimationController::NotifyObserversOpacityAnimated(
944 float opacity,
945 bool notify_active_observers,
946 bool notify_pending_observers) {
947 if (value_observers_.might_have_observers()) {
948 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
949 value_observers_);
950 LayerAnimationValueObserver* obs;
951 while ((obs = it.GetNext()) != NULL) {
952 if ((notify_active_observers && notify_pending_observers) ||
953 (notify_active_observers && obs->IsActive()) ||
954 (notify_pending_observers && !obs->IsActive()))
955 obs->OnOpacityAnimated(opacity);
956 }
957 }
958 }
959
NotifyObserversTransformAnimated(const gfx::Transform & transform,bool notify_active_observers,bool notify_pending_observers)960 void LayerAnimationController::NotifyObserversTransformAnimated(
961 const gfx::Transform& transform,
962 bool notify_active_observers,
963 bool notify_pending_observers) {
964 if (value_observers_.might_have_observers()) {
965 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
966 value_observers_);
967 LayerAnimationValueObserver* obs;
968 while ((obs = it.GetNext()) != NULL) {
969 if ((notify_active_observers && notify_pending_observers) ||
970 (notify_active_observers && obs->IsActive()) ||
971 (notify_pending_observers && !obs->IsActive()))
972 obs->OnTransformAnimated(transform);
973 }
974 }
975 }
976
NotifyObserversFilterAnimated(const FilterOperations & filters,bool notify_active_observers,bool notify_pending_observers)977 void LayerAnimationController::NotifyObserversFilterAnimated(
978 const FilterOperations& filters,
979 bool notify_active_observers,
980 bool notify_pending_observers) {
981 if (value_observers_.might_have_observers()) {
982 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
983 value_observers_);
984 LayerAnimationValueObserver* obs;
985 while ((obs = it.GetNext()) != NULL) {
986 if ((notify_active_observers && notify_pending_observers) ||
987 (notify_active_observers && obs->IsActive()) ||
988 (notify_pending_observers && !obs->IsActive()))
989 obs->OnFilterAnimated(filters);
990 }
991 }
992 }
993
NotifyObserversScrollOffsetAnimated(const gfx::Vector2dF & scroll_offset,bool notify_active_observers,bool notify_pending_observers)994 void LayerAnimationController::NotifyObserversScrollOffsetAnimated(
995 const gfx::Vector2dF& scroll_offset,
996 bool notify_active_observers,
997 bool notify_pending_observers) {
998 if (value_observers_.might_have_observers()) {
999 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1000 value_observers_);
1001 LayerAnimationValueObserver* obs;
1002 while ((obs = it.GetNext()) != NULL) {
1003 if ((notify_active_observers && notify_pending_observers) ||
1004 (notify_active_observers && obs->IsActive()) ||
1005 (notify_pending_observers && !obs->IsActive()))
1006 obs->OnScrollOffsetAnimated(scroll_offset);
1007 }
1008 }
1009 }
1010
NotifyObserversAnimationWaitingForDeletion()1011 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() {
1012 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
1013 value_observers_,
1014 OnAnimationWaitingForDeletion());
1015 }
1016
HasValueObserver()1017 bool LayerAnimationController::HasValueObserver() {
1018 if (value_observers_.might_have_observers()) {
1019 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1020 value_observers_);
1021 return it.GetNext() != NULL;
1022 }
1023 return false;
1024 }
1025
HasActiveValueObserver()1026 bool LayerAnimationController::HasActiveValueObserver() {
1027 if (value_observers_.might_have_observers()) {
1028 ObserverListBase<LayerAnimationValueObserver>::Iterator it(
1029 value_observers_);
1030 LayerAnimationValueObserver* obs;
1031 while ((obs = it.GetNext()) != NULL)
1032 if (obs->IsActive())
1033 return true;
1034 }
1035 return false;
1036 }
1037
1038 } // namespace cc
1039