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

Side by Side Diff: Source/core/platform/graphics/chromium/AnimationTranslationUtil.cpp

Issue 23431021: Refactoring animation code in accelerated path. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix typo Created 7 years, 3 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/graphics/chromium/AnimationTranslationUtil.h"
28
29 #include "core/css/LengthFunctions.h"
30 #include "core/platform/animation/CSSAnimationData.h"
31 #include "core/platform/animation/KeyframeValueList.h"
32 #include "core/platform/graphics/FloatSize.h"
33 #include "core/platform/graphics/chromium/TransformSkMatrix44Conversions.h"
34 #include "core/platform/graphics/transforms/InterpolatedTransformOperation.h"
35 #include "core/platform/graphics/transforms/Matrix3DTransformOperation.h"
36 #include "core/platform/graphics/transforms/MatrixTransformOperation.h"
37 #include "core/platform/graphics/transforms/PerspectiveTransformOperation.h"
38 #include "core/platform/graphics/transforms/RotateTransformOperation.h"
39 #include "core/platform/graphics/transforms/ScaleTransformOperation.h"
40 #include "core/platform/graphics/transforms/SkewTransformOperation.h"
41 #include "core/platform/graphics/transforms/TransformOperations.h"
42 #include "core/platform/graphics/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/WebFloatAnimationCurve.h"
49 #include "public/platform/WebTransformAnimationCurve.h"
50 #include "public/platform/WebTransformOperations.h"
51
52 #include "wtf/OwnPtr.h"
53 #include "wtf/text/CString.h"
54
55 using namespace std;
56 using namespace WebKit;
57
58 namespace WebCore {
59
60 PassOwnPtr<WebTransformOperations> toWebTransformOperations(const TransformOpera tions& transformOperations, const FloatSize& boxSize)
61 {
62 // We need to do a deep copy the transformOperations may contain ref pointer s to TransformOperation objects.
63 OwnPtr<WebTransformOperations> webTransformOperations = adoptPtr(Platform::c urrent()->compositorSupport()->createTransformOperations());
64 if (!webTransformOperations)
65 return nullptr;
66 for (size_t j = 0; j < transformOperations.size(); ++j) {
67 TransformOperation::OperationType operationType = transformOperations.op erations()[j]->getOperationType();
68 switch (operationType) {
69 case TransformOperation::ScaleX:
70 case TransformOperation::ScaleY:
71 case TransformOperation::ScaleZ:
72 case TransformOperation::Scale3D:
73 case TransformOperation::Scale: {
74 ScaleTransformOperation* transform = static_cast<ScaleTransformOpera tion*>(transformOperations.operations()[j].get());
75 webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
76 break;
77 }
78 case TransformOperation::TranslateX:
79 case TransformOperation::TranslateY:
80 case TransformOperation::TranslateZ:
81 case TransformOperation::Translate3D:
82 case TransformOperation::Translate: {
83 TranslateTransformOperation* transform = static_cast<TranslateTransf ormOperation*>(transformOperations.operations()[j].get());
84 webTransformOperations->appendTranslate(floatValueForLength(transfor m->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1));
85 break;
86 }
87 case TransformOperation::RotateX:
88 case TransformOperation::RotateY:
89 case TransformOperation::Rotate3D:
90 case TransformOperation::Rotate: {
91 RotateTransformOperation* transform = static_cast<RotateTransformOpe ration*>(transformOperations.operations()[j].get());
92 webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
93 break;
94 }
95 case TransformOperation::SkewX:
96 case TransformOperation::SkewY:
97 case TransformOperation::Skew: {
98 SkewTransformOperation* transform = static_cast<SkewTransformOperati on*>(transformOperations.operations()[j].get());
99 webTransformOperations->appendSkew(transform->angleX(), transform->a ngleY());
100 break;
101 }
102 case TransformOperation::Matrix: {
103 MatrixTransformOperation* transform = static_cast<MatrixTransformOpe ration*>(transformOperations.operations()[j].get());
104 TransformationMatrix m = transform->matrix();
105 webTransformOperations->appendMatrix(TransformSkMatrix44Conversions: :convert(m));
106 break;
107 }
108 case TransformOperation::Matrix3D: {
109 Matrix3DTransformOperation* transform = static_cast<Matrix3DTransfor mOperation*>(transformOperations.operations()[j].get());
110 TransformationMatrix m = transform->matrix();
111 webTransformOperations->appendMatrix(TransformSkMatrix44Conversions: :convert(m));
112 break;
113 }
114 case TransformOperation::Perspective: {
115 PerspectiveTransformOperation* transform = static_cast<PerspectiveTr ansformOperation*>(transformOperations.operations()[j].get());
116 webTransformOperations->appendPerspective(floatValueForLength(transf orm->perspective(), 0));
117 break;
118 }
119 case TransformOperation::Interpolated: {
120 TransformationMatrix m;
121 transformOperations.operations()[j]->apply(m, boxSize);
122 webTransformOperations->appendMatrix(TransformSkMatrix44Conversions: :convert(m));
123 break;
124 }
125 case TransformOperation::Identity:
126 webTransformOperations->appendIdentity();
127 break;
128 case TransformOperation::None:
129 // Do nothing.
130 break;
131 } // switch
132 } // for each operation
133
134 return webTransformOperations.release();
135 }
136
137 template <class Value, class Keyframe, class Curve>
138 bool appendKeyframeWithStandardTimingFunction(Curve* curve, double keyTime, cons t Value* value, const Value* lastValue, WebKit::WebAnimationCurve::TimingFunctio nType timingFunctionType, const FloatSize&)
139 {
140 curve->add(Keyframe(keyTime, value->value()), timingFunctionType);
141 return true;
142 }
143
144 template <class Value, class Keyframe, class Curve>
145 bool appendKeyframeWithCustomBezierTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, double x1, double y1, double x2, dou ble y2, const FloatSize&)
146 {
147 curve->add(Keyframe(keyTime, value->value()), x1, y1, x2, y2);
148 return true;
149 }
150
151 bool isRotationType(TransformOperation::OperationType transformType)
152 {
153 return transformType == TransformOperation::Rotate
154 || transformType == TransformOperation::RotateX
155 || transformType == TransformOperation::RotateY
156 || transformType == TransformOperation::RotateZ
157 || transformType == TransformOperation::Rotate3D;
158 }
159
160 template <>
161 bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransf ormKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, doub le keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, co nst FloatSize& boxSize)
162 {
163 bool canBlend = !lastValue;
164 OwnPtr<WebTransformOperations> operations(toWebTransformOperations(*value->v alue(), boxSize));
165 if (!operations)
166 return false;
167 if (!canBlend) {
168 OwnPtr<WebTransformOperations> lastOperations(toWebTransformOperations(* lastValue->value(), boxSize));
169 if (!lastOperations)
170 return false;
171 canBlend = lastOperations->canBlendWith(*operations);
172 }
173 if (canBlend) {
174 curve->add(WebTransformKeyframe(keyTime, operations.leakPtr()), timingFu nctionType);
175 return true;
176 }
177 return false;
178 }
179
180 template <>
181 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)
182 {
183 bool canBlend = !lastValue;
184 OwnPtr<WebTransformOperations> operations(toWebTransformOperations(*value->v alue(), boxSize));
185 if (!operations)
186 return false;
187 if (!canBlend) {
188 OwnPtr<WebTransformOperations> lastOperations(toWebTransformOperations(* lastValue->value(), boxSize));
189 if (!lastOperations)
190 return false;
191 canBlend = lastOperations->canBlendWith(*operations);
192 }
193 if (canBlend) {
194 curve->add(WebTransformKeyframe(keyTime, operations.leakPtr()), x1, y1, x2, y2);
195 return true;
196 }
197 return false;
198 }
199
200 template <class Value, class Keyframe, class Curve>
201 PassOwnPtr<WebKit::WebAnimation> createWebAnimation(const KeyframeValueList& val ueList, const CSSAnimationData* animation, int animationId, double timeOffset, C urve* curve, WebKit::WebAnimation::TargetProperty targetProperty, const FloatSiz e& boxSize)
202 {
203 bool alternate = false;
204 bool reverse = false;
205 if (animation && animation->isDirectionSet()) {
206 CSSAnimationData::AnimationDirection direction = animation->direction();
207 if (direction == CSSAnimationData::AnimationDirectionAlternate || direct ion == CSSAnimationData::AnimationDirectionAlternateReverse)
208 alternate = true;
209 if (direction == CSSAnimationData::AnimationDirectionReverse || directio n == CSSAnimationData::AnimationDirectionAlternateReverse)
210 reverse = true;
211 }
212
213 for (size_t i = 0; i < valueList.size(); i++) {
214 size_t index = reverse ? valueList.size() - i - 1 : i;
215 const Value* originalValue = static_cast<const Value*>(valueList.at(inde x));
216 const Value* lastOriginalValue = 0;
217 if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) | | (!reverse && index > 0)))
218 lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
219
220 const TimingFunction* originalTimingFunction = originalValue->timingFunc tion();
221
222 // If there hasn't been a timing function associated with this keyframe, use the
223 // animation's timing function, if we have one.
224 if (!originalTimingFunction && animation->isTimingFunctionSet())
225 originalTimingFunction = animation->timingFunction();
226
227 // Ease is the default timing function.
228 WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType = WebKi t::WebAnimationCurve::TimingFunctionTypeEase;
229
230 bool isUsingCustomBezierTimingFunction = false;
231 double x1 = 0;
232 double y1 = 0;
233 double x2 = 1;
234 double y2 = 1;
235
236 if (originalTimingFunction) {
237 switch (originalTimingFunction->type()) {
238 case TimingFunction::StepsFunction:
239 // FIXME: add support for steps timing function.
240 return nullptr;
241 case TimingFunction::LinearFunction:
242 timingFunctionType = WebKit::WebAnimationCurve::TimingFunctionTy peLinear;
243 break;
244 case TimingFunction::CubicBezierFunction:
245 {
246 const CubicBezierTimingFunction* originalBezierTimingFunctio n = static_cast<const CubicBezierTimingFunction*>(originalTimingFunction);
247 isUsingCustomBezierTimingFunction = true;
248 x1 = originalBezierTimingFunction->x1();
249 y1 = originalBezierTimingFunction->y1();
250 x2 = originalBezierTimingFunction->x2();
251 y2 = originalBezierTimingFunction->y2();
252 break;
253 }
254 default:
255 ASSERT_NOT_REACHED();
256 } // switch
257 }
258
259 double duration = (animation && animation->isDurationSet()) ? animation- >duration() : 1;
260 double keyTime = originalValue->keyTime() * duration;
261
262 if (reverse)
263 keyTime = duration - keyTime;
264
265 bool addedKeyframe = false;
266 if (isUsingCustomBezierTimingFunction)
267 addedKeyframe = appendKeyframeWithCustomBezierTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, x1, y1, x2, y 2, boxSize);
268 else
269 addedKeyframe = appendKeyframeWithStandardTimingFunction<Value, Keyf rame, Curve>(curve, keyTime, originalValue, lastOriginalValue, timingFunctionTyp e, boxSize);
270 if (!addedKeyframe)
271 return nullptr;
272 }
273
274 OwnPtr<WebKit::WebAnimation> webAnimation = adoptPtr(Platform::current()->co mpositorSupport()->createAnimation(*curve, targetProperty, animationId));
275
276 int iterations = (animation && animation->isIterationCountSet()) ? animation ->iterationCount() : 1;
277 webAnimation->setIterations(iterations);
278 webAnimation->setAlternatesDirection(alternate);
279
280 // If timeOffset > 0, then the animation has started in the past.
281 webAnimation->setTimeOffset(timeOffset);
282
283 return webAnimation.release();
284 }
285
286 PassOwnPtr<WebKit::WebAnimation> createWebAnimation(const KeyframeValueList& val ues, const CSSAnimationData* animation, int animationId, double timeOffset, cons t FloatSize& boxSize)
287 {
288
289
290 if (values.property() == AnimatedPropertyWebkitTransform) {
291 OwnPtr<WebTransformAnimationCurve> curve = adoptPtr(Platform::current()- >compositorSupport()->createTransformAnimationCurve());
292 return createWebAnimation<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(values, animation, animationId, timeOffset, curve.g et(), WebKit::WebAnimation::TargetPropertyTransform, FloatSize(boxSize));
293 }
294
295 if (values.property() == AnimatedPropertyOpacity) {
296 OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->com positorSupport()->createFloatAnimationCurve());
297 return createWebAnimation<FloatAnimationValue, WebFloatKeyframe, WebFloa tAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), WebKit ::WebAnimation::TargetPropertyOpacity, FloatSize());
298 }
299
300 return nullptr;
301 }
302
303 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698