blob: d5ed278bc57932638f4de36a9a67dc26f2399e3f [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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
[email protected]d50c6862012-10-23 02:08:315#include "cc/layer_animation_controller.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]ead39c52013-01-09 07:22:457#include <algorithm>
8
[email protected]4d0786a2013-01-07 16:21:209#include "cc/animation.h"
[email protected]de4afb5e2012-12-20 00:11:3410#include "cc/animation_registrar.h"
[email protected]d50c6862012-10-23 02:08:3111#include "cc/keyframed_animation_curve.h"
[email protected]de4afb5e2012-12-20 00:11:3412#include "cc/layer_animation_value_observer.h"
[email protected]ead39c52013-01-09 07:22:4513#include "cc/scoped_ptr_algorithm.h"
[email protected]c8686a02012-11-27 08:29:0014#include "ui/gfx/transform.h"
[email protected]94f206c12012-08-25 00:09:1415
[email protected]0e6ebab2013-01-04 00:09:3716namespace {
17gfx::Transform convertWebTransformationMatrixToTransform(const WebKit::WebTransformationMatrix& matrix)
18{
19 gfx::Transform transform;
20 transform.matrix().setDouble(0, 0, matrix.m11());
21 transform.matrix().setDouble(0, 1, matrix.m21());
22 transform.matrix().setDouble(0, 2, matrix.m31());
23 transform.matrix().setDouble(0, 3, matrix.m41());
24 transform.matrix().setDouble(1, 0, matrix.m12());
25 transform.matrix().setDouble(1, 1, matrix.m22());
26 transform.matrix().setDouble(1, 2, matrix.m32());
27 transform.matrix().setDouble(1, 3, matrix.m42());
28 transform.matrix().setDouble(2, 0, matrix.m13());
29 transform.matrix().setDouble(2, 1, matrix.m23());
30 transform.matrix().setDouble(2, 2, matrix.m33());
31 transform.matrix().setDouble(2, 3, matrix.m43());
32 transform.matrix().setDouble(3, 0, matrix.m14());
33 transform.matrix().setDouble(3, 1, matrix.m24());
34 transform.matrix().setDouble(3, 2, matrix.m34());
35 transform.matrix().setDouble(3, 3, matrix.m44());
36 return transform;
37}
38} // namespace
39
[email protected]9c88e562012-09-14 22:21:3040namespace cc {
[email protected]94f206c12012-08-25 00:09:1441
[email protected]de4afb5e2012-12-20 00:11:3442LayerAnimationController::LayerAnimationController(int id)
[email protected]94f206c12012-08-25 00:09:1443 : m_forceSync(false)
[email protected]de4afb5e2012-12-20 00:11:3444 , m_id(id)
45 , m_registrar(0)
46 , m_isActive(false)
[email protected]94f206c12012-08-25 00:09:1447{
48}
49
[email protected]96baf3e2012-10-22 23:09:5550LayerAnimationController::~LayerAnimationController()
[email protected]94f206c12012-08-25 00:09:1451{
[email protected]de4afb5e2012-12-20 00:11:3452 if (m_registrar)
53 m_registrar->UnregisterAnimationController(this);
[email protected]94f206c12012-08-25 00:09:1454}
55
[email protected]de4afb5e2012-12-20 00:11:3456scoped_refptr<LayerAnimationController> LayerAnimationController::create(int id)
[email protected]94f206c12012-08-25 00:09:1457{
[email protected]de4afb5e2012-12-20 00:11:3458 return make_scoped_refptr(new LayerAnimationController(id));
[email protected]94f206c12012-08-25 00:09:1459}
60
[email protected]96baf3e2012-10-22 23:09:5561void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
[email protected]94f206c12012-08-25 00:09:1462{
63 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
64 if (m_activeAnimations[i]->id() == animationId)
[email protected]4d0786a2013-01-07 16:21:2065 m_activeAnimations[i]->setRunState(Animation::Paused, timeOffset + m_activeAnimations[i]->startTime());
[email protected]94f206c12012-08-25 00:09:1466 }
67}
68
[email protected]ead39c52013-01-09 07:22:4569struct HasAnimationId {
70 HasAnimationId(int id) : m_id(id) { }
71 bool operator()(Animation* animation) const { return animation->id() == m_id; }
72private:
73 int m_id;
74};
75
[email protected]96baf3e2012-10-22 23:09:5576void LayerAnimationController::removeAnimation(int animationId)
[email protected]94f206c12012-08-25 00:09:1477{
[email protected]ead39c52013-01-09 07:22:4578 ScopedPtrVector<Animation>& animations = m_activeAnimations;
79 animations.erase(cc::remove_if(animations, animations.begin(), animations.end(), HasAnimationId(animationId)), animations.end());
[email protected]de4afb5e2012-12-20 00:11:3480 updateActivation();
[email protected]94f206c12012-08-25 00:09:1481}
82
[email protected]ead39c52013-01-09 07:22:4583struct HasAnimationIdAndProperty {
84 HasAnimationIdAndProperty(int id, Animation::TargetProperty targetProperty) : m_id(id), m_targetProperty(targetProperty) { }
85 bool operator()(Animation* animation) const { return animation->id() == m_id && animation->targetProperty() == m_targetProperty; }
86private:
87 int m_id;
88 Animation::TargetProperty m_targetProperty;
89};
90
[email protected]4d0786a2013-01-07 16:21:2091void LayerAnimationController::removeAnimation(int animationId, Animation::TargetProperty targetProperty)
[email protected]94f206c12012-08-25 00:09:1492{
[email protected]ead39c52013-01-09 07:22:4593 ScopedPtrVector<Animation>& animations = m_activeAnimations;
94 animations.erase(cc::remove_if(animations, animations.begin(), animations.end(), HasAnimationIdAndProperty(animationId, targetProperty)), animations.end());
[email protected]de4afb5e2012-12-20 00:11:3495 updateActivation();
[email protected]94f206c12012-08-25 00:09:1496}
97
98// According to render layer backing, these are for testing only.
[email protected]96baf3e2012-10-22 23:09:5599void LayerAnimationController::suspendAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14100{
101 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
102 if (!m_activeAnimations[i]->isFinished())
[email protected]4d0786a2013-01-07 16:21:20103 m_activeAnimations[i]->setRunState(Animation::Paused, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14104 }
105}
106
107// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
[email protected]96baf3e2012-10-22 23:09:55108void LayerAnimationController::resumeAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14109{
110 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20111 if (m_activeAnimations[i]->runState() == Animation::Paused)
112 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14113 }
114}
115
116// Ensures that the list of active animations on the main thread and the impl thread
117// are kept in sync.
[email protected]96baf3e2012-10-22 23:09:55118void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
[email protected]94f206c12012-08-25 00:09:14119{
120 if (m_forceSync) {
121 replaceImplThreadAnimations(controllerImpl);
122 m_forceSync = false;
123 } else {
124 purgeAnimationsMarkedForDeletion();
125 pushNewAnimationsToImplThread(controllerImpl);
126
127 // Remove finished impl side animations only after pushing,
128 // and only after the animations are deleted on the main thread
129 // this insures we will never push an animation twice.
130 removeAnimationsCompletedOnMainThread(controllerImpl);
131
132 pushPropertiesToImplThread(controllerImpl);
133 }
[email protected]de4afb5e2012-12-20 00:11:34134 controllerImpl->updateActivation();
135 updateActivation();
[email protected]94f206c12012-08-25 00:09:14136}
137
[email protected]96baf3e2012-10-22 23:09:55138void LayerAnimationController::animate(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14139{
[email protected]58676772013-01-07 15:50:15140 if (!hasActiveObserver())
141 return;
142
[email protected]94f206c12012-08-25 00:09:14143 startAnimationsWaitingForNextTick(monotonicTime, events);
144 startAnimationsWaitingForStartTime(monotonicTime, events);
145 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
146 resolveConflicts(monotonicTime);
147 tickAnimations(monotonicTime);
148 markAnimationsForDeletion(monotonicTime, events);
149 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
[email protected]de4afb5e2012-12-20 00:11:34150
151 updateActivation();
[email protected]94f206c12012-08-25 00:09:14152}
153
[email protected]4d0786a2013-01-07 16:21:20154void LayerAnimationController::addAnimation(scoped_ptr<Animation> animation)
[email protected]94f206c12012-08-25 00:09:14155{
[email protected]ead39c52013-01-09 07:22:45156 m_activeAnimations.push_back(animation.Pass());
[email protected]de4afb5e2012-12-20 00:11:34157 updateActivation();
[email protected]94f206c12012-08-25 00:09:14158}
159
[email protected]4d0786a2013-01-07 16:21:20160Animation* LayerAnimationController::getAnimation(int groupId, Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14161{
162 for (size_t i = 0; i < m_activeAnimations.size(); ++i)
163 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03164 return m_activeAnimations[i];
[email protected]94f206c12012-08-25 00:09:14165 return 0;
166}
167
[email protected]4d0786a2013-01-07 16:21:20168Animation* LayerAnimationController::getAnimation(Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14169{
170 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
171 size_t index = m_activeAnimations.size() - i - 1;
172 if (m_activeAnimations[index]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03173 return m_activeAnimations[index];
[email protected]94f206c12012-08-25 00:09:14174 }
175 return 0;
176}
177
[email protected]96baf3e2012-10-22 23:09:55178bool LayerAnimationController::hasActiveAnimation() const
[email protected]94f206c12012-08-25 00:09:14179{
180 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
181 if (!m_activeAnimations[i]->isFinished())
182 return true;
183 }
184 return false;
185}
186
[email protected]4d0786a2013-01-07 16:21:20187bool LayerAnimationController::isAnimatingProperty(Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14188{
189 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20190 if (m_activeAnimations[i]->runState() != Animation::Finished && m_activeAnimations[i]->runState() != Animation::Aborted && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]94f206c12012-08-25 00:09:14191 return true;
192 }
193 return false;
194}
195
[email protected]e10cd022012-12-18 00:32:26196void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
[email protected]94f206c12012-08-25 00:09:14197{
198 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
199 if (m_activeAnimations[i]->group() == event.groupId && m_activeAnimations[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSynchronizedStartTime()) {
200 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
201 m_activeAnimations[i]->setStartTime(event.monotonicTime);
202 return;
203 }
204 }
205}
206
[email protected]de4afb5e2012-12-20 00:11:34207void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registrar)
[email protected]94f206c12012-08-25 00:09:14208{
[email protected]de4afb5e2012-12-20 00:11:34209 if (m_registrar == registrar)
210 return;
211
212 if (m_registrar)
213 m_registrar->UnregisterAnimationController(this);
214
215 m_registrar = registrar;
216 if (m_registrar)
217 m_registrar->RegisterAnimationController(this);
218
219 bool force = true;
220 updateActivation(force);
221}
222
223void LayerAnimationController::addObserver(LayerAnimationValueObserver* observer)
224{
225 if (!m_observers.HasObserver(observer))
226 m_observers.AddObserver(observer);
227}
228
229void LayerAnimationController::removeObserver(LayerAnimationValueObserver* observer)
230{
231 m_observers.RemoveObserver(observer);
[email protected]94f206c12012-08-25 00:09:14232}
233
[email protected]96baf3e2012-10-22 23:09:55234void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14235{
236 // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
237 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
238 // If the animation is already running on the impl thread, there is no need to copy it over.
[email protected]4d0786a2013-01-07 16:21:20239 if (controllerImpl->getAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
[email protected]94f206c12012-08-25 00:09:14240 continue;
241
242 // If the animation is not running on the impl thread, it does not necessarily mean that it needs
243 // to be copied over and started; it may have already finished. In this case, the impl thread animation
244 // will have already notified that it has started and the main thread animation will no longer need
245 // a synchronized start time.
246 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
247 continue;
248
249 // The new animation should be set to run as soon as possible.
[email protected]4d0786a2013-01-07 16:21:20250 Animation::RunState initialRunState = Animation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14251 double startTime = 0;
[email protected]4d0786a2013-01-07 16:21:20252 scoped_ptr<Animation> toAdd(m_activeAnimations[i]->cloneAndInitialize(Animation::ControllingInstance, initialRunState, startTime));
[email protected]1d993172012-10-18 18:15:04253 DCHECK(!toAdd->needsSynchronizedStartTime());
[email protected]9aca3592012-10-12 15:57:09254 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14255 }
256}
257
[email protected]ead39c52013-01-09 07:22:45258struct IsCompleted {
259 IsCompleted(const LayerAnimationController& mainThreadController) : m_mainThreadController(mainThreadController) { }
260 bool operator()(Animation* animation) const { return !m_mainThreadController.getAnimation(animation->group(), animation->targetProperty()); }
261private:
262 const LayerAnimationController& m_mainThreadController;
263};
264
[email protected]96baf3e2012-10-22 23:09:55265void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14266{
267 // Delete all impl thread animations for which there is no corresponding main thread animation.
268 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
269 // guaranteeing progress towards loop termination.
[email protected]ead39c52013-01-09 07:22:45270 ScopedPtrVector<Animation>& animations = controllerImpl->m_activeAnimations;
271 animations.erase(cc::remove_if(animations, animations.begin(), animations.end(), IsCompleted(*this)), animations.end());
[email protected]94f206c12012-08-25 00:09:14272}
273
[email protected]96baf3e2012-10-22 23:09:55274void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14275{
276 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20277 Animation* currentImpl = controllerImpl->getAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14278 if (currentImpl)
279 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
280 }
281}
282
[email protected]96baf3e2012-10-22 23:09:55283void LayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14284{
285 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20286 if (m_activeAnimations[i]->runState() == Animation::WaitingForNextTick) {
287 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14288 if (!m_activeAnimations[i]->hasSetStartTime())
289 m_activeAnimations[i]->setStartTime(monotonicTime);
290 if (events)
[email protected]de4afb5e2012-12-20 00:11:34291 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14292 }
293 }
294}
295
[email protected]96baf3e2012-10-22 23:09:55296void LayerAnimationController::startAnimationsWaitingForStartTime(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14297{
298 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20299 if (m_activeAnimations[i]->runState() == Animation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
300 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14301 if (events)
[email protected]de4afb5e2012-12-20 00:11:34302 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14303 }
304 }
305}
306
[email protected]96baf3e2012-10-22 23:09:55307void LayerAnimationController::startAnimationsWaitingForTargetAvailability(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14308{
309 // First collect running properties.
310 TargetProperties blockedProperties;
311 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20312 if (m_activeAnimations[i]->runState() == Animation::Running || m_activeAnimations[i]->runState() == Animation::Finished)
[email protected]c7278e5b2012-10-11 02:35:46313 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14314 }
315
316 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20317 if (m_activeAnimations[i]->runState() == Animation::WaitingForTargetAvailability) {
[email protected]94f206c12012-08-25 00:09:14318 // Collect all properties for animations with the same group id (they should all also be in the list of animations).
319 TargetProperties enqueuedProperties;
[email protected]c7278e5b2012-10-11 02:35:46320 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14321 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
322 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group())
[email protected]c7278e5b2012-10-11 02:35:46323 enqueuedProperties.insert(m_activeAnimations[j]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14324 }
325
326 // Check to see if intersection of the list of properties affected by the group and the list of currently
327 // blocked properties is null. In any case, the group's target properties need to be added to the list
328 // of blocked properties.
329 bool nullIntersection = true;
330 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
[email protected]c7278e5b2012-10-11 02:35:46331 if (!blockedProperties.insert(*pIter).second)
[email protected]94f206c12012-08-25 00:09:14332 nullIntersection = false;
333 }
334
335 // If the intersection is null, then we are free to start the animations in the group.
336 if (nullIntersection) {
[email protected]4d0786a2013-01-07 16:21:20337 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14338 if (!m_activeAnimations[i]->hasSetStartTime())
339 m_activeAnimations[i]->setStartTime(monotonicTime);
340 if (events)
[email protected]de4afb5e2012-12-20 00:11:34341 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14342 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
343 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
[email protected]4d0786a2013-01-07 16:21:20344 m_activeAnimations[j]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14345 if (!m_activeAnimations[j]->hasSetStartTime())
346 m_activeAnimations[j]->setStartTime(monotonicTime);
347 }
348 }
349 }
350 }
351 }
352}
353
[email protected]96baf3e2012-10-22 23:09:55354void LayerAnimationController::resolveConflicts(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14355{
356 // Find any animations that are animating the same property and resolve the
357 // confict. We could eventually blend, but for now we'll just abort the
358 // previous animation (where 'previous' means: (1) has a prior start time or
359 // (2) has an equal start time, but was added to the queue earlier, i.e.,
360 // has a lower index in m_activeAnimations).
361 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20362 if (m_activeAnimations[i]->runState() == Animation::Running) {
[email protected]94f206c12012-08-25 00:09:14363 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
[email protected]4d0786a2013-01-07 16:21:20364 if (m_activeAnimations[j]->runState() == Animation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
[email protected]94f206c12012-08-25 00:09:14365 if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
[email protected]4d0786a2013-01-07 16:21:20366 m_activeAnimations[j]->setRunState(Animation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14367 else
[email protected]4d0786a2013-01-07 16:21:20368 m_activeAnimations[i]->setRunState(Animation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14369 }
370 }
371 }
372 }
373}
374
[email protected]96baf3e2012-10-22 23:09:55375void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14376{
377 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
378 int groupId = m_activeAnimations[i]->group();
379 bool allAnimsWithSameIdAreFinished = false;
380 // If an animation is finished, and not already marked for deletion,
381 // Find out if all other animations in the same group are also finished.
382 if (m_activeAnimations[i]->isFinished()) {
383 allAnimsWithSameIdAreFinished = true;
384 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
385 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimations[j]->isFinished()) {
386 allAnimsWithSameIdAreFinished = false;
387 break;
388 }
389 }
390 }
391 if (allAnimsWithSameIdAreFinished) {
392 // We now need to remove all animations with the same group id as groupId
393 // (and send along animation finished notifications, if necessary).
394 for (size_t j = i; j < m_activeAnimations.size(); j++) {
395 if (groupId == m_activeAnimations[j]->group()) {
396 if (events)
[email protected]de4afb5e2012-12-20 00:11:34397 events->push_back(AnimationEvent(AnimationEvent::Finished, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
[email protected]4d0786a2013-01-07 16:21:20398 m_activeAnimations[j]->setRunState(Animation::WaitingForDeletion, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14399 }
400 }
401 }
402 }
403}
404
[email protected]ead39c52013-01-09 07:22:45405static bool isWaitingForDeletion(Animation* animation) { return animation->runState() == Animation::WaitingForDeletion; }
406
[email protected]96baf3e2012-10-22 23:09:55407void LayerAnimationController::purgeAnimationsMarkedForDeletion()
[email protected]94f206c12012-08-25 00:09:14408{
[email protected]ead39c52013-01-09 07:22:45409 ScopedPtrVector<Animation>& animations = m_activeAnimations;
410 animations.erase(cc::remove_if(animations, animations.begin(), animations.end(), isWaitingForDeletion), animations.end());
[email protected]94f206c12012-08-25 00:09:14411}
412
[email protected]96baf3e2012-10-22 23:09:55413void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14414{
415 controllerImpl->m_activeAnimations.clear();
416 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20417 scoped_ptr<Animation> toAdd;
[email protected]94f206c12012-08-25 00:09:14418 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
419 // We haven't received an animation started notification yet, so it
420 // is important that we add it in a 'waiting' and not 'running' state.
[email protected]4d0786a2013-01-07 16:21:20421 Animation::RunState initialRunState = Animation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14422 double startTime = 0;
[email protected]4d0786a2013-01-07 16:21:20423 toAdd = m_activeAnimations[i]->cloneAndInitialize(Animation::ControllingInstance, initialRunState, startTime).Pass();
[email protected]94f206c12012-08-25 00:09:14424 } else
[email protected]4d0786a2013-01-07 16:21:20425 toAdd = m_activeAnimations[i]->clone(Animation::ControllingInstance).Pass();
[email protected]94f206c12012-08-25 00:09:14426
[email protected]9aca3592012-10-12 15:57:09427 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14428 }
429}
430
[email protected]96baf3e2012-10-22 23:09:55431void LayerAnimationController::tickAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14432{
[email protected]df1ec1a2012-12-08 17:01:18433 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20434 if (m_activeAnimations[i]->runState() == Animation::Running || m_activeAnimations[i]->runState() == Animation::Paused) {
[email protected]94f206c12012-08-25 00:09:14435 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
436
437 // Animation assumes its initial value until it gets the synchronized start time
438 // from the impl thread and can start ticking.
439 if (m_activeAnimations[i]->needsSynchronizedStartTime())
440 trimmed = 0;
441
442 switch (m_activeAnimations[i]->targetProperty()) {
443
[email protected]4d0786a2013-01-07 16:21:20444 case Animation::Transform: {
[email protected]96baf3e2012-10-22 23:09:55445 const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
[email protected]0e6ebab2013-01-04 00:09:37446 const gfx::Transform transform = convertWebTransformationMatrixToTransform(transformAnimationCurve->getValue(trimmed));
[email protected]94f206c12012-08-25 00:09:14447 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]4d0786a2013-01-07 16:21:20448 m_activeAnimations[i]->setRunState(Animation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18449
[email protected]de4afb5e2012-12-20 00:11:34450 notifyObserversTransformAnimated(transform);
[email protected]94f206c12012-08-25 00:09:14451 break;
452 }
453
[email protected]4d0786a2013-01-07 16:21:20454 case Animation::Opacity: {
[email protected]96baf3e2012-10-22 23:09:55455 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
[email protected]df1ec1a2012-12-08 17:01:18456 const float opacity = floatAnimationCurve->getValue(trimmed);
[email protected]94f206c12012-08-25 00:09:14457 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]4d0786a2013-01-07 16:21:20458 m_activeAnimations[i]->setRunState(Animation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18459
[email protected]de4afb5e2012-12-20 00:11:34460 notifyObserversOpacityAnimated(opacity);
[email protected]94f206c12012-08-25 00:09:14461 break;
462 }
463
464 // Do nothing for sentinel value.
[email protected]4d0786a2013-01-07 16:21:20465 case Animation::TargetPropertyEnumSize:
[email protected]1d993172012-10-18 18:15:04466 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14467 }
468 }
469 }
470}
471
[email protected]de4afb5e2012-12-20 00:11:34472void LayerAnimationController::updateActivation(bool force)
473{
474 if (m_registrar) {
[email protected]ead39c52013-01-09 07:22:45475 if (!m_activeAnimations.empty() && (!m_isActive || force))
[email protected]de4afb5e2012-12-20 00:11:34476 m_registrar->DidActivateAnimationController(this);
[email protected]ead39c52013-01-09 07:22:45477 else if (m_activeAnimations.empty() && (m_isActive || force))
[email protected]de4afb5e2012-12-20 00:11:34478 m_registrar->DidDeactivateAnimationController(this);
[email protected]ead39c52013-01-09 07:22:45479 m_isActive = !m_activeAnimations.empty();
[email protected]de4afb5e2012-12-20 00:11:34480 }
481}
482
483void LayerAnimationController::notifyObserversOpacityAnimated(float opacity)
484{
485 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
486 m_observers,
487 OnOpacityAnimated(opacity));
488}
489
490void LayerAnimationController::notifyObserversTransformAnimated(const gfx::Transform& transform)
491{
492 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
493 m_observers,
494 OnTransformAnimated(transform));
495}
496
[email protected]58676772013-01-07 15:50:15497bool LayerAnimationController::hasActiveObserver()
498{
499 if (m_observers.might_have_observers()) {
500 ObserverListBase<LayerAnimationValueObserver>::Iterator it(m_observers);
501 LayerAnimationValueObserver* obs;
502 while ((obs = it.GetNext()) != NULL)
503 if (obs->IsActive())
504 return true;
505 }
506 return false;
507}
508
[email protected]d3143c732012-10-05 19:17:59509} // namespace cc