[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

simon.fraser at apple.com simon.fraser at apple.com
Thu Apr 8 00:33:12 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d2fbbe1ffc01e87800aeb8d58197682e874d58d9
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 11 20:57:27 2009 +0000

    2009-12-11  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            Accelerated transitions broken when mixed with paused animations
            https://bugs.webkit.org/show_bug.cgi?id=32387
    
            Synchronization of a mixture of accelerated and software animations occurs via
            a callback from GraphicsLayerCA, which ends up in
            AnimationControllerPrivate::receivedStartTimeResponse(). The time passed in is
            the exact time at which the accelerated animations started, so is used as the
            start time for all animations and transitions which are marked as waiting.
    
            The bug was that the callback called when re-starting animations that were
            paused sent back an old time value, but this was used to start normal
            transitions. Therefore the transition would start with a stale start time, and
            thus end prematurely.
    
            The fix is to change the way that GraphicsLayerCA handles paused animations.
            Rather than setting the beginTime of the animation, it uses a beginTime of 0
            and a timeOffset that gets passed down. Thus the callbacks always come with
            beginTime for 'now'.
    
            Also clarify the role of AnimationBase::endAnimation() by splitting it into
            pauseAnimation() and endAnimation(), and pass down timeOffsets, rather than
            beginTimes when starting and pausing.
    
            Manual test only, because the bug requires a non-trivial combination of
            animation pausing and transitions which take time, and the bug only shows in
            pixel results.
    
            * manual-tests/animation/transitions-and-paused-animations.html
    
            * page/animation/AnimationBase.cpp:
            (WebCore::AnimationBase::updateStateMachine):
            * page/animation/AnimationBase.h:
            (WebCore::AnimationBase::startAnimation):
            (WebCore::AnimationBase::pauseAnimation):
            (WebCore::AnimationBase::endAnimation):
            * page/animation/ImplicitAnimation.cpp:
            (WebCore::ImplicitAnimation::~ImplicitAnimation):
            (WebCore::ImplicitAnimation::startAnimation):
            (WebCore::ImplicitAnimation::endAnimation):
            (WebCore::ImplicitAnimation::onAnimationEnd):
            * page/animation/ImplicitAnimation.h:
            (WebCore::ImplicitAnimation::pauseAnimation):
            * page/animation/KeyframeAnimation.cpp:
            (WebCore::KeyframeAnimation::~KeyframeAnimation):
            (WebCore::KeyframeAnimation::startAnimation):
            (WebCore::KeyframeAnimation::pauseAnimation):
            (WebCore::KeyframeAnimation::endAnimation):
            (WebCore::KeyframeAnimation::onAnimationEnd):
            * page/animation/KeyframeAnimation.h:
            * platform/graphics/GraphicsLayer.h:
            (WebCore::GraphicsLayer::addAnimation):
            (WebCore::GraphicsLayer::pauseAnimation):
            * platform/graphics/mac/GraphicsLayerCA.h:
            (WebCore::GraphicsLayerCA::LayerAnimation::LayerAnimation):
            (WebCore::GraphicsLayerCA::AnimationProcessingAction::AnimationProcessingAction):
            * platform/graphics/mac/GraphicsLayerCA.mm:
            (WebCore::GraphicsLayerCA::addAnimation):
            (WebCore::GraphicsLayerCA::removeAnimationsForKeyframes):
            (WebCore::GraphicsLayerCA::pauseAnimation):
            (WebCore::GraphicsLayerCA::updateLayerAnimations):
            (WebCore::GraphicsLayerCA::setAnimationOnLayer):
            (WebCore::GraphicsLayerCA::pauseAnimationOnLayer):
            (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
            (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):
            * rendering/RenderLayerBacking.cpp:
            (WebCore::RenderLayerBacking::startAnimation):
            (WebCore::RenderLayerBacking::startTransition):
            (WebCore::RenderLayerBacking::animationPaused):
            * rendering/RenderLayerBacking.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52017 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 790a541..84e0a63 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,77 @@
+2009-12-11  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Accelerated transitions broken when mixed with paused animations
+        https://bugs.webkit.org/show_bug.cgi?id=32387
+
+        Synchronization of a mixture of accelerated and software animations occurs via
+        a callback from GraphicsLayerCA, which ends up in
+        AnimationControllerPrivate::receivedStartTimeResponse(). The time passed in is
+        the exact time at which the accelerated animations started, so is used as the
+        start time for all animations and transitions which are marked as waiting.
+
+        The bug was that the callback called when re-starting animations that were
+        paused sent back an old time value, but this was used to start normal
+        transitions. Therefore the transition would start with a stale start time, and
+        thus end prematurely.
+
+        The fix is to change the way that GraphicsLayerCA handles paused animations.
+        Rather than setting the beginTime of the animation, it uses a beginTime of 0
+        and a timeOffset that gets passed down. Thus the callbacks always come with
+        beginTime for 'now'.
+
+        Also clarify the role of AnimationBase::endAnimation() by splitting it into
+        pauseAnimation() and endAnimation(), and pass down timeOffsets, rather than
+        beginTimes when starting and pausing.
+
+        Manual test only, because the bug requires a non-trivial combination of
+        animation pausing and transitions which take time, and the bug only shows in
+        pixel results.
+        
+        * manual-tests/animation/transitions-and-paused-animations.html
+
+        * page/animation/AnimationBase.cpp:
+        (WebCore::AnimationBase::updateStateMachine):
+        * page/animation/AnimationBase.h:
+        (WebCore::AnimationBase::startAnimation):
+        (WebCore::AnimationBase::pauseAnimation):
+        (WebCore::AnimationBase::endAnimation):
+        * page/animation/ImplicitAnimation.cpp:
+        (WebCore::ImplicitAnimation::~ImplicitAnimation):
+        (WebCore::ImplicitAnimation::startAnimation):
+        (WebCore::ImplicitAnimation::endAnimation):
+        (WebCore::ImplicitAnimation::onAnimationEnd):
+        * page/animation/ImplicitAnimation.h:
+        (WebCore::ImplicitAnimation::pauseAnimation):
+        * page/animation/KeyframeAnimation.cpp:
+        (WebCore::KeyframeAnimation::~KeyframeAnimation):
+        (WebCore::KeyframeAnimation::startAnimation):
+        (WebCore::KeyframeAnimation::pauseAnimation):
+        (WebCore::KeyframeAnimation::endAnimation):
+        (WebCore::KeyframeAnimation::onAnimationEnd):
+        * page/animation/KeyframeAnimation.h:
+        * platform/graphics/GraphicsLayer.h:
+        (WebCore::GraphicsLayer::addAnimation):
+        (WebCore::GraphicsLayer::pauseAnimation):
+        * platform/graphics/mac/GraphicsLayerCA.h:
+        (WebCore::GraphicsLayerCA::LayerAnimation::LayerAnimation):
+        (WebCore::GraphicsLayerCA::AnimationProcessingAction::AnimationProcessingAction):
+        * platform/graphics/mac/GraphicsLayerCA.mm:
+        (WebCore::GraphicsLayerCA::addAnimation):
+        (WebCore::GraphicsLayerCA::removeAnimationsForKeyframes):
+        (WebCore::GraphicsLayerCA::pauseAnimation):
+        (WebCore::GraphicsLayerCA::updateLayerAnimations):
+        (WebCore::GraphicsLayerCA::setAnimationOnLayer):
+        (WebCore::GraphicsLayerCA::pauseAnimationOnLayer):
+        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes):
+        (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::startAnimation):
+        (WebCore::RenderLayerBacking::startTransition):
+        (WebCore::RenderLayerBacking::animationPaused):
+        * rendering/RenderLayerBacking.h:
+
 2009-12-11  Brian Weinstein  <bweinstein at apple.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/manual-tests/animation/transitions-and-paused-animations.html b/WebCore/manual-tests/animation/transitions-and-paused-animations.html
new file mode 100644
index 0000000..388d837
--- /dev/null
+++ b/WebCore/manual-tests/animation/transitions-and-paused-animations.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+   "http://www.w3.org/TR/html4/loose.dtd">
+
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  <title>Transitions and paused animations</title>
+  <style type="text/css" media="screen">
+    
+    .container {
+      height: 200px;
+      width: 200px;
+      border: 1px solid black;
+      -webkit-transition: -webkit-transform 0.5s;
+    }
+    
+    .moved {
+      -webkit-transform: translateX(100px);
+      
+    }
+    .box {
+      position: relative;
+      height: 100px;
+      width: 100px;
+      margin: 50px;
+      background-color: blue;
+      -webkit-transform: translateZ(0);
+      -webkit-animation: fade 1s infinite linear alternate;
+    }
+    
+    .moved .box {
+      -webkit-animation-play-state: paused;
+    }
+    
+    @-webkit-keyframes fade {
+      from { -webkit-transform: rotate(-20deg); }
+      to   { -webkit-transform: rotate(20deg);   }
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    
+    function runTest()
+    {
+      var box = document.querySelectorAll('.box')[0];
+      var container = document.querySelectorAll('.container')[0];
+      
+      window.setTimeout(function() {
+        container.className = 'container';
+      }, 250);
+      
+      window.setTimeout(function() {
+        container.className = 'container moved';
+      }, 1500);
+
+      window.setTimeout(function() {
+        container.className = 'container';
+      }, 3000);
+    }
+    
+    window.addEventListener('load', runTest, false)
+  </script>
+</head>
+<body>
+
+<p>Box should animate smoothly left, then right then left again, and not jump at the end.</p>
+<div class="container moved">
+  <div class="box"></div>
+</div>
+
+</body>
+</html>
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index f1ee750..2c74de2 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -863,7 +863,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
         m_pauseTime = -1;
         m_requestedStartTime = 0;
         m_nextIterationDuration = -1;
-        endAnimation(false);
+        endAnimation();
         return;
     }
 
@@ -875,7 +875,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
         m_pauseTime = -1;
         m_requestedStartTime = 0;
         m_nextIterationDuration = -1;
-        endAnimation(false);
+        endAnimation();
 
         if (!paused())
             updateStateMachine(AnimationStateInputStartAnimation, -1);
@@ -886,7 +886,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
         if (m_animState == AnimationStateStartWaitStyleAvailable)
             m_compAnim->animationController()->removeFromStyleAvailableWaitList(this);
         m_animState = AnimationStateDone;
-        endAnimation(true);
+        endAnimation();
         return;
     }
 
