Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: Source/core/platform/graphics/GraphicsLayerAnimation.cpp

Issue 15804002: Remove unused GraphicsLayerAnimation (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/platform/graphics/GraphicsLayerAnimation.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #include "core/platform/graphics/GraphicsLayerAnimation.h"
23
24 #include "core/platform/graphics/LayoutSize.h"
25 #include "core/platform/graphics/UnitBezier.h"
26 #include <wtf/CurrentTime.h>
27
28 namespace WebCore {
29
30 static inline PassRefPtr<FilterOperation> blendFunc(FilterOperation* fromOp, Fil terOperation* toOp, double progress, const IntSize& size, bool blendToPassthroug h = false)
31 {
32 ASSERT(toOp);
33 if (toOp->blendingNeedsRendererSize())
34 return toOp->blend(fromOp, progress, LayoutSize(size.width(), size.heigh t()), blendToPassthrough);
35
36 return toOp->blend(fromOp, progress, blendToPassthrough);
37 }
38
39
40 static FilterOperations applyFilterAnimation(const FilterOperations* from, const FilterOperations* to, double progress, const IntSize& boxSize)
41 {
42 // First frame of an animation.
43 if (!progress)
44 return *from;
45
46 // Last frame of an animation.
47 if (progress == 1)
48 return *to;
49
50 if (!from->operationsMatch(*to))
51 return *to;
52
53 FilterOperations result;
54
55 size_t fromSize = from->operations().size();
56 size_t toSize = to->operations().size();
57 size_t size = std::max(fromSize, toSize);
58 for (size_t i = 0; i < size; i++) {
59 RefPtr<FilterOperation> fromOp = (i < fromSize) ? from->operations()[i]. get() : 0;
60 RefPtr<FilterOperation> toOp = (i < toSize) ? to->operations()[i].get() : 0;
61 RefPtr<FilterOperation> blendedOp = toOp ? blendFunc(fromOp.get(), toOp. get(), progress, boxSize) : (fromOp ? blendFunc(0, fromOp.get(), progress, boxSi ze, true) : 0);
62 if (blendedOp)
63 result.operations().append(blendedOp);
64 else {
65 RefPtr<FilterOperation> identityOp = PassthroughFilterOperation::cre ate();
66 if (progress > 0.5)
67 result.operations().append(toOp ? toOp : identityOp);
68 else
69 result.operations().append(fromOp ? fromOp : identityOp);
70 }
71 }
72
73 return result;
74 }
75
76 static bool shouldReverseAnimationValue(CSSAnimationData::AnimationDirection dir ection, int loopCount)
77 {
78 if (((direction == CSSAnimationData::AnimationDirectionAlternate) && (loopCo unt & 1))
79 || ((direction == CSSAnimationData::AnimationDirectionAlternateReverse) && !(loopCount & 1))
80 || direction == CSSAnimationData::AnimationDirectionReverse)
81 return true;
82 return false;
83 }
84
85 static double normalizedAnimationValue(double runningTime, double duration, CSSA nimationData::AnimationDirection direction, double iterationCount)
86 {
87 if (!duration)
88 return 0;
89
90 const int loopCount = runningTime / duration;
91 const double lastFullLoop = duration * double(loopCount);
92 const double remainder = runningTime - lastFullLoop;
93 // Ignore remainder when we've reached the end of animation.
94 const double normalized = (loopCount == iterationCount) ? 1.0 : (remainder / duration);
95
96 return shouldReverseAnimationValue(direction, loopCount) ? 1 - normalized : normalized;
97 }
98
99 static double normalizedAnimationValueForFillsForwards(double iterationCount, CS SAnimationData::AnimationDirection direction)
100 {
101 if (direction == CSSAnimationData::AnimationDirectionNormal)
102 return 1;
103 if (direction == CSSAnimationData::AnimationDirectionReverse)
104 return 0;
105 return shouldReverseAnimationValue(direction, iterationCount) ? 1 : 0;
106 }
107
108 static float applyOpacityAnimation(float fromOpacity, float toOpacity, double pr ogress)
109 {
110 // Optimization: special case the edge values (0 and 1).
111 if (progress == 1.0)
112 return toOpacity;
113
114 if (!progress)
115 return fromOpacity;
116
117 return fromOpacity + progress * (toOpacity - fromOpacity);
118 }
119
120 static inline double solveEpsilon(double duration)
121 {
122 return 1.0 / (200.0 * duration);
123 }
124
125 static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x , double p2y, double t, double duration)
126 {
127 return UnitBezier(p1x, p1y, p2x, p2y).solve(t, solveEpsilon(duration));
128 }
129
130 static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t )
131 {
132 if (stepAtStart)
133 return std::min(1.0, (floor(numSteps * t) + 1) / numSteps);
134 return floor(numSteps * t) / numSteps;
135 }
136
137 static inline float applyTimingFunction(const TimingFunction* timingFunction, fl oat progress, double duration)
138 {
139 if (!timingFunction)
140 return progress;
141
142 if (timingFunction->isCubicBezierTimingFunction()) {
143 const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimi ngFunction*>(timingFunction);
144 return solveCubicBezierFunction(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2 (), progress, duration);
145 }
146
147 if (timingFunction->isStepsTimingFunction()) {
148 const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*> (timingFunction);
149 return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), doub le(progress));
150 }
151
152 return progress;
153 }
154
155 static TransformationMatrix applyTransformAnimation(const TransformOperations* f rom, const TransformOperations* to, double progress, const IntSize& boxSize, boo l listsMatch)
156 {
157 TransformationMatrix matrix;
158
159 // First frame of an animation.
160 if (!progress) {
161 from->apply(boxSize, matrix);
162 return matrix;
163 }
164
165 // Last frame of an animation.
166 if (progress == 1) {
167 to->apply(boxSize, matrix);
168 return matrix;
169 }
170
171 // If we have incompatible operation lists, we blend the resulting matrices.
172 if (!listsMatch) {
173 TransformationMatrix fromMatrix;
174 to->apply(boxSize, matrix);
175 from->apply(boxSize, fromMatrix);
176 matrix.blend(fromMatrix, progress);
177 return matrix;
178 }
179
180 // Animation to "-webkit-transform: none".
181 if (!to->size()) {
182 TransformOperations blended(*from);
183 for (size_t i = 0; i < blended.operations().size(); ++i)
184 blended.operations()[i]->blend(0, progress, true)->apply(matrix, box Size);
185 return matrix;
186 }
187
188 // Animation from "-webkit-transform: none".
189 if (!from->size()) {
190 TransformOperations blended(*to);
191 for (size_t i = 0; i < blended.operations().size(); ++i)
192 blended.operations()[i]->blend(0, 1. - progress, true)->apply(matrix , boxSize);
193 return matrix;
194 }
195
196 // Normal animation with a matching operation list.
197 TransformOperations blended(*to);
198 for (size_t i = 0; i < blended.operations().size(); ++i)
199 blended.operations()[i]->blend(from->at(i), progress, !from->at(i))->app ly(matrix, boxSize);
200 return matrix;
201 }
202
203 static const TimingFunction* timingFunctionForAnimationValue(const AnimationValu e* animValue, const CSSAnimationData* anim)
204 {
205 if (animValue->timingFunction())
206 return animValue->timingFunction();
207 if (anim->timingFunction())
208 return anim->timingFunction().get();
209
210 return CubicBezierTimingFunction::defaultTimingFunction();
211 }
212
213 GraphicsLayerAnimation::GraphicsLayerAnimation(const String& name, const Keyfram eValueList& keyframes, const IntSize& boxSize, const CSSAnimationData* animation , double startTime, bool listsMatch)
214 : m_keyframes(keyframes)
215 , m_boxSize(boxSize)
216 , m_animation(CSSAnimationData::create(animation))
217 , m_name(name)
218 , m_listsMatch(listsMatch)
219 , m_startTime(startTime)
220 , m_pauseTime(0)
221 , m_totalRunningTime(0)
222 , m_lastRefreshedTime(m_startTime)
223 , m_state(PlayingState)
224 {
225 }
226
227 void GraphicsLayerAnimation::applyInternal(Client* client, const AnimationValue* from, const AnimationValue* to, float progress)
228 {
229 switch (m_keyframes.property()) {
230 case AnimatedPropertyOpacity:
231 client->setAnimatedOpacity(applyOpacityAnimation((static_cast<const Floa tAnimationValue*>(from)->value()), (static_cast<const FloatAnimationValue*>(to)- >value()), progress));
232 return;
233 case AnimatedPropertyWebkitTransform:
234 client->setAnimatedTransform(applyTransformAnimation(static_cast<const T ransformAnimationValue*>(from)->value(), static_cast<const TransformAnimationVal ue*>(to)->value(), progress, m_boxSize, m_listsMatch));
235 return;
236 case AnimatedPropertyWebkitFilter:
237 client->setAnimatedFilters(applyFilterAnimation(static_cast<const Filter AnimationValue*>(from)->value(), static_cast<const FilterAnimationValue*>(to)->v alue(), progress, m_boxSize));
238 return;
239 default:
240 ASSERT_NOT_REACHED();
241 }
242 }
243
244 bool GraphicsLayerAnimation::isActive() const
245 {
246 if (state() != StoppedState)
247 return true;
248
249 return m_animation->fillsForwards();
250 }
251
252 bool GraphicsLayerAnimations::hasActiveAnimationsOfType(AnimatedPropertyID type) const
253 {
254 for (size_t i = 0; i < m_animations.size(); ++i) {
255 if (m_animations[i].isActive() && m_animations[i].property() == type)
256 return true;
257 }
258 return false;
259 }
260
261 bool GraphicsLayerAnimations::hasRunningAnimations() const
262 {
263 for (size_t i = 0; i < m_animations.size(); ++i) {
264 if (m_animations[i].state() == GraphicsLayerAnimation::PlayingState)
265 return true;
266 }
267
268 return false;
269 }
270
271 void GraphicsLayerAnimation::apply(Client* client)
272 {
273 if (!isActive())
274 return;
275
276 double totalRunningTime = computeTotalRunningTime();
277 double normalizedValue = normalizedAnimationValue(totalRunningTime, m_animat ion->duration(), m_animation->direction(), m_animation->iterationCount());
278
279 if (m_animation->iterationCount() != CSSAnimationData::IterationCountInfinit e && totalRunningTime >= m_animation->duration() * m_animation->iterationCount() ) {
280 setState(StoppedState);
281 if (m_animation->fillsForwards())
282 normalizedValue = normalizedAnimationValueForFillsForwards(m_animati on->iterationCount(), m_animation->direction());
283 }
284
285 if (!normalizedValue) {
286 applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), 0);
287 return;
288 }
289
290 if (normalizedValue == 1.0) {
291 applyInternal(client, m_keyframes.at(m_keyframes.size() - 2), m_keyframe s.at(m_keyframes.size() - 1), 1);
292 return;
293 }
294 if (m_keyframes.size() == 2) {
295 const TimingFunction* timingFunction = timingFunctionForAnimationValue(m _keyframes.at(0), m_animation.get());
296 normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m _animation->duration());
297 applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), normalizedVa lue);
298 return;
299 }
300
301 for (size_t i = 0; i < m_keyframes.size() - 1; ++i) {
302 const AnimationValue* from = m_keyframes.at(i);
303 const AnimationValue* to = m_keyframes.at(i + 1);
304 if (from->keyTime() > normalizedValue || to->keyTime() < normalizedValue )
305 continue;
306
307 normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime());
308 const TimingFunction* timingFunction = timingFunctionForAnimationValue(f rom, m_animation.get());
309 normalizedValue = applyTimingFunction(timingFunction, normalizedValue, m _animation->duration());
310 applyInternal(client, from, to, normalizedValue);
311 break;
312 }
313 }
314
315 double GraphicsLayerAnimation::computeTotalRunningTime()
316 {
317 if (state() == PausedState)
318 return m_pauseTime;
319
320 double oldLastRefreshedTime = m_lastRefreshedTime;
321 m_lastRefreshedTime = WTF::currentTime();
322 m_totalRunningTime += m_lastRefreshedTime - oldLastRefreshedTime;
323 return m_totalRunningTime;
324 }
325
326 void GraphicsLayerAnimation::pause(double time)
327 {
328 setState(PausedState);
329 m_pauseTime = time;
330 }
331
332 void GraphicsLayerAnimation::resume()
333 {
334 setState(PlayingState);
335 m_totalRunningTime = m_pauseTime;
336 m_lastRefreshedTime = WTF::currentTime();
337 }
338
339 void GraphicsLayerAnimations::add(const GraphicsLayerAnimation& animation)
340 {
341 // Remove the old state if we are resuming a paused animation.
342 remove(animation.name(), animation.property());
343
344 m_animations.append(animation);
345 }
346
347 void GraphicsLayerAnimations::pause(const String& name, double offset)
348 {
349 for (size_t i = 0; i < m_animations.size(); ++i) {
350 if (m_animations[i].name() == name)
351 m_animations[i].pause(offset);
352 }
353 }
354
355 void GraphicsLayerAnimations::suspend(double offset)
356 {
357 for (size_t i = 0; i < m_animations.size(); ++i)
358 m_animations[i].pause(offset);
359 }
360
361 void GraphicsLayerAnimations::resume()
362 {
363 for (size_t i = 0; i < m_animations.size(); ++i)
364 m_animations[i].resume();
365 }
366
367 void GraphicsLayerAnimations::remove(const String& name)
368 {
369 for (int i = m_animations.size() - 1; i >= 0; --i) {
370 if (m_animations[i].name() == name)
371 m_animations.remove(i);
372 }
373 }
374
375 void GraphicsLayerAnimations::remove(const String& name, AnimatedPropertyID prop erty)
376 {
377 for (int i = m_animations.size() - 1; i >= 0; --i) {
378 if (m_animations[i].name() == name && m_animations[i].property() == prop erty)
379 m_animations.remove(i);
380 }
381 }
382
383 void GraphicsLayerAnimations::apply(GraphicsLayerAnimation::Client* client)
384 {
385 for (size_t i = 0; i < m_animations.size(); ++i)
386 m_animations[i].apply(client);
387 }
388
389 GraphicsLayerAnimations GraphicsLayerAnimations::getActiveAnimations() const
390 {
391 GraphicsLayerAnimations active;
392 for (size_t i = 0; i < m_animations.size(); ++i) {
393 if (m_animations[i].isActive())
394 active.add(m_animations[i]);
395 }
396 return active;
397 }
398 }
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/GraphicsLayerAnimation.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698