blob: 4d7e6f836dba439e08f18f3705766fee67611e24 [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
5#include "config.h"
6
7#include "CCLayerAnimationController.h"
8
[email protected]1c0088f2012-10-17 00:29:309#include "CCActiveAnimation.h"
[email protected]94f206c12012-08-25 00:09:1410#include "CCKeyframedAnimationCurve.h"
11#include <public/WebTransformationMatrix.h>
[email protected]94f206c12012-08-25 00:09:1412
13using WebKit::WebTransformationMatrix;
14
[email protected]9c88e562012-09-14 22:21:3015namespace cc {
[email protected]94f206c12012-08-25 00:09:1416
[email protected]96baf3e2012-10-22 23:09:5517LayerAnimationController::LayerAnimationController(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:1418 : m_forceSync(false)
19 , m_client(client)
20{
21}
22
[email protected]96baf3e2012-10-22 23:09:5523LayerAnimationController::~LayerAnimationController()
[email protected]94f206c12012-08-25 00:09:1424{
25}
26
[email protected]96baf3e2012-10-22 23:09:5527scoped_ptr<LayerAnimationController> LayerAnimationController::create(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:1428{
[email protected]96baf3e2012-10-22 23:09:5529 return make_scoped_ptr(new LayerAnimationController(client));
[email protected]94f206c12012-08-25 00:09:1430}
31
[email protected]96baf3e2012-10-22 23:09:5532void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
[email protected]94f206c12012-08-25 00:09:1433{
34 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
35 if (m_activeAnimations[i]->id() == animationId)
[email protected]96baf3e2012-10-22 23:09:5536 m_activeAnimations[i]->setRunState(ActiveAnimation::Paused, timeOffset + m_activeAnimations[i]->startTime());
[email protected]94f206c12012-08-25 00:09:1437 }
38}
39
[email protected]96baf3e2012-10-22 23:09:5540void LayerAnimationController::removeAnimation(int animationId)
[email protected]94f206c12012-08-25 00:09:1441{
42 for (size_t i = 0; i < m_activeAnimations.size();) {
43 if (m_activeAnimations[i]->id() == animationId)
44 m_activeAnimations.remove(i);
45 else
46 i++;
47 }
48}
49
[email protected]96baf3e2012-10-22 23:09:5550void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty)
[email protected]94f206c12012-08-25 00:09:1451{
52 for (size_t i = 0; i < m_activeAnimations.size();) {
53 if (m_activeAnimations[i]->id() == animationId && m_activeAnimations[i]->targetProperty() == targetProperty)
54 m_activeAnimations.remove(i);
55 else
56 i++;
57 }
58}
59
60// According to render layer backing, these are for testing only.
[email protected]96baf3e2012-10-22 23:09:5561void LayerAnimationController::suspendAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1462{
63 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
64 if (!m_activeAnimations[i]->isFinished())
[email protected]96baf3e2012-10-22 23:09:5565 m_activeAnimations[i]->setRunState(ActiveAnimation::Paused, monotonicTime);
[email protected]94f206c12012-08-25 00:09:1466 }
67}
68
69// Looking at GraphicsLayerCA, this appears to be the analog to suspendAnimations, which is for testing.
[email protected]96baf3e2012-10-22 23:09:5570void LayerAnimationController::resumeAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:1471{
72 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:5573 if (m_activeAnimations[i]->runState() == ActiveAnimation::Paused)
74 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:1475 }
76}
77
78// Ensures that the list of active animations on the main thread and the impl thread
79// are kept in sync.
[email protected]96baf3e2012-10-22 23:09:5580void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
[email protected]94f206c12012-08-25 00:09:1481{
82 if (m_forceSync) {
83 replaceImplThreadAnimations(controllerImpl);
84 m_forceSync = false;
85 } else {
86 purgeAnimationsMarkedForDeletion();
87 pushNewAnimationsToImplThread(controllerImpl);
88
89 // Remove finished impl side animations only after pushing,
90 // and only after the animations are deleted on the main thread
91 // this insures we will never push an animation twice.
92 removeAnimationsCompletedOnMainThread(controllerImpl);
93
94 pushPropertiesToImplThread(controllerImpl);
95 }
96}
97
[email protected]96baf3e2012-10-22 23:09:5598void LayerAnimationController::animate(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:1499{
100 startAnimationsWaitingForNextTick(monotonicTime, events);
101 startAnimationsWaitingForStartTime(monotonicTime, events);
102 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
103 resolveConflicts(monotonicTime);
104 tickAnimations(monotonicTime);
105 markAnimationsForDeletion(monotonicTime, events);
106 startAnimationsWaitingForTargetAvailability(monotonicTime, events);
107}
108
[email protected]96baf3e2012-10-22 23:09:55109void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation)
[email protected]94f206c12012-08-25 00:09:14110{
[email protected]9aca3592012-10-12 15:57:09111 m_activeAnimations.append(animation.Pass());
[email protected]94f206c12012-08-25 00:09:14112}
113
[email protected]96baf3e2012-10-22 23:09:55114ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14115{
116 for (size_t i = 0; i < m_activeAnimations.size(); ++i)
117 if (m_activeAnimations[i]->group() == groupId && m_activeAnimations[i]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03118 return m_activeAnimations[i];
[email protected]94f206c12012-08-25 00:09:14119 return 0;
120}
121
[email protected]96baf3e2012-10-22 23:09:55122ActiveAnimation* LayerAnimationController::getActiveAnimation(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14123{
124 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
125 size_t index = m_activeAnimations.size() - i - 1;
126 if (m_activeAnimations[index]->targetProperty() == targetProperty)
[email protected]0920e24f2012-09-20 03:34:03127 return m_activeAnimations[index];
[email protected]94f206c12012-08-25 00:09:14128 }
129 return 0;
130}
131
[email protected]96baf3e2012-10-22 23:09:55132bool LayerAnimationController::hasActiveAnimation() const
[email protected]94f206c12012-08-25 00:09:14133{
134 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
135 if (!m_activeAnimations[i]->isFinished())
136 return true;
137 }
138 return false;
139}
140
[email protected]96baf3e2012-10-22 23:09:55141bool LayerAnimationController::isAnimatingProperty(ActiveAnimation::TargetProperty targetProperty) const
[email protected]94f206c12012-08-25 00:09:14142{
143 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55144 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:14145 return true;
146 }
147 return false;
148}
149
[email protected]96baf3e2012-10-22 23:09:55150void LayerAnimationController::notifyAnimationStarted(const AnimationEvent& event)
[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() == event.groupId && m_activeAnimations[i]->targetProperty() == event.targetProperty && m_activeAnimations[i]->needsSynchronizedStartTime()) {
154 m_activeAnimations[i]->setNeedsSynchronizedStartTime(false);
155 m_activeAnimations[i]->setStartTime(event.monotonicTime);
156 return;
157 }
158 }
159}
160
[email protected]96baf3e2012-10-22 23:09:55161void LayerAnimationController::setClient(LayerAnimationControllerClient* client)
[email protected]94f206c12012-08-25 00:09:14162{
163 m_client = client;
164}
165
[email protected]96baf3e2012-10-22 23:09:55166void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14167{
168 // Any new animations owned by the main thread's controller are cloned and adde to the impl thread's controller.
169 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
170 // If the animation is already running on the impl thread, there is no need to copy it over.
171 if (controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty()))
172 continue;
173
174 // If the animation is not running on the impl thread, it does not necessarily mean that it needs
175 // to be copied over and started; it may have already finished. In this case, the impl thread animation
176 // will have already notified that it has started and the main thread animation will no longer need
177 // a synchronized start time.
178 if (!m_activeAnimations[i]->needsSynchronizedStartTime())
179 continue;
180
181 // The new animation should be set to run as soon as possible.
[email protected]96baf3e2012-10-22 23:09:55182 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14183 double startTime = 0;
[email protected]96baf3e2012-10-22 23:09:55184 scoped_ptr<ActiveAnimation> toAdd(m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime));
[email protected]1d993172012-10-18 18:15:04185 DCHECK(!toAdd->needsSynchronizedStartTime());
[email protected]9aca3592012-10-12 15:57:09186 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14187 }
188}
189
[email protected]96baf3e2012-10-22 23:09:55190void LayerAnimationController::removeAnimationsCompletedOnMainThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14191{
192 // Delete all impl thread animations for which there is no corresponding main thread animation.
193 // Each iteration, controller->m_activeAnimations.size() is decremented or i is incremented
194 // guaranteeing progress towards loop termination.
195 for (size_t i = 0; i < controllerImpl->m_activeAnimations.size();) {
[email protected]96baf3e2012-10-22 23:09:55196 ActiveAnimation* current = getActiveAnimation(controllerImpl->m_activeAnimations[i]->group(), controllerImpl->m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14197 if (!current)
198 controllerImpl->m_activeAnimations.remove(i);
199 else
200 i++;
201 }
202}
203
[email protected]96baf3e2012-10-22 23:09:55204void LayerAnimationController::pushPropertiesToImplThread(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14205{
206 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55207 ActiveAnimation* currentImpl = controllerImpl->getActiveAnimation(m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14208 if (currentImpl)
209 m_activeAnimations[i]->pushPropertiesTo(currentImpl);
210 }
211}
212
[email protected]96baf3e2012-10-22 23:09:55213void LayerAnimationController::startAnimationsWaitingForNextTick(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14214{
215 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55216 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForNextTick) {
217 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14218 if (!m_activeAnimations[i]->hasSetStartTime())
219 m_activeAnimations[i]->setStartTime(monotonicTime);
220 if (events)
[email protected]96baf3e2012-10-22 23:09:55221 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:14222 }
223 }
224}
225
[email protected]96baf3e2012-10-22 23:09:55226void LayerAnimationController::startAnimationsWaitingForStartTime(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14227{
228 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55229 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
230 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14231 if (events)
[email protected]96baf3e2012-10-22 23:09:55232 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:14233 }
234 }
235}
236
[email protected]96baf3e2012-10-22 23:09:55237void LayerAnimationController::startAnimationsWaitingForTargetAvailability(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14238{
239 // First collect running properties.
240 TargetProperties blockedProperties;
241 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55242 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Finished)
[email protected]c7278e5b2012-10-11 02:35:46243 blockedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14244 }
245
246 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55247 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForTargetAvailability) {
[email protected]94f206c12012-08-25 00:09:14248 // Collect all properties for animations with the same group id (they should all also be in the list of animations).
249 TargetProperties enqueuedProperties;
[email protected]c7278e5b2012-10-11 02:35:46250 enqueuedProperties.insert(m_activeAnimations[i]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14251 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
252 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group())
[email protected]c7278e5b2012-10-11 02:35:46253 enqueuedProperties.insert(m_activeAnimations[j]->targetProperty());
[email protected]94f206c12012-08-25 00:09:14254 }
255
256 // Check to see if intersection of the list of properties affected by the group and the list of currently
257 // blocked properties is null. In any case, the group's target properties need to be added to the list
258 // of blocked properties.
259 bool nullIntersection = true;
260 for (TargetProperties::iterator pIter = enqueuedProperties.begin(); pIter != enqueuedProperties.end(); ++pIter) {
[email protected]c7278e5b2012-10-11 02:35:46261 if (!blockedProperties.insert(*pIter).second)
[email protected]94f206c12012-08-25 00:09:14262 nullIntersection = false;
263 }
264
265 // If the intersection is null, then we are free to start the animations in the group.
266 if (nullIntersection) {
[email protected]96baf3e2012-10-22 23:09:55267 m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14268 if (!m_activeAnimations[i]->hasSetStartTime())
269 m_activeAnimations[i]->setStartTime(monotonicTime);
270 if (events)
[email protected]96baf3e2012-10-22 23:09:55271 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:14272 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
273 if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
[email protected]96baf3e2012-10-22 23:09:55274 m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14275 if (!m_activeAnimations[j]->hasSetStartTime())
276 m_activeAnimations[j]->setStartTime(monotonicTime);
277 }
278 }
279 }
280 }
281 }
282}
283
[email protected]96baf3e2012-10-22 23:09:55284void LayerAnimationController::resolveConflicts(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14285{
286 // Find any animations that are animating the same property and resolve the
287 // confict. We could eventually blend, but for now we'll just abort the
288 // previous animation (where 'previous' means: (1) has a prior start time or
289 // (2) has an equal start time, but was added to the queue earlier, i.e.,
290 // has a lower index in m_activeAnimations).
291 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55292 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running) {
[email protected]94f206c12012-08-25 00:09:14293 for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
[email protected]96baf3e2012-10-22 23:09:55294 if (m_activeAnimations[j]->runState() == ActiveAnimation::Running && m_activeAnimations[i]->targetProperty() == m_activeAnimations[j]->targetProperty()) {
[email protected]94f206c12012-08-25 00:09:14295 if (m_activeAnimations[i]->startTime() > m_activeAnimations[j]->startTime())
[email protected]96baf3e2012-10-22 23:09:55296 m_activeAnimations[j]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14297 else
[email protected]96baf3e2012-10-22 23:09:55298 m_activeAnimations[i]->setRunState(ActiveAnimation::Aborted, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14299 }
300 }
301 }
302 }
303}
304
[email protected]96baf3e2012-10-22 23:09:55305void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, AnimationEventsVector* events)
[email protected]94f206c12012-08-25 00:09:14306{
307 for (size_t i = 0; i < m_activeAnimations.size(); i++) {
308 int groupId = m_activeAnimations[i]->group();
309 bool allAnimsWithSameIdAreFinished = false;
310 // If an animation is finished, and not already marked for deletion,
311 // Find out if all other animations in the same group are also finished.
312 if (m_activeAnimations[i]->isFinished()) {
313 allAnimsWithSameIdAreFinished = true;
314 for (size_t j = 0; j < m_activeAnimations.size(); ++j) {
315 if (groupId == m_activeAnimations[j]->group() && !m_activeAnimations[j]->isFinished()) {
316 allAnimsWithSameIdAreFinished = false;
317 break;
318 }
319 }
320 }
321 if (allAnimsWithSameIdAreFinished) {
322 // We now need to remove all animations with the same group id as groupId
323 // (and send along animation finished notifications, if necessary).
324 for (size_t j = i; j < m_activeAnimations.size(); j++) {
325 if (groupId == m_activeAnimations[j]->group()) {
326 if (events)
[email protected]96baf3e2012-10-22 23:09:55327 events->push_back(AnimationEvent(AnimationEvent::Finished, m_client->id(), m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
328 m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14329 }
330 }
331 }
332 }
333}
334
[email protected]96baf3e2012-10-22 23:09:55335void LayerAnimationController::purgeAnimationsMarkedForDeletion()
[email protected]94f206c12012-08-25 00:09:14336{
337 for (size_t i = 0; i < m_activeAnimations.size();) {
[email protected]96baf3e2012-10-22 23:09:55338 if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForDeletion)
[email protected]94f206c12012-08-25 00:09:14339 m_activeAnimations.remove(i);
340 else
341 i++;
342 }
343}
344
[email protected]96baf3e2012-10-22 23:09:55345void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationController* controllerImpl) const
[email protected]94f206c12012-08-25 00:09:14346{
347 controllerImpl->m_activeAnimations.clear();
348 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55349 scoped_ptr<ActiveAnimation> toAdd;
[email protected]94f206c12012-08-25 00:09:14350 if (m_activeAnimations[i]->needsSynchronizedStartTime()) {
351 // We haven't received an animation started notification yet, so it
352 // is important that we add it in a 'waiting' and not 'running' state.
[email protected]96baf3e2012-10-22 23:09:55353 ActiveAnimation::RunState initialRunState = ActiveAnimation::WaitingForTargetAvailability;
[email protected]94f206c12012-08-25 00:09:14354 double startTime = 0;
[email protected]96baf3e2012-10-22 23:09:55355 toAdd = m_activeAnimations[i]->cloneAndInitialize(ActiveAnimation::ControllingInstance, initialRunState, startTime).Pass();
[email protected]94f206c12012-08-25 00:09:14356 } else
[email protected]96baf3e2012-10-22 23:09:55357 toAdd = m_activeAnimations[i]->clone(ActiveAnimation::ControllingInstance).Pass();
[email protected]94f206c12012-08-25 00:09:14358
[email protected]9aca3592012-10-12 15:57:09359 controllerImpl->addAnimation(toAdd.Pass());
[email protected]94f206c12012-08-25 00:09:14360 }
361}
362
[email protected]96baf3e2012-10-22 23:09:55363void LayerAnimationController::tickAnimations(double monotonicTime)
[email protected]94f206c12012-08-25 00:09:14364{
365 for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
[email protected]96baf3e2012-10-22 23:09:55366 if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Paused) {
[email protected]94f206c12012-08-25 00:09:14367 double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
368
369 // Animation assumes its initial value until it gets the synchronized start time
370 // from the impl thread and can start ticking.
371 if (m_activeAnimations[i]->needsSynchronizedStartTime())
372 trimmed = 0;
373
374 switch (m_activeAnimations[i]->targetProperty()) {
375
[email protected]96baf3e2012-10-22 23:09:55376 case ActiveAnimation::Transform: {
377 const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
[email protected]94f206c12012-08-25 00:09:14378 const WebTransformationMatrix matrix = transformAnimationCurve->getValue(trimmed);
379 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]96baf3e2012-10-22 23:09:55380 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14381
382 m_client->setTransformFromAnimation(matrix);
383 break;
384 }
385
[email protected]96baf3e2012-10-22 23:09:55386 case ActiveAnimation::Opacity: {
387 const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
[email protected]94f206c12012-08-25 00:09:14388 const float opacity = floatAnimationCurve->getValue(trimmed);
389 if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
[email protected]96baf3e2012-10-22 23:09:55390 m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
[email protected]94f206c12012-08-25 00:09:14391
392 m_client->setOpacityFromAnimation(opacity);
393 break;
394 }
395
396 // Do nothing for sentinel value.
[email protected]96baf3e2012-10-22 23:09:55397 case ActiveAnimation::TargetPropertyEnumSize:
[email protected]1d993172012-10-18 18:15:04398 NOTREACHED();
[email protected]94f206c12012-08-25 00:09:14399 }
400 }
401 }
402}
403
[email protected]d3143c732012-10-05 19:17:59404} // namespace cc