blob: 1e7d1c1b63dd367a0fa9a37db46ca03c3532a624 [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]4d0786a2013-01-07 16:21:207#include "cc/animation.h"
[email protected]de4afb5e2012-12-20 00:11:348#include "cc/animation_registrar.h"
[email protected]d50c6862012-10-23 02:08:319#include "cc/keyframed_animation_curve.h"
[email protected]de4afb5e2012-12-20 00:11:3410#include "cc/layer_animation_value_observer.h"
[email protected]c8686a02012-11-27 08:29:0011#include "ui/gfx/transform.h"
[email protected]94f206c12012-08-25 00:09:1412
[email protected]0e6ebab2013-01-04 00:09:3713namespace {
14gfx::Transform convertWebTransformationMatrixToTransform(const WebKit::WebTransformationMatrix& matrix)
15{
16 gfx::Transform transform;
17 transform.matrix().setDouble(0, 0, matrix.m11());
18 transform.matrix().setDouble(0, 1, matrix.m21());
19 transform.matrix().setDouble(0, 2, matrix.m31());
20 transform.matrix().setDouble(0, 3, matrix.m41());
21 transform.matrix().setDouble(1, 0, matrix.m12());
22 transform.matrix().setDouble(1, 1, matrix.m22());
23 transform.matrix().setDouble(1, 2, matrix.m32());
24 transform.matrix().setDouble(1, 3, matrix.m42());
25 transform.matrix().setDouble(2, 0, matrix.m13());
26 transform.matrix().setDouble(2, 1, matrix.m23());
27 transform.matrix().setDouble(2, 2, matrix.m33());
28 transform.matrix().setDouble(2, 3, matrix.m43());
29 transform.matrix().setDouble(3, 0, matrix.m14());
30 transform.matrix().setDouble(3, 1, matrix.m24());
31 transform.matrix().setDouble(3, 2, matrix.m34());
32 transform.matrix().setDouble(3, 3, matrix.m44());
33 return transform;
34}
35} // namespace
36
[email protected]9c88e562012-09-14 22:21:3037namespace cc {
[email protected]94f206c12012-08-25 00:09:1438
[email protected]de4afb5e2012-12-20 00:11:3439LayerAnimationController::LayerAnimationController(int id)
[email protected]94f206c12012-08-25 00:09:1440 : m_forceSync(false)
[email protected]de4afb5e2012-12-20 00:11:3441 , m_id(id)
42 , m_registrar(0)
43 , m_isActive(false)
[email protected]94f206c12012-08-25 00:09:1444{
45}
46
[email protected]96baf3e2012-10-22 23:09:5547LayerAnimationController::~LayerAnimationController()
[email protected]94f206c12012-08-25 00:09:1448{
[email protected]de4afb5e2012-12-20 00:11:3449 if (m_registrar)
50 m_registrar->UnregisterAnimationController(this);
[email protected]94f206c12012-08-25 00:09:1451}
52
[email protected]de4afb5e2012-12-20 00:11:3453scoped_refptr<LayerAnimationController> LayerAnimationController::create(int id)
[email protected]94f206c12012-08-25 00:09:1454{
[email protected]de4afb5e2012-12-20 00:11:3455 return make_scoped_refptr(new LayerAnimationController(id));
[email protected]94f206c12012-08-25 00:09:1456}
57
[email protected]96baf3e2012-10-22 23:09:5558void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
[email protected]94f206c12012-08-25 00:09:1459{
60 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
61 if (m_activeAnimations[i]->id() == animationId)
[email protected]4d0786a2013-01-07 16:21:2062 m_activeAnimations[i]->setRunState(Animation::Paused, timeOffset + m_activeAnimations[i]->startTime());
[email protected]94f206c12012-08-25 00:09:1463 }
64}
65
[email protected]96baf3e2012-10-22 23:09:5566void LayerAnimationController::removeAnimation(int animationId)
[email protected]94f206c12012-08-25 00:09:1467{
68 for (size_t i = 0; i < m_activeAnimations.size();) {
69 if (m_activeAnimations[i]->id() == animationId)
70 m_activeAnimations.remove(i);
71 else
72 i++;
73 }
[email protected]de4afb5e2012-12-20 00:11:3474 updateActivation();
[email protected]94f206c12012-08-25 00:09:1475}
76
[email protected]4d0786a2013-01-07 16:21:2077void LayerAnimationController::removeAnimation(int animationId, Animation::TargetProperty targetProperty)
[email protected]94f206c12012-08-25 00:09:1478{
79 for (size_t i = 0; i < m_activeAnimations.size();) {
80 if (m_activeAnimations[i]->id() == animationId && m_activeAnimations[i]->targetProperty() == targetProperty)
81 m_activeAnimations.remove(i);
82 else
83 i++;
84 }
[email protected]de4afb5e2012-12-20 00:11:3485 updateActivation();
[email protected]94f206c12012-08-25 00:09:1486}
87
88// According to render layer backing, these are for testing only.
[email protected]96baf3e2012-10-22 23:09:5589void LayerAnimationController::suspendAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1490{
91 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
92 if (!m_activeAnimations[i]->isFinished())
[email protected]4d0786a2013-01-07 16:21:2093 m_activeAnimations[i]->setRunState(Animation::Paused, monotonicTime);
[email protected]94f206c12012-08-25 00:09:1494 }
95}
96
97// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
[email protected]96baf3e2012-10-22 23:09:5598void LayerAnimationController::resumeAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1499{
100 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20101 if (m_activeAnimations[i]->runState() == Animation::Paused)
102 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14103 }
104}
105
106// Ensures that the list of active animations on the main thread and the impl thread
107// are kept in sync.
[email protected]96baf3e2012-10-22 23:09:55108void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
[email protected]94f206c12012-08-25 00:09:14109{
110 if (m_forceSync) {
111 replaceImplThreadAnimations(controllerImpl);
112 m_forceSync = false;
113 } else {
114 purgeAnimationsMarkedForDeletion();
115 pushNewAnimationsToImplThread(controllerImpl);
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(controllerImpl);
121
122 pushPropertiesToImplThread(controllerImpl);
123 }
[email protected]de4afb5e2012-12-20 00:11:34124 controllerImpl->updateActivation();
125 updateActivation();
[email protected]94f206c12012-08-25 00:09:14126}
127
[email protected]96baf3e2012-10-22 23:09:55128void LayerAnimationController::animate(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14129{
[email protected]58676772013-01-07 15:50:15130 if (!hasActiveObserver())
131 return;
132
[email protected]94f206c12012-08-25 00:09:14133 startAnimationsWaitingForNextTick(monotonicTime, events);
134 startAnimationsWaitingForStartTime(monotonicTime, events);
135 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
136 resolveConflicts(monotonicTime);
137 tickAnimations(monotonicTime);
138 markAnimationsForDeletion(monotonicTime, events);
139 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
[email protected]de4afb5e2012-12-20 00:11:34140
141 updateActivation();
[email protected]94f206c12012-08-25 00:09:14142}
143
[email protected]4d0786a2013-01-07 16:21:20144void LayerAnimationController::addAnimation(scoped_ptr<Animation> animation)
[email protected]94f206c12012-08-25 00:09:14145{
[email protected]9aca3592012-10-12 15:57:09146 m_activeAnimations.append(animation.Pass());
[email protected]de4afb5e2012-12-20 00:11:34147 updateActivation();
[email protected]94f206c12012-08-25 00:09:14148}
149
[email protected]4d0786a2013-01-07 16:21:20150Animation* LayerAnimationController::getAnimation(int groupId, Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14151{
152 for (size_t i = 0; i < m_activeAnimations.size(); ++i)
153 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03154 return m_activeAnimations[i];
[email protected]94f206c12012-08-25 00:09:14155 return 0;
156}
157
[email protected]4d0786a2013-01-07 16:21:20158Animation* LayerAnimationController::getAnimation(Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14159{
160 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
161 size_t index = m_activeAnimations.size() - i - 1;
162 if (m_activeAnimations[index]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03163 return m_activeAnimations[index];
[email protected]94f206c12012-08-25 00:09:14164 }
165 return 0;
166}
167
[email protected]96baf3e2012-10-22 23:09:55168bool LayerAnimationController::hasActiveAnimation() const
[email protected]94f206c12012-08-25 00:09:14169{
170 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
171 if (!m_activeAnimations[i]->isFinished())
172 return true;
173 }
174 return false;
175}
176
[email protected]4d0786a2013-01-07 16:21:20177bool LayerAnimationController::isAnimatingProperty(Animation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14178{
179 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20180 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:14181 return true;
182 }
183 return false;
184}
185
[email protected]e10cd022012-12-18 00:32:26186void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
[email protected]94f206c12012-08-25 00:09:14187{
188 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
189 if (m_activeAnimations[i]->group() == event.groupId && m_activeAnimations[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSynchronizedStartTime()) {
190 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
191 m_activeAnimations[i]->setStartTime(event.monotonicTime);
192 return;
193 }
194 }
195}
196
[email protected]de4afb5e2012-12-20 00:11:34197void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registrar)
[email protected]94f206c12012-08-25 00:09:14198{
[email protected]de4afb5e2012-12-20 00:11:34199 if (m_registrar == registrar)
200 return;
201
202 if (m_registrar)
203 m_registrar->UnregisterAnimationController(this);
204
205 m_registrar = registrar;
206 if (m_registrar)
207 m_registrar->RegisterAnimationController(this);
208
209 bool force = true;
210 updateActivation(force);
211}
212
213void LayerAnimationController::addObserver(LayerAnimationValueObserver* observer)
214{
215 if (!m_observers.HasObserver(observer))
216 m_observers.AddObserver(observer);
217}
218
219void LayerAnimationController::removeObserver(LayerAnimationValueObserver* observer)
220{
221 m_observers.RemoveObserver(observer);
[email protected]94f206c12012-08-25 00:09:14222}
223
[email protected]96baf3e2012-10-22 23:09:55224void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14225{
226 // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
227 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
228 // 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:20229 if (controllerImpl->getAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
[email protected]94f206c12012-08-25 00:09:14230 continue;
231
232 // If the animation is not running on the impl thread, it does not necessarily mean that it needs
233 // to be copied over and started; it may have already finished. In this case, the impl thread animation
234 // will have already notified that it has started and the main thread animation will no longer need
235 // a synchronized start time.
236 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
237 continue;
238
239 // The new animation should be set to run as soon as possible.
[email protected]4d0786a2013-01-07 16:21:20240 Animation::RunState initialRunState = Animation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14241 double startTime = 0;
[email protected]4d0786a2013-01-07 16:21:20242 scoped_ptr<Animation> toAdd(m_activeAnimations[i]->cloneAndInitialize(Animation::ControllingInstance, initialRunState, startTime));
[email protected]1d993172012-10-18 18:15:04243 DCHECK(!toAdd->needsSynchronizedStartTime());
[email protected]9aca3592012-10-12 15:57:09244 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14245 }
246}
247
[email protected]96baf3e2012-10-22 23:09:55248void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14249{
250 // Delete all impl thread animations for which there is no corresponding main thread animation.
251 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
252 // guaranteeing progress towards loop termination.
253 for (size_t i = 0; i < controllerImpl->m_activeAnimations.size();) {
[email protected]4d0786a2013-01-07 16:21:20254 Animation* current = getAnimation(controllerImpl->m_activeAnimations[i]->group(), controllerImpl->m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14255 if (!current)
256 controllerImpl->m_activeAnimations.remove(i);
257 else
258 i++;
259 }
260}
261
[email protected]96baf3e2012-10-22 23:09:55262void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14263{
264 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20265 Animation* currentImpl = controllerImpl->getAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14266 if (currentImpl)
267 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
268 }
269}
270
[email protected]96baf3e2012-10-22 23:09:55271void LayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14272{
273 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20274 if (m_activeAnimations[i]->runState() == Animation::WaitingForNextTick) {
275 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14276 if (!m_activeAnimations[i]->hasSetStartTime())
277 m_activeAnimations[i]->setStartTime(monotonicTime);
278 if (events)
[email protected]de4afb5e2012-12-20 00:11:34279 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14280 }
281 }
282}
283
[email protected]96baf3e2012-10-22 23:09:55284void LayerAnimationController::startAnimationsWaitingForStartTime(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14285{
286 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20287 if (m_activeAnimations[i]->runState() == Animation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
288 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14289 if (events)
[email protected]de4afb5e2012-12-20 00:11:34290 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14291 }
292 }
293}
294
[email protected]96baf3e2012-10-22 23:09:55295void LayerAnimationController::startAnimationsWaitingForTargetAvailability(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14296{
297 // First collect running properties.
298 TargetProperties blockedProperties;
299 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20300 if (m_activeAnimations[i]->runState() == Animation::Running || m_activeAnimations[i]->runState() == Animation::Finished)
[email protected]c7278e5b2012-10-11 02:35:46301 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14302 }
303
304 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20305 if (m_activeAnimations[i]->runState() == Animation::WaitingForTargetAvailability) {
[email protected]94f206c12012-08-25 00:09:14306 // Collect all properties for animations with the same group id (they should all also be in the list of animations).
307 TargetProperties enqueuedProperties;
[email protected]c7278e5b2012-10-11 02:35:46308 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14309 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
310 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group())
[email protected]c7278e5b2012-10-11 02:35:46311 enqueuedProperties.insert(m_activeAnimations[j]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14312 }
313
314 // Check to see if intersection of the list of properties affected by the group and the list of currently
315 // blocked properties is null. In any case, the group's target properties need to be added to the list
316 // of blocked properties.
317 bool nullIntersection = true;
318 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
[email protected]c7278e5b2012-10-11 02:35:46319 if (!blockedProperties.insert(*pIter).second)
[email protected]94f206c12012-08-25 00:09:14320 nullIntersection = false;
321 }
322
323 // If the intersection is null, then we are free to start the animations in the group.
324 if (nullIntersection) {
[email protected]4d0786a2013-01-07 16:21:20325 m_activeAnimations[i]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14326 if (!m_activeAnimations[i]->hasSetStartTime())
327 m_activeAnimations[i]->setStartTime(monotonicTime);
328 if (events)
[email protected]de4afb5e2012-12-20 00:11:34329 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14330 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
331 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
[email protected]4d0786a2013-01-07 16:21:20332 m_activeAnimations[j]->setRunState(Animation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14333 if (!m_activeAnimations[j]->hasSetStartTime())
334 m_activeAnimations[j]->setStartTime(monotonicTime);
335 }
336 }
337 }
338 }
339 }
340}
341
[email protected]96baf3e2012-10-22 23:09:55342void LayerAnimationController::resolveConflicts(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14343{
344 // Find any animations that are animating the same property and resolve the
345 // confict. We could eventually blend, but for now we'll just abort the
346 // previous animation (where 'previous' means: (1) has a prior start time or
347 // (2) has an equal start time, but was added to the queue earlier, i.e.,
348 // has a lower index in m_activeAnimations).
349 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20350 if (m_activeAnimations[i]->runState() == Animation::Running) {
[email protected]94f206c12012-08-25 00:09:14351 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
[email protected]4d0786a2013-01-07 16:21:20352 if (m_activeAnimations[j]->runState() == Animation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
[email protected]94f206c12012-08-25 00:09:14353 if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
[email protected]4d0786a2013-01-07 16:21:20354 m_activeAnimations[j]->setRunState(Animation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14355 else
[email protected]4d0786a2013-01-07 16:21:20356 m_activeAnimations[i]->setRunState(Animation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14357 }
358 }
359 }
360 }
361}
362
[email protected]96baf3e2012-10-22 23:09:55363void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14364{
365 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
366 int groupId = m_activeAnimations[i]->group();
367 bool allAnimsWithSameIdAreFinished = false;
368 // If an animation is finished, and not already marked for deletion,
369 // Find out if all other animations in the same group are also finished.
370 if (m_activeAnimations[i]->isFinished()) {
371 allAnimsWithSameIdAreFinished = true;
372 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
373 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimations[j]->isFinished()) {
374 allAnimsWithSameIdAreFinished = false;
375 break;
376 }
377 }
378 }
379 if (allAnimsWithSameIdAreFinished) {
380 // We now need to remove all animations with the same group id as groupId
381 // (and send along animation finished notifications, if necessary).
382 for (size_t j = i; j < m_activeAnimations.size(); j++) {
383 if (groupId == m_activeAnimations[j]->group()) {
384 if (events)
[email protected]de4afb5e2012-12-20 00:11:34385 events->push_back(AnimationEvent(AnimationEvent::Finished, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
[email protected]4d0786a2013-01-07 16:21:20386 m_activeAnimations[j]->setRunState(Animation::WaitingForDeletion, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14387 }
388 }
389 }
390 }
391}
392
[email protected]96baf3e2012-10-22 23:09:55393void LayerAnimationController::purgeAnimationsMarkedForDeletion()
[email protected]94f206c12012-08-25 00:09:14394{
395 for (size_t i = 0; i < m_activeAnimations.size();) {
[email protected]4d0786a2013-01-07 16:21:20396 if (m_activeAnimations[i]->runState() == Animation::WaitingForDeletion)
[email protected]94f206c12012-08-25 00:09:14397 m_activeAnimations.remove(i);
398 else
399 i++;
400 }
401}
402
[email protected]96baf3e2012-10-22 23:09:55403void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14404{
405 controllerImpl->m_activeAnimations.clear();
406 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20407 scoped_ptr<Animation> toAdd;
[email protected]94f206c12012-08-25 00:09:14408 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
409 // We haven't received an animation started notification yet, so it
410 // is important that we add it in a 'waiting' and not 'running' state.
[email protected]4d0786a2013-01-07 16:21:20411 Animation::RunState initialRunState = Animation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14412 double startTime = 0;
[email protected]4d0786a2013-01-07 16:21:20413 toAdd = m_activeAnimations[i]->cloneAndInitialize(Animation::ControllingInstance, initialRunState, startTime).Pass();
[email protected]94f206c12012-08-25 00:09:14414 } else
[email protected]4d0786a2013-01-07 16:21:20415 toAdd = m_activeAnimations[i]->clone(Animation::ControllingInstance).Pass();
[email protected]94f206c12012-08-25 00:09:14416
[email protected]9aca3592012-10-12 15:57:09417 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14418 }
419}
420
[email protected]96baf3e2012-10-22 23:09:55421void LayerAnimationController::tickAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14422{
[email protected]df1ec1a2012-12-08 17:01:18423 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]4d0786a2013-01-07 16:21:20424 if (m_activeAnimations[i]->runState() == Animation::Running || m_activeAnimations[i]->runState() == Animation::Paused) {
[email protected]94f206c12012-08-25 00:09:14425 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
426
427 // Animation assumes its initial value until it gets the synchronized start time
428 // from the impl thread and can start ticking.
429 if (m_activeAnimations[i]->needsSynchronizedStartTime())
430 trimmed = 0;
431
432 switch (m_activeAnimations[i]->targetProperty()) {
433
[email protected]4d0786a2013-01-07 16:21:20434 case Animation::Transform: {
[email protected]96baf3e2012-10-22 23:09:55435 const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
[email protected]0e6ebab2013-01-04 00:09:37436 const gfx::Transform transform = convertWebTransformationMatrixToTransform(transformAnimationCurve->getValue(trimmed));
[email protected]94f206c12012-08-25 00:09:14437 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]4d0786a2013-01-07 16:21:20438 m_activeAnimations[i]->setRunState(Animation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18439
[email protected]de4afb5e2012-12-20 00:11:34440 notifyObserversTransformAnimated(transform);
[email protected]94f206c12012-08-25 00:09:14441 break;
442 }
443
[email protected]4d0786a2013-01-07 16:21:20444 case Animation::Opacity: {
[email protected]96baf3e2012-10-22 23:09:55445 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
[email protected]df1ec1a2012-12-08 17:01:18446 const float opacity = floatAnimationCurve->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 notifyObserversOpacityAnimated(opacity);
[email protected]94f206c12012-08-25 00:09:14451 break;
452 }
453
454 // Do nothing for sentinel value.
[email protected]4d0786a2013-01-07 16:21:20455 case Animation::TargetPropertyEnumSize:
[email protected]1d993172012-10-18 18:15:04456 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14457 }
458 }
459 }
460}
461
[email protected]de4afb5e2012-12-20 00:11:34462void LayerAnimationController::updateActivation(bool force)
463{
464 if (m_registrar) {
465 if (!m_activeAnimations.isEmpty() && (!m_isActive || force))
466 m_registrar->DidActivateAnimationController(this);
467 else if (m_activeAnimations.isEmpty() && (m_isActive || force))
468 m_registrar->DidDeactivateAnimationController(this);
469 m_isActive = !m_activeAnimations.isEmpty();
470 }
471}
472
473void LayerAnimationController::notifyObserversOpacityAnimated(float opacity)
474{
475 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
476 m_observers,
477 OnOpacityAnimated(opacity));
478}
479
480void LayerAnimationController::notifyObserversTransformAnimated(const gfx::Transform& transform)
481{
482 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
483 m_observers,
484 OnTransformAnimated(transform));
485}
486
[email protected]58676772013-01-07 15:50:15487bool LayerAnimationController::hasActiveObserver()
488{
489 if (m_observers.might_have_observers()) {
490 ObserverListBase<LayerAnimationValueObserver>::Iterator it(m_observers);
491 LayerAnimationValueObserver* obs;
492 while ((obs = it.GetNext()) != NULL)
493 if (obs->IsActive())
494 return true;
495 }
496 return false;
497}
498
[email protected]d3143c732012-10-05 19:17:59499} // namespace cc