@@ -894,7 +894,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
         if (m_animState == AnimationStateStartWaitResponse) {
             // If we are in AnimationStateStartWaitResponse, the animation will get canceled before 
             // we get a response, so move to the next state.
-            endAnimation(false);
+            endAnimation();
             updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
         }
         return;
@@ -903,7 +903,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
     if (input == AnimationStateInputResumeOverride) {
         if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
             // Start the animation
-            startAnimation(m_startTime);
+            startAnimation(beginAnimationUpdateTime() - m_startTime);
         }
         return;
     }
@@ -980,7 +980,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
                 // We are pausing while waiting for a start response. Cancel the animation and wait. When 
                 // we unpause, we will act as though the start timer just fired
                 m_pauseTime = -1;
-                endAnimation(false);
+                pauseAnimation(beginAnimationUpdateTime() - m_startTime);
                 m_animState = AnimationStatePausedWaitResponse;
             }
             break;
@@ -997,7 +997,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
             } else {
                 // We are pausing while running. Cancel the animation and wait
                 m_pauseTime = beginAnimationUpdateTime();
-                endAnimation(false);
+                pauseAnimation(beginAnimationUpdateTime() - m_startTime);
                 m_animState = AnimationStatePausedRun;
             }
             break;
@@ -1020,7 +1020,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
             } else {
                 // We are pausing while running. Cancel the animation and wait
                 m_pauseTime = beginAnimationUpdateTime();
-                endAnimation(false);
+                pauseAnimation(beginAnimationUpdateTime() - m_startTime);
                 m_animState = AnimationStatePausedRun;
             }
             // |this| may be deleted here
