Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(994)

Side by Side Diff: cc/layer_animation_controller.cc

Issue 12517003: cc: Chromify the Animation and LayerAnimationController classes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/layer_animation_controller.h" 5 #include "cc/layer_animation_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "cc/animation.h" 9 #include "cc/animation.h"
10 #include "cc/animation_registrar.h" 10 #include "cc/animation_registrar.h"
11 #include "cc/keyframed_animation_curve.h" 11 #include "cc/keyframed_animation_curve.h"
12 #include "cc/layer_animation_value_observer.h" 12 #include "cc/layer_animation_value_observer.h"
13 #include "cc/scoped_ptr_algorithm.h" 13 #include "cc/scoped_ptr_algorithm.h"
14 #include "ui/gfx/transform.h" 14 #include "ui/gfx/transform.h"
15 15
16 namespace cc { 16 namespace cc { LayerAnimationController::LayerAnimationController(int id)
jamesr 2013/03/09 02:44:56 this one's on the same line too
danakj 2013/03/09 03:01:11 Done.
17 17 : force_sync_(false),
18 LayerAnimationController::LayerAnimationController(int id) 18 id_(id),
19 : m_forceSync(false) 19 registrar_(0),
20 , m_id(id) 20 is_active_(false),
21 , m_registrar(0) 21 last_tick_time_(0) {}
22 , m_isActive(false) 22
23 , m_lastTickTime(0) 23 LayerAnimationController::~LayerAnimationController() {
24 { 24 if (registrar_)
25 } 25 registrar_->UnregisterAnimationController(this);
26 26 }
27 LayerAnimationController::~LayerAnimationController() 27
28 { 28 scoped_refptr<LayerAnimationController> LayerAnimationController::Create(
29 if (m_registrar) 29 int id) {
30 m_registrar->UnregisterAnimationController(this); 30 return make_scoped_refptr(new LayerAnimationController(id));
31 } 31 }
32 32
33 scoped_refptr<LayerAnimationController> LayerAnimationController::create(int id) 33 void LayerAnimationController::PauseAnimation(int animation_id,
34 { 34 double time_offset) {
35 return make_scoped_refptr(new LayerAnimationController(id)); 35 for (size_t i = 0; i < active_animations_.size(); ++i) {
36 } 36 if (active_animations_[i]->id() == animation_id) {
37 37 active_animations_[i]->SetRunState(
38 void LayerAnimationController::pauseAnimation(int animationId, double timeOffset ) 38 Animation::Paused, time_offset + active_animations_[i]->start_time());
39 { 39 }
40 for (size_t i = 0; i < m_activeAnimations.size(); ++i) { 40 }
41 if (m_activeAnimations[i]->id() == animationId)
42 m_activeAnimations[i]->setRunState(Animation::Paused, timeOffset + m _activeAnimations[i]->startTime());
43 }
44 } 41 }
45 42
46 struct HasAnimationId { 43 struct HasAnimationId {
47 HasAnimationId(int id) : m_id(id) { } 44 HasAnimationId(int id) : id_(id) {}
48 bool operator()(Animation* animation) const { return animation->id() == m_id ; } 45 bool operator()(Animation* animation) const {
49 private: 46 return animation->id() == id_;
50 int m_id; 47 }
48
49 private:
50 int id_;
51 }; 51 };
52 52
53 void LayerAnimationController::removeAnimation(int animationId) 53 void LayerAnimationController::RemoveAnimation(int animation_id) {
54 { 54 ScopedPtrVector<Animation>& animations = active_animations_;
55 ScopedPtrVector<Animation>& animations = m_activeAnimations; 55 animations.erase(cc::remove_if(animations,
56 animations.erase(cc::remove_if(animations, animations.begin(), animations.en d(), HasAnimationId(animationId)), animations.end()); 56 animations.begin(),
57 updateActivation(); 57 animations.end(),
58 HasAnimationId(animation_id)),
59 animations.end());
60 UpdateActivation(NormalActivation);
58 } 61 }
59 62
60 struct HasAnimationIdAndProperty { 63 struct HasAnimationIdAndProperty {
61 HasAnimationIdAndProperty(int id, Animation::TargetProperty targetProperty) : m_id(id), m_targetProperty(targetProperty) { } 64 HasAnimationIdAndProperty(int id, Animation::TargetProperty target_property)
62 bool operator()(Animation* animation) const { return animation->id() == m_id && animation->targetProperty() == m_targetProperty; } 65 : id_(id), target_property_(target_property) {}
63 private: 66 bool operator()(Animation* animation) const {
64 int m_id; 67 return animation->id() == id_ &&
65 Animation::TargetProperty m_targetProperty; 68 animation->target_property() == target_property_;
69 }
70
71 private:
72 int id_;
73 Animation::TargetProperty target_property_;
66 }; 74 };
67 75
68 void LayerAnimationController::removeAnimation(int animationId, Animation::Targe tProperty targetProperty) 76 void LayerAnimationController::RemoveAnimation(
69 { 77 int animation_id,
70 ScopedPtrVector<Animation>& animations = m_activeAnimations; 78 Animation::TargetProperty target_property) {
71 animations.erase(cc::remove_if(animations, animations.begin(), animations.en d(), HasAnimationIdAndProperty(animationId, targetProperty)), animations.end()); 79 ScopedPtrVector<Animation>& animations = active_animations_;
72 updateActivation(); 80 animations.erase(cc::remove_if(animations,
81 animations.begin(),
82 animations.end(),
83 HasAnimationIdAndProperty(animation_id,
84 target_property)),
85 animations.end());
86 UpdateActivation(NormalActivation);
73 } 87 }
74 88
75 // According to render layer backing, these are for testing only. 89 // According to render layer backing, these are for testing only.
76 void LayerAnimationController::suspendAnimations(double monotonicTime) 90 void LayerAnimationController::SuspendAnimations(double monotonic_time) {
77 { 91 for (size_t i = 0; i < active_animations_.size(); ++i) {
78 for (size_t i = 0; i < m_activeAnimations.size(); ++i) { 92 if (!active_animations_[i]->is_finished())
79 if (!m_activeAnimations[i]->isFinished()) 93 active_animations_[i]->SetRunState(Animation::Paused, monotonic_time);
80 m_activeAnimations[i]->setRunState(Animation::Paused, monotonicTime) ; 94 }
81 } 95 }
82 } 96
83 97 // Looking at GraphicsLayerCA, this appears to be the analog to
84 // Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimation s, which is for testing. 98 // suspendAnimations, which is for testing.
85 void LayerAnimationController::resumeAnimations(double monotonicTime) 99 void LayerAnimationController::ResumeAnimations(double monotonic_time) {
86 { 100 for (size_t i = 0; i < active_animations_.size(); ++i) {
87 for (size_t i = 0; i < m_activeAnimations.size(); ++i) { 101 if (active_animations_[i]->run_state() == Animation::Paused)
88 if (m_activeAnimations[i]->runState() == Animation::Paused) 102 active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
89 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime ); 103 }
90 } 104 }
91 } 105
92 106 // Ensures that the list of active animations on the main thread and the impl
93 // Ensures that the list of active animations on the main thread and the impl th read 107 // thread are kept in sync.
94 // are kept in sync. 108 void LayerAnimationController::PushAnimationUpdatesTo(
95 void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) 109 LayerAnimationController* controller_impl) {
96 { 110 if (force_sync_) {
97 if (m_forceSync) { 111 ReplaceImplThreadAnimations(controller_impl);
98 replaceImplThreadAnimations(controllerImpl); 112 force_sync_ = false;
99 m_forceSync = false; 113 } else {
114 PurgeAnimationsMarkedForDeletion();
115 PushNewAnimationsToImplThread(controller_impl);
116
117 // Remove finished impl side animations only after pushing,
118 // and only after the animations are deleted on the main thread
119 // this insures we will never push an animation twice.
120 RemoveAnimationsCompletedOnMainThread(controller_impl);
121
122 PushPropertiesToImplThread(controller_impl);
123 }
124 controller_impl->UpdateActivation(NormalActivation);
125 UpdateActivation(NormalActivation);
126 }
127
128 void LayerAnimationController::Animate(double monotonic_time) {
129 if (!HasActiveObserver())
130 return;
131
132 StartAnimationsWaitingForNextTick(monotonic_time);
133 StartAnimationsWaitingForStartTime(monotonic_time);
134 StartAnimationsWaitingForTargetAvailability(monotonic_time);
135 ResolveConflicts(monotonic_time);
136 TickAnimations(monotonic_time);
137 last_tick_time_ = monotonic_time;
138 }
139
140 void LayerAnimationController::AccumulatePropertyUpdates(
141 double monotonic_time,
142 AnimationEventsVector* events) {
143 if (!events)
144 return;
145
146 for (size_t i = 0; i < active_animations_.size(); ++i) {
147 Animation* animation = active_animations_[i];
148 if (!animation->is_impl_only())
149 continue;
150
151 if (animation->target_property() == Animation::Opacity) {
152 AnimationEvent event(AnimationEvent::PropertyUpdate,
153 id_,
154 animation->group(),
155 Animation::Opacity,
156 monotonic_time);
157 event.opacity = animation->curve()->ToFloatAnimationCurve()->GetValue(
158 monotonic_time);
159
160 events->push_back(event);
161 }
162 else if (animation->target_property() == Animation::Transform) {
163 AnimationEvent event(AnimationEvent::PropertyUpdate,
164 id_,
165 animation->group(),
166 Animation::Transform,
167 monotonic_time);
168 event.transform =
169 animation->curve()->ToTransformAnimationCurve()->GetValue(
170 monotonic_time);
171 events->push_back(event);
172 }
173 }
174 }
175
176 void LayerAnimationController::UpdateState(AnimationEventsVector* events) {
177 if (!HasActiveObserver())
178 return;
179
180 PromoteStartedAnimations(last_tick_time_, events);
181 MarkFinishedAnimations(last_tick_time_);
182 MarkAnimationsForDeletion(last_tick_time_, events);
183 StartAnimationsWaitingForTargetAvailability(last_tick_time_);
184 PromoteStartedAnimations(last_tick_time_, events);
185
186 AccumulatePropertyUpdates(last_tick_time_, events);
187
188 UpdateActivation(NormalActivation);
189 }
190
191 void LayerAnimationController::AddAnimation(scoped_ptr<Animation> animation) {
192 active_animations_.push_back(animation.Pass());
193 UpdateActivation(NormalActivation);
194 }
195
196 Animation* LayerAnimationController::GetAnimation(
197 int group_id,
198 Animation::TargetProperty target_property) const {
199 for (size_t i = 0; i < active_animations_.size(); ++i)
200 if (active_animations_[i]->group() == group_id &&
201 active_animations_[i]->target_property() == target_property)
202 return active_animations_[i];
203 return 0;
204 }
205
206 Animation* LayerAnimationController::GetAnimation(
207 Animation::TargetProperty target_property) const {
208 for (size_t i = 0; i < active_animations_.size(); ++i) {
209 size_t index = active_animations_.size() - i - 1;
210 if (active_animations_[index]->target_property() == target_property)
211 return active_animations_[index];
212 }
213 return 0;
214 }
215
216 bool LayerAnimationController::HasActiveAnimation() const {
217 for (size_t i = 0; i < active_animations_.size(); ++i) {
218 if (!active_animations_[i]->is_finished())
219 return true;
220 }
221 return false;
222 }
223
224 bool LayerAnimationController::IsAnimatingProperty(
225 Animation::TargetProperty target_property) const {
226 for (size_t i = 0; i < active_animations_.size(); ++i) {
227 if (active_animations_[i]->run_state() != Animation::Finished &&
228 active_animations_[i]->run_state() != Animation::Aborted &&
229 active_animations_[i]->target_property() == target_property)
230 return true;
231 }
232 return false;
233 }
234
235 void LayerAnimationController::OnAnimationStarted(
236 const AnimationEvent& event) {
237 for (size_t i = 0; i < active_animations_.size(); ++i) {
238 if (active_animations_[i]->group() == event.group_id &&
239 active_animations_[i]->target_property() == event.target_property &&
240 active_animations_[i]->needs_synchronized_start_time()) {
241 active_animations_[i]->set_needs_synchronized_start_time(false);
242 active_animations_[i]->set_start_time(event.monotonic_time);
243 return;
244 }
245 }
246 }
247
248 void LayerAnimationController::SetAnimationRegistrar(
249 AnimationRegistrar* registrar) {
250 if (registrar_ == registrar)
251 return;
252
253 if (registrar_)
254 registrar_->UnregisterAnimationController(this);
255
256 registrar_ = registrar;
257 if (registrar_)
258 registrar_->RegisterAnimationController(this);
259
260 bool force = true;
261 UpdateActivation(ForceActivation);
262 }
263
264 void LayerAnimationController::AddObserver(
265 LayerAnimationValueObserver* observer) {
266 if (!observers_.HasObserver(observer))
267 observers_.AddObserver(observer);
268 }
269
270 void LayerAnimationController::RemoveObserver(
271 LayerAnimationValueObserver* observer) {
272 observers_.RemoveObserver(observer);
273 }
274
275 void LayerAnimationController::PushNewAnimationsToImplThread(
276 LayerAnimationController* controller_impl) const {
277 // Any new animations owned by the main thread's controller are cloned and
278 // add to the impl thread's controller.
279 for (size_t i = 0; i < active_animations_.size(); ++i) {
280 // If the animation is already running on the impl thread, there is no
281 // need to copy it over.
282 if (controller_impl->GetAnimation(active_animations_[i]->group(),
283 active_animations_[i]->target_property()))
284 continue;
285
286 // If the animation is not running on the impl thread, it does not
287 // necessarily mean that it needs to be copied over and started; it may
288 // have already finished. In this case, the impl thread animation will
289 // have already notified that it has started and the main thread animation
290 // will no longer need
291 // a synchronized start time.
292 if (!active_animations_[i]->needs_synchronized_start_time())
293 continue;
294
295 // The new animation should be set to run as soon as possible.
296 Animation::RunState initial_run_state =
297 Animation::WaitingForTargetAvailability;
298 double start_time = 0;
299 scoped_ptr<Animation> to_add(active_animations_[i]->CloneAndInitialize(
300 Animation::ControllingInstance, initial_run_state, start_time));
301 DCHECK(!to_add->needs_synchronized_start_time());
302 controller_impl->AddAnimation(to_add.Pass());
303 }
304 }
305
306 struct IsCompleted {
307 IsCompleted(const LayerAnimationController& main_thread_controller)
308 : main_thread_controller_(main_thread_controller) {}
309 bool operator()(Animation* animation) const {
310 if (animation->is_impl_only())
311 return false;
312 return !main_thread_controller_.GetAnimation(animation->group(),
313 animation->target_property());
314 }
315
316 private:
317 const LayerAnimationController& main_thread_controller_;
318 };
319
320 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread(
321 LayerAnimationController* controller_impl) const {
322 // Delete all impl thread animations for which there is no corresponding
323 // main thread animation. Each iteration,
324 // controller->active_animations_.size() is decremented or i is incremented
325 // guaranteeing progress towards loop termination.
326 ScopedPtrVector<Animation>& animations =
327 controller_impl->active_animations_;
328 animations.erase(cc::remove_if(animations,
329 animations.begin(),
330 animations.end(),
331 IsCompleted(*this)),
332 animations.end());
333 }
334
335 void LayerAnimationController::PushPropertiesToImplThread(
336 LayerAnimationController* controller_impl) const {
337 for (size_t i = 0; i < active_animations_.size(); ++i) {
338 Animation* current_impl =
339 controller_impl->GetAnimation(
340 active_animations_[i]->group(),
341 active_animations_[i]->target_property());
342 if (current_impl)
343 active_animations_[i]->PushPropertiesTo(current_impl);
344 }
345 }
346
347 void LayerAnimationController::StartAnimationsWaitingForNextTick(
348 double monotonic_time) {
349 for (size_t i = 0; i < active_animations_.size(); ++i) {
350 if (active_animations_[i]->run_state() == Animation::WaitingForNextTick)
351 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
352 }
353 }
354
355 void LayerAnimationController::StartAnimationsWaitingForStartTime(
356 double monotonic_time) {
357 for (size_t i = 0; i < active_animations_.size(); ++i) {
358 if (active_animations_[i]->run_state() == Animation::WaitingForStartTime &&
359 active_animations_[i]->start_time() <= monotonic_time)
360 active_animations_[i]->SetRunState(Animation::Starting, monotonic_time);
361 }
362 }
363
364 void LayerAnimationController::StartAnimationsWaitingForTargetAvailability(
365 double monotonic_time) {
366 // First collect running properties.
367 TargetProperties blocked_properties;
368 for (size_t i = 0; i < active_animations_.size(); ++i) {
369 if (active_animations_[i]->run_state() == Animation::Starting ||
370 active_animations_[i]->run_state() == Animation::Running ||
371 active_animations_[i]->run_state() == Animation::Finished)
372 blocked_properties.insert(active_animations_[i]->target_property());
373 }
374
375 for (size_t i = 0; i < active_animations_.size(); ++i) {
376 if (active_animations_[i]->run_state() ==
377 Animation::WaitingForTargetAvailability) {
378 // Collect all properties for animations with the same group id (they
379 // should all also be in the list of animations).
380 TargetProperties enqueued_properties;
381 enqueued_properties.insert(active_animations_[i]->target_property());
382 for (size_t j = i + 1; j < active_animations_.size(); ++j) {
383 if (active_animations_[i]->group() == active_animations_[j]->group())
384 enqueued_properties.insert(active_animations_[j]->target_property());
385 }
386
387 // Check to see if intersection of the list of properties affected by
388 // the group and the list of currently blocked properties is null. In
389 // any case, the group's target properties need to be added to the list
390 // of blocked properties.
391 bool null_intersection = true;
392 for (TargetProperties::iterator p_iter = enqueued_properties.begin();
393 p_iter != enqueued_properties.end();
394 ++p_iter) {
395 if (!blocked_properties.insert(*p_iter).second)
396 null_intersection = false;
397 }
398
399 // If the intersection is null, then we are free to start the animations
400 // in the group.
401 if (null_intersection) {
402 active_animations_[i]->SetRunState(
403 Animation::Starting, monotonic_time);
404 for (size_t j = i + 1; j < active_animations_.size(); ++j) {
405 if (active_animations_[i]->group() ==
406 active_animations_[j]->group()) {
407 active_animations_[j]->SetRunState(
408 Animation::Starting, monotonic_time);
409 }
410 }
411 }
412 }
413 }
414 }
415
416 void LayerAnimationController::PromoteStartedAnimations(
417 double monotonic_time,
418 AnimationEventsVector* events) {
419 for (size_t i = 0; i < active_animations_.size(); ++i) {
420 if (active_animations_[i]->run_state() == Animation::Starting) {
421 active_animations_[i]->SetRunState(Animation::Running, monotonic_time);
422 if (!active_animations_[i]->has_set_start_time())
423 active_animations_[i]->set_start_time(monotonic_time);
424 if (events) {
425 events->push_back(AnimationEvent(
426 AnimationEvent::Started,
427 id_,
428 active_animations_[i]->group(),
429 active_animations_[i]->target_property(),
430 monotonic_time));
431 }
432 }
433 }
434 }
435
436 void LayerAnimationController::MarkFinishedAnimations(double monotonic_time) {
437 for (size_t i = 0; i < active_animations_.size(); ++i) {
438 if (active_animations_[i]->IsFinishedAt(monotonic_time))
439 active_animations_[i]->SetRunState(Animation::Finished, monotonic_time);
440 }
441 }
442
443 void LayerAnimationController::ResolveConflicts(double monotonic_time) {
444 // Find any animations that are animating the same property and resolve the
445 // confict. We could eventually blend, but for now we'll just abort the
446 // previous animation (where 'previous' means: (1) has a prior start time or
447 // (2) has an equal start time, but was added to the queue earlier, i.e.,
448 // has a lower index in active_animations_).
449 for (size_t i = 0; i < active_animations_.size(); ++i) {
450 if (active_animations_[i]->run_state() == Animation::Starting ||
451 active_animations_[i]->run_state() == Animation::Running) {
452 for (size_t j = i + 1; j < active_animations_.size(); ++j) {
453 if ((active_animations_[j]->run_state() == Animation::Starting ||
454 active_animations_[j]->run_state() == Animation::Running) &&
455 active_animations_[i]->target_property() ==
456 active_animations_[j]->target_property()) {
457 if (active_animations_[i]->start_time() >
458 active_animations_[j]->start_time()) {
459 active_animations_[j]->SetRunState(Animation::Aborted,
460 monotonic_time);
461 } else {
462 active_animations_[i]->SetRunState(Animation::Aborted,
463 monotonic_time);
464 }
465 }
466 }
467 }
468 }
469 }
470
471 void LayerAnimationController::MarkAnimationsForDeletion(
472 double monotonic_time, AnimationEventsVector* events) {
473 for (size_t i = 0; i < active_animations_.size(); i++) {
474 int group_id = active_animations_[i]->group();
475 bool all_anims_with_same_id_are_finished = false;
476 // If an animation is finished, and not already marked for deletion,
477 // Find out if all other animations in the same group are also finished.
478 if (active_animations_[i]->is_finished() &&
479 active_animations_[i]->run_state() != Animation::WaitingForDeletion) {
480 all_anims_with_same_id_are_finished = true;
481 for (size_t j = 0; j < active_animations_.size(); ++j) {
482 if (group_id == active_animations_[j]->group() &&
483 !active_animations_[j]->is_finished()) {
484 all_anims_with_same_id_are_finished = false;
485 break;
486 }
487 }
488 }
489 if (all_anims_with_same_id_are_finished) {
490 // We now need to remove all animations with the same group id as
491 // group_id (and send along animation finished notifications, if
492 // necessary).
493 for (size_t j = i; j < active_animations_.size(); j++) {
494 if (group_id == active_animations_[j]->group()) {
495 if (events) {
496 events->push_back(AnimationEvent(
497 AnimationEvent::Finished,
498 id_,
499 active_animations_[j]->group(),
500 active_animations_[j]->target_property(),
501 monotonic_time));
502 }
503 active_animations_[j]->SetRunState(Animation::WaitingForDeletion,
504 monotonic_time);
505 }
506 }
507 }
508 }
509 }
510
511 static bool IsWaitingForDeletion(Animation* animation) {
512 return animation->run_state() == Animation::WaitingForDeletion;
513 }
514
515 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() {
516 ScopedPtrVector<Animation>& animations = active_animations_;
517 animations.erase(cc::remove_if(animations,
518 animations.begin(),
519 animations.end(),
520 IsWaitingForDeletion),
521 animations.end());
522 }
523
524 void LayerAnimationController::ReplaceImplThreadAnimations(
525 LayerAnimationController* controller_impl) const {
526 controller_impl->active_animations_.clear();
527 for (size_t i = 0; i < active_animations_.size(); ++i) {
528 scoped_ptr<Animation> to_add;
529 if (active_animations_[i]->needs_synchronized_start_time()) {
530 // We haven't received an animation started notification yet, so it
531 // is important that we add it in a 'waiting' and not 'running' state.
532 Animation::RunState initial_run_state =
533 Animation::WaitingForTargetAvailability;
534 double start_time = 0;
535 to_add = active_animations_[i]->CloneAndInitialize(
536 Animation::ControllingInstance,
537 initial_run_state, start_time).Pass();
100 } else { 538 } else {
101 purgeAnimationsMarkedForDeletion(); 539 to_add = active_animations_[i]->Clone(
102 pushNewAnimationsToImplThread(controllerImpl); 540 Animation::ControllingInstance).Pass();
103 541 }
104 // Remove finished impl side animations only after pushing, 542
105 // and only after the animations are deleted on the main thread 543 controller_impl->AddAnimation(to_add.Pass());
106 // this insures we will never push an animation twice. 544 }
107 removeAnimationsCompletedOnMainThread(controllerImpl); 545 }
108 546
109 pushPropertiesToImplThread(controllerImpl); 547 void LayerAnimationController::TickAnimations(double monotonic_time) {
110 } 548 for (size_t i = 0; i < active_animations_.size(); ++i) {
111 controllerImpl->updateActivation(); 549 if (active_animations_[i]->run_state() == Animation::Starting ||
112 updateActivation(); 550 active_animations_[i]->run_state() == Animation::Running ||
113 } 551 active_animations_[i]->run_state() == Animation::Paused) {
114 552 double trimmed =
115 void LayerAnimationController::animate(double monotonicTime) 553 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time);
116 { 554
117 if (!hasActiveObserver()) 555 // Animation assumes its initial value until it gets the synchronized
118 return; 556 // start time from the impl thread and can start ticking.
119 557 if (active_animations_[i]->needs_synchronized_start_time())
120 startAnimationsWaitingForNextTick(monotonicTime); 558 trimmed = 0;
121 startAnimationsWaitingForStartTime(monotonicTime); 559
122 startAnimationsWaitingForTargetAvailability(monotonicTime); 560 // A just-started animation assumes its initial value.
123 resolveConflicts(monotonicTime); 561 if (active_animations_[i]->run_state() == Animation::Starting &&
124 tickAnimations(monotonicTime); 562 !active_animations_[i]->has_set_start_time())
125 m_lastTickTime = monotonicTime; 563 trimmed = 0;
126 } 564
127 565 switch (active_animations_[i]->target_property()) {
128 void LayerAnimationController::accumulatePropertyUpdates(double monotonicTime, 566
129 AnimationEventsVector* events) 567 case Animation::Transform: {
130 { 568 const TransformAnimationCurve* transform_animation_curve =
131 if (!events) 569 active_animations_[i]->curve()->ToTransformAnimationCurve();
132 return; 570 const gfx::Transform transform =
133 571 transform_animation_curve->GetValue(trimmed);
134 for (size_t i = 0; i < m_activeAnimations.size(); ++i) { 572 NotifyObserversTransformAnimated(transform);
135 Animation* animation = m_activeAnimations[i]; 573 break;
136 if (!animation->isImplOnly())
137 continue;
138
139 if (animation->targetProperty() == Animation::Opacity) {
140 AnimationEvent event(AnimationEvent::PropertyUpdate,
141 m_id, animation->group(),
142 Animation::Opacity, monotonicTime);
143 event.opacity = animation->curve()->toFloatAnimationCurve()->getValu e(monotonicTime);
144
145 events->push_back(event);
146 } 574 }
147 else if (animation->targetProperty() == Animation::Transform) { 575
148 AnimationEvent event(AnimationEvent::PropertyUpdate, 576 case Animation::Opacity: {
149 m_id, animation->group(), 577 const FloatAnimationCurve* float_animation_curve =
150 Animation::Transform, monotonicTime); 578 active_animations_[i]->curve()->ToFloatAnimationCurve();
151 event.transform = animation->curve()->toTransformAnimationCurve()->g etValue(monotonicTime); 579 const float opacity = float_animation_curve->GetValue(trimmed);
152 events->push_back(event); 580 NotifyObserversOpacityAnimated(opacity);
581 break;
153 } 582 }
154 } 583
155 } 584 // Do nothing for sentinel value.
156 585 case Animation::TargetPropertyEnumSize:
157 void LayerAnimationController::updateState(AnimationEventsVector* events) 586 NOTREACHED();
158 { 587 }
159 if (!hasActiveObserver()) 588 }
160 return; 589 }
161 590 }
162 promoteStartedAnimations(m_lastTickTime, events); 591
163 markFinishedAnimations(m_lastTickTime); 592 void LayerAnimationController::UpdateActivation(UpdateActivationType type) {
164 markAnimationsForDeletion(m_lastTickTime, events); 593 bool force = type == ForceActivation;
165 startAnimationsWaitingForTargetAvailability(m_lastTickTime); 594 if (registrar_) {
166 promoteStartedAnimations(m_lastTickTime, events); 595 if (!active_animations_.empty() && (!is_active_ || force))
167 596 registrar_->DidActivateAnimationController(this);
168 accumulatePropertyUpdates(m_lastTickTime, events); 597 else if (active_animations_.empty() && (is_active_ || force))
169 598 registrar_->DidDeactivateAnimationController(this);
170 updateActivation(); 599 is_active_ = !active_animations_.empty();
171 } 600 }
172 601 }
173 void LayerAnimationController::addAnimation(scoped_ptr<Animation> animation) 602
174 { 603 void LayerAnimationController::NotifyObserversOpacityAnimated(float opacity) {
175 m_activeAnimations.push_back(animation.Pass()); 604 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
176 updateActivation(); 605 observers_,
177 } 606 OnOpacityAnimated(opacity));
178 607 }
179 Animation* LayerAnimationController::getAnimation(int groupId, Animation::Target Property targetProperty) const 608
180 { 609 void LayerAnimationController::NotifyObserversTransformAnimated(
181 for (size_t i = 0; i < m_activeAnimations.size(); ++i) 610 const gfx::Transform& transform) {
182 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]-> targetProperty() == targetProperty) 611 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
183 return m_activeAnimations[i]; 612 observers_,
184 return 0; 613 OnTransformAnimated(transform));
185 } 614 }
186 615
187 Animation* LayerAnimationController::getAnimation(Animation::TargetProperty targ etProperty) const 616 bool LayerAnimationController::HasActiveObserver() {
188 { 617 if (observers_.might_have_observers()) {
189 for (size_t i = 0; i < m_activeAnimations.size(); ++i) { 618 ObserverListBase<LayerAnimationValueObserver>::Iterator it(observers_);
190 size_t index = m_activeAnimations.size() - i - 1; 619 LayerAnimationValueObserver* obs;
191 if (m_activeAnimations[index]->targetProperty() == targetProperty) 620 while ((obs = it.GetNext()) != NULL)
192 return m_activeAnimations[index]; 621 if (obs->IsActive())
193 } 622 return true;
194 return 0; 623 }
195 } 624 return false;
196
197 bool LayerAnimationController::hasActiveAnimation() const
198 {
199 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
200 if (!m_activeAnimations[i]->isFinished())
201 return true;
202 }
203 return false;
204 }
205
206 bool LayerAnimationController::isAnimatingProperty(Animation::TargetProperty tar getProperty) const
207 {
208 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
209 if (m_activeAnimations[i]->runState() != Animation::Finished && m_active Animations[i]->runState() != Animation::Aborted && m_activeAnimations[i]->target Property() == targetProperty)
210 return true;
211 }
212 return false;
213 }
214
215 void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
216 {
217 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
218 if (m_activeAnimations[i]->group() == event.groupId && m_activeAnimation s[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSy nchronizedStartTime()) {
219 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
220 m_activeAnimations[i]->setStartTime(event.monotonicTime);
221 return;
222 }
223 }
224 }
225
226 void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registr ar)
227 {
228 if (m_registrar == registrar)
229 return;
230
231 if (m_registrar)
232 m_registrar->UnregisterAnimationController(this);
233
234 m_registrar = registrar;
235 if (m_registrar)
236 m_registrar->RegisterAnimationController(this);
237
238 bool force = true;
239 updateActivation(force);
240 }
241
242 void LayerAnimationController::addObserver(LayerAnimationValueObserver* observer )
243 {
244 if (!m_observers.HasObserver(observer))
245 m_observers.AddObserver(observer);
246 }
247
248 void LayerAnimationController::removeObserver(LayerAnimationValueObserver* obser ver)
249 {
250 m_observers.RemoveObserver(observer);
251 }
252
253 void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationContr oller* controllerImpl) const
254 {
255 // Any new animations owned by the main thread's controller are cloned and a dde to the impl thread's controller.
256 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
257 // If the animation is already running on the impl thread, there is no n eed to copy it over.
258 if (controllerImpl->getAnimation(m_activeAnimations[i]->group(), m_activ eAnimations[i]->targetProperty()))
259 continue;
260
261 // If the animation is not running on the impl thread, it does not neces sarily mean that it needs
262 // to be copied over and started; it may have already finished. In this case, the impl thread animation
263 // will have already notified that it has started and the main thread an imation will no longer need
264 // a synchronized start time.
265 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
266 continue;
267
268 // The new animation should be set to run as soon as possible.
269 Animation::RunState initialRunState = Animation::WaitingForTargetAvailab ility;
270 double startTime = 0;
271 scoped_ptr<Animation> toAdd(m_activeAnimations[i]->cloneAndInitialize(An imation::ControllingInstance, initialRunState, startTime));
272 DCHECK(!toAdd->needsSynchronizedStartTime());
273 controllerImpl->addAnimation(toAdd.Pass());
274 }
275 }
276
277 struct IsCompleted {
278 IsCompleted(const LayerAnimationController& mainThreadController) : m_mainTh readController(mainThreadController) { }
279 bool operator()(Animation* animation) const {
280 if (animation->isImplOnly())
281 return false;
282 return !m_mainThreadController.getAnimation(animation->group(), animatio n->targetProperty()); }
283 private:
284 const LayerAnimationController& m_mainThreadController;
285 };
286
287 void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimat ionController* controllerImpl) const
288 {
289 // Delete all impl thread animations for which there is no corresponding mai n thread animation.
290 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
291 // guaranteeing progress towards loop termination.
292 ScopedPtrVector<Animation>& animations = controllerImpl->m_activeAnimations;
293 animations.erase(cc::remove_if(animations, animations.begin(), animations.en d(), IsCompleted(*this)), animations.end());
294 }
295
296 void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationControll er* controllerImpl) const
297 {
298 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
299 Animation* currentImpl = controllerImpl->getAnimation(m_activeAnimations [i]->group(), m_activeAnimations[i]->targetProperty());
300 if (currentImpl)
301 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
302 }
303 }
304
305 void LayerAnimationController::startAnimationsWaitingForNextTick(double monotoni cTime)
306 {
307 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
308 if (m_activeAnimations[i]->runState() == Animation::WaitingForNextTick)
309 m_activeAnimations[i]->setRunState(Animation::Starting, monotonicTim e);
310 }
311 }
312
313 void LayerAnimationController::startAnimationsWaitingForStartTime(double monoton icTime)
314 {
315 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
316 if (m_activeAnimations[i]->runState() == Animation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime)
317 m_activeAnimations[i]->setRunState(Animation::Starting, monotonicTim e);
318 }
319 }
320
321 void LayerAnimationController::startAnimationsWaitingForTargetAvailability(doubl e monotonicTime)
322 {
323 // First collect running properties.
324 TargetProperties blockedProperties;
325 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
326 if (m_activeAnimations[i]->runState() == Animation::Starting || m_active Animations[i]->runState() == Animation::Running || m_activeAnimations[i]->runSta te() == Animation::Finished)
327 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
328 }
329
330 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
331 if (m_activeAnimations[i]->runState() == Animation::WaitingForTargetAvai lability) {
332 // Collect all properties for animations with the same group id (the y should all also be in the list of animations).
333 TargetProperties enqueuedProperties;
334 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
335 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
336 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->gro up())
337 enqueuedProperties.insert(m_activeAnimations[j]->targetPrope rty());
338 }
339
340 // Check to see if intersection of the list of properties affected b y the group and the list of currently
341 // blocked properties is null. In any case, the group's target prope rties need to be added to the list
342 // of blocked properties.
343 bool nullIntersection = true;
344 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
345 if (!blockedProperties.insert(*pIter).second)
346 nullIntersection = false;
347 }
348
349 // If the intersection is null, then we are free to start the animat ions in the group.
350 if (nullIntersection) {
351 m_activeAnimations[i]->setRunState(Animation::Starting, monotoni cTime);
352 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
353 if (m_activeAnimations[i]->group() == m_activeAnimations[j]- >group())
354 m_activeAnimations[j]->setRunState(Animation::Starting, monotonicTime);
355 }
356 }
357 }
358 }
359 }
360
361 void LayerAnimationController::promoteStartedAnimations(double monotonicTime, An imationEventsVector* events)
362 {
363 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
364 if (m_activeAnimations[i]->runState() == Animation::Starting) {
365 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime );
366 if (!m_activeAnimations[i]->hasSetStartTime())
367 m_activeAnimations[i]->setStartTime(monotonicTime);
368 if (events)
369 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monoton icTime));
370 }
371 }
372 }
373
374 void LayerAnimationController::markFinishedAnimations(double monotonicTime)
375 {
376 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
377 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
378 m_activeAnimations[i]->setRunState(Animation::Finished, monotonicTim e);
379 }
380 }
381
382 void LayerAnimationController::resolveConflicts(double monotonicTime)
383 {
384 // Find any animations that are animating the same property and resolve the
385 // confict. We could eventually blend, but for now we'll just abort the
386 // previous animation (where 'previous' means: (1) has a prior start time or
387 // (2) has an equal start time, but was added to the queue earlier, i.e.,
388 // has a lower index in m_activeAnimations).
389 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
390 if (m_activeAnimations[i]->runState() == Animation::Starting || m_active Animations[i]->runState() == Animation::Running) {
391 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
392 if ((m_activeAnimations[j]->runState() == Animation::Starting ||
393 m_activeAnimations[j]->runState() == Animation::Running) &&
394 m_activeAnimations[i]->targetProperty() == m_activeAnimation s[j]->targetProperty()) {
395 if (m_activeAnimations[i]->startTime() > m_activeAnimations[ j]->startTime())
396 m_activeAnimations[j]->setRunState(Animation::Aborted, m onotonicTime);
397 else
398 m_activeAnimations[i]->setRunState(Animation::Aborted, m onotonicTime);
399 }
400 }
401 }
402 }
403 }
404
405 void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, A nimationEventsVector* events)
406 {
407 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
408 int groupId = m_activeAnimations[i]->group();
409 bool allAnimsWithSameIdAreFinished = false;
410 // If an animation is finished, and not already marked for deletion,
411 // Find out if all other animations in the same group are also finished.
412 if (m_activeAnimations[i]->isFinished() && m_activeAnimations[i]->runSta te() != Animation::WaitingForDeletion) {
413 allAnimsWithSameIdAreFinished = true;
414 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
415 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimat ions[j]->isFinished()) {
416 allAnimsWithSameIdAreFinished = false;
417 break;
418 }
419 }
420 }
421 if (allAnimsWithSameIdAreFinished) {
422 // We now need to remove all animations with the same group id as gr oupId
423 // (and send along animation finished notifications, if necessary).
424 for (size_t j = i; j < m_activeAnimations.size(); j++) {
425 if (groupId == m_activeAnimations[j]->group()) {
426 if (events)
427 events->push_back(AnimationEvent(AnimationEvent::Finishe d, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty() , monotonicTime));
428 m_activeAnimations[j]->setRunState(Animation::WaitingForDele tion, monotonicTime);
429 }
430 }
431 }
432 }
433 }
434
435 static bool isWaitingForDeletion(Animation* animation) { return animation->runSt ate() == Animation::WaitingForDeletion; }
436
437 void LayerAnimationController::purgeAnimationsMarkedForDeletion()
438 {
439 ScopedPtrVector<Animation>& animations = m_activeAnimations;
440 animations.erase(cc::remove_if(animations, animations.begin(), animations.en d(), isWaitingForDeletion), animations.end());
441 }
442
443 void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationControl ler* controllerImpl) const
444 {
445 controllerImpl->m_activeAnimations.clear();
446 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
447 scoped_ptr<Animation> toAdd;
448 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
449 // We haven't received an animation started notification yet, so it
450 // is important that we add it in a 'waiting' and not 'running' stat e.
451 Animation::RunState initialRunState = Animation::WaitingForTargetAva ilability;
452 double startTime = 0;
453 toAdd = m_activeAnimations[i]->cloneAndInitialize(Animation::Control lingInstance, initialRunState, startTime).Pass();
454 } else
455 toAdd = m_activeAnimations[i]->clone(Animation::ControllingInstance) .Pass();
456
457 controllerImpl->addAnimation(toAdd.Pass());
458 }
459 }
460
461 void LayerAnimationController::tickAnimations(double monotonicTime)
462 {
463 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
464 if (m_activeAnimations[i]->runState() == Animation::Starting ||
465 m_activeAnimations[i]->runState() == Animation::Running ||
466 m_activeAnimations[i]->runState() == Animation::Paused) {
467 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(m onotonicTime);
468
469 // Animation assumes its initial value until it gets the synchronize d start time
470 // from the impl thread and can start ticking.
471 if (m_activeAnimations[i]->needsSynchronizedStartTime())
472 trimmed = 0;
473
474 // A just-started animation assumes its initial value.
475 if (m_activeAnimations[i]->runState() == Animation::Starting && !m_a ctiveAnimations[i]->hasSetStartTime())
476 trimmed = 0;
477
478 switch (m_activeAnimations[i]->targetProperty()) {
479
480 case Animation::Transform: {
481 const TransformAnimationCurve* transformAnimationCurve = m_activ eAnimations[i]->curve()->toTransformAnimationCurve();
482 const gfx::Transform transform = transformAnimationCurve->getVal ue(trimmed);
483 notifyObserversTransformAnimated(transform);
484 break;
485 }
486
487 case Animation::Opacity: {
488 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimati ons[i]->curve()->toFloatAnimationCurve();
489 const float opacity = floatAnimationCurve->getValue(trimmed);
490 notifyObserversOpacityAnimated(opacity);
491 break;
492 }
493
494 // Do nothing for sentinel value.
495 case Animation::TargetPropertyEnumSize:
496 NOTREACHED();
497 }
498 }
499 }
500 }
501
502 void LayerAnimationController::updateActivation(bool force)
503 {
504 if (m_registrar) {
505 if (!m_activeAnimations.empty() && (!m_isActive || force))
506 m_registrar->DidActivateAnimationController(this);
507 else if (m_activeAnimations.empty() && (m_isActive || force))
508 m_registrar->DidDeactivateAnimationController(this);
509 m_isActive = !m_activeAnimations.empty();
510 }
511 }
512
513 void LayerAnimationController::notifyObserversOpacityAnimated(float opacity)
514 {
515 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
516 m_observers,
517 OnOpacityAnimated(opacity));
518 }
519
520 void LayerAnimationController::notifyObserversTransformAnimated(const gfx::Trans form& transform)
521 {
522 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
523 m_observers,
524 OnTransformAnimated(transform));
525 }
526
527 bool LayerAnimationController::hasActiveObserver()
528 {
529 if (m_observers.might_have_observers()) {
530 ObserverListBase<LayerAnimationValueObserver>::Iterator it(m_observers);
531 LayerAnimationValueObserver* obs;
532 while ((obs = it.GetNext()) != NULL)
533 if (obs->IsActive())
534 return true;
535 }
536 return false;
537 } 625 }
538 626
539 } // namespace cc 627 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698