Changeset 142749 in webkit


Ignore:
Timestamp:
Feb 13, 2013 8:12:44 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[GTK][AC] Implement basic transform animations with clutter ac backend
https://bugs.webkit.org/show_bug.cgi?id=109363

Patch by ChangSeok Oh <ChangSeok Oh> on 2013-02-13
Reviewed by Gustavo Noronha Silva.

Implement basic transform animation with clutter ac backend.
GraphicsLayerClutter is almost same with GraphicsLayerCA. And PlatformClutterAnimation
interfaces are also similar with PlatformCAAnimation, but they are implemented
with native clutter APIs. Clutter backend AC supports a basic single transform animation
with this patch now, but additive animation combination and keyframe animation
are not supported yet.

Covered by existing animation tests.

  • platform/graphics/clutter/GraphicsLayerActor.cpp:

(graphicsLayerActorSetTransform):

  • platform/graphics/clutter/GraphicsLayerClutter.cpp:

(WebCore::isTransformTypeTransformationMatrix):
(WebCore):
(WebCore::isTransformTypeFloatPoint3D):
(WebCore::isTransformTypeNumber):
(WebCore::getTransformFunctionValue):
(WebCore::getValueFunctionNameForTransformOperation):
(WebCore::GraphicsLayerClutter::setTransformAnimationEndpoints):
(WebCore::GraphicsLayerClutter::appendToUncommittedAnimations):
(WebCore::GraphicsLayerClutter::createTransformAnimationsFromKeyframes):

  • platform/graphics/clutter/GraphicsLayerClutter.h:

(GraphicsLayerClutter):

  • platform/graphics/clutter/PlatformClutterAnimation.cpp:

