[GTK][AC] Implement matrix transform animation with clutter ac backend
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2013 20:10:11 +0000 (20:10 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2013 20:10:11 +0000 (20:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109848

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

Clutter 1.12 doesn't support additive transform animations yet, so the combination
of two or more transformations(such as rotation after translation) runs unexpectedly.
So we use a matrix transformation instead for the case.

Covered by existing animation tests.

* platform/graphics/clutter/GraphicsLayerClutter.cpp:
(WebCore::getValueFunctionNameForTransformOperation):
(WebCore::GraphicsLayerClutter::createTransformAnimationsFromKeyframes):
* platform/graphics/clutter/PlatformClutterAnimation.cpp:
(WebCore::toClutterActorPropertyString): Add actor property "transform"
(WebCore::clutterMatrixProgress): Handle interpolation between two matrices instead of default clutter_matrix_progress.
(WebCore):
(WebCore::PlatformClutterAnimation::supportsAdditiveValueFunction):
(WebCore::PlatformClutterAnimation::setFromValue): for TransformationMatrix.
(WebCore::PlatformClutterAnimation::setToValue): ditto.
(WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
(WebCore::PlatformClutterAnimation::addTransformTransition):
* platform/graphics/clutter/PlatformClutterAnimation.h:
(PlatformClutterAnimation):
* platform/graphics/clutter/TransformationMatrixClutter.cpp: Add copy constructor for CoglMatrix.
(WebCore::TransformationMatrix::TransformationMatrix):
(WebCore):
* platform/graphics/transforms/TransformationMatrix.h:
(TransformationMatrix):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143369 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
Source/WebCore/platform/graphics/clutter/TransformationMatrixClutter.cpp
Source/WebCore/platform/graphics/transforms/TransformationMatrix.h

index 1894b9e3a7b7041fb71a4cb0be4c2700c7980210..3591aa1e6a768c0d8bc55fd1686e124712e8c0ac 100644 (file)
@@ -1,3 +1,36 @@
+2013-02-19  ChangSeok Oh  <changseok.oh@collabora.com>
+
+        [GTK][AC] Implement matrix transform animation with clutter ac backend
+        https://bugs.webkit.org/show_bug.cgi?id=109848
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Clutter 1.12 doesn't support additive transform animations yet, so the combination
+        of two or more transformations(such as rotation after translation) runs unexpectedly.
+        So we use a matrix transformation instead for the case.
+
+        Covered by existing animation tests.
+
+        * platform/graphics/clutter/GraphicsLayerClutter.cpp:
+        (WebCore::getValueFunctionNameForTransformOperation):
+        (WebCore::GraphicsLayerClutter::createTransformAnimationsFromKeyframes):
+        * platform/graphics/clutter/PlatformClutterAnimation.cpp:
+        (WebCore::toClutterActorPropertyString): Add actor property "transform"
+        (WebCore::clutterMatrixProgress): Handle interpolation between two matrices instead of default clutter_matrix_progress.
+        (WebCore):
+        (WebCore::PlatformClutterAnimation::supportsAdditiveValueFunction):
+        (WebCore::PlatformClutterAnimation::setFromValue): for TransformationMatrix.
+        (WebCore::PlatformClutterAnimation::setToValue): ditto.
+        (WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
+        (WebCore::PlatformClutterAnimation::addTransformTransition):
+        * platform/graphics/clutter/PlatformClutterAnimation.h:
+        (PlatformClutterAnimation):
+        * platform/graphics/clutter/TransformationMatrixClutter.cpp: Add copy constructor for CoglMatrix.
+        (WebCore::TransformationMatrix::TransformationMatrix):
+        (WebCore):
+        * platform/graphics/transforms/TransformationMatrix.h:
+        (TransformationMatrix):
+
 2013-02-19  Kassy Coan  <kassycoan@chromium.org>
 
         Update FeatureObserver on top level navigation in addition to page destruction.
index 0b6679fa2efe83ccb5ddd3a46e77c1bc958d248f..328214d5341ed73e71af43c21b3e6d4e1ca309a6 100644 (file)
@@ -190,6 +190,8 @@ static PlatformClutterAnimation::ValueFunctionType getValueFunctionNameForTransf
     case TransformOperation::TRANSLATE:
     case TransformOperation::TRANSLATE_3D:
         return PlatformClutterAnimation::Translate;
+    case TransformOperation::MATRIX_3D:
+        return PlatformClutterAnimation::Matrix;
     default:
         return PlatformClutterAnimation::NoValueFunction;
     }
@@ -925,7 +927,7 @@ bool GraphicsLayerClutter::createTransformAnimationsFromKeyframes(const Keyframe
     // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
     // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
     // if that's not true as well.
-    bool isMatrixAnimation = listIndex < 0 || !PlatformClutterAnimation::supportsValueFunction();
+    bool isMatrixAnimation = listIndex < 0 || !PlatformClutterAnimation::supportsValueFunction() || (operations->size() >= 2 && !PlatformClutterAnimation::supportsAdditiveValueFunction());
     int numAnimations = isMatrixAnimation ? 1 : operations->size();
 
     for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
index b3792b89b0a80191109f9aed67521b1903d984d9..5751a30d81c4ed2fb57be926d4ed8e6790d0b997 100644 (file)
@@ -56,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", "scale", "translation-x", "translation-y", "translation-z", "translate" }; 
+    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", "transform" }; 
     return clutterActorProperty[valueFunctionType];
 }
 
@@ -85,6 +85,23 @@ static ClutterAnimationMode toClutterAnimationMode(const TimingFunction* timingF
     return CLUTTER_EASE;
 }
 
+static gboolean clutterMatrixProgress(const GValue* fromValue, const GValue* toValue, gdouble progress, GValue* returnValue)
+{
+    const CoglMatrix* fromCoglMatrix = static_cast<CoglMatrix*>(g_value_get_boxed(fromValue));
+    const CoglMatrix* toCoglMatrix = static_cast<CoglMatrix*>(g_value_get_boxed(toValue));
+
+    ASSERT(fromCoglMatrix && toCoglMatrix);
+
+    TransformationMatrix fromMatrix(fromCoglMatrix);
+    TransformationMatrix toMatrix(toCoglMatrix);
+    toMatrix.blend(fromMatrix, progress);
+
+    CoglMatrix resultCoglMatrix = toMatrix;
+    g_value_set_boxed(returnValue, &resultCoglMatrix);
+
+    return true;
+}
+
 PlatformClutterAnimation::AnimatedPropertyType PlatformClutterAnimation::stringToAnimatedPropertyType(const String& keyPath) const
 {
     if (keyPath == "transform")
@@ -135,6 +152,13 @@ bool PlatformClutterAnimation::supportsValueFunction()
     return true;
 }
 
+bool PlatformClutterAnimation::supportsAdditiveValueFunction()
+{
+    // FIXME: Clutter 1.12 doesn't support additive valueFunction type animations.
+    // So, we use matrix animation instead until clutter supports it.
+    return false;
+}
+
 double PlatformClutterAnimation::beginTime() const
 {
     notImplemented();
@@ -277,7 +301,10 @@ void PlatformClutterAnimation::setFromValue(float value)
 
 void PlatformClutterAnimation::setFromValue(const WebCore::TransformationMatrix& value)
 {
-    notImplemented();
+    if (animationType() != Basic || m_fromValueMatrix == value)
+        return;
+
+    m_fromValueMatrix = value;
 }
 
 void PlatformClutterAnimation::setFromValue(const FloatPoint3D& value)
@@ -308,7 +335,10 @@ void PlatformClutterAnimation::setToValue(float value)
 
 void PlatformClutterAnimation::setToValue(const WebCore::TransformationMatrix& value)
 {
-    notImplemented();
+    if (animationType() != Basic || m_toValueMatrix == value)
+        return;
+
+    m_toValueMatrix = value;
 }
 
 void PlatformClutterAnimation::setToValue(const FloatPoint3D& value)
@@ -414,6 +444,27 @@ void PlatformClutterAnimation::addClutterTransitionForProperty(const String& pro
     clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
 }
 
+void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const WebCore::TransformationMatrix& fromValue, const WebCore::TransformationMatrix& toValue)
+{
+    ASSERT(property != "NoProperty");
+
+    const CoglMatrix fromCoglMatrix = fromValue;
+    const CoglMatrix toCoglMatrix = toValue;
+
+    GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new(property.utf8().data()));
+    clutter_transition_set_from(transition.get(), CLUTTER_TYPE_MATRIX, &fromCoglMatrix);
+    clutter_transition_set_to(transition.get(), CLUTTER_TYPE_MATRIX, &toCoglMatrix);
+
+    clutter_timeline_set_progress_mode(timeline(), toClutterAnimationMode(m_timingFunction));
+
+    clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
+
+    // FIXME: The matrix interpolation api, clutter_matrix_progress of Clutter 1.12 works unexpectedly.
+    // So we overwrite it and handle the interpolation of two matrices with TransformationMatrix.
+    // See https://bugzilla.gnome.org/show_bug.cgi?id=694197
+    clutter_interval_register_progress_func(CLUTTER_TYPE_MATRIX, clutterMatrixProgress);
+}
+
 void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const FloatPoint3D& fromValue, const FloatPoint3D& toValue)
 {
     ASSERT(property != "NoProperty");
@@ -545,6 +596,9 @@ void PlatformClutterAnimation::addTransformTransition()
         else
             addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue3D, m_toValue3D);
         break;
+    case Matrix:
+        addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValueMatrix, m_toValueMatrix);
+        break;
     default:
         ASSERT_NOT_REACHED();
     }