@@ -1072,7 +1072,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
                 updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
                 m_fallbackAnimating = true;
             } else {
-                bool started = startAnimation(m_startTime);
+                bool started = startAnimation(beginAnimationUpdateTime() - m_startTime);
                 m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started);
                 m_fallbackAnimating = !started;
             }
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
index 3482f65..c367e0a 100644
--- a/WebCore/page/animation/AnimationBase.h
+++ b/WebCore/page/animation/AnimationBase.h
@@ -186,8 +186,13 @@ protected:
     virtual void onAnimationStart(double /*elapsedTime*/) { }
     virtual void onAnimationIteration(double /*elapsedTime*/) { }
     virtual void onAnimationEnd(double /*elapsedTime*/) { }
-    virtual bool startAnimation(double /*beginTime*/) { return false; }
-    virtual void endAnimation(bool /*reset*/) { }
+    
+    // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
+    // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
+    virtual bool startAnimation(double /*timeOffset*/) { return false; }
+    // timeOffset is the time at which the animation is being paused.
+    virtual void pauseAnimation(double /*timeOffset*/) { }
+    virtual void endAnimation() { }
 
     void goIntoEndingOrLoopingState();
 
diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp
index 50fc781..d39f5fc 100644
--- a/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/WebCore/page/animation/ImplicitAnimation.cpp
@@ -55,7 +55,7 @@ ImplicitAnimation::~ImplicitAnimation()
 {
     // // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
     if (!postActive())
-        endAnimation(true);
+        endAnimation();
 }
 
 bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const
