initial import
[vuplus_webkit] / Source / WebCore / platform / graphics / ca / win / PlatformCAAnimationWin.cpp
1 /*
2  * Copyright (C) 2011 Apple 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if USE(ACCELERATED_COMPOSITING)
29
30 #include "PlatformCAAnimation.h"
31
32 #include "FloatConversion.h"
33 #include "PlatformString.h"
34 #include "TimingFunction.h"
35 #include <QuartzCore/CACFAnimation.h>
36 #include <QuartzCore/CACFTiming.h>
37 #include <QuartzCore/CACFTimingFunction.h>
38 #include <QuartzCore/CACFValueFunction.h>
39 #include <QuartzCore/CACFVector.h>
40 #include <wtf/UnusedParam.h>
41
42 using namespace WebCore;
43
44 static CFStringRef toCACFFillModeType(PlatformCAAnimation::FillModeType type)
45 {
46     switch (type) {
47     case PlatformCAAnimation::NoFillMode:
48     case PlatformCAAnimation::Forwards: return kCACFFillModeForwards;
49     case PlatformCAAnimation::Backwards: return kCACFFillModeBackwards;
50     case PlatformCAAnimation::Both: return kCACFFillModeBoth;
51     }
52     ASSERT_NOT_REACHED();
53     return 0;
54 }
55
56 static PlatformCAAnimation::FillModeType fromCACFFillModeType(CFStringRef string)
57 {
58     if (string == kCACFFillModeBackwards)
59         return PlatformCAAnimation::Backwards;
60
61     if (string == kCACFFillModeBoth)
62         return PlatformCAAnimation::Both;
63
64     return PlatformCAAnimation::Forwards;
65 }
66
67 static CFStringRef toCACFValueFunctionType(PlatformCAAnimation::ValueFunctionType type)
68 {
69     switch (type) {
70     case PlatformCAAnimation::NoValueFunction: return 0;
71     case PlatformCAAnimation::RotateX: return kCACFValueFunctionRotateX;
72     case PlatformCAAnimation::RotateY: return kCACFValueFunctionRotateY;
73     case PlatformCAAnimation::RotateZ: return kCACFValueFunctionRotateZ;
74     case PlatformCAAnimation::ScaleX: return kCACFValueFunctionScaleX;
75     case PlatformCAAnimation::ScaleY: return kCACFValueFunctionScaleY;
76     case PlatformCAAnimation::ScaleZ: return kCACFValueFunctionScaleZ;
77     case PlatformCAAnimation::Scale: return kCACFValueFunctionScale;
78     case PlatformCAAnimation::TranslateX: return kCACFValueFunctionTranslateX;
79     case PlatformCAAnimation::TranslateY: return kCACFValueFunctionTranslateY;
80     case PlatformCAAnimation::TranslateZ: return kCACFValueFunctionTranslateZ;
81     case PlatformCAAnimation::Translate: return kCACFValueFunctionTranslate;
82     }
83     ASSERT_NOT_REACHED();
84     return 0;
85 }
86
87 static PlatformCAAnimation::ValueFunctionType fromCACFValueFunctionType(CFStringRef string)
88 {
89     if (string == kCACFValueFunctionRotateX)
90         return PlatformCAAnimation::RotateX;
91
92     if (string == kCACFValueFunctionRotateY)
93         return PlatformCAAnimation::RotateY;
94
95     if (string == kCACFValueFunctionRotateZ)
96         return PlatformCAAnimation::RotateZ;
97
98     if (string == kCACFValueFunctionScaleX)
99         return PlatformCAAnimation::ScaleX;
100
101     if (string == kCACFValueFunctionScaleY)
102         return PlatformCAAnimation::ScaleY;
103
104     if (string == kCACFValueFunctionScaleZ)
105         return PlatformCAAnimation::ScaleZ;
106
107     if (string == kCACFValueFunctionScale)
108         return PlatformCAAnimation::Scale;
109
110     if (string == kCACFValueFunctionTranslateX)
111         return PlatformCAAnimation::TranslateX;
112
113     if (string == kCACFValueFunctionTranslateY)
114         return PlatformCAAnimation::TranslateY;
115
116     if (string == kCACFValueFunctionTranslateZ)
117         return PlatformCAAnimation::TranslateZ;
118
119     if (string == kCACFValueFunctionTranslate)
120         return PlatformCAAnimation::Translate;
121
122     return PlatformCAAnimation::NoValueFunction;
123 }
124
125 static RetainPtr<CACFTimingFunctionRef> toCACFTimingFunction(const TimingFunction* timingFunction)
126 {
127     ASSERT(timingFunction);
128     if (timingFunction->isCubicBezierTimingFunction()) {
129         const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
130         return RetainPtr<CACFTimingFunctionRef>(AdoptCF, CACFTimingFunctionCreate(static_cast<float>(ctf->x1()), static_cast<float>(ctf->y1()), static_cast<float>(ctf->x2()), static_cast<float>(ctf->y2())));
131     }
132     
133     return CACFTimingFunctionGetFunctionWithName(kCACFTimingFunctionLinear);
134 }
135
136 PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(AnimationType type, const String& keyPath)
137 {
138     return adoptRef(new PlatformCAAnimation(type, keyPath));
139 }
140
141 PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(PlatformAnimationRef animation)
142 {
143     return adoptRef(new PlatformCAAnimation(animation));
144 }
145
146 PlatformCAAnimation::PlatformCAAnimation(AnimationType type, const String& keyPath)
147     : m_type(type)
148 {
149     if (type == Basic)
150         m_animation.adoptCF(CACFAnimationCreate(kCACFBasicAnimation));
151     else
152         m_animation.adoptCF(CACFAnimationCreate(kCACFKeyframeAnimation));
153     
154     RetainPtr<CFStringRef> s(AdoptCF, keyPath.createCFString());
155     CACFAnimationSetKeyPath(m_animation.get(), s.get());
156 }
157
158 PlatformCAAnimation::PlatformCAAnimation(PlatformAnimationRef animation)
159 {
160     if (CACFAnimationGetClass(animation) == kCACFBasicAnimation)
161         m_type = Basic;
162     else if (CACFAnimationGetClass(animation) == kCACFKeyframeAnimation)
163         m_type = Keyframe;
164     else {
165         ASSERT_NOT_REACHED();
166         return;
167     }
168     
169     m_animation = animation;
170 }
171
172 PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::copy() const
173 {
174     RefPtr<PlatformCAAnimation> animation = create(animationType(), keyPath());
175     
176     animation->setBeginTime(beginTime());
177     animation->setDuration(duration());
178     animation->setSpeed(speed());
179     animation->setTimeOffset(timeOffset());
180     animation->setRepeatCount(repeatCount());
181     animation->setAutoreverses(autoreverses());
182     animation->setFillMode(fillMode());
183     animation->setRemovedOnCompletion(isRemovedOnCompletion());
184     animation->setAdditive(isAdditive());
185     animation->copyTimingFunctionFrom(this);
186     animation->setValueFunction(valueFunction());
187     
188     // Copy the specific Basic or Keyframe values
189     if (animationType() == Keyframe) {
190         animation->copyValuesFrom(this);
191         animation->copyKeyTimesFrom(this);
192         animation->copyTimingFunctionsFrom(this);
193     } else {
194         animation->copyFromValueFrom(this);
195         animation->copyToValueFrom(this);
196     }
197     
198     return animation;
199 }
200
201 PlatformCAAnimation::~PlatformCAAnimation()
202 {
203 }
204
205 bool PlatformCAAnimation::supportsValueFunction()
206 {
207     return true;
208 }
209
210 PlatformAnimationRef PlatformCAAnimation::platformAnimation() const
211 {
212     return m_animation.get();
213 }
214
215 String PlatformCAAnimation::keyPath() const
216 {
217     return CACFAnimationGetKeyPath(m_animation.get());
218 }
219
220 CFTimeInterval PlatformCAAnimation::beginTime() const
221 {
222     return CACFAnimationGetBeginTime(m_animation.get());
223 }
224
225 void PlatformCAAnimation::setBeginTime(CFTimeInterval value)
226 {
227     CACFAnimationSetBeginTime(m_animation.get(), value);
228 }
229
230 CFTimeInterval PlatformCAAnimation::duration() const
231 {
232     return CACFAnimationGetDuration(m_animation.get());
233 }
234
235 void PlatformCAAnimation::setDuration(CFTimeInterval value)
236 {
237     CACFAnimationSetDuration(m_animation.get(), value);
238 }
239
240 float PlatformCAAnimation::speed() const
241 {
242     return CACFAnimationGetSpeed(m_animation.get());
243 }
244
245 void PlatformCAAnimation::setSpeed(float value)
246 {
247     CACFAnimationSetSpeed(m_animation.get(), value);
248 }
249
250 CFTimeInterval PlatformCAAnimation::timeOffset() const
251 {
252     return CACFAnimationGetTimeOffset(m_animation.get());
253 }
254
255 void PlatformCAAnimation::setTimeOffset(CFTimeInterval value)
256 {
257     CACFAnimationSetTimeOffset(m_animation.get(), value);
258 }
259
260 float PlatformCAAnimation::repeatCount() const
261 {
262     return CACFAnimationGetRepeatCount(m_animation.get());
263 }
264
265 void PlatformCAAnimation::setRepeatCount(float value)
266 {
267     CACFAnimationSetRepeatCount(m_animation.get(), value);
268 }
269
270 bool PlatformCAAnimation::autoreverses() const
271 {
272     return CACFAnimationGetAutoreverses(m_animation.get());
273 }
274
275 void PlatformCAAnimation::setAutoreverses(bool value)
276 {
277     CACFAnimationSetAutoreverses(m_animation.get(), value);
278 }
279
280 PlatformCAAnimation::FillModeType PlatformCAAnimation::fillMode() const
281 {
282     return fromCACFFillModeType(CACFAnimationGetFillMode(m_animation.get()));
283 }
284
285 void PlatformCAAnimation::setFillMode(FillModeType value)
286 {
287     CACFAnimationSetFillMode(m_animation.get(), toCACFFillModeType(value));
288 }
289
290 void PlatformCAAnimation::setTimingFunction(const TimingFunction* value)
291 {
292     CACFAnimationSetTimingFunction(m_animation.get(), toCACFTimingFunction(value).get());
293 }
294
295 void PlatformCAAnimation::copyTimingFunctionFrom(const PlatformCAAnimation* value)
296 {
297     CACFAnimationSetTimingFunction(m_animation.get(), CACFAnimationGetTimingFunction(value->m_animation.get()));
298 }
299
300 bool PlatformCAAnimation::isRemovedOnCompletion() const
301 {
302     return CACFAnimationIsRemovedOnCompletion(m_animation.get());
303 }
304
305 void PlatformCAAnimation::setRemovedOnCompletion(bool value)
306 {
307     CACFAnimationSetRemovedOnCompletion(m_animation.get(), value);
308 }
309
310 bool PlatformCAAnimation::isAdditive() const
311 {
312     return CACFAnimationIsAdditive(m_animation.get());
313 }
314
315 void PlatformCAAnimation::setAdditive(bool value)
316 {
317     CACFAnimationSetAdditive(m_animation.get(), value);
318 }
319
320 PlatformCAAnimation::ValueFunctionType PlatformCAAnimation::valueFunction() const
321 {
322     CACFValueFunctionRef func = CACFAnimationGetValueFunction(m_animation.get());
323     return func ? fromCACFValueFunctionType(CACFValueFunctionGetName(func)) : NoValueFunction;
324 }
325
326 void PlatformCAAnimation::setValueFunction(ValueFunctionType value)
327 {
328     CFStringRef valueString = toCACFValueFunctionType(value);
329     CACFAnimationSetValueFunction(m_animation.get(), valueString ? CACFValueFunctionGetFunctionWithName(valueString) : 0);
330 }
331
332 void PlatformCAAnimation::setFromValue(float value)
333 {
334     if (animationType() != Basic)
335         return;
336
337     RetainPtr<CFNumberRef> v(AdoptCF, CFNumberCreate(0, kCFNumberFloatType, &value));
338     CACFAnimationSetFromValue(m_animation.get(), v.get());
339 }
340
341 void PlatformCAAnimation::setFromValue(const WebCore::TransformationMatrix& value)
342 {
343     if (animationType() != Basic)
344         return;
345     
346     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreateTransform(value));
347     CACFAnimationSetFromValue(m_animation.get(), v.get());
348 }
349
350 void PlatformCAAnimation::setFromValue(const FloatPoint3D& value)
351 {
352     if (animationType() != Basic)
353         return;
354
355     float a[3] = { value.x(), value.y(), value.z() };
356     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(3, a));
357     CACFAnimationSetFromValue(m_animation.get(), v.get());
358 }
359
360 void PlatformCAAnimation::setFromValue(const WebCore::Color& value)
361 {
362     if (animationType() != Basic)
363         return;
364
365     float a[4] = { value.red(), value.green(), value.blue(), value.alpha() };
366     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(4, a));
367     CACFAnimationSetFromValue(m_animation.get(), v.get());
368 }
369
370 void PlatformCAAnimation::copyFromValueFrom(const PlatformCAAnimation* value)
371 {
372     if (animationType() != Basic || value->animationType() != Basic)
373         return;
374     
375     CACFAnimationSetFromValue(m_animation.get(), CACFAnimationGetFromValue(value->platformAnimation()));
376 }
377
378 void PlatformCAAnimation::setToValue(float value)
379 {
380     if (animationType() != Basic)
381         return;
382
383     RetainPtr<CFNumberRef> v(AdoptCF, CFNumberCreate(0, kCFNumberFloatType, &value));
384     CACFAnimationSetToValue(m_animation.get(), v.get());
385 }
386
387 void PlatformCAAnimation::setToValue(const WebCore::TransformationMatrix& value)
388 {
389     if (animationType() != Basic)
390         return;
391
392     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreateTransform(value));
393     CACFAnimationSetToValue(m_animation.get(), v.get());
394 }
395
396 void PlatformCAAnimation::setToValue(const FloatPoint3D& value)
397 {
398     if (animationType() != Basic)
399         return;
400
401     float a[3] = { value.x(), value.y(), value.z() };
402     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(3, a));
403     CACFAnimationSetToValue(m_animation.get(), v.get());
404 }
405
406 void PlatformCAAnimation::setToValue(const WebCore::Color& value)
407 {
408     if (animationType() != Basic)
409         return;
410
411     float a[4] = { value.red(), value.green(), value.blue(), value.alpha() };
412     RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(4, a));
413     CACFAnimationSetToValue(m_animation.get(), v.get());
414 }
415
416 void PlatformCAAnimation::copyToValueFrom(const PlatformCAAnimation* value)
417 {
418     if (animationType() != Basic || value->animationType() != Basic)
419         return;
420         
421     CACFAnimationSetToValue(m_animation.get(), CACFAnimationGetToValue(value->platformAnimation()));
422 }
423
424
425 // Keyframe-animation properties.
426 void PlatformCAAnimation::setValues(const Vector<float>& value)
427 {
428     if (animationType() != Keyframe)
429         return;
430
431     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
432     for (size_t i = 0; i < value.size(); ++i) {
433         RetainPtr<CFNumberRef> v(AdoptCF, CFNumberCreate(0, kCFNumberFloatType, &value[i]));
434         CFArrayAppendValue(array.get(), v.get());
435     }
436
437     CACFAnimationSetValues(m_animation.get(), array.get());
438 }
439
440 void PlatformCAAnimation::setValues(const Vector<WebCore::TransformationMatrix>& value)
441 {
442     if (animationType() != Keyframe)
443         return;
444
445     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
446     for (size_t i = 0; i < value.size(); ++i) {
447         RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreateTransform(value[i]));
448         CFArrayAppendValue(array.get(), v.get());
449     }
450
451     CACFAnimationSetValues(m_animation.get(), array.get());
452 }
453
454 void PlatformCAAnimation::setValues(const Vector<FloatPoint3D>& value)
455 {
456     if (animationType() != Keyframe)
457         return;
458         
459     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
460     for (size_t i = 0; i < value.size(); ++i) {
461         float a[3] = { value[i].x(), value[i].y(), value[i].z() };
462         RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(3, a));
463         CFArrayAppendValue(array.get(), v.get());
464     }
465
466     CACFAnimationSetValues(m_animation.get(), array.get());
467 }
468
469 void PlatformCAAnimation::setValues(const Vector<WebCore::Color>& value)
470 {
471     if (animationType() != Keyframe)
472         return;
473         
474     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
475     for (size_t i = 0; i < value.size(); ++i) {
476         float a[4] = { value[i].red(), value[i].green(), value[i].blue(), value[i].alpha() };
477         RetainPtr<CACFVectorRef> v(AdoptCF, CACFVectorCreate(4, a));
478         CFArrayAppendValue(array.get(), v.get());
479     }
480
481     CACFAnimationSetValues(m_animation.get(), array.get());
482 }
483
484 void PlatformCAAnimation::copyValuesFrom(const PlatformCAAnimation* value)
485 {
486     if (animationType() != Keyframe || value->animationType() != Keyframe)
487         return;
488     
489     CACFAnimationSetValues(m_animation.get(), CACFAnimationGetValues(value->platformAnimation()));
490 }
491
492 void PlatformCAAnimation::setKeyTimes(const Vector<float>& value)
493 {
494     if (animationType() != Keyframe)
495         return;
496         
497     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
498     for (size_t i = 0; i < value.size(); ++i) {
499         RetainPtr<CFNumberRef> v(AdoptCF, CFNumberCreate(0, kCFNumberFloatType, &value[i]));
500         CFArrayAppendValue(array.get(), v.get());
501     }
502
503     CACFAnimationSetKeyTimes(m_animation.get(), array.get());
504 }
505
506 void PlatformCAAnimation::copyKeyTimesFrom(const PlatformCAAnimation* value)
507 {
508     if (animationType() != Keyframe)
509         return;
510
511     CACFAnimationSetKeyTimes(m_animation.get(), CACFAnimationGetKeyTimes(value->platformAnimation()));
512 }
513
514 void PlatformCAAnimation::setTimingFunctions(const Vector<const TimingFunction*>& value)
515 {
516     if (animationType() != Keyframe)
517         return;
518
519     RetainPtr<CFMutableArrayRef> array(AdoptCF, CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
520     for (size_t i = 0; i < value.size(); ++i) {
521         RetainPtr<CFNumberRef> v(AdoptCF, CFNumberCreate(0, kCFNumberFloatType, &value[i]));
522         CFArrayAppendValue(array.get(), toCACFTimingFunction(value[i]).get());
523     }
524
525     CACFAnimationSetTimingFunctions(m_animation.get(), array.get());
526 }
527
528 void PlatformCAAnimation::copyTimingFunctionsFrom(const PlatformCAAnimation* value)
529 {
530     CACFAnimationSetTimingFunctions(m_animation.get(), CACFAnimationGetTimingFunctions(value->platformAnimation()));
531 }
532
533 #endif // USE(ACCELERATED_COMPOSITING)