index d2f7ad64c36f0df617f02ba997fb52129400b0fa..e8dbd3101a1a0f2261a0cfc928d33b6abf28b3f9 100644 (file)
@@ -55,7 +55,7 @@ public:
     enum AnimationType { Basic, Keyframe };
     enum AnimatedPropertyType { NoAnimatedPropertyType, Transform, Opacity, BackgroundColor };
     enum FillModeType { NoFillMode, Forwards, Backwards, Both };
-    enum ValueFunctionType { NoValueFunction, RotateX, RotateY, RotateZ, ScaleX, ScaleY, ScaleZ, Scale, TranslateX, TranslateY, TranslateZ, Translate };
+    enum ValueFunctionType { NoValueFunction, RotateX, RotateY, RotateZ, ScaleX, ScaleY, ScaleZ, Scale, TranslateX, TranslateY, TranslateZ, Translate, Matrix };
 
     static PassRefPtr<PlatformClutterAnimation> create(AnimationType, const String& keyPath);
     static PassRefPtr<PlatformClutterAnimation> create(PlatformClutterAnimation*);
@@ -63,6 +63,7 @@ public:
     ~PlatformClutterAnimation();
 
     static bool supportsValueFunction();
+    static bool supportsAdditiveValueFunction();
 
     AnimationType animationType() const { return m_type; }
 