@@ -106,13 +106,13 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
     blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
 }
 
-bool ImplicitAnimation::startAnimation(double beginTime)
+bool ImplicitAnimation::startAnimation(double timeOffset)
 {
 #if USE(ACCELERATED_COMPOSITING)
     if (m_object && m_object->hasLayer()) {
         RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
         if (layer->isComposited())
-            return layer->backing()->startTransition(beginTime, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+            return layer->backing()->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
     }
 #else
     UNUSED_PARAM(beginTime);
@@ -120,7 +120,7 @@ bool ImplicitAnimation::startAnimation(double beginTime)
     return false;
 }
 
-void ImplicitAnimation::endAnimation(bool /*reset*/)
+void ImplicitAnimation::endAnimation()
 {
 #if USE(ACCELERATED_COMPOSITING)
     if (m_object && m_object->hasLayer()) {
@@ -143,7 +143,7 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime)
         keyframeAnim->setUnanimatedStyle(m_toStyle);
     
     sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime);
-    endAnimation(true);
+    endAnimation();
 }
 
 bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h
index 7e286d2..be5c197 100644
--- a/WebCore/page/animation/ImplicitAnimation.h
+++ b/WebCore/page/animation/ImplicitAnimation.h
@@ -47,8 +47,9 @@ public:
     int animatingProperty() const { return m_animatingProperty; }
 
     virtual void onAnimationEnd(double elapsedTime);
-    virtual bool startAnimation(double beginTime);
-    virtual void endAnimation(bool reset);
+    virtual bool startAnimation(double timeOffset);
+    virtual void pauseAnimation(double /*timeOffset*/) { }
+    virtual void endAnimation();
 
     virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
     virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index 500bf6f..bbfb6ae 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -59,7 +59,7 @@ KeyframeAnimation::~KeyframeAnimation()
 {
     // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
     if (!postActive())
-        endAnimation(true);
+        endAnimation();
 }
 
 void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
@@ -192,13 +192,13 @@ bool KeyframeAnimation::hasAnimationForProperty(int property) const
     return false;
 }
 
-bool KeyframeAnimation::startAnimation(double beginTime)
+bool KeyframeAnimation::startAnimation(double timeOffset)
 {
 #if USE(ACCELERATED_COMPOSITING)
     if (m_object && m_object->hasLayer()) {
         RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
         if (layer->isComposited())
-            return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes);
+            return layer->backing()->startAnimation(timeOffset, m_animation.get(), m_keyframes);
     }
 #else
     UNUSED_PARAM(beginTime);
@@ -206,26 +206,38 @@ bool KeyframeAnimation::startAnimation(double beginTime)
     return false;
 }
 
-void KeyframeAnimation::endAnimation(bool reset)
+void KeyframeAnimation::pauseAnimation(double timeOffset)
 {
-    if (m_object) {
+    if (!m_object)
+        return;
+
 #if USE(ACCELERATED_COMPOSITING)
-        if (m_object->hasLayer()) {
-            RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
-            if (layer->isComposited()) {
-                if (reset)
-                    layer->backing()->animationFinished(m_keyframes.animationName());
-                else
-                    layer->backing()->animationPaused(m_keyframes.animationName());
-            }
-        }
-#else
-        UNUSED_PARAM(reset);
+    if (m_object->hasLayer()) {
+        RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+        if (layer->isComposited())
+            layer->backing()->animationPaused(timeOffset, m_keyframes.animationName());
+    }
 #endif
-        // Restore the original (unanimated) style
-        if (!paused())
-            setNeedsStyleRecalc(m_object->node());
+    // Restore the original (unanimated) style
+    if (!paused())
+        setNeedsStyleRecalc(m_object->node());
+}
+
+void KeyframeAnimation::endAnimation()
+{
+    if (!m_object)
+        return;
+
+#if USE(ACCELERATED_COMPOSITING)
+    if (m_object->hasLayer()) {
+        RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+        if (layer->isComposited())
+            layer->backing()->animationFinished(m_keyframes.animationName());
     }
+#endif
+    // Restore the original (unanimated) style
+    if (!paused())
+        setNeedsStyleRecalc(m_object->node());
 }
 
 bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
@@ -246,7 +258,7 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime)
 void KeyframeAnimation::onAnimationEnd(double elapsedTime)
 {
     sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime);