(WebCore::toClutterActorPropertyString):
(WebCore):
(WebCore::PlatformClutterAnimation::supportsValueFunction):
(WebCore::PlatformClutterAnimation::duration):
(WebCore::PlatformClutterAnimation::setDuration):
(WebCore::PlatformClutterAnimation::setAdditive):
(WebCore::PlatformClutterAnimation::valueFunction):
(WebCore::PlatformClutterAnimation::setValueFunction):
(WebCore::PlatformClutterAnimation::setFromValue):
(WebCore::PlatformClutterAnimation::setToValue):
(WebCore::PlatformClutterAnimation::timeline):
(WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
(WebCore::PlatformClutterAnimation::addOpacityTransition):
(WebCore::PlatformClutterAnimation::addTransformTransition):
(WebCore::PlatformClutterAnimation::addAnimationForKey):

  • platform/graphics/clutter/PlatformClutterAnimation.h:

(PlatformClutterAnimation):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r142747 r142749  
     12013-02-13  ChangSeok Oh  <shivamidow@gmail.com>
     2
     3        [GTK][AC] Implement basic transform animations with clutter ac backend
     4        https://bugs.webkit.org/show_bug.cgi?id=109363
     5
     6        Reviewed by Gustavo Noronha Silva.
     7
     8        Implement basic transform animation with clutter ac backend.
     9        GraphicsLayerClutter is almost same with GraphicsLayerCA. And PlatformClutterAnimation
     10        interfaces are also similar with PlatformCAAnimation, but they are implemented
     11        with native clutter APIs. Clutter backend AC supports a basic single transform animation
     12        with this patch now, but additive animation combination and keyframe animation
     13        are not supported yet.
     14
     15        Covered by existing animation tests.
     16
     17        * platform/graphics/clutter/GraphicsLayerActor.cpp:
     18        (graphicsLayerActorSetTransform):
     19        * platform/graphics/clutter/GraphicsLayerClutter.cpp:
     20        (WebCore::isTransformTypeTransformationMatrix):
     21        (WebCore):
     22        (WebCore::isTransformTypeFloatPoint3D):
     23        (WebCore::isTransformTypeNumber):
     24        (WebCore::getTransformFunctionValue):
     25        (WebCore::getValueFunctionNameForTransformOperation):
     26        (WebCore::GraphicsLayerClutter::setTransformAnimationEndpoints):
     27        (WebCore::GraphicsLayerClutter::appendToUncommittedAnimations):
     28        (WebCore::GraphicsLayerClutter::createTransformAnimationsFromKeyframes):
     29        * platform/graphics/clutter/GraphicsLayerClutter.h:
     30        (GraphicsLayerClutter):
     31        * platform/graphics/clutter/PlatformClutterAnimation.cpp:
     32        (WebCore::toClutterActorPropertyString):
     33        (WebCore):
     34        (WebCore::PlatformClutterAnimation::supportsValueFunction):
     35        (WebCore::PlatformClutterAnimation::duration):
     36        (WebCore::PlatformClutterAnimation::setDuration):
     37        (WebCore::PlatformClutterAnimation::setAdditive):
     38        (WebCore::PlatformClutterAnimation::valueFunction):
     39        (WebCore::PlatformClutterAnimation::setValueFunction):
     40        (WebCore::PlatformClutterAnimation::setFromValue):
     41        (WebCore::PlatformClutterAnimation::setToValue):
     42        (WebCore::PlatformClutterAnimation::timeline):
     43        (WebCore::PlatformClutterAnimation::addClutterTransitionForProperty):
     44        (WebCore::PlatformClutterAnimation::addOpacityTransition):
     45        (WebCore::PlatformClutterAnimation::addTransformTransition):
     46        (WebCore::PlatformClutterAnimation::addAnimationForKey):
     47        * platform/graphics/clutter/PlatformClutterAnimation.h:
     48        (PlatformClutterAnimation):
     49
    1502013-02-13  Ilya Tikhonovsky  <loislo@chromium.org>
    251
  • trunk/Source/WebCore/platform/graphics/clutter/GraphicsLayerActor.cpp

    r142297 r142749  
    393393    }
    394394
    395     if (!cogl_matrix_is_identity(matrix)) {
     395    if (matrix && !cogl_matrix_is_identity(matrix)) {
    396396        priv->matrix = cogl_matrix_copy(matrix);
    397397        needToRedraw = true;
  • trunk/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.cpp

    r142265 r142749  
    5454static const float cAnimationAlmostZeroDuration = 1e-3f;
    5555
     56static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
     57{
     58    switch (transformType) {
     59    case TransformOperation::SKEW_X:
     60    case TransformOperation::SKEW_Y:
     61    case TransformOperation::SKEW:
     62    case TransformOperation::MATRIX:
     63    case TransformOperation::ROTATE_3D:
     64    case TransformOperation::MATRIX_3D:
     65    case TransformOperation::PERSPECTIVE:
     66    case TransformOperation::IDENTITY:
     67    case TransformOperation::NONE:
     68        return true;
     69    default:
     70        return false;
     71    }
     72}
     73
     74static bool isTransformTypeFloatPoint3D(TransformOperation::OperationType transformType)
     75{
     76    switch (transformType) {
     77    case TransformOperation::SCALE:
     78    case TransformOperation::SCALE_3D:
     79    case TransformOperation::TRANSLATE:
     80    case TransformOperation::TRANSLATE_3D:
     81        return true;
     82    default:
     83        return false;
     84    }
     85}
     86
     87static bool isTransformTypeNumber(TransformOperation::OperationType transformType)
     88{
     89    return !isTransformTypeTransformationMatrix(transformType) && !isTransformTypeFloatPoint3D(transformType);
     90}
     91
     92static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, float& value)
     93{
     94    switch (transformType) {
     95    case TransformOperation::ROTATE:
     96    case TransformOperation::ROTATE_X:
     97    case TransformOperation::ROTATE_Y:
     98        value = transformOp ? narrowPrecisionToFloat(deg2rad(static_cast<const RotateTransformOperation*>(transformOp)->angle())) : 0;
     99        break;
     100    case TransformOperation::SCALE_X:
     101        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1;
     102        break;
     103    case TransformOperation::SCALE_Y:
     104        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1;
     105        break;
     106    case TransformOperation::SCALE_Z:
     107        value = transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1;
     108        break;
     109    case TransformOperation::TRANSLATE_X:
     110        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0;
     111        break;
     112    case TransformOperation::TRANSLATE_Y:
     113        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0;
     114        break;
     115    case TransformOperation::TRANSLATE_Z:
     116        value = transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0;
     117        break;
     118    default:
     119        break;
     120    }
     121}
     122
     123static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, FloatPoint3D& value)
     124{
     125    switch (transformType) {
     126    case TransformOperation::SCALE:
     127    case TransformOperation::SCALE_3D:
     128        value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->x()) : 1);
     129        value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->y()) : 1);
     130        value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const ScaleTransformOperation*>(transformOp)->z()) : 1);
     131        break;
     132    case TransformOperation::TRANSLATE:
     133    case TransformOperation::TRANSLATE_3D:
     134        value.setX(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->x(size)) : 0);
     135        value.setY(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->y(size)) : 0);
     136        value.setZ(transformOp ? narrowPrecisionToFloat(static_cast<const TranslateTransformOperation*>(transformOp)->z(size)) : 0);
     137        break;
     138    default:
     139        break;
     140    }
     141}
     142
     143static void getTransformFunctionValue(const TransformOperation* transformOp, TransformOperation::OperationType transformType, const IntSize& size, TransformationMatrix& value)
     144{
     145    switch (transformType) {
     146    case TransformOperation::SKEW_X:
     147    case TransformOperation::SKEW_Y:
     148    case TransformOperation::SKEW:
     149    case TransformOperation::MATRIX:
     150    case TransformOperation::ROTATE_3D:
     151    case TransformOperation::MATRIX_3D:
     152    case TransformOperation::PERSPECTIVE:
     153    case TransformOperation::IDENTITY:
     154    case TransformOperation::NONE:
     155        if (transformOp)
     156            transformOp->apply(value, size);
     157        else
     158            value.makeIdentity();
     159        break;
     160    default:
     161        break;
     162    }
     163}
     164
     165static PlatformClutterAnimation::ValueFunctionType getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
     166{
     167    // Use literal strings to avoid link-time dependency on those symbols.
     168    switch (transformType) {
     169    case TransformOperation::ROTATE_X:
     170        return PlatformClutterAnimation::RotateX;
     171    case TransformOperation::ROTATE_Y:
     172        return PlatformClutterAnimation::RotateY;
     173    case TransformOperation::ROTATE:
     174        return PlatformClutterAnimation::RotateZ;
     175    case TransformOperation::SCALE_X:
     176        return PlatformClutterAnimation::ScaleX;
     177    case TransformOperation::SCALE_Y:
     178        return PlatformClutterAnimation::ScaleY;
     179    case TransformOperation::SCALE_Z:
     180        return PlatformClutterAnimation::ScaleZ;
     181    case TransformOperation::TRANSLATE_X:
     182        return PlatformClutterAnimation::TranslateX;
     183    case TransformOperation::TRANSLATE_Y:
     184        return PlatformClutterAnimation::TranslateY;
     185    case TransformOperation::TRANSLATE_Z:
     186        return PlatformClutterAnimation::TranslateZ;
     187    case TransformOperation::SCALE:
     188    case TransformOperation::SCALE_3D:
     189        return PlatformClutterAnimation::Scale;
     190    case TransformOperation::TRANSLATE:
     191    case TransformOperation::TRANSLATE_3D:
     192        return PlatformClutterAnimation::Translate;
     193    default:
     194        return PlatformClutterAnimation::NoValueFunction;
     195    }
     196}
     197
    56198static String propertyIdToString(AnimatedPropertyID property)
    57199{
     
    619761bool GraphicsLayerClutter::setTransformAnimationEndpoints(const KeyframeValueList& valueList, const Animation* animation, PlatformClutterAnimation* basicAnim, int functionIndex, TransformOperation::OperationType transformOpType, bool isMatrixAnimation, const IntSize& boxSize)
    620762{
    621     notImplemented();
    622     return false;
     763    ASSERT(valueList.size() == 2);
     764
     765    bool forwards = animation->directionIsForwards();
     766
     767    unsigned fromIndex = !forwards;
     768    unsigned toIndex = forwards;
     769
     770    const TransformAnimationValue* startValue = static_cast<const TransformAnimationValue*>(valueList.at(fromIndex));
     771    const TransformAnimationValue* endValue = static_cast<const TransformAnimationValue*>(valueList.at(toIndex));
     772
     773    if (isMatrixAnimation) {
     774        TransformationMatrix fromTransform, toTransform;
     775        startValue->value()->apply(boxSize, fromTransform);
     776        endValue->value()->apply(boxSize, toTransform);
     777
     778        // FIXME: If any matrix is singular, CA won't animate it correctly.
     779        // So fall back to software animation, But it's not sure in clutter case.
     780        // We need to investigate it more.
     781        if (!fromTransform.isInvertible() || !toTransform.isInvertible())
     782            return false;
     783
     784        basicAnim->setFromValue(fromTransform);
     785        basicAnim->setToValue(toTransform);
     786    } else {
     787        if (isTransformTypeNumber(transformOpType)) {
     788            float fromValue;
     789            getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
     790            basicAnim->setFromValue(fromValue);
     791
     792            float toValue;
     793            getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
     794            basicAnim->setToValue(toValue);
     795        } else if (isTransformTypeFloatPoint3D(transformOpType)) {
     796            FloatPoint3D fromValue;
     797            getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
     798            basicAnim->setFromValue(fromValue);
     799
     800            FloatPoint3D toValue;
     801            getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
     802            basicAnim->setToValue(toValue);
     803        } else {
     804            TransformationMatrix fromValue;
     805            getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue);
     806            basicAnim->setFromValue(fromValue);
     807
     808            TransformationMatrix toValue;
     809            getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue);
     810            basicAnim->setToValue(toValue);
     811        }
     812    }
     813
     814    // This codepath is used for 2-keyframe animations, so we still need to look in the start
     815    // for a timing function. Even in the reversing animation case, the first keyframe provides the timing function.
     816    const TimingFunction* timingFunction = timingFunctionForAnimationValue(valueList.at(0), animation);
     817    basicAnim->setTimingFunction(timingFunction, !forwards);
     818
     819    PlatformClutterAnimation::ValueFunctionType valueFunction = getValueFunctionNameForTransformOperation(transformOpType);
     820    if (valueFunction != PlatformClutterAnimation::NoValueFunction)
     821        basicAnim->setValueFunction(valueFunction);
     822
     823    return true;
     824}
     825
     826bool GraphicsLayerClutter::appendToUncommittedAnimations(const KeyframeValueList& valueList, const TransformOperations* operations, const Animation* animation, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation)
     827{
     828    TransformOperation::OperationType transformOp = isMatrixAnimation ? TransformOperation::MATRIX_3D : operations->operations().at(animationIndex)->getOperationType();
     829    bool additive = animationIndex > 0;
     830    bool isKeyframe = valueList.size() > 2;
     831
     832    RefPtr<PlatformClutterAnimation> clutterAnimation;
     833    bool validMatrices = true;
     834    if (isKeyframe) {
     835        clutterAnimation = createKeyframeAnimation(animation, propertyIdToString(valueList.property()), additive);
     836        validMatrices = setTransformAnimationKeyframes(valueList, animation, clutterAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
     837    } else {
     838        clutterAnimation = createBasicAnimation(animation, propertyIdToString(valueList.property()), additive);
     839        validMatrices = setTransformAnimationEndpoints(valueList, animation, clutterAnimation.get(), animationIndex, transformOp, isMatrixAnimation, boxSize);
     840    }
     841
     842    if (!validMatrices)
     843        return false;
     844
     845    m_uncomittedAnimations.append(LayerPropertyAnimation(clutterAnimation, animationName, valueList.property(), animationIndex, timeOffset));
     846    return true;
    623847}
    624848
    625849bool GraphicsLayerClutter::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
    626850{
    627     notImplemented();
    628     return false;
     851    ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
     852
     853    bool hasBigRotation;
     854    int listIndex = validateTransformOperations(valueList, hasBigRotation);
     855    const TransformOperations* operations = (listIndex >= 0) ? static_cast<const TransformAnimationValue*>(valueList.at(listIndex))->value() : 0;
     856
     857    // We need to fall back to software animation if we don't have setValueFunction:, and
     858    // we would need to animate each incoming transform function separately. This is the
     859    // case if we have a rotation >= 180 or we have more than one transform function.
     860    if ((hasBigRotation || (operations && operations->size() > 1)) && !PlatformClutterAnimation::supportsValueFunction())
     861        return false;
     862
     863    bool validMatrices = true;
     864
     865    // If function lists don't match we do a matrix animation, otherwise we do a component hardware animation.
     866    // Also, we can't do component animation unless we have valueFunction, so we need to do matrix animation
     867    // if that's not true as well.
     868    bool isMatrixAnimation = listIndex < 0 || !PlatformClutterAnimation::supportsValueFunction();
     869    int numAnimations = isMatrixAnimation ? 1 : operations->size();
     870
     871    for (int animationIndex = 0; animationIndex < numAnimations; ++animationIndex) {
     872        if (!appendToUncommittedAnimations(valueList, operations, animation, animationName, boxSize, animationIndex, timeOffset, isMatrixAnimation)) {
     873            validMatrices = false;
     874            break;
     875        }
     876    }
     877
     878    return validMatrices;
    629879}
    630880
  • trunk/Source/WebCore/platform/graphics/clutter/GraphicsLayerClutter.h

    r142094 r142749  
    120120    bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, PlatformClutterAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
    121121
     122    bool appendToUncommittedAnimations(const KeyframeValueList&, const TransformOperations*, const Animation*, const String& animationName, const IntSize& boxSize, int animationIndex, double timeOffset, bool isMatrixAnimation);
     123
    122124    enum LayerChange {
    123125        NoChange = 0,
  • trunk/Source/WebCore/platform/graphics/clutter/PlatformClutterAnimation.cpp

    r142094 r142749  
    5151}
    5252
     53static String toClutterActorPropertyString(const PlatformClutterAnimation::ValueFunctionType valueFunctionType)
     54{
     55    // ClutterActor doesn't have 'scale' and 'translate' properties. So we should support
     56    // 'scale' and 'translate' ValueFunctionType by combination of existing property animations.
     57    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" };
     58    return clutterActorProperty[valueFunctionType];
     59}
     60
    5361static ClutterAnimationMode toClutterAnimationMode(const TimingFunction* timingFunction)
    5462{
     
    125133bool PlatformClutterAnimation::supportsValueFunction()
    126134{
    127     return false;
     135    return true;
    128136}
    129137
     
    141149double PlatformClutterAnimation::duration() const
    142150{
    143     ASSERT(m_type == Basic);
    144 
    145151    double duration = clutter_timeline_get_duration(CLUTTER_TIMELINE(m_animation.get()));
    146152    return duration / 1000;
     
    149155void PlatformClutterAnimation::setDuration(double value)
    150156{
    151     ASSERT(m_type == Basic);
    152 
    153157    // Clutter Animation sets the duration time in milliseconds.
    154158    gint duration = value * 1000;
     
    246250    if (m_additive == value)
    247251        return;
     252
    248253    m_additive = value;
    249254}
     
    251256PlatformClutterAnimation::ValueFunctionType PlatformClutterAnimation::valueFunction() const
    252257{
    253     notImplemented();
    254     return NoValueFunction;
     258    return m_valueFunctionType;
    255259}
    256260
    257261void PlatformClutterAnimation::setValueFunction(ValueFunctionType value)
    258262{
    259     notImplemented();
     263    if (m_valueFunctionType == value)
     264        return;
     265
     266    m_valueFunctionType = value;
    260267}
    261268
    262269void PlatformClutterAnimation::setFromValue(float value)
    263270{
    264     if (m_fromValue == value)
    265         return;
     271    if (animationType() != Basic || m_fromValue == value)
     272        return;
     273
    266274    m_fromValue = value;
    267275}
     
    274282void PlatformClutterAnimation::setFromValue(const FloatPoint3D& value)
    275283{
    276     notImplemented();
     284    if (animationType() != Basic || m_fromValue3D == value)
     285        return;
     286
     287    m_fromValue3D = value;
    277288}
    278289
     
    289300void PlatformClutterAnimation::setToValue(float value)
    290301{
    291     if (m_toValue == value)
    292         return;
     302    if (animationType() != Basic || m_toValue == value)
     303        return;
     304
    293305    m_toValue = value;
    294306}
     
    301313void PlatformClutterAnimation::setToValue(const FloatPoint3D& value)
    302314{
    303     notImplemented();
     315    if (animationType() != Basic || m_toValue3D == value)
     316        return;
     317
     318    m_toValue3D = value;
    304319}
    305320
     
    373388{
    374389    ASSERT(m_animation);
    375     ASSERT(m_type == Basic);
    376390    return CLUTTER_TIMELINE(m_animation.get());
    377391}
    378392
     393void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const unsigned fromValue, const unsigned toValue)
     394{
     395    ASSERT(property != "NoProperty");
     396
     397    GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new(property.utf8().data()));
     398    clutter_transition_set_from(transition.get(), G_TYPE_UINT, fromValue);
     399    clutter_transition_set_to(transition.get(), G_TYPE_UINT, toValue);
     400
     401    clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
     402}
     403
     404void PlatformClutterAnimation::addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue)
     405{
     406    ASSERT(property != "NoProperty");
     407
     408    GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new(property.utf8().data()));
     409    clutter_transition_set_from(transition.get(), G_TYPE_FLOAT, fromValue);
     410    clutter_transition_set_to(transition.get(), G_TYPE_FLOAT, toValue);
     411
     412    clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
     413}
     414
    379415void PlatformClutterAnimation::addOpacityTransition()
    380416{
    381     GRefPtr<ClutterTransition> transition = adoptGRef(clutter_property_transition_new("opacity"));
    382     clutter_transition_set_from(transition.get(), G_TYPE_UINT, static_cast<guint8>(255 * m_fromValue));
    383     clutter_transition_set_to(transition.get(), G_TYPE_UINT, static_cast<guint8>(255 * m_toValue));
    384 
    385     clutter_transition_group_add_transition(CLUTTER_TRANSITION_GROUP(m_animation.get()), transition.get());
     417    addClutterTransitionForProperty(String("opacity"), static_cast<unsigned>(255 * m_fromValue), static_cast<unsigned>(255 * m_toValue));
     418}
     419
     420void PlatformClutterAnimation::addTransformTransition()
     421{
     422    switch (m_valueFunctionType) {
     423    case RotateX:
     424    case RotateY:
     425    case RotateZ:
     426        addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), rad2deg(m_fromValue), rad2deg(m_toValue));
     427        break;
     428    case ScaleX:
     429    case ScaleY:
     430    case ScaleZ:
     431    case TranslateX:
     432    case TranslateY:
     433    case TranslateZ:
     434        addClutterTransitionForProperty(toClutterActorPropertyString(m_valueFunctionType), m_fromValue, m_toValue);
     435        break;
     436    case Scale:
     437        addClutterTransitionForProperty(String("scale-x"), m_fromValue3D.x(), m_toValue3D.x());
     438        addClutterTransitionForProperty(String("scale-y"), m_fromValue3D.y(), m_toValue3D.y());
     439        break;
     440    case Translate:
     441        addClutterTransitionForProperty(String("translation-x"), m_fromValue3D.x(), m_toValue3D.x());
     442        addClutterTransitionForProperty(String("translation-y"), m_fromValue3D.x(), m_toValue3D.y());
     443        break;
     444    default:
     445        ASSERT_NOT_REACHED();
     446    }
     447
     448    // If clutter covers valueFunction type animations, we should release keeping transform matrix.
     449    // Otherwise, the transformation is applied twice unexpectedly. See graphicsLayerActorApplyTransform.
     450    graphicsLayerActorSetTransform(GRAPHICS_LAYER_ACTOR(m_layer.get()), 0);
    386451}
    387452
     
    390455    ASSERT(animationType() == Basic);
    391456    ASSERT(!g_object_get_data(G_OBJECT(platformLayer), key.utf8().data()));
     457
     458    m_layer = CLUTTER_ACTOR(platformLayer);
    392459
    393460    if (m_animatedPropertyType == Opacity)
    394461        addOpacityTransition();
    395462    else if (m_animatedPropertyType == Transform)
    396         ASSERT_NOT_REACHED();
     463        addTransformTransition();
    397464    else if (m_animatedPropertyType == BackgroundColor)
    398465        ASSERT_NOT_REACHED();
     
    407474    g_object_set_data(G_OBJECT(platformLayer), key.utf8().data(), this);
    408475
    409     m_layer = CLUTTER_ACTOR(platformLayer);
    410 
    411476    clutter_actor_add_transition(m_layer.get(), key.utf8().data(), CLUTTER_TRANSITION(m_animation.get()));
    412477}
  • trunk/Source/WebCore/platform/graphics/clutter/PlatformClutterAnimation.h

    r142297 r142749  
    139139    AnimatedPropertyType stringToAnimatedPropertyType(const String& keyPath) const;
    140140
     141    void addClutterTransitionForProperty(const String& property, const unsigned fromValue, const unsigned toValue);
     142    void addClutterTransitionForProperty(const String& property, const float fromValue, const float toValue);
     143
    141144    void addOpacityTransition();
     145    void addTransformTransition();
    142146
    143147    AnimationType m_type;
     
    152156    float m_toValue;
    153157
     158    FloatPoint3D m_fromValue3D;
     159    FloatPoint3D m_toValue3D;
     160
    154161    float m_repeatCount;
    155162
Note: See TracChangeset for help on using the changeset viewer.