blob: a45bb4318235fb3b8d23f4d5fde80119faef427a [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]aa0a9d32012-10-24 01:58:107#include "cc/active_animation.h"
[email protected]d50c6862012-10-23 02:08:318#include "cc/keyframed_animation_curve.h"
[email protected]c8686a02012-11-27 08:29:009#include "ui/gfx/transform.h"
[email protected]94f206c12012-08-25 00:09:1410
[email protected]9c88e562012-09-14 22:21:3011namespace cc {
[email protected]94f206c12012-08-25 00:09:1412
[email protected]df1ec1a2012-12-08 17:01:1813LayerAnimationController::LayerAnimationController(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:1414 : m_forceSync(false)
[email protected]df1ec1a2012-12-08 17:01:1815 , m_client(client)
[email protected]94f206c12012-08-25 00:09:1416{
17}
18
[email protected]96baf3e2012-10-22 23:09:5519LayerAnimationController::~LayerAnimationController()
[email protected]94f206c12012-08-25 00:09:1420{
21}
22
[email protected]df1ec1a2012-12-08 17:01:1823scoped_ptr<LayerAnimationController> LayerAnimationController::create(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:1424{
[email protected]df1ec1a2012-12-08 17:01:1825 return make_scoped_ptr(new LayerAnimationController(client));
[email protected]94f206c12012-08-25 00:09:1426}
27
[email protected]96baf3e2012-10-22 23:09:5528void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
[email protected]94f206c12012-08-25 00:09:1429{
30 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
31 if (m_activeAnimations[i]->id() == animationId)
[email protected]96baf3e2012-10-22 23:09:5532 m_activeAnimations[i]->setRunState(ActiveAnimation::Paused, timeOffset + m_activeAnimations[i]->startTime());
[email protected]94f206c12012-08-25 00:09:1433 }
34}
35
[email protected]96baf3e2012-10-22 23:09:5536void LayerAnimationController::removeAnimation(int animationId)
[email protected]94f206c12012-08-25 00:09:1437{
38 for (size_t i = 0; i < m_activeAnimations.size();) {
39 if (m_activeAnimations[i]->id() == animationId)
40 m_activeAnimations.remove(i);
41 else
42 i++;
43 }
44}
45
[email protected]96baf3e2012-10-22 23:09:5546void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty)
[email protected]94f206c12012-08-25 00:09:1447{
48 for (size_t i = 0; i < m_activeAnimations.size();) {
49 if (m_activeAnimations[i]->id() == animationId && m_activeAnimations[i]->targetProperty() == targetProperty)
50 m_activeAnimations.remove(i);
51 else
52 i++;
53 }
54}
55
56// According to render layer backing, these are for testing only.
[email protected]96baf3e2012-10-22 23:09:5557void LayerAnimationController::suspendAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1458{
59 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
60 if (!m_activeAnimations[i]->isFinished())
[email protected]96baf3e2012-10-22 23:09:5561 m_activeAnimations[i]->setRunState(ActiveAnimation::Paused, monotonicTime);
[email protected]94f206c12012-08-25 00:09:1462 }
63}
64
65// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
[email protected]96baf3e2012-10-22 23:09:5566void LayerAnimationController::resumeAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1467{
68 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:5569 if (m_activeAnimations[i]->runState() == ActiveAnimation::Paused)
70 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:1471 }
72}
73
74// Ensures that the list of active animations on the main thread and the impl thread
75// are kept in sync.
[email protected]96baf3e2012-10-22 23:09:5576void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
[email protected]94f206c12012-08-25 00:09:1477{
78 if (m_forceSync) {
79 replaceImplThreadAnimations(controllerImpl);
80 m_forceSync = false;
81 } else {
82 purgeAnimationsMarkedForDeletion();
83 pushNewAnimationsToImplThread(controllerImpl);
84
85 // Remove finished impl side animations only after pushing,
86 // and only after the animations are deleted on the main thread
87 // this insures we will never push an animation twice.
88 removeAnimationsCompletedOnMainThread(controllerImpl);
89
90 pushPropertiesToImplThread(controllerImpl);
91 }
92}
93
[email protected]96baf3e2012-10-22 23:09:5594void LayerAnimationController::animate(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:1495{
96 startAnimationsWaitingForNextTick(monotonicTime, events);
97 startAnimationsWaitingForStartTime(monotonicTime, events);
98 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
99 resolveConflicts(monotonicTime);
100 tickAnimations(monotonicTime);
101 markAnimationsForDeletion(monotonicTime, events);
102 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
103}
104
[email protected]96baf3e2012-10-22 23:09:55105void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation)
[email protected]94f206c12012-08-25 00:09:14106{
[email protected]9aca3592012-10-12 15:57:09107 m_activeAnimations.append(animation.Pass());
[email protected]94f206c12012-08-25 00:09:14108}
109
[email protected]96baf3e2012-10-22 23:09:55110ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14111{
112 for (size_t i = 0; i < m_activeAnimations.size(); ++i)
113 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03114 return m_activeAnimations[i];
[email protected]94f206c12012-08-25 00:09:14115 return 0;
116}
117
[email protected]96baf3e2012-10-22 23:09:55118ActiveAnimation* LayerAnimationController::getActiveAnimation(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14119{
120 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
121 size_t index = m_activeAnimations.size() - i - 1;
122 if (m_activeAnimations[index]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03123 return m_activeAnimations[index];
[email protected]94f206c12012-08-25 00:09:14124 }
125 return 0;
126}
127
[email protected]96baf3e2012-10-22 23:09:55128bool LayerAnimationController::hasActiveAnimation() const
[email protected]94f206c12012-08-25 00:09:14129{
130 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
131 if (!m_activeAnimations[i]->isFinished())
132 return true;
133 }
134 return false;
135}
136
[email protected]96baf3e2012-10-22 23:09:55137bool LayerAnimationController::isAnimatingProperty(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14138{
139 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55140 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:14141 return true;
142 }
143 return false;
144}
145
[email protected]e10cd022012-12-18 00:32:26146void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
[email protected]94f206c12012-08-25 00:09:14147{
148 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
149 if (m_activeAnimations[i]->group() == event.groupId && m_activeAnimations[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSynchronizedStartTime()) {
150 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
151 m_activeAnimations[i]->setStartTime(event.monotonicTime);
152 return;
153 }
154 }
155}
156
[email protected]df1ec1a2012-12-08 17:01:18157void LayerAnimationController::setClient(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:14158{
[email protected]df1ec1a2012-12-08 17:01:18159 m_client = client;
[email protected]94f206c12012-08-25 00:09:14160}
161
[email protected]96baf3e2012-10-22 23:09:55162void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14163{
164 // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
165 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
166 // If the animation is already running on the impl thread, there is no need to copy it over.
167 if (controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
168 continue;
169
170 // If the animation is not running on the impl thread, it does not necessarily mean that it needs
171 // to be copied over and started; it may have already finished. In this case, the impl thread animation
172 // will have already notified that it has started and the main thread animation will no longer need
173 // a synchronized start time.
174 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
175 continue;
176
177 // The new animation should be set to run as soon as possible.
[email protected]96baf3e2012-10-22 23:09:55178 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14179 double startTime = 0;
[email protected]96baf3e2012-10-22 23:09:55180 scoped_ptr<ActiveAnimation> toAdd(m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime));
[email protected]1d993172012-10-18 18:15:04181 DCHECK(!toAdd->needsSynchronizedStartTime());
[email protected]9aca3592012-10-12 15:57:09182 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14183 }
184}
185
[email protected]96baf3e2012-10-22 23:09:55186void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14187{
188 // Delete all impl thread animations for which there is no corresponding main thread animation.
189 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
190 // guaranteeing progress towards loop termination.
191 for (size_t i = 0; i < controllerImpl->m_activeAnimations.size();) {
[email protected]96baf3e2012-10-22 23:09:55192 ActiveAnimation* current = getActiveAnimation(controllerImpl->m_activeAnimations[i]->group(), controllerImpl->m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14193 if (!current)
194 controllerImpl->m_activeAnimations.remove(i);
195 else
196 i++;
197 }
198}
199
[email protected]96baf3e2012-10-22 23:09:55200void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14201{
202 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55203 ActiveAnimation* currentImpl = controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14204 if (currentImpl)
205 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
206 }
207}
208
[email protected]96baf3e2012-10-22 23:09:55209void LayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14210{
211 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55212 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForNextTick) {
213 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14214 if (!m_activeAnimations[i]->hasSetStartTime())
215 m_activeAnimations[i]->setStartTime(monotonicTime);
216 if (events)
[email protected]df1ec1a2012-12-08 17:01:18217 events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14218 }
219 }
220}
221
[email protected]96baf3e2012-10-22 23:09:55222void LayerAnimationController::startAnimationsWaitingForStartTime(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14223{
224 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55225 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
226 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14227 if (events)
[email protected]df1ec1a2012-12-08 17:01:18228 events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14229 }
230 }
231}
232
[email protected]96baf3e2012-10-22 23:09:55233void LayerAnimationController::startAnimationsWaitingForTargetAvailability(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14234{
235 // First collect running properties.
236 TargetProperties blockedProperties;
237 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55238 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Finished)
[email protected]c7278e5b2012-10-11 02:35:46239 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14240 }
241
242 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55243 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForTargetAvailability) {
[email protected]94f206c12012-08-25 00:09:14244 // Collect all properties for animations with the same group id (they should all also be in the list of animations).
245 TargetProperties enqueuedProperties;
[email protected]c7278e5b2012-10-11 02:35:46246 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14247 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
248 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group())
[email protected]c7278e5b2012-10-11 02:35:46249 enqueuedProperties.insert(m_activeAnimations[j]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14250 }
251
252 // Check to see if intersection of the list of properties affected by the group and the list of currently
253 // blocked properties is null. In any case, the group's target properties need to be added to the list
254 // of blocked properties.
255 bool nullIntersection = true;
256 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
[email protected]c7278e5b2012-10-11 02:35:46257 if (!blockedProperties.insert(*pIter).second)
[email protected]94f206c12012-08-25 00:09:14258 nullIntersection = false;
259 }
260
261 // If the intersection is null, then we are free to start the animations in the group.
262 if (nullIntersection) {
[email protected]96baf3e2012-10-22 23:09:55263 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14264 if (!m_activeAnimations[i]->hasSetStartTime())
265 m_activeAnimations[i]->setStartTime(monotonicTime);
266 if (events)
[email protected]df1ec1a2012-12-08 17:01:18267 events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
[email protected]94f206c12012-08-25 00:09:14268 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
269 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
[email protected]96baf3e2012-10-22 23:09:55270 m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14271 if (!m_activeAnimations[j]->hasSetStartTime())
272 m_activeAnimations[j]->setStartTime(monotonicTime);
273 }
274 }
275 }
276 }
277 }
278}
279
[email protected]96baf3e2012-10-22 23:09:55280void LayerAnimationController::resolveConflicts(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14281{
282 // Find any animations that are animating the same property and resolve the
283 // confict. We could eventually blend, but for now we'll just abort the
284 // previous animation (where 'previous' means: (1) has a prior start time or
285 // (2) has an equal start time, but was added to the queue earlier, i.e.,
286 // has a lower index in m_activeAnimations).
287 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55288 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running) {
[email protected]94f206c12012-08-25 00:09:14289 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
[email protected]96baf3e2012-10-22 23:09:55290 if (m_activeAnimations[j]->runState() == ActiveAnimation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
[email protected]94f206c12012-08-25 00:09:14291 if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
[email protected]96baf3e2012-10-22 23:09:55292 m_activeAnimations[j]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14293 else
[email protected]96baf3e2012-10-22 23:09:55294 m_activeAnimations[i]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14295 }
296 }
297 }
298 }
299}
300
[email protected]96baf3e2012-10-22 23:09:55301void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14302{
303 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
304 int groupId = m_activeAnimations[i]->group();
305 bool allAnimsWithSameIdAreFinished = false;
306 // If an animation is finished, and not already marked for deletion,
307 // Find out if all other animations in the same group are also finished.
308 if (m_activeAnimations[i]->isFinished()) {
309 allAnimsWithSameIdAreFinished = true;
310 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
311 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimations[j]->isFinished()) {
312 allAnimsWithSameIdAreFinished = false;
313 break;
314 }
315 }
316 }
317 if (allAnimsWithSameIdAreFinished) {
318 // We now need to remove all animations with the same group id as groupId
319 // (and send along animation finished notifications, if necessary).
320 for (size_t j = i; j < m_activeAnimations.size(); j++) {
321 if (groupId == m_activeAnimations[j]->group()) {
322 if (events)
[email protected]df1ec1a2012-12-08 17:01:18323 events->push_back(AnimationEvent(AnimationEvent::Finished, m_client->id(), m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
[email protected]96baf3e2012-10-22 23:09:55324 m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14325 }
326 }
327 }
328 }
329}
330
[email protected]96baf3e2012-10-22 23:09:55331void LayerAnimationController::purgeAnimationsMarkedForDeletion()
[email protected]94f206c12012-08-25 00:09:14332{
333 for (size_t i = 0; i < m_activeAnimations.size();) {
[email protected]96baf3e2012-10-22 23:09:55334 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForDeletion)
[email protected]94f206c12012-08-25 00:09:14335 m_activeAnimations.remove(i);
336 else
337 i++;
338 }
339}
340
[email protected]96baf3e2012-10-22 23:09:55341void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14342{
343 controllerImpl->m_activeAnimations.clear();
344 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55345 scoped_ptr<ActiveAnimation> toAdd;
[email protected]94f206c12012-08-25 00:09:14346 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
347 // We haven't received an animation started notification yet, so it
348 // is important that we add it in a 'waiting' and not 'running' state.
[email protected]96baf3e2012-10-22 23:09:55349 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14350 double startTime = 0;
[email protected]96baf3e2012-10-22 23:09:55351 toAdd = m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime).Pass();
[email protected]94f206c12012-08-25 00:09:14352 } else
[email protected]96baf3e2012-10-22 23:09:55353 toAdd = m_activeAnimations[i]->clone(ActiveAnimation::ControllingInstance).Pass();
[email protected]94f206c12012-08-25 00:09:14354
[email protected]9aca3592012-10-12 15:57:09355 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14356 }
357}
358
[email protected]96baf3e2012-10-22 23:09:55359void LayerAnimationController::tickAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14360{
[email protected]df1ec1a2012-12-08 17:01:18361 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55362 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Paused) {
[email protected]94f206c12012-08-25 00:09:14363 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
364
365 // Animation assumes its initial value until it gets the synchronized start time
366 // from the impl thread and can start ticking.
367 if (m_activeAnimations[i]->needsSynchronizedStartTime())
368 trimmed = 0;
369
370 switch (m_activeAnimations[i]->targetProperty()) {
371
[email protected]96baf3e2012-10-22 23:09:55372 case ActiveAnimation::Transform: {
373 const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
[email protected]df1ec1a2012-12-08 17:01:18374 const gfx::Transform matrix = transformAnimationCurve->getValue(trimmed).toTransform();
[email protected]94f206c12012-08-25 00:09:14375 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]96baf3e2012-10-22 23:09:55376 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18377
378 m_client->setTransformFromAnimation(matrix);
[email protected]94f206c12012-08-25 00:09:14379 break;
380 }
381
[email protected]96baf3e2012-10-22 23:09:55382 case ActiveAnimation::Opacity: {
383 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
[email protected]df1ec1a2012-12-08 17:01:18384 const float opacity = floatAnimationCurve->getValue(trimmed);
[email protected]94f206c12012-08-25 00:09:14385 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]96baf3e2012-10-22 23:09:55386 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]df1ec1a2012-12-08 17:01:18387
388 m_client->setOpacityFromAnimation(opacity);
[email protected]94f206c12012-08-25 00:09:14389 break;
390 }
391
392 // Do nothing for sentinel value.
[email protected]96baf3e2012-10-22 23:09:55393 case ActiveAnimation::TargetPropertyEnumSize:
[email protected]1d993172012-10-18 18:15:04394 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14395 }
396 }
397 }
398}
399
[email protected]d3143c732012-10-05 19:17:59400} // namespace cc