-    endAnimation(true);
+    endAnimation();
 }
 
 bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h
index e3b8f53..fab0ae8 100644
--- a/WebCore/page/animation/KeyframeAnimation.h
+++ b/WebCore/page/animation/KeyframeAnimation.h
@@ -64,8 +64,9 @@ protected:
     virtual void onAnimationStart(double elapsedTime);
     virtual void onAnimationIteration(double elapsedTime);
     virtual void onAnimationEnd(double elapsedTime);
-    virtual bool startAnimation(double beginTime);
-    virtual void endAnimation(bool reset);
+    virtual bool startAnimation(double timeOffset);
+    virtual void pauseAnimation(double timeOffset);
+    virtual void endAnimation();
 
     virtual void overrideAnimations();
     virtual void resumeOverriddenAnimations();
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 0456bad..1ad7a1e 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -260,10 +260,10 @@ public:
     
     // Return true if the animation is handled by the compositing system. If this returns
     // false, the animation will be run by AnimationController.
-    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*beginTime*/) { return false; }
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
     virtual void removeAnimationsForProperty(AnimatedPropertyID) { }
     virtual void removeAnimationsForKeyframes(const String& /* keyframesName */) { }
-    virtual void pauseAnimation(const String& /* keyframesName */) { }
+    virtual void pauseAnimation(const String& /* keyframesName */, double /*timeOffset*/) { }
     
     virtual void suspendAnimations(double time);
     virtual void resumeAnimations();
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index 8024091..5f6161c 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -98,10 +98,10 @@ public:
     virtual void suspendAnimations(double time);
     virtual void resumeAnimations();
 
-    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double beginTime);
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double timeOffset);
     virtual void removeAnimationsForProperty(AnimatedPropertyID);
     virtual void removeAnimationsForKeyframes(const String& keyframesName);
-    virtual void pauseAnimation(const String& keyframesName);
+    virtual void pauseAnimation(const String& keyframesName, double timeOffset);
     
     virtual void setContentsToImage(Image*);
     virtual void setContentsToVideo(PlatformLayer*);
@@ -132,8 +132,8 @@ private:
     WebLayer* layerForSuperlayer() const;
     CALayer* animatedLayer(AnimatedPropertyID property) const;
 
-    bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double beginTime);
-    bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double beginTime, const IntSize& boxSize);
+    bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset);
+    bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset, const IntSize& boxSize);
 
     // Return autoreleased animation (use RetainPtr?)
     CABasicAnimation* createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
@@ -187,9 +187,9 @@ private:
 
     void updateLayerAnimations();
 
-    void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, int index, double beginTime);
+    void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, int index, double timeOffset);
     bool removeAnimationFromLayer(AnimatedPropertyID, int index);
-    void pauseAnimationOnLayer(AnimatedPropertyID, int index);
+    void pauseAnimationOnLayer(AnimatedPropertyID, int index, double timeOffset);
 
     enum LayerChange {
         NoChange = 0,
@@ -244,19 +244,19 @@ private:
     RetainPtr<CGImageRef> m_pendingContentsImage;
     
     struct LayerAnimation {
-        LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double beginTime)
+        LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double timeOffset)
         : m_animation(caAnim)
         , m_keyframesName(keyframesName)
         , m_property(property)
         , m_index(index)
-        , m_beginTime(beginTime)
+        , m_timeOffset(timeOffset)
         { }
 
         RetainPtr<CAPropertyAnimation*> m_animation;
         String m_keyframesName;
         AnimatedPropertyID m_property;
         int m_index;
-        double m_beginTime;
+        double m_timeOffset;
     };
     
     Vector<LayerAnimation> m_uncomittedAnimations;
@@ -267,8 +267,16 @@ private:
 
     HashSet<AnimatedProperty> m_transitionPropertiesToRemove;
     
