Title: [117000] branches/chromium/1132/Source
Revision
117000
Author
[email protected]
Date
2012-05-14 14:17:42 -0700 (Mon, 14 May 2012)

Log Message

Merge 116554 - [chromium] Add impl-thread support for fill-mode and direction css animation properties
https://bugs.webkit.org/show_bug.cgi?id=77662

Patch by Ian Vollick <[email protected]> on 2012-05-09
Reviewed by James Robinson.

Source/WebCore:

Adds support for accelerating css animations with -webkit-animation-fill-mode,
and -webkit-animation-direction properties.

Tested in:
  CCActiveAnimationTest.TrimTimeAlternating
  CCLayerAnimationControllerTest.createReversedAnimation
  CCLayerAnimationControllerTest.createAlternatingAnimation
  CCLayerAnimationControllerTest.createReversedAlternatingAnimation

* platform/graphics/chromium/cc/CCActiveAnimation.cpp:
(WebCore::CCActiveAnimation::CCActiveAnimation):
(WebCore::CCActiveAnimation::trimTimeToCurrentIteration):
(WebCore::CCActiveAnimation::cloneForImplThread):
* platform/graphics/chromium/cc/CCActiveAnimation.h:
(CCActiveAnimation):
(WebCore::CCActiveAnimation::alternatesDirection):
(WebCore::CCActiveAnimation::setAlternatesDirection):
* platform/graphics/chromium/cc/CCLayerAnimationController.cpp:

Source/WebKit/chromium:

* tests/CCActiveAnimationTest.cpp:
(WebCore::TEST):
(WebCore):
* tests/CCLayerAnimationControllerTest.cpp:
(WebKitTests::TEST):
(WebKitTests):

[email protected]
Review URL: https://chromiumcodereview.appspot.com/10384167

Modified Paths

Diff

Modified: branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp (116999 => 117000)


--- branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp	2012-05-14 21:12:38 UTC (rev 116999)
+++ branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.cpp	2012-05-14 21:17:42 UTC (rev 117000)
@@ -45,6 +45,7 @@
     , m_runState(WaitingForTargetAvailability)
     , m_iterations(1)
     , m_startTime(0)
+    , m_alternatesDirection(false)
     , m_timeOffset(0)
     , m_needsSynchronizedStartTime(false)
     , m_suspended(false)
@@ -119,11 +120,23 @@
         return trimmed;
 
     // If greater than or equal to the total duration, return iteration duration.
-    if (m_iterations >= 0 && trimmed >= m_curve->duration() * m_iterations)
+    if (m_iterations >= 0 && trimmed >= m_curve->duration() * m_iterations) {
+        if (m_alternatesDirection && !(m_iterations % 2))
+            return 0;
         return m_curve->duration();
+    }
 
-    // Finally, return x where trimmed = x + n * m_animation->duration() for some positive integer n.
-    return fmod(trimmed, m_curve->duration());
+    // We need to know the current iteration if we're alternating.
+    int iteration = static_cast<int>(trimmed / m_curve->duration());
+
+    // Calculate x where trimmed = x + n * m_curve->duration() for some positive integer n.
+    trimmed = fmod(trimmed, m_curve->duration());
+
+    // If we're alternating and on an odd iteration, reverse the direction.
+    if (m_alternatesDirection && iteration % 2 == 1)
+        return m_curve->duration() - trimmed;
+
+    return trimmed;
 }
 
 PassOwnPtr<CCActiveAnimation> CCActiveAnimation::cloneForImplThread() const
@@ -135,6 +148,7 @@
     toReturn->m_pauseTime = m_pauseTime;
     toReturn->m_totalPausedTime = m_totalPausedTime;
     toReturn->m_timeOffset = m_timeOffset;
+    toReturn->m_alternatesDirection = m_alternatesDirection;
     return toReturn.release();
 }
 

Modified: branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h (116999 => 117000)


--- branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h	2012-05-14 21:12:38 UTC (rev 116999)
+++ branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCActiveAnimation.h	2012-05-14 21:17:42 UTC (rev 117000)
@@ -90,6 +90,10 @@
     void suspend(double monotonicTime);
     void resume(double monotonicTime);
 
+    // If alternatesDirection is true, on odd numbered iterations we reverse the curve.
+    bool alternatesDirection() const { return m_alternatesDirection; }
+    void setAlternatesDirection(bool alternates) { m_alternatesDirection = alternates; }
+
     bool isFinishedAt(double monotonicTime) const;
     bool isFinished() const { return m_runState == Finished || m_runState == Aborted; }
 
@@ -128,6 +132,7 @@
     RunState m_runState;
     int m_iterations;
     double m_startTime;
+    bool m_alternatesDirection;
 
     // The time offset effectively pushes the start of the animation back in time. This is
     // used for resuming paused animations -- an animation is added with a non-zero time

Modified: branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp (116999 => 117000)


--- branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp	2012-05-14 21:12:38 UTC (rev 116999)
+++ branches/chromium/1132/Source/WebCore/platform/graphics/chromium/cc/CCLayerAnimationController.cpp	2012-05-14 21:17:42 UTC (rev 117000)
@@ -52,20 +52,24 @@
 template <class Value, class Keyframe, class Curve>
 PassOwnPtr<CCActiveAnimation> createActiveAnimation(const KeyframeValueList& valueList, const Animation* animation, size_t animationId, size_t groupId, double timeOffset, CCActiveAnimation::TargetProperty targetProperty)
 {
-    // FIXME: add support for different directions.
-    if (animation && animation->isDirectionSet() && animation->direction() != Animation::AnimationDirectionNormal)
-        return nullptr;
+    bool alternate = false;
+    bool reverse = false;
+    if (animation && animation->isDirectionSet()) {
+        Animation::AnimationDirection direction = animation->direction();
+        if (direction == Animation::AnimationDirectionAlternate || direction == Animation::AnimationDirectionAlternateReverse)
+            alternate = true;
+        if (direction == Animation::AnimationDirectionReverse || direction == Animation::AnimationDirectionAlternateReverse)
+            reverse = true;
+    }
 
-    // FIXME: add support for fills forwards and fills backwards
-    if (animation && animation->isFillModeSet() && (animation->fillsForwards() || animation->fillsBackwards()))
-        return nullptr;
-
     OwnPtr<Curve> curve = Curve::create();
     Vector<Keyframe> keyframes;
 
     for (size_t i = 0; i < valueList.size(); i++) {
-        const Value* originalValue = static_cast<const Value*>(valueList.at(i));
+        size_t index = reverse ? valueList.size() - i - 1 : i;
 
+        const Value* originalValue = static_cast<const Value*>(valueList.at(index));
+
         OwnPtr<CCTimingFunction> timingFunction;
         const TimingFunction* originalTimingFunction = originalValue->timingFunction();
 
@@ -91,7 +95,10 @@
             timingFunction = CCEaseTimingFunction::create();
 
         double duration = (animation && animation->isDurationSet()) ? animation->duration() : 1;
-        appendKeyframe<Value, Keyframe, Curve>(*curve, originalValue->keyTime() * duration, originalValue, timingFunction.release());
+        double keyTime = originalValue->keyTime() * duration;
+        if (reverse)
+            keyTime = duration - keyTime;
+        appendKeyframe<Value, Keyframe, Curve>(*curve, keyTime, originalValue, timingFunction.release());
     }
 
     OwnPtr<CCActiveAnimation> anim = CCActiveAnimation::create(curve.release(), animationId, groupId, targetProperty);
@@ -101,6 +108,7 @@
     if (anim.get()) {
         int iterations = (animation && animation->isIterationCountSet()) ? animation->iterationCount() : 1;
         anim->setIterations(iterations);
+        anim->setAlternatesDirection(alternate);
     }
 
     // In order to avoid skew, the main thread animation cannot tick until it has received the start time of

Modified: branches/chromium/1132/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp (116999 => 117000)


--- branches/chromium/1132/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp	2012-05-14 21:12:38 UTC (rev 116999)
+++ branches/chromium/1132/Source/WebKit/chromium/tests/CCActiveAnimationTest.cpp	2012-05-14 21:17:42 UTC (rev 117000)
@@ -69,6 +69,16 @@
     EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(1.5));
 }
 
