blob: 06b22bc65cf344e9a59b965bf26af03a356c9d06 [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]415f53e2012-12-21 01:02:157#include "cc/active_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]415f53e2012-12-21 01:02:1562 m_activeAnimations[i]->setRunState(ActiveAnimation::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]415f53e2012-12-21 01:02:1577void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::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]415f53e2012-12-21 01:02:1593 m_activeAnimations[i]->setRunState(ActiveAnimation::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]415f53e2012-12-21 01:02:15101 if (m_activeAnimations[i]->runState() == ActiveAnimation::Paused)
102 m_activeAnimations[i]->setRunState(ActiveAnimation::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{
130 startAnimationsWaitingForNextTick(monotonicTime, events);
131 startAnimationsWaitingForStartTime(monotonicTime, events);
132 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
133 resolveConflicts(monotonicTime);
134 tickAnimations(monotonicTime);
135 markAnimationsForDeletion(monotonicTime, events);
136 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
[email protected]de4afb5e2012-12-20 00:11:34137
138 updateActivation();
[email protected]94f206c12012-08-25 00:09:14139}
140
[email protected]415f53e2012-12-21 01:02:15141void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation)
[email protected]94f206c12012-08-25 00:09:14142{
[email protected]9aca3592012-10-12 15:57:09143 m_activeAnimations.append(animation.Pass());
[email protected]de4afb5e2012-12-20 00:11:34144 updateActivation();
[email protected]94f206c12012-08-25 00:09:14145}
146
[email protected]415f53e2012-12-21 01:02:15147ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14148{
149 for (size_t i = 0; i < m_activeAnimations.size(); ++i)
150 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03151 return m_activeAnimations[i];
[email protected]94f206c12012-08-25 00:09:14152 return 0;
153}
154
[email protected]415f53e2012-12-21 01:02:15155ActiveAnimation* LayerAnimationController::getActiveAnimation(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14156{
157 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
158 size_t index = m_activeAnimations.size() - i - 1;
159 if (m_activeAnimations[index]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03160 return m_activeAnimations[index];
[email protected]94f206c12012-08-25 00:09:14161 }
162 return 0;
163}
164
[email protected]96baf3e2012-10-22 23:09:55165bool LayerAnimationController::hasActiveAnimation() const
[email protected]94f206c12012-08-25 00:09:14166{
167 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
168 if (!m_activeAnimations[i]->isFinished())
169 return true;
170 }
171 return false;
172}
173
[email protected]415f53e2012-12-21 01:02:15174bool LayerAnimationController::isAnimatingProperty(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14175{
176 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15177 if (m_activeAnimations[i]->runState() != ActiveAnimation::Finished && m_activeAnimations[i]->runState() != ActiveAnimation::Aborted && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]94f206c12012-08-25 00:09:14178 return true;
179 }
180 return false;
181}
182
[email protected]e10cd022012-12-18 00:32:26183void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
[email protected]94f206c12012-08-25 00:09:14184{
185 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
186 if (m_activeAnimations[i]->group() == event.groupId && m_activeAnimations[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSynchronizedStartTime()) {
187 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
188 m_activeAnimations[i]->setStartTime(event.monotonicTime);
189 return;
190 }
191 }
192}
193
[email protected]de4afb5e2012-12-20 00:11:34194void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registrar)
[email protected]94f206c12012-08-25 00:09:14195{
[email protected]de4afb5e2012-12-20 00:11:34196 if (m_registrar == registrar)
197 return;
198
199 if (m_registrar)
200 m_registrar->UnregisterAnimationController(this);
201
202 m_registrar = registrar;
203 if (m_registrar)
204 m_registrar->RegisterAnimationController(this);
205
206 bool force = true;
207 updateActivation(force);
208}
209
210void LayerAnimationController::addObserver(LayerAnimationValueObserver* observer)
211{
212 if (!m_observers.HasObserver(observer))
213 m_observers.AddObserver(observer);
214}
215
216void LayerAnimationController::removeObserver(LayerAnimationValueObserver* observer)
217{
218 m_observers.RemoveObserver(observer);
[email protected]94f206c12012-08-25 00:09:14219}
220
[email protected]96baf3e2012-10-22 23:09:55221void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14222{
223 // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
224 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
225 // If the animation is already running on the impl thread, there is no need to copy it over.
[email protected]415f53e2012-12-21 01:02:15226 if (controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
[email protected]94f206c12012-08-25 00:09:14227 continue;
228
229 // If the animation is not running on the impl thread, it does not necessarily mean that it needs
230 // to be copied over and started; it may have already finished. In this case, the impl thread animation
231 // will have already notified that it has started and the main thread animation will no longer need
232 // a synchronized start time.
233 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
234 continue;
235
236 // The new animation should be set to run as soon as possible.
[email protected]415f53e2012-12-21 01:02:15237 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14238 double startTime = 0;
[email protected]415f53e2012-12-21 01:02:15239 scoped_ptr<ActiveAnimation> toAdd(m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime));
[email protected]1d993172012-10-18 18:15:04240 DCHECK(!toAdd->needsSynchronizedStartTime());
[email protected]9aca3592012-10-12 15:57:09241 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14242 }
243}
244
[email protected]96baf3e2012-10-22 23:09:55245void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14246{
247 // Delete all impl thread animations for which there is no corresponding main thread animation.
248 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
249 // guaranteeing progress towards loop termination.
250 for (size_t i = 0; i < controllerImpl->m_activeAnimations.size();) {
[email protected]415f53e2012-12-21 01:02:15251 ActiveAnimation* current = getActiveAnimation(controllerImpl->m_activeAnimations[i]->group(), controllerImpl->m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14252 if (!current)
253 controllerImpl->m_activeAnimations.remove(i);
254 else
255 i++;
256 }
257}
258
[email protected]96baf3e2012-10-22 23:09:55259void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14260{
261 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15262 ActiveAnimation* currentImpl = controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14263 if (currentImpl)
264 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
265 }
266}
267
[email protected]96baf3e2012-10-22 23:09:55268void LayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14269{
270 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15271 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForNextTick) {
272 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14273 if (!m_activeAnimations[i]->hasSetStartTime())
274 m_activeAnimations[i]->setStartTime(monotonicTime);
275 if (events)
[email protected]de4afb5e2012-12-20 00:11:34276 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14277 }
278 }
279}
280
[email protected]96baf3e2012-10-22 23:09:55281void LayerAnimationController::startAnimationsWaitingForStartTime(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14282{
283 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15284 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
285 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14286 if (events)
[email protected]de4afb5e2012-12-20 00:11:34287 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14288 }
289 }
290}
291
[email protected]96baf3e2012-10-22 23:09:55292void LayerAnimationController::startAnimationsWaitingForTargetAvailability(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14293{
294 // First collect running properties.
295 TargetProperties blockedProperties;
296 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15297 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Finished)
[email protected]c7278e5b2012-10-11 02:35:46298 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14299 }
300
301 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15302 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForTargetAvailability) {
[email protected]94f206c12012-08-25 00:09:14303 // Collect all properties for animations with the same group id (they should all also be in the list of animations).
304 TargetProperties enqueuedProperties;
[email protected]c7278e5b2012-10-11 02:35:46305 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14306 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
307 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group())
[email protected]c7278e5b2012-10-11 02:35:46308 enqueuedProperties.insert(m_activeAnimations[j]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14309 }
310
311 // Check to see if intersection of the list of properties affected by the group and the list of currently
312 // blocked properties is null. In any case, the group's target properties need to be added to the list
313 // of blocked properties.
314 bool nullIntersection = true;
315 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
[email protected]c7278e5b2012-10-11 02:35:46316 if (!blockedProperties.insert(*pIter).second)
[email protected]94f206c12012-08-25 00:09:14317 nullIntersection = false;
318 }
319
320 // If the intersection is null, then we are free to start the animations in the group.
321 if (nullIntersection) {
[email protected]415f53e2012-12-21 01:02:15322 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14323 if (!m_activeAnimations[i]->hasSetStartTime())
324 m_activeAnimations[i]->setStartTime(monotonicTime);
325 if (events)
[email protected]de4afb5e2012-12-20 00:11:34326 events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14327 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
328 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
[email protected]415f53e2012-12-21 01:02:15329 m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14330 if (!m_activeAnimations[j]->hasSetStartTime())
331 m_activeAnimations[j]->setStartTime(monotonicTime);
332 }
333 }
334 }
335 }
336 }
337}
338
[email protected]96baf3e2012-10-22 23:09:55339void LayerAnimationController::resolveConflicts(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14340{
341 // Find any animations that are animating the same property and resolve the
342 // confict. We could eventually blend, but for now we'll just abort the
343 // previous animation (where 'previous' means: (1) has a prior start time or
344 // (2) has an equal start time, but was added to the queue earlier, i.e.,
345 // has a lower index in m_activeAnimations).
346 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15347 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running) {
[email protected]94f206c12012-08-25 00:09:14348 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
[email protected]415f53e2012-12-21 01:02:15349 if (m_activeAnimations[j]->runState() == ActiveAnimation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
[email protected]94f206c12012-08-25 00:09:14350 if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
[email protected]415f53e2012-12-21 01:02:15351 m_activeAnimations[j]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14352 else
[email protected]415f53e2012-12-21 01:02:15353 m_activeAnimations[i]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14354 }
355 }
356 }
357 }
358}
359
[email protected]96baf3e2012-10-22 23:09:55360void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14361{
362 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
363 int groupId = m_activeAnimations[i]->group();
364 bool allAnimsWithSameIdAreFinished = false;
365 // If an animation is finished, and not already marked for deletion,
366 // Find out if all other animations in the same group are also finished.
367 if (m_activeAnimations[i]->isFinished()) {
368 allAnimsWithSameIdAreFinished = true;
369 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
370 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimations[j]->isFinished()) {
371 allAnimsWithSameIdAreFinished = false;
372 break;
373 }
374 }
375 }
376 if (allAnimsWithSameIdAreFinished) {
377 // We now need to remove all animations with the same group id as groupId
378 // (and send along animation finished notifications, if necessary).
379 for (size_t j = i; j < m_activeAnimations.size(); j++) {
380 if (groupId == m_activeAnimations[j]->group()) {
381 if (events)
[email protected]de4afb5e2012-12-20 00:11:34382 events->push_back(AnimationEvent(AnimationEvent::Finished, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
[email protected]415f53e2012-12-21 01:02:15383 m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14384 }
385 }
386 }
387 }
388}
389
[email protected]96baf3e2012-10-22 23:09:55390void LayerAnimationController::purgeAnimationsMarkedForDeletion()
[email protected]94f206c12012-08-25 00:09:14391{
392 for (size_t i = 0; i < m_activeAnimations.size();) {
[email protected]415f53e2012-12-21 01:02:15393 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForDeletion)
[email protected]94f206c12012-08-25 00:09:14394 m_activeAnimations.remove(i);
395 else
396 i++;
397 }
398}
399
[email protected]96baf3e2012-10-22 23:09:55400void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14401{
402 controllerImpl->m_activeAnimations.clear();
403 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15404 scoped_ptr<ActiveAnimation> toAdd;
[email protected]94f206c12012-08-25 00:09:14405 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
406 // We haven't received an animation started notification yet, so it
407 // is important that we add it in a 'waiting' and not 'running' state.
[email protected]415f53e2012-12-21 01:02:15408 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14409 double startTime = 0;
[email protected]415f53e2012-12-21 01:02:15410 toAdd = m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime).Pass();
[email protected]94f206c12012-08-25 00:09:14411 } else
[email protected]415f53e2012-12-21 01:02:15412 toAdd = m_activeAnimations[i]->clone(ActiveAnimation::ControllingInstance).Pass();
[email protected]94f206c12012-08-25 00:09:14413
[email protected]9aca3592012-10-12 15:57:09414 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14415 }
416}
417
[email protected]96baf3e2012-10-22 23:09:55418void LayerAnimationController::tickAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14419{
[email protected]df1ec1a2012-12-08 17:01:18420 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]415f53e2012-12-21 01:02:15421 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Paused) {
[email protected]94f206c12012-08-25 00:09:14422 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
423
424 // Animation assumes its initial value until it gets the synchronized start time
425 // from the impl thread and can start ticking.
426 if (m_activeAnimations[i]->needsSynchronizedStartTime())
427 trimmed = 0;
428
429 switch (m_activeAnimations[i]->targetProperty()) {
430
[email protected]415f53e2012-12-21 01:02:15431 case ActiveAnimation::Transform: {
[email protected]96baf3e2012-10-22 23:09:55432 const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
[email protected]0e6ebab2013-01-04 00:09:37433 const gfx::Transform transform = convertWebTransformationMatrixToTransform(transformAnimationCurve->getValue(trimmed));
[email protected]94f206c12012-08-25 00:09:14434 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]415f53e2012-12-21 01:02:15435 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18436
[email protected]de4afb5e2012-12-20 00:11:34437 notifyObserversTransformAnimated(transform);
[email protected]94f206c12012-08-25 00:09:14438 break;
439 }
440
[email protected]415f53e2012-12-21 01:02:15441 case ActiveAnimation::Opacity: {
[email protected]96baf3e2012-10-22 23:09:55442 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
[email protected]df1ec1a2012-12-08 17:01:18443 const float opacity = floatAnimationCurve->getValue(trimmed);
[email protected]94f206c12012-08-25 00:09:14444 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]415f53e2012-12-21 01:02:15445 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18446
[email protected]de4afb5e2012-12-20 00:11:34447 notifyObserversOpacityAnimated(opacity);
[email protected]94f206c12012-08-25 00:09:14448 break;
449 }
450
451 // Do nothing for sentinel value.
[email protected]415f53e2012-12-21 01:02:15452 case ActiveAnimation::TargetPropertyEnumSize:
[email protected]1d993172012-10-18 18:15:04453 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14454 }
455 }
456 }
457}
458
[email protected]de4afb5e2012-12-20 00:11:34459void LayerAnimationController::updateActivation(bool force)
460{
461 if (m_registrar) {
462 if (!m_activeAnimations.isEmpty() && (!m_isActive || force))
463 m_registrar->DidActivateAnimationController(this);
464 else if (m_activeAnimations.isEmpty() && (m_isActive || force))
465 m_registrar->DidDeactivateAnimationController(this);
466 m_isActive = !m_activeAnimations.isEmpty();
467 }
468}
469
470void LayerAnimationController::notifyObserversOpacityAnimated(float opacity)
471{
472 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
473 m_observers,
474 OnOpacityAnimated(opacity));
475}
476
477void LayerAnimationController::notifyObserversTransformAnimated(const gfx::Transform& transform)
478{
479 FOR_EACH_OBSERVER(LayerAnimationValueObserver,
480 m_observers,
481 OnTransformAnimated(transform));
482}
483
[email protected]d3143c732012-10-05 19:17:59484} // namespace cc