-    enum { Remove, Pause };
-    typedef int AnimationProcessingAction;
+    enum Action { Remove, Pause };
+    struct AnimationProcessingAction {
+        AnimationProcessingAction(Action action = Remove, double timeOffset = 0)
+            : action(action)
+            , timeOffset(timeOffset)
+        {
+        }
+        Action action;
+        double timeOffset;      // only used for pause
+    };
     typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
     AnimationsToProcessMap m_keyframeAnimationsToProcess;
 
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index dea6bfc..a38a728 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -643,7 +643,7 @@ void GraphicsLayerCA::setContentsRect(const IntRect& rect)
     noteLayerPropertyChanged(ContentsRectChanged);
 }
 
-bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double beginTime)
+bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
 {
     if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
         return false;
@@ -657,9 +657,9 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
 
     bool createdAnimations = false;
     if (valueList.property() == AnimatedPropertyWebkitTransform)
-        createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, beginTime, boxSize);
+        createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, timeOffset, boxSize);
     else
-        createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, beginTime);
+        createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, timeOffset);
 
     if (createdAnimations)
         noteLayerPropertyChanged(AnimationChanged);
@@ -681,22 +681,23 @@ void GraphicsLayerCA::removeAnimationsForKeyframes(const String& animationName)
     if (!animationIsRunning(animationName))
         return;
 
-    m_keyframeAnimationsToProcess.add(animationName, Remove);
+    m_keyframeAnimationsToProcess.add(animationName, AnimationProcessingAction(Remove));
     noteLayerPropertyChanged(AnimationChanged);
 }
 
-void GraphicsLayerCA::pauseAnimation(const String& keyframesName)
+void GraphicsLayerCA::pauseAnimation(const String& keyframesName, double timeOffset)
 {
     if (!animationIsRunning(keyframesName))
         return;
 
     AnimationsToProcessMap::iterator it = m_keyframeAnimationsToProcess.find(keyframesName);
     if (it != m_keyframeAnimationsToProcess.end()) {
+        AnimationProcessingAction& processingInfo = it->second;
         // If an animation is scheduled to be removed, don't change the remove to a pause.
-        if (it->second != Remove)
-            it->second = Pause;
+        if (processingInfo.action != Remove)
+            processingInfo.action = Pause;
     } else
-        m_keyframeAnimationsToProcess.add(keyframesName, Pause);
+        m_keyframeAnimationsToProcess.add(keyframesName, AnimationProcessingAction(Pause, timeOffset));
 
     noteLayerPropertyChanged(AnimationChanged);
 }
@@ -1182,21 +1183,21 @@ void GraphicsLayerCA::updateLayerAnimations()
             if (animationIt == m_runningKeyframeAnimations.end())
                 continue;
 
-            AnimationProcessingAction action = it->second;
+            const AnimationProcessingAction& processingInfo = it->second;
             const Vector<AnimationPair>& animations = animationIt->second;
             for (size_t i = 0; i < animations.size(); ++i) {
                 const AnimationPair& currPair = animations[i];
-                switch (action) {
+                switch (processingInfo.action) {
                     case Remove:
                         removeAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currPair.second);
                         break;
                     case Pause:
-                        pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currPair.second);
+                        pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currPair.second, processingInfo.timeOffset);
                         break;
                 }
             }
 
-            if (action == Remove)
+            if (processingInfo.action == Remove)
                 m_runningKeyframeAnimations.remove(currKeyframeName);
         }
     
@@ -1207,7 +1208,7 @@ void GraphicsLayerCA::updateLayerAnimations()
     if ((numAnimations = m_uncomittedAnimations.size())) {
         for (size_t i = 0; i < numAnimations; ++i) {
             const LayerAnimation& pendingAnimation = m_uncomittedAnimations[i];
-            setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_index, pendingAnimation.m_beginTime);
+            setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
             
             if (!pendingAnimation.m_keyframesName.isEmpty()) {
                 // If this is a keyframe anim, we have to remember the association of keyframes name to property/index pairs,
@@ -1229,14 +1230,11 @@ void GraphicsLayerCA::updateLayerAnimations()
     }
 }
 
-void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, int index, double beginTime)
+void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, int index, double timeOffset)
 {
     PlatformLayer* layer = animatedLayer(property);
 
-    if (beginTime) {
-        NSTimeInterval time = [layer convertTime:currentTimeToMediaTime(beginTime) fromLayer:nil];
-        [caAnim setBeginTime:time];
-    }
+    [caAnim setTimeOffset:timeOffset];
     
     String animationName = animationIdentifier(property, index);
     
@@ -1290,7 +1288,7 @@ static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimati
 #endif
 }
 
