layer_animation_controller.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1951a39d68df598db08dfced8b4707755864a0492Ying Wang// Copyright 2012 The Chromium Authors. All rights reserved.
2951a39d68df598db08dfced8b4707755864a0492Ying Wang// Use of this source code is governed by a BSD-style license that can be
3951a39d68df598db08dfced8b4707755864a0492Ying Wang// found in the LICENSE file.
4951a39d68df598db08dfced8b4707755864a0492Ying Wang
5951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/layer_animation_controller.h"
6951a39d68df598db08dfced8b4707755864a0492Ying Wang
7951a39d68df598db08dfced8b4707755864a0492Ying Wang#include <algorithm>
8951a39d68df598db08dfced8b4707755864a0492Ying Wang
9951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation.h"
10951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation_delegate.h"
11951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/animation_registrar.h"
12951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/keyframed_animation_curve.h"
13951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/animation/layer_animation_value_observer.h"
14951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/base/scoped_ptr_algorithm.h"
15951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "cc/output/filter_operations.h"
16951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "ui/gfx/box_f.h"
17951a39d68df598db08dfced8b4707755864a0492Ying Wang#include "ui/gfx/transform.h"
18951a39d68df598db08dfced8b4707755864a0492Ying Wang
19951a39d68df598db08dfced8b4707755864a0492Ying Wangnamespace cc {
20951a39d68df598db08dfced8b4707755864a0492Ying Wang
21951a39d68df598db08dfced8b4707755864a0492Ying WangLayerAnimationController::LayerAnimationController(int id)
22951a39d68df598db08dfced8b4707755864a0492Ying Wang    : force_sync_(false),
23951a39d68df598db08dfced8b4707755864a0492Ying Wang      registrar_(0),
24951a39d68df598db08dfced8b4707755864a0492Ying Wang      id_(id),
25951a39d68df598db08dfced8b4707755864a0492Ying Wang      is_active_(false),
26951a39d68df598db08dfced8b4707755864a0492Ying Wang      last_tick_time_(0),
27951a39d68df598db08dfced8b4707755864a0492Ying Wang      layer_animation_delegate_(NULL) {}
28951a39d68df598db08dfced8b4707755864a0492Ying Wang
29951a39d68df598db08dfced8b4707755864a0492Ying WangLayerAnimationController::~LayerAnimationController() {
30951a39d68df598db08dfced8b4707755864a0492Ying Wang  if (registrar_)
31951a39d68df598db08dfced8b4707755864a0492Ying Wang    registrar_->UnregisterAnimationController(this);
32951a39d68df598db08dfced8b4707755864a0492Ying Wang}
33951a39d68df598db08dfced8b4707755864a0492Ying Wang
34951a39d68df598db08dfced8b4707755864a0492Ying Wangscoped_refptr<LayerAnimationController> LayerAnimationController::Create(
35951a39d68df598db08dfced8b4707755864a0492Ying Wang    int id) {
36951a39d68df598db08dfced8b4707755864a0492Ying Wang  return make_scoped_refptr(new LayerAnimationController(id));
37951a39d68df598db08dfced8b4707755864a0492Ying Wang}
38951a39d68df598db08dfced8b4707755864a0492Ying Wang
39951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::PauseAnimation(int animation_id,
40951a39d68df598db08dfced8b4707755864a0492Ying Wang                                              double time_offset) {
41951a39d68df598db08dfced8b4707755864a0492Ying Wang  for (size_t i = 0; i < active_animations_.size(); ++i) {
42951a39d68df598db08dfced8b4707755864a0492Ying Wang    if (active_animations_[i]->id() == animation_id) {
43951a39d68df598db08dfced8b4707755864a0492Ying Wang      active_animations_[i]->SetRunState(
44951a39d68df598db08dfced8b4707755864a0492Ying Wang          Animation::Paused, time_offset + active_animations_[i]->start_time());
45951a39d68df598db08dfced8b4707755864a0492Ying Wang    }
46951a39d68df598db08dfced8b4707755864a0492Ying Wang  }
47951a39d68df598db08dfced8b4707755864a0492Ying Wang}
48951a39d68df598db08dfced8b4707755864a0492Ying Wang
49951a39d68df598db08dfced8b4707755864a0492Ying Wangstruct HasAnimationId {
50951a39d68df598db08dfced8b4707755864a0492Ying Wang  explicit HasAnimationId(int id) : id_(id) {}
51951a39d68df598db08dfced8b4707755864a0492Ying Wang  bool operator()(Animation* animation) const {
52951a39d68df598db08dfced8b4707755864a0492Ying Wang    return animation->id() == id_;
53951a39d68df598db08dfced8b4707755864a0492Ying Wang  }
54951a39d68df598db08dfced8b4707755864a0492Ying Wang
55951a39d68df598db08dfced8b4707755864a0492Ying Wang private:
56951a39d68df598db08dfced8b4707755864a0492Ying Wang  int id_;
57951a39d68df598db08dfced8b4707755864a0492Ying Wang};
58951a39d68df598db08dfced8b4707755864a0492Ying Wang
59951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::RemoveAnimation(int animation_id) {
60951a39d68df598db08dfced8b4707755864a0492Ying Wang  ScopedPtrVector<Animation>& animations = active_animations_;
61951a39d68df598db08dfced8b4707755864a0492Ying Wang  animations.erase(cc::remove_if(&animations,
62951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 animations.begin(),
63951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 animations.end(),
64951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 HasAnimationId(animation_id)),
65951a39d68df598db08dfced8b4707755864a0492Ying Wang                   animations.end());
66951a39d68df598db08dfced8b4707755864a0492Ying Wang  UpdateActivation(NormalActivation);
67951a39d68df598db08dfced8b4707755864a0492Ying Wang}
68951a39d68df598db08dfced8b4707755864a0492Ying Wang
69951a39d68df598db08dfced8b4707755864a0492Ying Wangstruct HasAnimationIdAndProperty {
70951a39d68df598db08dfced8b4707755864a0492Ying Wang  HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
71951a39d68df598db08dfced8b4707755864a0492Ying Wang      : id_(id), target_property_(target_property) {}
72951a39d68df598db08dfced8b4707755864a0492Ying Wang  bool operator()(Animation* animation) const {
73951a39d68df598db08dfced8b4707755864a0492Ying Wang    return animation->id() == id_ &&
74951a39d68df598db08dfced8b4707755864a0492Ying Wang        animation->target_property() == target_property_;
75951a39d68df598db08dfced8b4707755864a0492Ying Wang  }
76951a39d68df598db08dfced8b4707755864a0492Ying Wang
77951a39d68df598db08dfced8b4707755864a0492Ying Wang private:
78951a39d68df598db08dfced8b4707755864a0492Ying Wang  int id_;
79951a39d68df598db08dfced8b4707755864a0492Ying Wang  Animation::TargetProperty target_property_;
80951a39d68df598db08dfced8b4707755864a0492Ying Wang};
81951a39d68df598db08dfced8b4707755864a0492Ying Wang
82951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::RemoveAnimation(
83951a39d68df598db08dfced8b4707755864a0492Ying Wang    int animation_id,
84951a39d68df598db08dfced8b4707755864a0492Ying Wang    Animation::TargetProperty target_property) {
85951a39d68df598db08dfced8b4707755864a0492Ying Wang  ScopedPtrVector<Animation>& animations = active_animations_;
86951a39d68df598db08dfced8b4707755864a0492Ying Wang  animations.erase(cc::remove_if(&animations,
87951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 animations.begin(),
88951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 animations.end(),
89951a39d68df598db08dfced8b4707755864a0492Ying Wang                                 HasAnimationIdAndProperty(animation_id,
90951a39d68df598db08dfced8b4707755864a0492Ying Wang                                                           target_property)),
91951a39d68df598db08dfced8b4707755864a0492Ying Wang                   animations.end());
92951a39d68df598db08dfced8b4707755864a0492Ying Wang  UpdateActivation(NormalActivation);
93951a39d68df598db08dfced8b4707755864a0492Ying Wang}
94951a39d68df598db08dfced8b4707755864a0492Ying Wang
95951a39d68df598db08dfced8b4707755864a0492Ying Wang// Ensures that the list of active animations on the main thread and the impl
96951a39d68df598db08dfced8b4707755864a0492Ying Wang// thread are kept in sync.
97951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::PushAnimationUpdatesTo(
98951a39d68df598db08dfced8b4707755864a0492Ying Wang    LayerAnimationController* controller_impl) {
99951a39d68df598db08dfced8b4707755864a0492Ying Wang  DCHECK(this != controller_impl);
100951a39d68df598db08dfced8b4707755864a0492Ying Wang  if (force_sync_) {
101951a39d68df598db08dfced8b4707755864a0492Ying Wang    ReplaceImplThreadAnimations(controller_impl);
102951a39d68df598db08dfced8b4707755864a0492Ying Wang    force_sync_ = false;
103951a39d68df598db08dfced8b4707755864a0492Ying Wang  } else {
104951a39d68df598db08dfced8b4707755864a0492Ying Wang    PurgeAnimationsMarkedForDeletion();
105951a39d68df598db08dfced8b4707755864a0492Ying Wang    PushNewAnimationsToImplThread(controller_impl);
106951a39d68df598db08dfced8b4707755864a0492Ying Wang
107951a39d68df598db08dfced8b4707755864a0492Ying Wang    // Remove finished impl side animations only after pushing,
108951a39d68df598db08dfced8b4707755864a0492Ying Wang    // and only after the animations are deleted on the main thread
109951a39d68df598db08dfced8b4707755864a0492Ying Wang    // this insures we will never push an animation twice.
110951a39d68df598db08dfced8b4707755864a0492Ying Wang    RemoveAnimationsCompletedOnMainThread(controller_impl);
111951a39d68df598db08dfced8b4707755864a0492Ying Wang
112951a39d68df598db08dfced8b4707755864a0492Ying Wang    PushPropertiesToImplThread(controller_impl);
113951a39d68df598db08dfced8b4707755864a0492Ying Wang  }
114951a39d68df598db08dfced8b4707755864a0492Ying Wang  controller_impl->UpdateActivation(NormalActivation);
115951a39d68df598db08dfced8b4707755864a0492Ying Wang  UpdateActivation(NormalActivation);
116951a39d68df598db08dfced8b4707755864a0492Ying Wang}
117951a39d68df598db08dfced8b4707755864a0492Ying Wang
118951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::Animate(double monotonic_time) {
119951a39d68df598db08dfced8b4707755864a0492Ying Wang  if (!HasValueObserver())
120951a39d68df598db08dfced8b4707755864a0492Ying Wang    return;
121951a39d68df598db08dfced8b4707755864a0492Ying Wang
122951a39d68df598db08dfced8b4707755864a0492Ying Wang  StartAnimationsWaitingForNextTick(monotonic_time);
123951a39d68df598db08dfced8b4707755864a0492Ying Wang  StartAnimationsWaitingForStartTime(monotonic_time);
124951a39d68df598db08dfced8b4707755864a0492Ying Wang  StartAnimationsWaitingForTargetAvailability(monotonic_time);
125951a39d68df598db08dfced8b4707755864a0492Ying Wang  ResolveConflicts(monotonic_time);
126951a39d68df598db08dfced8b4707755864a0492Ying Wang  TickAnimations(monotonic_time);
127951a39d68df598db08dfced8b4707755864a0492Ying Wang  last_tick_time_ = monotonic_time;
128951a39d68df598db08dfced8b4707755864a0492Ying Wang}
129951a39d68df598db08dfced8b4707755864a0492Ying Wang
130951a39d68df598db08dfced8b4707755864a0492Ying Wangvoid LayerAnimationController::AccumulatePropertyUpdates(
131951a39d68df598db08dfced8b4707755864a0492Ying Wang    double monotonic_time,
132951a39d68df598db08dfced8b4707755864a0492Ying Wang    AnimationEventsVector* events) {
133951a39d68df598db08dfced8b4707755864a0492Ying Wang  if (!events)
134951a39d68df598db08dfced8b4707755864a0492Ying Wang    return;
135951a39d68df598db08dfced8b4707755864a0492Ying Wang
136951a39d68df598db08dfced8b4707755864a0492Ying Wang  for (size_t i = 0; i < active_animations_.size(); ++i) {
137951a39d68df598db08dfced8b4707755864a0492Ying Wang    Animation* animation = active_animations_[i];
138951a39d68df598db08dfced8b4707755864a0492Ying Wang    if (!animation->is_impl_only())
139951a39d68df598db08dfced8b4707755864a0492Ying Wang      continue;
140951a39d68df598db08dfced8b4707755864a0492Ying Wang
141951a39d68df598db08dfced8b4707755864a0492Ying Wang    switch (animation->target_property()) {
142951a39d68df598db08dfced8b4707755864a0492Ying Wang      case Animation::Opacity: {
143951a39d68df598db08dfced8b4707755864a0492Ying Wang        AnimationEvent event(AnimationEvent::PropertyUpdate,
144951a39d68df598db08dfced8b4707755864a0492Ying Wang                             id_,
145951a39d68df598db08dfced8b4707755864a0492Ying Wang                             animation->group(),
146951a39d68df598db08dfced8b4707755864a0492Ying Wang                             Animation::Opacity,
147951a39d68df598db08dfced8b4707755864a0492Ying Wang                             monotonic_time);
148951a39d68df598db08dfced8b4707755864a0492Ying Wang        event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
149951a39d68df598db08dfced8b4707755864a0492Ying Wang            monotonic_time);
150951a39d68df598db08dfced8b4707755864a0492Ying Wang        event.is_impl_only = true;
151951a39d68df598db08dfced8b4707755864a0492Ying Wang        events->push_back(event);
152951a39d68df598db08dfced8b4707755864a0492Ying Wang        break;
153951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
154951a39d68df598db08dfced8b4707755864a0492Ying Wang
155951a39d68df598db08dfced8b4707755864a0492Ying Wang      case Animation::Transform: {
156951a39d68df598db08dfced8b4707755864a0492Ying Wang        AnimationEvent event(AnimationEvent::PropertyUpdate,
157951a39d68df598db08dfced8b4707755864a0492Ying Wang                             id_,
158951a39d68df598db08dfced8b4707755864a0492Ying Wang                             animation->group(),
159951a39d68df598db08dfced8b4707755864a0492Ying Wang                             Animation::Transform,
160951a39d68df598db08dfced8b4707755864a0492Ying Wang                             monotonic_time);
161951a39d68df598db08dfced8b4707755864a0492Ying Wang        event.transform =
162951a39d68df598db08dfced8b4707755864a0492Ying Wang            animation->curve()->ToTransformAnimationCurve()->GetValue(
163951a39d68df598db08dfced8b4707755864a0492Ying Wang                monotonic_time);
164951a39d68df598db08dfced8b4707755864a0492Ying Wang        event.is_impl_only = true;
165951a39d68df598db08dfced8b4707755864a0492Ying Wang        events->push_back(event);
166951a39d68df598db08dfced8b4707755864a0492Ying Wang        break;
167951a39d68df598db08dfced8b4707755864a0492Ying Wang      }
168951a39d68df598db08dfced8b4707755864a0492Ying Wang
169951a39d68df598db08dfced8b4707755864a0492Ying Wang      case Animation::Filter: {
170951a39d68df598db08dfced8b4707755864a0492Ying Wang        AnimationEvent event(AnimationEvent::PropertyUpdate,
171951a39d68df598db08dfced8b4707755864a0492Ying Wang                             id_,
172951a39d68df598db08dfced8b4707755864a0492Ying Wang                             animation->group(),
173                             Animation::Filter,
174                             monotonic_time);
175        event.filters = animation->curve()->ToFilterAnimationCurve()->GetValue(
176            monotonic_time);
177        event.is_impl_only = true;
178        events->push_back(event);
179        break;
180      }
181
182      case Animation::BackgroundColor: { break; }
183
184      case Animation::TargetPropertyEnumSize:
185        NOTREACHED();
186    }
187  }
188}
189
190void LayerAnimationController::UpdateState(bool start_ready_animations,
191                                           AnimationEventsVector* events) {
192  if (!HasActiveValueObserver())
193    return;
194
195  if (start_ready_animations)
196    PromoteStartedAnimations(last_tick_time_, events);
197
198  MarkFinishedAnimations(last_tick_time_);
199  MarkAnimationsForDeletion(last_tick_time_, events);
200
201  if (start_ready_animations) {
202    StartAnimationsWaitingForTargetAvailability(last_tick_time_);
203    PromoteStartedAnimations(last_tick_time_, events);
204  }
205
206  AccumulatePropertyUpdates(last_tick_time_, events);
207
208  UpdateActivation(NormalActivation);
209}
210
211void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
212  active_animations_.push_back(animation.Pass());
213  UpdateActivation(NormalActivation);
214}
215
216Animation* LayerAnimationController::GetAnimation(
217    int group_id,
218    Animation::TargetProperty target_property) const {
219  for (size_t i = 0; i < active_animations_.size(); ++i)
220    if (active_animations_[i]->group() == group_id &&
221        active_animations_[i]->target_property() == target_property)
222      return active_animations_[i];
223  return 0;
224}
225
226Animation* LayerAnimationController::GetAnimation(
227    Animation::TargetProperty target_property) const {
228  for (size_t i = 0; i < active_animations_.size(); ++i) {
229    size_t index = active_animations_.size() - i - 1;
230    if (active_animations_[index]->target_property() == target_property)
231      return active_animations_[index];
232  }
233  return 0;
234}
235
236bool LayerAnimationController::HasActiveAnimation() const {
237  for (size_t i = 0; i < active_animations_.size(); ++i) {
238    if (!active_animations_[i]->is_finished())
239      return true;
240  }
241  return false;
242}
243
244bool LayerAnimationController::IsAnimatingProperty(
245    Animation::TargetProperty target_property) const {
246  for (size_t i = 0; i < active_animations_.size(); ++i) {
247    if (!active_animations_[i]->is_finished() &&
248        active_animations_[i]->target_property() == target_property)
249      return true;
250  }
251  return false;
252}
253
254void LayerAnimationController::SetAnimationRegistrar(
255    AnimationRegistrar* registrar) {
256  if (registrar_ == registrar)
257    return;
258
259  if (registrar_)
260    registrar_->UnregisterAnimationController(this);
261
262  registrar_ = registrar;
263  if (registrar_)
264    registrar_->RegisterAnimationController(this);
265
266  UpdateActivation(ForceActivation);
267}
268
269void LayerAnimationController::NotifyAnimationStarted(
270    const AnimationEvent& event,
271    double wall_clock_time) {
272  if (event.is_impl_only) {
273    FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
274                      OnAnimationStarted(event));
275    if (layer_animation_delegate_)
276      layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time);
277
278    return;
279  }
280
281  for (size_t i = 0; i < active_animations_.size(); ++i) {
282    if (active_animations_[i]->group() == event.group_id &&
283        active_animations_[i]->target_property() == event.target_property &&
284        active_animations_[i]->needs_synchronized_start_time()) {
285      active_animations_[i]->set_needs_synchronized_start_time(false);
286      active_animations_[i]->set_start_time(event.monotonic_time);
287
288      FOR_EACH_OBSERVER(LayerAnimationEventObserver, event_observers_,
289                        OnAnimationStarted(event));
290      if (layer_animation_delegate_)
291        layer_animation_delegate_->NotifyAnimationStarted(wall_clock_time);
292
293      return;
294    }
295  }
296}
297
298void LayerAnimationController::NotifyAnimationFinished(
299    const AnimationEvent& event,
300    double wall_clock_time) {
301  if (event.is_impl_only) {
302    if (layer_animation_delegate_)
303      layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time);
304    return;
305  }
306
307  for (size_t i = 0; i < active_animations_.size(); ++i) {
308    if (active_animations_[i]->group() == event.group_id &&
309        active_animations_[i]->target_property() == event.target_property) {
310      active_animations_[i]->set_received_finished_event(true);
311      if (layer_animation_delegate_)
312        layer_animation_delegate_->NotifyAnimationFinished(wall_clock_time);
313
314      return;
315    }
316  }
317}
318
319void LayerAnimationController::NotifyAnimationPropertyUpdate(
320    const AnimationEvent& event) {
321  switch (event.target_property) {
322    case Animation::Opacity:
323      NotifyObserversOpacityAnimated(event.opacity);
324      break;
325    case Animation::Transform:
326      NotifyObserversTransformAnimated(event.transform);
327      break;
328    default:
329      NOTREACHED();
330  }
331}
332
333void LayerAnimationController::AddValueObserver(
334    LayerAnimationValueObserver* observer) {
335  if (!value_observers_.HasObserver(observer))
336    value_observers_.AddObserver(observer);
337}
338
339void LayerAnimationController::RemoveValueObserver(
340    LayerAnimationValueObserver* observer) {
341  value_observers_.RemoveObserver(observer);
342}
343
344void LayerAnimationController::AddEventObserver(
345    LayerAnimationEventObserver* observer) {
346  if (!event_observers_.HasObserver(observer))
347    event_observers_.AddObserver(observer);
348}
349
350void LayerAnimationController::RemoveEventObserver(
351    LayerAnimationEventObserver* observer) {
352  event_observers_.RemoveObserver(observer);
353}
354
355bool LayerAnimationController::AnimatedBoundsForBox(const gfx::BoxF& box,
356                                                    gfx::BoxF* bounds) {
357  // Compute bounds based on animations for which is_finished() is false.
358  // Do nothing if there are no such animations; in this case, it is assumed
359  // that callers will take care of computing bounds based on the owning layer's
360  // actual transform.
361  *bounds = gfx::BoxF();
362  for (size_t i = 0; i < active_animations_.size(); ++i) {
363    if (active_animations_[i]->is_finished() ||
364        active_animations_[i]->target_property() != Animation::Transform)
365      continue;
366
367    const TransformAnimationCurve* transform_animation_curve =
368        active_animations_[i]->curve()->ToTransformAnimationCurve();
369    gfx::BoxF animation_bounds;
370    bool success =
371        transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds);
372    if (!success)
373      return false;
374    bounds->Union(animation_bounds);
375  }
376
377  return true;
378}
379
380void LayerAnimationController::PushNewAnimationsToImplThread(
381    LayerAnimationController* controller_impl) const {
382  // Any new animations owned by the main thread's controller are cloned and
383  // add to the impl thread's controller.
384  for (size_t i = 0; i < active_animations_.size(); ++i) {
385    // If the animation is already running on the impl thread, there is no
386    // need to copy it over.
387    if (controller_impl->GetAnimation(active_animations_[i]->group(),
388                                      active_animations_[i]->target_property()))
389      continue;
390
391    // If the animation is not running on the impl thread, it does not
392    // necessarily mean that it needs to be copied over and started; it may
393    // have already finished. In this case, the impl thread animation will
394    // have already notified that it has started and the main thread animation
395    // will no longer need
396    // a synchronized start time.
397    if (!active_animations_[i]->needs_synchronized_start_time())
398      continue;
399
400    // The new animation should be set to run as soon as possible.
401    Animation::RunState initial_run_state =
402        Animation::WaitingForTargetAvailability;
403    double start_time = 0;
404    scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize(
405        initial_run_state, start_time));
406    DCHECK(!to_add->needs_synchronized_start_time());
407    controller_impl->AddAnimation(to_add.Pass());
408  }
409}
410
411struct IsCompleted {
412  explicit IsCompleted(const LayerAnimationController& main_thread_controller)
413      : main_thread_controller_(main_thread_controller) {}
414  bool operator()(Animation* animation) const {
415    if (animation->is_impl_only()) {
416      return (animation->run_state() == Animation::WaitingForDeletion);
417    } else {
418      return !main_thread_controller_.GetAnimation(
419          animation->group(),
420          animation->target_property());
421    }
422  }
423
424 private:
425  const LayerAnimationController& main_thread_controller_;
426};
427
428void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
429    LayerAnimationController* controller_impl) const {
430  // Delete all impl thread animations for which there is no corresponding
431  // main thread animation. Each iteration,
432  // controller->active_animations_.size() is decremented or i is incremented
433  // guaranteeing progress towards loop termination.
434  ScopedPtrVector<Animation>& animations =
435      controller_impl->active_animations_;
436  animations.erase(cc::remove_if(&animations,
437                                 animations.begin(),
438                                 animations.end(),
439                                 IsCompleted(*this)),
440                   animations.end());
441}
442
443void LayerAnimationController::PushPropertiesToImplThread(
444    LayerAnimationController* controller_impl) const {
445  for (size_t i = 0; i < active_animations_.size(); ++i) {
446    Animation* current_impl =
447        controller_impl->GetAnimation(
448            active_animations_[i]->group(),
449            active_animations_[i]->target_property());
450    if (current_impl)
451      active_animations_[i]->PushPropertiesTo(current_impl);
452  }
453}
454
455void LayerAnimationController::StartAnimationsWaitingForNextTick(
456    double monotonic_time) {
457  for (size_t i = 0; i < active_animations_.size(); ++i) {
458    if (active_animations_[i]->run_state() == Animation::WaitingForNextTick)
459      active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
460  }
461}
462
463void LayerAnimationController::StartAnimationsWaitingForStartTime(
464    double monotonic_time) {
465  for (size_t i = 0; i < active_animations_.size(); ++i) {
466    if (active_animations_[i]->run_state() == Animation::WaitingForStartTime &&
467        active_animations_[i]->start_time() <= monotonic_time)
468      active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
469  }
470}
471
472void LayerAnimationController::StartAnimationsWaitingForTargetAvailability(
473    double monotonic_time) {
474  // First collect running properties.
475  TargetProperties blocked_properties;
476  for (size_t i = 0; i < active_animations_.size(); ++i) {
477    if (active_animations_[i]->run_state() == Animation::Starting ||
478        active_animations_[i]->run_state() == Animation::Running)
479      blocked_properties.insert(active_animations_[i]->target_property());
480  }
481
482  for (size_t i = 0; i < active_animations_.size(); ++i) {
483    if (active_animations_[i]->run_state() ==
484        Animation::WaitingForTargetAvailability) {
485      // Collect all properties for animations with the same group id (they
486      // should all also be in the list of animations).
487      TargetProperties enqueued_properties;
488      enqueued_properties.insert(active_animations_[i]->target_property());
489      for (size_t j = i + 1; j < active_animations_.size(); ++j) {
490        if (active_animations_[i]->group() == active_animations_[j]->group())
491          enqueued_properties.insert(active_animations_[j]->target_property());
492      }
493
494      // Check to see if intersection of the list of properties affected by
495      // the group and the list of currently blocked properties is null. In
496      // any case, the group's target properties need to be added to the list
497      // of blocked properties.
498      bool null_intersection = true;
499      for (TargetProperties::iterator p_iter = enqueued_properties.begin();
500           p_iter != enqueued_properties.end();
501           ++p_iter) {
502        if (!blocked_properties.insert(*p_iter).second)
503          null_intersection = false;
504      }
505
506      // If the intersection is null, then we are free to start the animations
507      // in the group.
508      if (null_intersection) {
509        active_animations_[i]->SetRunState(
510            Animation::Starting, monotonic_time);
511        for (size_t j = i + 1; j < active_animations_.size(); ++j) {
512          if (active_animations_[i]->group() ==
513              active_animations_[j]->group()) {
514            active_animations_[j]->SetRunState(
515                Animation::Starting, monotonic_time);
516          }
517        }
518      }
519    }
520  }
521}
522
523void LayerAnimationController::PromoteStartedAnimations(
524    double monotonic_time,
525    AnimationEventsVector* events) {
526  for (size_t i = 0; i < active_animations_.size(); ++i) {
527    if (active_animations_[i]->run_state() == Animation::Starting) {
528      active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
529      if (!active_animations_[i]->has_set_start_time())
530        active_animations_[i]->set_start_time(monotonic_time);
531      if (events) {
532        AnimationEvent started_event(
533            AnimationEvent::Started,
534            id_,
535            active_animations_[i]->group(),
536            active_animations_[i]->target_property(),
537            monotonic_time);
538        started_event.is_impl_only = active_animations_[i]->is_impl_only();
539        events->push_back(started_event);
540      }
541    }
542  }
543}
544
545void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) {
546  for (size_t i = 0; i < active_animations_.size(); ++i) {
547    if (active_animations_[i]->IsFinishedAt(monotonic_time) &&
548        active_animations_[i]->run_state() != Animation::WaitingForDeletion)
549      active_animations_[i]->SetRunState(Animation::Finished, monotonic_time);
550  }
551}
552
553void LayerAnimationController::ResolveConflicts(double monotonic_time) {
554  // Find any animations that are animating the same property and resolve the
555  // confict. We could eventually blend, but for now we'll just abort the
556  // previous animation (where 'previous' means: (1) has a prior start time or
557  // (2) has an equal start time, but was added to the queue earlier, i.e.,
558  // has a lower index in active_animations_).
559  for (size_t i = 0; i < active_animations_.size(); ++i) {
560    if (active_animations_[i]->run_state() == Animation::Starting ||
561        active_animations_[i]->run_state() == Animation::Running) {
562      for (size_t j = i + 1; j < active_animations_.size(); ++j) {
563        if ((active_animations_[j]->run_state() == Animation::Starting ||
564             active_animations_[j]->run_state() == Animation::Running) &&
565            active_animations_[i]->target_property() ==
566            active_animations_[j]->target_property()) {
567          if (active_animations_[i]->start_time() >
568              active_animations_[j]->start_time()) {
569            active_animations_[j]->SetRunState(Animation::Aborted,
570                                               monotonic_time);
571          } else {
572            active_animations_[i]->SetRunState(Animation::Aborted,
573                                               monotonic_time);
574          }
575        }
576      }
577    }
578  }
579}
580
581void LayerAnimationController::MarkAnimationsForDeletion(
582    double monotonic_time, AnimationEventsVector* events) {
583  // Non-aborted animations are marked for deletion after a corresponding
584  // AnimationEvent::Finished event is sent or received. This means that if
585  // we don't have an events vector, we must ensure that non-aborted animations
586  // have received a finished event before marking them for deletion.
587  for (size_t i = 0; i < active_animations_.size(); i++) {
588    int group_id = active_animations_[i]->group();
589    bool all_anims_with_same_id_are_finished = false;
590
591    // Since deleting an animation on the main thread leads to its deletion
592    // on the impl thread, we only mark a Finished main thread animation for
593    // deletion once it has received a Finished event from the impl thread.
594    bool animation_i_will_send_or_has_received_finish_event =
595        events || active_animations_[i]->received_finished_event();
596    // If an animation is finished, and not already marked for deletion,
597    // find out if all other animations in the same group are also finished.
598    if (active_animations_[i]->run_state() == Animation::Aborted ||
599        (active_animations_[i]->run_state() == Animation::Finished &&
600         animation_i_will_send_or_has_received_finish_event)) {
601      all_anims_with_same_id_are_finished = true;
602      for (size_t j = 0; j < active_animations_.size(); ++j) {
603        bool animation_j_will_send_or_has_received_finish_event =
604            events || active_animations_[j]->received_finished_event();
605        if (group_id == active_animations_[j]->group() &&
606            (!active_animations_[j]->is_finished() ||
607             (active_animations_[j]->run_state() == Animation::Finished &&
608              !animation_j_will_send_or_has_received_finish_event))) {
609          all_anims_with_same_id_are_finished = false;
610          break;
611        }
612      }
613    }
614    if (all_anims_with_same_id_are_finished) {
615      // We now need to remove all animations with the same group id as
616      // group_id (and send along animation finished notifications, if
617      // necessary).
618      for (size_t j = i; j < active_animations_.size(); j++) {
619        if (group_id == active_animations_[j]->group()) {
620          if (events) {
621            AnimationEvent finished_event(
622                AnimationEvent::Finished,
623                id_,
624                active_animations_[j]->group(),
625                active_animations_[j]->target_property(),
626                monotonic_time);
627            finished_event.is_impl_only = active_animations_[j]->is_impl_only();
628            events->push_back(finished_event);
629          }
630          active_animations_[j]->SetRunState(Animation::WaitingForDeletion,
631                                             monotonic_time);
632        }
633      }
634    }
635  }
636}
637
638static bool IsWaitingForDeletion(Animation* animation) {
639  return animation->run_state() == Animation::WaitingForDeletion;
640}
641
642void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
643  ScopedPtrVector<Animation>& animations = active_animations_;
644  animations.erase(cc::remove_if(&animations,
645                                 animations.begin(),
646                                 animations.end(),
647                                 IsWaitingForDeletion),
648                   animations.end());
649}
650
651void LayerAnimationController::ReplaceImplThreadAnimations(
652    LayerAnimationController* controller_impl) const {
653  controller_impl->active_animations_.clear();
654  for (size_t i = 0; i < active_animations_.size(); ++i) {
655    scoped_ptr<Animation> to_add;
656    if (active_animations_[i]->needs_synchronized_start_time()) {
657      // We haven't received an animation started notification yet, so it
658      // is important that we add it in a 'waiting' and not 'running' state.
659      Animation::RunState initial_run_state =
660          Animation::WaitingForTargetAvailability;
661      double start_time = 0;
662      to_add = active_animations_[i]->CloneAndInitialize(
663          initial_run_state, start_time).Pass();
664    } else {
665      to_add = active_animations_[i]->Clone().Pass();
666    }
667
668    controller_impl->AddAnimation(to_add.Pass());
669  }
670}
671
672void LayerAnimationController::TickAnimations(double monotonic_time) {
673  for (size_t i = 0; i < active_animations_.size(); ++i) {
674    if (active_animations_[i]->run_state() == Animation::Starting ||
675        active_animations_[i]->run_state() == Animation::Running ||
676        active_animations_[i]->run_state() == Animation::Paused) {
677      double trimmed =
678          active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
679
680      switch (active_animations_[i]->target_property()) {
681        case Animation::Transform: {
682          const TransformAnimationCurve* transform_animation_curve =
683              active_animations_[i]->curve()->ToTransformAnimationCurve();
684          const gfx::Transform transform =
685              transform_animation_curve->GetValue(trimmed);
686          NotifyObserversTransformAnimated(transform);
687          break;
688        }
689
690        case Animation::Opacity: {
691          const FloatAnimationCurve* float_animation_curve =
692              active_animations_[i]->curve()->ToFloatAnimationCurve();
693          const float opacity = float_animation_curve->GetValue(trimmed);
694          NotifyObserversOpacityAnimated(opacity);
695          break;
696        }
697
698        case Animation::Filter: {
699          const FilterAnimationCurve* filter_animation_curve =
700              active_animations_[i]->curve()->ToFilterAnimationCurve();
701          const FilterOperations filter =
702              filter_animation_curve->GetValue(trimmed);
703          NotifyObserversFilterAnimated(filter);
704          break;
705        }
706
707        case Animation::BackgroundColor: {
708          // Not yet implemented.
709          break;
710        }
711
712        // Do nothing for sentinel value.
713        case Animation::TargetPropertyEnumSize:
714          NOTREACHED();
715      }
716    }
717  }
718}
719
720void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
721  bool force = type == ForceActivation;
722  if (registrar_) {
723    if (!active_animations_.empty() && (!is_active_ || force))
724      registrar_->DidActivateAnimationController(this);
725    else if (active_animations_.empty() && (is_active_ || force))
726      registrar_->DidDeactivateAnimationController(this);
727    is_active_ = !active_animations_.empty();
728  }
729}
730
731void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) {
732  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
733                    value_observers_,
734                    OnOpacityAnimated(opacity));
735}
736
737void LayerAnimationController::NotifyObserversTransformAnimated(
738    const gfx::Transform& transform) {
739  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
740                    value_observers_,
741                    OnTransformAnimated(transform));
742}
743
744void LayerAnimationController::NotifyObserversFilterAnimated(
745    const FilterOperations& filters) {
746  FOR_EACH_OBSERVER(LayerAnimationValueObserver,
747                    value_observers_,
748                    OnFilterAnimated(filters));
749}
750
751bool LayerAnimationController::HasValueObserver() {
752  if (value_observers_.might_have_observers()) {
753    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
754        value_observers_);
755    return it.GetNext() != NULL;
756  }
757  return false;
758}
759
760bool LayerAnimationController::HasActiveValueObserver() {
761  if (value_observers_.might_have_observers()) {
762    ObserverListBase<LayerAnimationValueObserver>::Iterator it(
763        value_observers_);
764    LayerAnimationValueObserver* obs;
765    while ((obs = it.GetNext()) != NULL)
766      if (obs->IsActive())
767        return true;
768  }
769  return false;
770}
771
772}  // namespace cc
773