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

Side by Side Diff: Source/core/platform/animation/AnimationTranslationUtil.cpp

Issue 112463008: Move core/platform/animation files (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add comments and platform tests Created 6 years, 11 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
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN Y
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN Y
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O N
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include "config.h"
26
27 #include "core/platform/animation/AnimationTranslationUtil.h"
28
29 #include "core/platform/animation/CSSAnimationData.h"
30 #include "core/platform/animation/KeyframeValueList.h"
31 #include "platform/LengthFunctions.h"
32 #include "platform/geometry/FloatSize.h"
33 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
34 #include "platform/transforms/InterpolatedTransformOperation.h"
35 #include "platform/transforms/Matrix3DTransformOperation.h"
36 #include "platform/transforms/MatrixTransformOperation.h"
37 #include "platform/transforms/PerspectiveTransformOperation.h"
38 #include "platform/transforms/RotateTransformOperation.h"
39 #include "platform/transforms/ScaleTransformOperation.h"
40 #include "platform/transforms/SkewTransformOperation.h"
41 #include "platform/transforms/TransformationMatrix.h"
42 #include "platform/transforms/TranslateTransformOperation.h"
43
44 #include "public/platform/Platform.h"
45 #include "public/platform/WebAnimation.h"
46 #include "public/platform/WebAnimationCurve.h"
47 #include "public/platform/WebCompositorSupport.h"
48 #include "public/platform/WebFilterAnimationCurve.h"
49 #include "public/platform/WebFloatAnimationCurve.h"
50 #include "public/platform/WebTransformAnimationCurve.h"
51
52 #include "wtf/OwnPtr.h"
53 #include "wtf/text/CString.h"
54
55 using namespace std;
56 using namespace blink;
57
58 namespace WebCore {
59
60 void toWebTransformOperations(const TransformOperations& transformOperations, co nst FloatSize& boxSize, WebTransformOperations* webTransformOperations)
61 {
62 // We need to do a deep copy the transformOperations may contain ref pointer s to TransformOperation objects.
63 for (size_t j = 0; j < transformOperations.size(); ++j) {
64 switch (transformOperations.operations()[j]->type()) {
65 case TransformOperation::ScaleX:
66 case TransformOperation::ScaleY:
67 case TransformOperation::ScaleZ:
68 case TransformOperation::Scale3D:
69 case TransformOperation::Scale: {
70 ScaleTransformOperation* transform = static_cast<ScaleTransformOpera tion*>(transformOperations.operations()[j].get());
71 webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
72 break;
73 }
74 case TransformOperation::TranslateX:
75 case TransformOperation::TranslateY:
76 case TransformOperation::TranslateZ:
77 case TransformOperation::Translate3D:
78 case TransformOperation::Translate: {
79 TranslateTransformOperation* transform = static_cast<TranslateTransf ormOperation*>(transformOperations.operations()[j].get());
80 webTransformOperations->appendTranslate(floatValueForLength(transfor m->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), transform->z());
81 break;
82 }
83 case TransformOperation::RotateX:
84 case TransformOperation::RotateY:
85 case TransformOperation::Rotate3D:
86 case TransformOperation::Rotate: {
87 RotateTransformOperation* transform = static_cast<RotateTransformOpe ration*>(transformOperations.operations()[j].get());
88 webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
89 break;
90 }
91 case TransformOperation::SkewX:
92 case TransformOperation::SkewY:
93 case TransformOperation::Skew: {
94 SkewTransformOperation* transform = static_cast<SkewTransformOperati on*>(transformOperations.operations()[j].get());
95 webTransformOperations->appendSkew(transform->angleX(), transform->a ngleY());
96 break;
97 }
98 case TransformOperation::Matrix: {
99 MatrixTransformOperation* transform = static_cast<MatrixTransformOpe ration*>(transformOperations.operations()[j].get());
100 TransformationMatrix m = transform->matrix();
101 webTransformOperations->appendMatrix(TransformationMatrix::toSkMatri x44(m));
102 break;
103 }
104 case TransformOperation::Matrix3D: {
105 Matrix3DTransformOperation* transform = static_cast<Matrix3DTransfor mOperation*>(transformOperations.operations()[j].get());
106 TransformationMatrix m = transform->matrix();
107 webTransformOperations->appendMatrix(TransformationMatrix::toSkMatri x44(m));
108 break;
109 }
110 case TransformOperation::Perspective: {
111 PerspectiveTransformOperation* transform = static_cast<PerspectiveTr ansformOperation*>(transformOperations.operations()[j].get());
112 webTransformOperations->appendPerspective(transform->perspective());
113 break;
114 }
115 case TransformOperation::Interpolated: {
116 TransformationMatrix m;
117 transformOperations.operations()[j]->apply(m, boxSize);
118 webTransformOperations->appendMatrix(TransformationMatrix::toSkMatri x44(m));
119 break;
120 }
121 case TransformOperation::Identity:
122 webTransformOperations->appendIdentity();
123 break;
124 case TransformOperation::None:
125 // Do nothing.
126 break;
127 } // switch
128 } // for each operation
129 }
130
131 template <class Value, class Keyframe, class Curve>
132 bool appendKeyframeWithStandardTimingFunction(Curve* curve, double keyTime, cons t Value* value, const Value* lastValue, blink::WebAnimationCurve::TimingFunction Type timingFunctionType, const FloatSize&)
133 {
134 curve->add(Keyframe(keyTime, value->value()), timingFunctionType);
135 return true;
136 }
137
138 template <class Value, class Keyframe, class Curve>
139 bool appendKeyframeWithCustomBezierTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, double x1, double y1, double x2, dou ble y2, const FloatSize&)
140 {
141 curve->add(Keyframe(keyTime, value->value()), x1, y1, x2, y2);
142 return true;
143 }
144
145 template <>
146 bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransf ormKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, doub le keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, blink::WebAnimationCurve::TimingFunctionType timingFunctionType, con st FloatSize& boxSize)
147 {
148 bool canBlend = !lastValue;
149 OwnPtr<WebTransformOperations> operations = adoptPtr(Platform::current()->co mpositorSupport()->createTransformOperations());
150 if (!operations)
151 return false;
152 toWebTransformOperations(*value->value(), boxSize, operations.get());
153 if (!canBlend) {
154 OwnPtr<WebTransformOperations> lastOperations = adoptPtr(Platform::curre nt()->compositorSupport()->createTransformOperations());
155 if (!lastOperations)
156 return false;
157 toWebTransformOperations(*lastValue->value(), boxSize, lastOperations.ge t());
158 canBlend = lastOperations->canBlendWith(*operations);
159 }
160 if (canBlend) {
161 curve->add(WebTransformKeyframe(keyTime, operations.release()), timingFu nctionType);
162 return true;
163 }
164 return false;
165 }
166
167 template <>
168 bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTr ansformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationVa lue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& box Size)
169 {
170 bool canBlend = !lastValue;
171 OwnPtr<WebTransformOperations> operations = adoptPtr(Platform::current()->co mpositorSupport()->createTransformOperations());
172 if (!operations)
173 return false;
174 toWebTransformOperations(*value->value(), boxSize, operations.get());
175 if (!canBlend) {
176 OwnPtr<WebTransformOperations> lastOperations = adoptPtr(Platform::curre nt()->compositorSupport()->createTransformOperations());
177 if (!lastOperations)
178 return false;
179 toWebTransformOperations(*lastValue->value(), boxSize, lastOperations.ge t());
180 canBlend = lastOperations->canBlendWith(*operations);
181 }
182 if (canBlend) {
183 curve->add(WebTransformKeyframe(keyTime, operations.release()), x1, y1, x2, y2);
184 return true;
185 }
186 return false;
187 }
188
189 bool toWebFilterOperations(const FilterOperations& inOperations, WebFilterOperat ions* outOperations)
190 {
191 SkiaImageFilterBuilder builder;
192 FilterOutsets outsets = inOperations.outsets();
193 builder.setCropOffset(FloatSize(outsets.left(), outsets.top()));
194 return builder.buildFilterOperations(inOperations, outOperations);
195 }
196
197 template <>
198 bool appendKeyframeWithStandardTimingFunction<FilterAnimationValue, WebFilterKey frame, WebFilterAnimationCurve>(WebFilterAnimationCurve* curve, double keyTime, const FilterAnimationValue* value, const FilterAnimationValue* lastValue, blink: :WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxS ize)
199 {
200 // FIXME(ajuma): In order to animate pixel-moving filters on the compositor thread, we need
201 // to update overlap testing to take into account the bounds within which th e animation
202 // will be contained, and we need the compositor to update layer bounds as t he animation
203 // progresses.
204 if (value->value()->hasFilterThatMovesPixels())
205 return false;
206 OwnPtr<WebFilterOperations> operations = adoptPtr(Platform::current()->compo sitorSupport()->createFilterOperations());
207 if (!toWebFilterOperations(*(value->value()), operations.get()))
208 return false;
209 curve->add(WebFilterKeyframe(keyTime, operations.release()), timingFunctionT ype);
210 return true;
211 }
212
213 template <>
214 bool appendKeyframeWithCustomBezierTimingFunction<FilterAnimationValue, WebFilte rKeyframe, WebFilterAnimationCurve>(WebFilterAnimationCurve* curve, double keyTi me, const FilterAnimationValue* value, const FilterAnimationValue* lastValue, do uble x1, double y1, double x2, double y2, const FloatSize& boxSize)
215 {
216 // FIXME(ajuma): In order to animate pixel-moving filters on the compositor thread, we need
217 // to update overlap testing to take into account the bounds within which th e animation
218 // will be contained, and we need the compositor to update layer bounds as t he animation
219 // progresses.
220 if (value->value()->hasFilterThatMovesPixels())
221 return false;
222
223 OwnPtr<WebFilterOperations> operations = adoptPtr(Platform::current()->compo sitorSupport()->createFilterOperations());
224 if (!toWebFilterOperations(*(value->value()), operations.get()))
225 return false;
226 curve->add(WebFilterKeyframe(keyTime, operations.release()), x1, y1, x2, y2) ;
227 return true;
228 }
229
230 template <class Value, class Keyframe, class Curve>
231 PassOwnPtr<blink::WebAnimation> createWebAnimation(const KeyframeValueList& valu eList, const CSSAnimationData* animation, int animationId, double timeOffset, Cu rve* curve, blink::WebAnimation::TargetProperty targetProperty, const FloatSize& boxSize)
232 {
233 bool alternate = false;
234 bool reverse = false;
235 if (animation && animation->isDirectionSet()) {
236 CSSAnimationData::AnimationDirection direction = animation->direction();
237 if (direction == CSSAnimationData::AnimationDirectionAlternate || direct ion == CSSAnimationData::AnimationDirectionAlternateReverse)
238 alternate = true;
239 if (direction == CSSAnimationData::AnimationDirectionReverse || directio n == CSSAnimationData::AnimationDirectionAlternateReverse)
240 reverse = true;
241 }
242
243 for (size_t i = 0; i < valueList.size(); i++) {
244 size_t index = reverse ? valueList.size() - i - 1 : i;
245 const Value* originalValue = static_cast<const Value*>(valueList.at(inde x));
246 const Value* lastOriginalValue = 0;
247 if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) | | (!reverse && index > 0)))
248 lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
249
250 const TimingFunction* originalTimingFunction = originalValue->timingFunc tion();
251
252 // If there hasn't been a timing function associated with this keyframe, use the
253 // animation's timing function, if we have one.
254 if (!originalTimingFunction && animation->isTimingFunctionSet())
255 originalTimingFunction = animation->timingFunction();
256
257 // Ease is the default timing function.
258 blink::WebAnimationCurve::TimingFunctionType timingFunctionType = blink: :WebAnimationCurve::TimingFunctionTypeEase;
259
260 bool isUsingCustomBezierTimingFunction = false;
261 double x1 = 0;
262 double y1 = 0;
263 double x2 = 1;
264 double y2 = 1;
265
266 if (originalTimingFunction) {
267 switch (originalTimingFunction->type()) {
268 case TimingFunction::StepsFunction:
269 // FIXME: add support for steps timing function.
270 return nullptr;
271 case TimingFunction::LinearFunction:
272 // This doesn't need to be flipped when the animation is reverse d.
273 timingFunctionType = blink::WebAnimationCurve::TimingFunctionTyp eLinear;
274 break;
275 case TimingFunction::CubicBezierFunction:
276 {
277 const CubicBezierTimingFunction* originalBezierTimingFunctio n = toCubicBezierTimingFunction(originalTimingFunction);
278 isUsingCustomBezierTimingFunction = true;
279 x1 = originalBezierTimingFunction->x1();
280 y1 = originalBezierTimingFunction->y1();
281 x2 = originalBezierTimingFunction->x2();
282 y2 = originalBezierTimingFunction->y2();
283 if (reverse) {
284 // When the animation is reversed, we need to swap the
285 // start and end keyframes, and flip the timing
286 // function in both x and y.
287 double x1Old = x1;
288 double y1Old = y1;
289 x1 = 1 - x2;
290 y1 = 1 - y2;
291 x2 = 1 - x1Old;
292 y2 = 1 - y1Old;
293 }
294 break;
295 }
296 default:
297 ASSERT_NOT_REACHED();
298 } // switch
299 }
300
301 double duration = (animation && animation->isDurationSet()) ? animation- >duration() : 1;
302 double keyTime = originalValue->keyTime() * duration;
303
304 if (reverse)
305 keyTime = duration - keyTime;
306
307 bool addedKeyframe = false;
308 if (isUsingCustomBezierTimingFunction)
309 addedKeyframe = appendKeyframeWithCustomBezierTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, x1, y1, x2, y 2, boxSize);
310 else
311 addedKeyframe = appendKeyframeWithStandardTimingFunction<Value, Keyf rame, Curve>(curve, keyTime, originalValue, lastOriginalValue, timingFunctionTyp e, boxSize);
312
313 if (!addedKeyframe)
314 return nullptr;
315 }
316
317 OwnPtr<blink::WebAnimation> webAnimation = adoptPtr(Platform::current()->com positorSupport()->createAnimation(*curve, targetProperty, animationId));
318
319 int iterations = (animation && animation->isIterationCountSet()) ? animation ->iterationCount() : 1;
320 webAnimation->setIterations(iterations);
321 webAnimation->setAlternatesDirection(alternate);
322
323 // If timeOffset > 0, then the animation has started in the past.
324 webAnimation->setTimeOffset(timeOffset);
325
326 return webAnimation.release();
327 }
328
329 PassOwnPtr<blink::WebAnimation> createWebAnimation(const KeyframeValueList& valu es, const CSSAnimationData* animation, int animationId, double timeOffset, const FloatSize& boxSize)
330 {
331 switch (values.property()) {
332 case AnimatedPropertyWebkitTransform: {
333 OwnPtr<WebTransformAnimationCurve> curve = adoptPtr(Platform::current()- >compositorSupport()->createTransformAnimationCurve());
334 return createWebAnimation<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(values, animation, animationId, timeOffset, curve.g et(), blink::WebAnimation::TargetPropertyTransform, FloatSize(boxSize));
335 }
336
337 case AnimatedPropertyOpacity: {
338 OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->com positorSupport()->createFloatAnimationCurve());
339 return createWebAnimation<FloatAnimationValue, WebFloatKeyframe, WebFloa tAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), blink: :WebAnimation::TargetPropertyOpacity, FloatSize());
340 }
341
342 case AnimatedPropertyWebkitFilter: {
343 OwnPtr<WebFilterAnimationCurve> curve = adoptPtr(Platform::current()->co mpositorSupport()->createFilterAnimationCurve());
344 return createWebAnimation<FilterAnimationValue, WebFilterKeyframe, WebFi lterAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), bli nk::WebAnimation::TargetPropertyFilter, FloatSize(boxSize));
345 }
346
347 case AnimatedPropertyBackgroundColor:
348 case AnimatedPropertyInvalid:
349 return nullptr;
350 }
351
352 return nullptr;
353 }
354
355 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698