+TEST(CCActiveAnimationTest, TrimTimeAlternating)
+{
+    OwnPtr<CCActiveAnimation> anim(createActiveAnimation(-1));
+    anim->setAlternatesDirection(true);
+    EXPECT_EQ(0, anim->trimTimeToCurrentIteration(0));
+    EXPECT_EQ(0.5, anim->trimTimeToCurrentIteration(0.5));
+    EXPECT_EQ(1, anim->trimTimeToCurrentIteration(1));
+    EXPECT_EQ(0.75, anim->trimTimeToCurrentIteration(1.25));
+}
+
 TEST(CCActiveAnimationTest, TrimTimeStartTime)
 {
     OwnPtr<CCActiveAnimation> anim(createActiveAnimation(1));

Modified: branches/chromium/1132/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp (116999 => 117000)


--- branches/chromium/1132/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp	2012-05-14 21:12:38 UTC (rev 116999)
+++ branches/chromium/1132/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp	2012-05-14 21:17:42 UTC (rev 117000)
@@ -86,34 +86,45 @@
     EXPECT_EQ(1, curve->getValue(duration));
 }
 
-TEST(CCLayerAnimationControllerTest, ignoreUnsupportedAnimationDirections)
+TEST(CCLayerAnimationControllerTest, createTransformAnimation)
 {
     FakeLayerAnimationControllerClient dummy;
     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
     const double duration = 1;
-    WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
-    values.insert(new FloatAnimationValue(0, 0));
-    values.insert(new FloatAnimationValue(duration, 1));
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
 
+    TransformOperations operations1;
+    operations1.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(0, &operations1));
+
+    TransformOperations operations2;
+    operations2.operations().append(TranslateTransformOperation::create(Length(4, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(duration, &operations2));
+
     RefPtr<Animation> animation = Animation::create();
     animation->setDuration(duration);
 
     IntSize boxSize;
+    controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0);
 
-    animation->setDirection(Animation::AnimationDirectionAlternate);
-    EXPECT_FALSE(controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0));
+    EXPECT_TRUE(controller->hasActiveAnimation());
 
-    animation->setDirection(Animation::AnimationDirectionAlternateReverse);
-    EXPECT_FALSE(controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0));
+    CCActiveAnimation* activeAnimation = controller->getActiveAnimation(0, CCActiveAnimation::Transform);
+    EXPECT_TRUE(activeAnimation);
 
-    animation->setDirection(Animation::AnimationDirectionReverse);
-    EXPECT_FALSE(controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0));
+    EXPECT_EQ(1, activeAnimation->iterations());
+    EXPECT_EQ(CCActiveAnimation::Transform, activeAnimation->targetProperty());
 
-    animation->setDirection(Animation::AnimationDirectionNormal);
-    EXPECT_TRUE(controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0));
+    EXPECT_EQ(CCAnimationCurve::Transform, activeAnimation->curve()->type());
+
+    const CCTransformAnimationCurve* curve = activeAnimation->curve()->toTransformAnimationCurve();
+    EXPECT_TRUE(curve);
+
+    expectTranslateX(2, curve->getValue(0, boxSize));
+    expectTranslateX(4, curve->getValue(duration, boxSize));
 }
 
-TEST(CCLayerAnimationControllerTest, createTransformAnimation)
+TEST(CCLayerAnimationControllerTest, createReversedAnimation)
 {
     FakeLayerAnimationControllerClient dummy;
     OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
@@ -130,6 +141,7 @@
 
     RefPtr<Animation> animation = Animation::create();
     animation->setDuration(duration);
+    animation->setDirection(Animation::AnimationDirectionReverse);
 
     IntSize boxSize;
     controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0);