-void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int index)
+void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int index, double timeOffset)
 {
     PlatformLayer* layer = animatedLayer(property);
 
@@ -1319,9 +1317,10 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int ind
         pausedAnim = newAnim;
     }
 
-    double t = [layer convertTime:currentTimeToMediaTime(currentTime()) fromLayer:nil];
+    // pausedAnim has the beginTime of caAnim already.
     [pausedAnim setSpeed:0];
-    [pausedAnim setTimeOffset:t - [caAnim beginTime]];
+    [pausedAnim setTimeOffset:timeOffset];
+    
     [layer addAnimation:pausedAnim forKey:animationName];  // This will replace the running animation.
 }
 
@@ -1370,7 +1369,7 @@ void GraphicsLayerCA::repaintLayerDirtyRects()
     m_dirtyRects.clear();
 }
 
-bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime)
+bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset)
 {
     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
 
@@ -1396,14 +1395,14 @@ bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valu
     if (!valuesOK)
         return false;
 
-    m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, beginTime));
+    m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
     
     END_BLOCK_OBJC_EXCEPTIONS;
 
     return true;
 }
 
-bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double beginTime, const IntSize& boxSize)
+bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset, const IntSize& boxSize)
 {
     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
 
@@ -1450,7 +1449,7 @@ bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValue
         if (!validMatrices)
             break;
     
-        m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, beginTime));
+        m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
     }
 
     END_BLOCK_OBJC_EXCEPTIONS;
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index a62c1be..8c092c6 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -1060,7 +1060,7 @@ bool RenderLayerBacking::showRepaintCounter() const
     return compositor() ? compositor()->showRepaintCounter() : false;
 }
 
-bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes)
+bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes)
 {
     bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
     bool hasTransform = keyframes.containsProperty(CSSPropertyWebkitTransform);
@@ -1091,10 +1091,10 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim,
     bool didAnimateTransform = !hasTransform;
     bool didAnimateOpacity = !hasOpacity;
     
-    if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), beginTime))
+    if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset))
         didAnimateTransform = true;
 
-    if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), beginTime))
+    if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset))
         didAnimateOpacity = true;
     
     bool runningAcceleratedAnimation = didAnimateTransform && didAnimateOpacity;
@@ -1104,7 +1104,7 @@ bool RenderLayerBacking::startAnimation(double beginTime, const Animation* anim,
     return runningAcceleratedAnimation;
 }
 
-bool RenderLayerBacking::startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
+bool RenderLayerBacking::startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
 {
     bool didAnimate = false;
     ASSERT(property != cAnimateAll);
@@ -1116,7 +1116,7 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R
             opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
             opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
             // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
-            if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), beginTime)) {
+            if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, String(), timeOffset)) {
                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
                 updateLayerOpacity(toStyle);
                 didAnimate = true;
@@ -1130,7 +1130,7 @@ bool RenderLayerBacking::startTransition(double beginTime, int property, const R
             KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
             transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
             transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
-            if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, String(), beginTime)) {
+            if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, String(), timeOffset)) {
                 // To ensure that the correct transform is visible when the animation ends, also set the final opacity.
                 updateLayerTransform(toStyle);
                 didAnimate = true;
@@ -1160,9 +1160,9 @@ void RenderLayerBacking::animationFinished(const String& animationName)
     m_graphicsLayer->removeAnimationsForKeyframes(animationName);
 }
 
-void RenderLayerBacking::animationPaused(const String& animationName)
+void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
 {
-    m_graphicsLayer->pauseAnimation(animationName);
+    m_graphicsLayer->pauseAnimation(animationName, timeOffset);
 }
 
 void RenderLayerBacking::transitionFinished(int property)
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index 2bbb37f..cb80255 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -97,10 +97,10 @@ public:
     void rendererContentChanged();
 
     // Interface to start, finish, suspend and resume animations and transitions
-    bool startAnimation(double beginTime, const Animation* anim, const KeyframeList& keyframes);
-    bool startTransition(double beginTime, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle);
+    bool startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes);
+    bool startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle);
     void animationFinished(const String& name);
-    void animationPaused(const String& name);
+    void animationPaused(double timeOffset, const String& name);
     void transitionFinished(int property);
 
     void suspendAnimations(double time = 0);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list