@@ -139,6 +140,7 @@ private:
     AnimatedPropertyType stringToAnimatedPropertyType(const String& keyPath) const;
 
     void addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue);
+    void addClutterTransitionForProperty(const String& property, const WebCore::TransformationMatrix&, const WebCore::TransformationMatrix&);
     void addClutterTransitionForProperty(const String& property, const FloatPoint3D& fromValue, const FloatPoint3D& toValue);
 
     void addClutterKeyframeTransitionForProperty(const String& property, const Vector<float>& values);
@@ -161,6 +163,9 @@ private:
     FloatPoint3D m_fromValue3D;
     FloatPoint3D m_toValue3D;
 
+    WebCore::TransformationMatrix m_fromValueMatrix;
+    WebCore::TransformationMatrix m_toValueMatrix;
+
     float m_repeatCount;
 
     const TimingFunction* m_timingFunction;
index d5c3f2ae44c122bd08e77fb20d50343063fe41ab..56558739b2bc6a7aee20a18d3ab71915e212f988 100644 (file)
@@ -51,4 +51,12 @@ TransformationMatrix::operator CoglMatrix() const
     return matrix;
 }
 
+TransformationMatrix::TransformationMatrix(const CoglMatrix* matrix)
+{
+    setMatrix(matrix->xx, matrix->yx, matrix->zx, matrix->wx,
+        matrix->xy, matrix->yy, matrix->zy, matrix->wy,
+        matrix->xz, matrix->yz, matrix->zz, matrix->wz,
+        matrix->xw, matrix->yw, matrix->zw, matrix->ww);
+}
+
 }
index da91035457a9f015ecdeb9ec437466c955789d64..b1e56655cdfa37ffc265d91f712d13c73e6d2157 100644 (file)
@@ -341,6 +341,7 @@ public:
     operator CATransform3D() const;
 #endif
 #if USE(CLUTTER)
+    TransformationMatrix(const CoglMatrix*);
     operator CoglMatrix() const;
 #endif
 #if USE(CG)