@@ -147,10 +159,92 @@
     const CCTransformAnimationCurve* curve = activeAnimation->curve()->toTransformAnimationCurve();
     EXPECT_TRUE(curve);
 
+    expectTranslateX(4, curve->getValue(0, boxSize));
+    expectTranslateX(2, curve->getValue(duration, boxSize));
+}
+
+TEST(CCLayerAnimationControllerTest, createAlternatingAnimation)
+{
+    FakeLayerAnimationControllerClient dummy;
+    OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
+    const double duration = 1;
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+    TransformOperations operations1;
+    operations1.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(0, &operations1));
+
+    TransformOperations operations2;
+    operations2.operations().append(TranslateTransformOperation::create(Length(4, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(duration, &operations2));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(duration);
+    animation->setDirection(Animation::AnimationDirectionAlternate);
+    animation->setIterationCount(2);
+
+    IntSize boxSize;
+    controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0);
+
+    EXPECT_TRUE(controller->hasActiveAnimation());
+
+    CCActiveAnimation* activeAnimation = controller->getActiveAnimation(0, CCActiveAnimation::Transform);
+    EXPECT_TRUE(activeAnimation);
+    EXPECT_TRUE(activeAnimation->alternatesDirection());
+
+    EXPECT_EQ(2, activeAnimation->iterations());
+    EXPECT_EQ(CCActiveAnimation::Transform, activeAnimation->targetProperty());
+
+    EXPECT_EQ(CCAnimationCurve::Transform, activeAnimation->curve()->type());
+
+    const CCTransformAnimationCurve* curve = activeAnimation->curve()->toTransformAnimationCurve();
+    EXPECT_TRUE(curve);
+
     expectTranslateX(2, curve->getValue(0, boxSize));
     expectTranslateX(4, curve->getValue(duration, boxSize));
 }
 
+TEST(CCLayerAnimationControllerTest, createReversedAlternatingAnimation)
+{
+    FakeLayerAnimationControllerClient dummy;
+    OwnPtr<CCLayerAnimationController> controller(CCLayerAnimationController::create(&dummy));
+    const double duration = 1;
+    WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
+
+    TransformOperations operations1;
+    operations1.operations().append(TranslateTransformOperation::create(Length(2, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(0, &operations1));
+
+    TransformOperations operations2;
+    operations2.operations().append(TranslateTransformOperation::create(Length(4, Fixed), Length(0, Fixed), TransformOperation::TRANSLATE_X));
+    values.insert(new TransformAnimationValue(duration, &operations2));
+
+    RefPtr<Animation> animation = Animation::create();
+    animation->setDuration(duration);
+    animation->setDirection(Animation::AnimationDirectionAlternateReverse);
+    animation->setIterationCount(2);
+
+    IntSize boxSize;
+    controller->addAnimation(values, boxSize, animation.get(), 0, 0, 0);
+
+    EXPECT_TRUE(controller->hasActiveAnimation());
+
+    CCActiveAnimation* activeAnimation = controller->getActiveAnimation(0, CCActiveAnimation::Transform);
+    EXPECT_TRUE(activeAnimation);
+    EXPECT_TRUE(activeAnimation->alternatesDirection());
+
+    EXPECT_EQ(2, activeAnimation->iterations());
+    EXPECT_EQ(CCActiveAnimation::Transform, activeAnimation->targetProperty());
+
+    EXPECT_EQ(CCAnimationCurve::Transform, activeAnimation->curve()->type());
+
+    const CCTransformAnimationCurve* curve = activeAnimation->curve()->toTransformAnimationCurve();
+    EXPECT_TRUE(curve);
+
+    expectTranslateX(4, curve->getValue(0, boxSize));
+    expectTranslateX(2, curve->getValue(duration, boxSize));
+}
+
 TEST(CCLayerAnimationControllerTest, syncNewAnimation)
 {
     FakeLayerAnimationControllerClient dummyImpl;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to