[GTK][AC] Implement keyframe animations with clutter ac backend
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2013 17:01:32 +0000 (17:01 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2013 17:01:32 +0000 (17:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110057

Patch by ChangSeok Oh <changseok.oh@collabora.com> on 2013-02-19
Reviewed by Gustavo Noronha Silva.

This patch brings accelerated keyframe animation with clutter to WebKitGtk+.
Changes of GraphicsLayerClutter are based on GraphicsLayerCA. But major changes
of PlatformClutterAnimation are implemented with clutter keyframe transition apis.
See http://developer.gnome.org/clutter/stable/ClutterKeyframeTransition.html

Covered by existing animation tests.

* platform/graphics/clutter/GraphicsLayerClutter.cpp:
(WebCore::GraphicsLayerClutter::createKeyframeAnimation):
(WebCore::GraphicsLayerClutter::setTransformAnimationKeyframes):
(WebCore::GraphicsLayerClutter::setAnimationKeyframes):
* platform/graphics/clutter/PlatformClutterAnimation.cpp:
(WebCore::toClutterActorPropertyString):
(WebCore::PlatformClutterAnimation::PlatformClutterAnimation):
(WebCore::PlatformClutterAnimation::setTimingFunction):
(WebCore::PlatformClutterAnimation::setValues):
(WebCore::PlatformClutterAnimation::setKeyTimes):
(WebCore::PlatformClutterAnimation::setTimingFunctions):
(WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
(WebCore):
(WebCore::PlatformClutterAnimation::addClutterKeyframeTransitionForProperty):
(WebCore::PlatformClutterAnimation::addOpacityTransition):
(WebCore::PlatformClutterAnimation::addTransformTransition):
(WebCore::PlatformClutterAnimation::addAnimationForKey):
(WebCore::PlatformClutterAnimation::removeAnimationForKey):
* platform/graphics/clutter/PlatformClutterAnimation.h:
(PlatformClutterAnimation):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143343 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp
Source/WebCore/platform/graphics/clutter/PlatformClutterAnimation.cpp
Source/WebCore/platform/graphics/clutter/PlatformClutterAnimation.h

index 8c465b63749dde52945157e6f5eb26f9da5d11cb..b96bd0e0a60a43f63f80c463527cbf3a72c67aff 100644 (file)
@@ -1,3 +1,38 @@
+2013-02-19  ChangSeok Oh  <changseok.oh@collabora.com>
+
+        [GTK][AC] Implement keyframe animations with clutter ac backend
+        https://bugs.webkit.org/show_bug.cgi?id=110057
+
+        Reviewed by Gustavo Noronha Silva.
+
+        This patch brings accelerated keyframe animation with clutter to WebKitGtk+.
+        Changes of GraphicsLayerClutter are based on GraphicsLayerCA. But major changes
+        of PlatformClutterAnimation are implemented with clutter keyframe transition apis.
+        See http://developer.gnome.org/clutter/stable/ClutterKeyframeTransition.html
+
+        Covered by existing animation tests.
+
+        * platform/graphics/clutter/GraphicsLayerClutter.cpp:
+        (WebCore::GraphicsLayerClutter::createKeyframeAnimation):
+        (WebCore::GraphicsLayerClutter::setTransformAnimationKeyframes):
+        (WebCore::GraphicsLayerClutter::setAnimationKeyframes):
+        * platform/graphics/clutter/PlatformClutterAnimation.cpp:
+        (WebCore::toClutterActorPropertyString):
+        (WebCore::PlatformClutterAnimation::PlatformClutterAnimation):
+        (WebCore::PlatformClutterAnimation::setTimingFunction):
+        (WebCore::PlatformClutterAnimation::setValues):
+        (WebCore::PlatformClutterAnimation::setKeyTimes):
+        (WebCore::PlatformClutterAnimation::setTimingFunctions):
+        (WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
+        (WebCore):
+        (WebCore::PlatformClutterAnimation::addClutterKeyframeTransitionForProperty):
+        (WebCore::PlatformClutterAnimation::addOpacityTransition):
+        (WebCore::PlatformClutterAnimation::addTransformTransition):
+        (WebCore::PlatformClutterAnimation::addAnimationForKey):
+        (WebCore::PlatformClutterAnimation::removeAnimationForKey):
+        * platform/graphics/clutter/PlatformClutterAnimation.h:
+        (PlatformClutterAnimation):
+
 2013-02-19  Claudio Saavedra  <csaavedra@igalia.com>
 
         [harfbuzz] Crash in harfbuzz related code
index 53796ec897796d9b939c2121f1253d01bb571983..0b6679fa2efe83ccb5ddd3a46e77c1bc958d248f 100644 (file)
@@ -748,14 +748,74 @@ PassRefPtr<PlatformClutterAnimation> GraphicsLayerClutter::createBasicAnimation(
 
 PassRefPtr<PlatformClutterAnimation>GraphicsLayerClutter::createKeyframeAnimation(const Animation* anim, const String& keyPath, bool additive)
 {
-    notImplemented();
-    return 0;
+    RefPtr<PlatformClutterAnimation> keyframeAnim = PlatformClutterAnimation::create(PlatformClutterAnimation::Keyframe, keyPath);
+    setupAnimation(keyframeAnim.get(), anim, additive);
+    return keyframeAnim;
 }
 
 bool GraphicsLayerClutter::setTransformAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* keyframeAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
 {
-    notImplemented();
-    return false;
+    Vector<float> keyTimes;
+    Vector<float> floatValues;
+    Vector<FloatPoint3D> floatPoint3DValues;
+    Vector<TransformationMatrix> transformationMatrixValues;
+    Vector<const TimingFunction*> timingFunctions;
+
+    bool forwards = animation->directionIsForwards();
+
+    for (unsigned i = 0; i < valueList.size(); ++i) {
+        unsigned index = forwards ? i : (valueList.size() - i - 1);
+        const TransformAnimationValue* curValue = static_cast<const TransformAnimationValue*>(valueList.at(index));
+        keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
+
+        if (isMatrixAnimation) {
+            TransformationMatrix transform;
+            curValue->value()->apply(boxSize, transform);
+
+            // FIXME: In CoreAnimation case, if any matrix is singular, CA won't animate it correctly.
+            // But I'm not sure clutter also does. Check it later, and then decide
+            // whether removing following lines or not.
+            if (!transform.isInvertible())
+                return false;
+
+            transformationMatrixValues.append(transform);
+        } else {
+            const TransformOperation* transformOp = curValue->value()->at(functionIndex);
+            if (isTransformTypeNumber(transformOpType)) {
+                float value;
+                getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
+                floatValues.append(value);
+            } else if (isTransformTypeFloatPoint3D(transformOpType)) {
+                FloatPoint3D value;
+                getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
+                floatPoint3DValues.append(value);
+            } else {
+                TransformationMatrix value;
+                getTransformFunctionValue(transformOp, transformOpType, boxSize, value);
+                transformationMatrixValues.append(value);
+            }
+        }
+
+        if (i < (valueList.size() - 1))
+            timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
+    }
+
+    keyframeAnim->setKeyTimes(keyTimes);
+
+    if (isTransformTypeNumber(transformOpType))
+        keyframeAnim->setValues(floatValues);
+    else if (isTransformTypeFloatPoint3D(transformOpType))
+        keyframeAnim->setValues(floatPoint3DValues);
+    else
+        keyframeAnim->setValues(transformationMatrixValues);
+
+    keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
+
+    PlatformClutterAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
+    if (valueFunction != PlatformClutterAnimation::NoValueFunction)
+        keyframeAnim->setValueFunction(valueFunction);
+
+    return true;
 }
 
 bool GraphicsLayerClutter::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
@@ -986,8 +1046,37 @@ bool GraphicsLayerClutter::setAnimationEndpoints(const KeyframeValueList& valueL
 
 bool GraphicsLayerClutter::setAnimationKeyframes(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* keyframeAnim)
 {
-    notImplemented();
-    return false;
+    Vector<float> keyTimes;
+    Vector<float> values;
+    Vector<const TimingFunction*> timingFunctions;
+
+    bool forwards = animation->directionIsForwards();
+
+    for (unsigned i = 0; i < valueList.size(); ++i) {
+        unsigned index = forwards ? i : (valueList.size() - i - 1);
+        const AnimationValue* curValue = valueList.at(index);
+        keyTimes.append(forwards ? curValue->keyTime() : (1 - curValue->keyTime()));
+
+        switch (valueList.property()) {
+        case AnimatedPropertyOpacity: {
+            const FloatAnimationValue* floatValue = static_cast<const FloatAnimationValue*>(curValue);
+            values.append(floatValue->value());
+            break;
+        }
+        default:
+            ASSERT_NOT_REACHED(); // we don't animate color yet
+            break;
+        }
+
+        if (i < (valueList.size() - 1))
+            timingFunctions.append(timingFunctionForAnimationValue(forwards ? curValue : valueList.at(index - 1), animation));
+    }
+
+    keyframeAnim->setKeyTimes(keyTimes);
+    keyframeAnim->setValues(values);
+    keyframeAnim->setTimingFunctions(timingFunctions, !forwards);
+
+    return true;
 }
 
 GraphicsLayerActor* GraphicsLayerClutter::layerForSuperlayer() const
index 62fe761920c02123dab8ca2133b1fdce7adf02bf..b3792b89b0a80191109f9aed67521b1903d984d9 100644 (file)
@@ -38,7 +38,9 @@
 #include "UnitBezier.h"
 #include <limits.h>
 #include <wtf/CurrentTime.h>
+#include <wtf/OwnArrayPtr.h>
 #include <wtf/UnusedParam.h>
+#include <wtf/gobject/GOwnPtr.h>
 #include <wtf/text/CString.h>
 
 using namespace std;
@@ -54,7 +56,7 @@ static String toClutterActorPropertyString(const PlatformClutterAnimation::Value
 {
     // ClutterActor doesn't have 'scale' and 'translate' properties. So we should support
     // 'scale' and 'translate' ValueFunctionType by combination of existing property animations. 
-    const char* clutterActorProperty[] = { "NoProperty", "rotation-angle-x", "rotation-angle-y", "rotation-angle-z", "scale-x", "scale-y", "scale-z", "NoProperty", "translation-x", "translation-y", "translation-z", "NoProperty" }; 
+    const char* clutterActorProperty[] = { "NoProperty", "rotation-angle-x", "rotation-angle-y", "rotation-angle-z", "scale-x", "scale-y", "scale-z", "scale", "translation-x", "translation-y", "translation-z", "translate" }; 
     return clutterActorProperty[valueFunctionType];
 }
 
@@ -114,8 +116,6 @@ PlatformClutterAnimation::PlatformClutterAnimation(AnimationType type, const Str
     , m_timingFunction(0)
     , m_valueFunctionType(NoValueFunction)
 {
-    // FIXME: We support only Basic type now.
-    ASSERT(type == Basic);
     m_animation = adoptGRef(G_OBJECT(clutter_transition_group_new()));
 }
 
@@ -221,6 +221,7 @@ void PlatformClutterAnimation::setTimingFunction(const TimingFunction* timingFun
 {
     if (!timingFunction)
         return;
+
     m_timingFunction = timingFunction;
 }
 
@@ -330,7 +331,9 @@ void PlatformClutterAnimation::copyToValueFrom(const PlatformClutterAnimation* v
 
 void PlatformClutterAnimation::setValues(const Vector<float>& value)
 {
-    notImplemented();
+    ASSERT(animationType() == Keyframe);
+
+    m_values = value;
 }
 
 void PlatformClutterAnimation::setValues(const Vector<WebCore::TransformationMatrix>& value)
@@ -340,7 +343,9 @@ void PlatformClutterAnimation::setValues(const Vector<WebCore::TransformationMat
 
 void PlatformClutterAnimation::setValues(const Vector<FloatPoint3D>& value)
 {
-    notImplemented();
+    ASSERT(animationType() == Keyframe);
+
+    m_values3D = value;
 }
 
 void PlatformClutterAnimation::setValues(const Vector<WebCore::Color>& value)
@@ -355,7 +360,9 @@ void PlatformClutterAnimation::copyValuesFrom(const PlatformClutterAnimation* va
 
 void PlatformClutterAnimation::setKeyTimes(const Vector<float>& value)
 {
-    notImplemented();
+    ASSERT(animationType() == Keyframe);
+
+    m_keyTimes = value;
 }
 
 void PlatformClutterAnimation::copyKeyTimesFrom(const PlatformClutterAnimation* value)
@@ -365,7 +372,9 @@ void PlatformClutterAnimation::copyKeyTimesFrom(const PlatformClutterAnimation*
 
 void PlatformClutterAnimation::setTimingFunctions(const Vector<const TimingFunction*>& value, bool reverse)
 {
-    notImplemented();
+    ASSERT(animationType() == Keyframe);
+
+    m_timingFunctions = value;
 }
 
 void PlatformClutterAnimation::copyTimingFunctionsFrom(const PlatformClutterAnimation* value)
@@ -390,40 +399,133 @@ ClutterTimeline* PlatformClutterAnimation::timeline() const
     return CLUTTER_TIMELINE(m_animation.get());
 }
 
-void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const unsigned fromValue, const unsigned toValue)
+void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue)
 {
     ASSERT(property != "NoProperty");
 
+    GType gType = (property == "opacity" ? G_TYPE_UINT : G_TYPE_FLOAT);
+
     GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new(property.utf8().data()));
-    clutter_transition_set_from(transition.get(), G_TYPE_UINT, fromValue);
-    clutter_transition_set_to(transition.get(), G_TYPE_UINT, toValue);
+    clutter_transition_set_from(transition.get(), gType, (gType == G_TYPE_UINT ? static_cast<unsigned>(fromValue) : fromValue));
+    clutter_transition_set_to(transition.get(), gType, (gType == G_TYPE_UINT ? static_cast<unsigned>(toValue) : toValue));
+
+    clutter_timeline_set_progress_mode(timeline(), toClutterAnimationMode(m_timingFunction));
 
     clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
 }
 
-void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue)
+void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const FloatPoint3D& fromValue, const FloatPoint3D& toValue)
 {
     ASSERT(property != "NoProperty");
 
-    GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new(property.utf8().data()));
-    clutter_transition_set_from(transition.get(), G_TYPE_FLOAT, fromValue);
-    clutter_transition_set_to(transition.get(), G_TYPE_FLOAT, toValue);
+    if (property == "scale") {
+        addClutterTransitionForProperty(String("scale-x"), fromValue.x(), toValue.x());
+        addClutterTransitionForProperty(String("scale-y"), fromValue.y(), toValue.y());
+        return;
+    }
+    if (property == "translate") {
+        addClutterTransitionForProperty(String("translation-x"), fromValue.x(), toValue.x());
+        addClutterTransitionForProperty(String("translation-y"), fromValue.x(), toValue.y());
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
+}
+
+void PlatformClutterAnimation::addClutterKeyframeTransitionForProperty(const String& property, const Vector<float>& values)
+{
+    ASSERT(property != "NoProperty");
+
+    GType gType = (property == "opacity" ? G_TYPE_UINT : G_TYPE_FLOAT);
+
+    GRefPtr<ClutterTransition> transition = adoptGRef(clutter_keyframe_transition_new(property.utf8().data()));
+    clutter_transition_set_from(transition.get(), gType, values.first());
+    clutter_transition_set_to(transition.get(), gType, values.last());
+
+    // Ignore the first keyframe, since it's a '0' frame, meaningless.
+    const unsigned nKeyframes = values.size() - 1;
+    OwnArrayPtr<ClutterAnimationMode> animationModes = adoptArrayPtr(new ClutterAnimationMode[nKeyframes]);
+    OwnArrayPtr<double> keyTimes = adoptArrayPtr(new double[nKeyframes]);
+    GOwnPtr<GValue> keyValues(g_new0(GValue, nKeyframes));
+
+    for (unsigned i = 0; i < nKeyframes; ++i) {
+        keyTimes[i] = static_cast<double>(m_keyTimes[i + 1]);
+        animationModes[i] = toClutterAnimationMode(m_timingFunctions[i]);
+        g_value_init(&keyValues.get()[i], gType);
+        if (gType == G_TYPE_UINT)
+            g_value_set_uint(&keyValues.get()[i], static_cast<unsigned>(values[i + 1]));
+        else
+            g_value_set_float(&keyValues.get()[i], values[i + 1]);
+    }
+
+    clutter_keyframe_transition_set_key_frames(CLUTTER_KEYFRAME_TRANSITION(transition.get()), nKeyframes, keyTimes.get());
+    clutter_keyframe_transition_set_values(CLUTTER_KEYFRAME_TRANSITION(transition.get()), nKeyframes, keyValues.get());
+    clutter_keyframe_transition_set_modes(CLUTTER_KEYFRAME_TRANSITION(transition.get()), nKeyframes, animationModes.get());
 
     clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
+
+    for (unsigned i = 0; i < nKeyframes; ++i)
+        g_value_unset(&keyValues.get()[i]);
+}
+
+void PlatformClutterAnimation::addClutterKeyframeTransitionForProperty(const String& property, const Vector<FloatPoint3D>& values)
+{
+    ASSERT(property != "NoProperty");
+
+    Vector<float> valuesX, valuesY;
+    for (unsigned i = 0; i < values.size(); ++i) {
+        valuesX.append(values[i].x());
+        valuesY.append(values[i].y());
+    }
+
+    if (property == "scale") {
+        addClutterKeyframeTransitionForProperty(String("scale-x"), valuesX);
+        addClutterKeyframeTransitionForProperty(String("scale-y"), valuesY);
+        return;
+    }
+    if (property == "translate") {
+        addClutterKeyframeTransitionForProperty(String("translation-x"), valuesX);
+        addClutterKeyframeTransitionForProperty(String("translation-y"), valuesY);
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
 }
 
 void PlatformClutterAnimation::addOpacityTransition()
 {
-    addClutterTransitionForProperty(String("opacity"), static_cast<unsigned>(255 * m_fromValue), static_cast<unsigned>(255 * m_toValue));
+    if (animationType() == Keyframe) {
+        for (unsigned i = 0; i < m_values.size(); ++i)
+            m_values[i] *= 255;
+
+        addClutterKeyframeTransitionForProperty(String("opacity"), m_values);
+    } else {
+        m_fromValue *= 255;
+        m_toValue *= 255;
+
+        addClutterTransitionForProperty(String("opacity"), m_fromValue, m_toValue);
+    }
 }
 
 void PlatformClutterAnimation::addTransformTransition()
 {
+    const bool isKeyframe = (animationType() == Keyframe);
+
     switch (m_valueFunctionType) {
     case RotateX:
     case RotateY:
     case RotateZ:
-        addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), rad2deg(m_fromValue), rad2deg(m_toValue));
+        if (isKeyframe) {
+            for (unsigned i = 0; i < m_values.size(); ++i)
+                m_values[i] = rad2deg(m_values[i]);
+
+            addClutterKeyframeTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_values);
+        } else {
+            m_fromValue = rad2deg(m_fromValue);
+            m_toValue = rad2deg(m_toValue);
+
+            addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue, m_toValue);
+        }
         break;
     case ScaleX:
     case ScaleY:
@@ -431,15 +533,17 @@ void PlatformClutterAnimation::addTransformTransition()
     case TranslateX:
     case TranslateY:
     case TranslateZ:
-        addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue, m_toValue);
+        if (isKeyframe)
+            addClutterKeyframeTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_values);
+        else
+            addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue, m_toValue);
         break;
     case Scale:
-        addClutterTransitionForProperty(String("scale-x"), m_fromValue3D.x(), m_toValue3D.x());
-        addClutterTransitionForProperty(String("scale-y"), m_fromValue3D.y(), m_toValue3D.y());
-        break;
     case Translate:
-        addClutterTransitionForProperty(String("translation-x"), m_fromValue3D.x(), m_toValue3D.x());
-        addClutterTransitionForProperty(String("translation-y"), m_fromValue3D.x(), m_toValue3D.y());
+        if (isKeyframe)
+            addClutterKeyframeTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_values3D); 
+        else
+            addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue3D, m_toValue3D);
         break;
     default:
         ASSERT_NOT_REACHED();
@@ -452,7 +556,6 @@ void PlatformClutterAnimation::addTransformTransition()
 
 void PlatformClutterAnimation::addAnimationForKey(GraphicsLayerActor* platformLayer, const String& key)
 {
-    ASSERT(animationType() == Basic);
     ASSERT(!g_object_get_data(G_OBJECT(platformLayer), key.utf8().data()));
 
     m_layer = CLUTTER_ACTOR(platformLayer);
@@ -466,11 +569,7 @@ void PlatformClutterAnimation::addAnimationForKey(GraphicsLayerActor* platformLa
     else
         ASSERT_NOT_REACHED();
 
-    ClutterAnimationMode animationMode = toClutterAnimationMode(m_timingFunction);
-    ClutterTimeline* clutterTimeline = timeline();
-    clutter_timeline_set_progress_mode(clutterTimeline, animationMode);
-
-    g_signal_connect(clutterTimeline, "started", G_CALLBACK(timelineStartedCallback), this);
+    g_signal_connect(timeline(), "started", G_CALLBACK(timelineStartedCallback), this);
     g_object_set_data(G_OBJECT(platformLayer), key.utf8().data(), this);
 
     clutter_actor_add_transition(m_layer.get(), key.utf8().data(), CLUTTER_TRANSITION(m_animation.get()));
@@ -478,8 +577,6 @@ void PlatformClutterAnimation::addAnimationForKey(GraphicsLayerActor* platformLa
 
 void PlatformClutterAnimation::removeAnimationForKey(GraphicsLayerActor* layer, const String& key)
 {
-    ASSERT(animationType() == Basic);
-
     clutter_actor_remove_transition(CLUTTER_ACTOR(layer), key.utf8().data());
     g_object_set_data(G_OBJECT(layer), key.utf8().data(), 0);
 }
index b892dd3ccf51a45cf9dca9ae79374c9a41256aeb..d2f7ad64c36f0df617f02ba997fb52129400b0fa 100644 (file)
@@ -138,8 +138,11 @@ private:
     ClutterTimeline* timeline() const;
     AnimatedPropertyType stringToAnimatedPropertyType(const String& keyPath) const;
 
-    void addClutterTransitionForProperty(const String& property, const unsigned fromValue, const unsigned toValue);
     void addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue);
+    void addClutterTransitionForProperty(const String& property, const FloatPoint3D& fromValue, const FloatPoint3D& toValue);
+
+    void addClutterKeyframeTransitionForProperty(const String& property, const Vector<float>& values);
+    void addClutterKeyframeTransitionForProperty(const String& property, const Vector<FloatPoint3D>& values);
 
     void addOpacityTransition();
     void addTransformTransition();
@@ -162,6 +165,12 @@ private:
 
     const TimingFunction* m_timingFunction;
     ValueFunctionType m_valueFunctionType;
+
+    Vector<float> m_keyTimes;
+    Vector<const TimingFunction*> m_timingFunctions;
+
+    Vector<float> m_values;
+    Vector<FloatPoint3D> m_values3D;
 };
 
 }