2010-09-23 Simon Fraser <simon.fraser@apple.com>
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Sep 2010 04:17:03 +0000 (04:17 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 24 Sep 2010 04:17:03 +0000 (04:17 +0000)
        Reviewed by Dan Bernstein.

        Accelerated transitions do not suspend/resume properly.
        https://bugs.webkit.org/show_bug.cgi?id=43792

        Fix suspending of accelerated transitions.

        GraphicsLayer changes unify the handling of transitions and animations
        in GraphicsLayer. Both are now identified by name, so the code
        now refers to "animationName" rather than "keyframesName". Transitions
        use a dummy name which is not a valid keyframe identifier.

        Tests: animations/suspend-transform-animation.html
               transitions/suspend-transform-transition.html

        * page/animation/ImplicitAnimation.h:
        * page/animation/ImplicitAnimation.cpp:
        (WebCore::ImplicitAnimation::pauseAnimation): Call down to the RenderLayerBacking
        to tell it that an accelerated transition was paused.

        * platform/graphics/GraphicsLayer.h:
        * platform/graphics/GraphicsLayer.cpp:
        (WebCore::GraphicsLayer::animationNameForTransition): Create a name
        for the transition of the given property.
        (WebCore::GraphicsLayer::addAnimation): Generalize "keyframe" to "animation" in the parameter names.
        (WebCore::GraphicsLayer::pauseAnimation): ditto
        (WebCore::GraphicsLayer::removeAnimation): ditto

        * platform/graphics/mac/GraphicsLayerCA.h: Parameter renaming, and some method renames for clarity.
        (WebCore::GraphicsLayerCA::animationIsRunning):
        (WebCore::GraphicsLayerCA::LayerPropertyAnimation::LayerPropertyAnimation): struct rename for clarity.

        * platform/graphics/mac/GraphicsLayerCA.mm:
        (WebCore::animationIdentifier): the animationName already has the property baked in.
        (WebCore::GraphicsLayerCA::moveOrCopyLayerAnimation): just deals with one animation now.
        (WebCore::GraphicsLayerCA::moveOrCopyAnimationsForProperty): we have to trawl through
        m_runningAnimations to get the identifiers for the animations that need to be copied.
        (WebCore::GraphicsLayerCA::addAnimation): rename parameters.
        (WebCore::GraphicsLayerCA::pauseAnimation): re-ordered methods here. member var renames.
        (WebCore::GraphicsLayerCA::removeAnimation): ditto.
        (WebCore::GraphicsLayerCA::updateLayerAnimations): no need to iterate over m_transitionPropertiesToRemove,
        and no more divergence between transitions and animations.
        (WebCore::GraphicsLayerCA::setCAAnimationOnLayer): renames for clarity.
        (WebCore::GraphicsLayerCA::removeCAAnimationFromLayer): ditto
        (WebCore::GraphicsLayerCA::pauseCAAnimationOnLayer): ditto
        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes): renames
        (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes): renames
        (WebCore::GraphicsLayerCA::suspendAnimations): whitespace.

        * rendering/RenderLayerBacking.h: Group the transition and animation methods together.
        * rendering/RenderLayerBacking.cpp:
        (WebCore::RenderLayerBacking::animationPaused): Re-ordered methods for clarity.
        (WebCore::RenderLayerBacking::animationFinished): ditto
        (WebCore::RenderLayerBacking::startTransition): Use animationNameForTransition() to generate
        the animation identifier.
        (WebCore::RenderLayerBacking::transitionPaused): Call pauseAnimation, using animationNameForTransition()
        to generate the animation identifier.
        (WebCore::RenderLayerBacking::transitionFinished): Call removeAnimation, using animationNameForTransition()
        to generate the animation identifier.
        (WebCore::RenderLayerBacking::notifyAnimationStarted): Moved.
        (WebCore::RenderLayerBacking::notifySyncRequired): Moved.

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/animations/suspend-transform-animation-expected.checksum [new file with mode: 0644]
LayoutTests/animations/suspend-transform-animation-expected.png [new file with mode: 0644]
LayoutTests/animations/suspend-transform-animation-expected.txt [new file with mode: 0644]
LayoutTests/animations/suspend-transform-animation.html [new file with mode: 0644]
LayoutTests/transitions/repeated-firing-background-color.html
LayoutTests/transitions/suspend-transform-transition-expected.checksum [new file with mode: 0644]
LayoutTests/transitions/suspend-transform-transition-expected.png [new file with mode: 0644]
LayoutTests/transitions/suspend-transform-transition-expected.txt [new file with mode: 0644]
LayoutTests/transitions/suspend-transform-transition.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/page/animation/ImplicitAnimation.cpp
WebCore/page/animation/ImplicitAnimation.h
WebCore/platform/graphics/GraphicsLayer.cpp
WebCore/platform/graphics/GraphicsLayer.h
WebCore/platform/graphics/mac/GraphicsLayerCA.h
WebCore/platform/graphics/mac/GraphicsLayerCA.mm
WebCore/rendering/RenderLayerBacking.cpp
WebCore/rendering/RenderLayerBacking.h

index 370bd80..9c7aea3 100644 (file)
@@ -1,3 +1,22 @@
+2010-09-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Accelerated transitions do not suspend/resume properly.
+        https://bugs.webkit.org/show_bug.cgi?id=43792
+        
+        Tests for suspending hardware-accelerated transitions and animations.
+
+        * animations/suspend-transform-animation-expected.checksum: Added.
+        * animations/suspend-transform-animation-expected.png: Added.
+        * animations/suspend-transform-animation-expected.txt: Added.
+        * animations/suspend-transform-animation.html: Added.
+        * transitions/repeated-firing-background-color.html:
+        * transitions/suspend-transform-transition-expected.checksum: Added.
+        * transitions/suspend-transform-transition-expected.png: Added.
+        * transitions/suspend-transform-transition-expected.txt: Added.
+        * transitions/suspend-transform-transition.html: Added.
+
 2010-09-23  Tony Chang  <tony@chromium.org>
 
         Unreviewed.  Removing a png that I didn't mean to check in.  This
diff --git a/LayoutTests/animations/suspend-transform-animation-expected.checksum b/LayoutTests/animations/suspend-transform-animation-expected.checksum
new file mode 100644 (file)
index 0000000..129db12
--- /dev/null
@@ -0,0 +1 @@
+71e8c47597a07100ddc8ecd015fe21fb
\ No newline at end of file
diff --git a/LayoutTests/animations/suspend-transform-animation-expected.png b/LayoutTests/animations/suspend-transform-animation-expected.png
new file mode 100644 (file)
index 0000000..21da8c7
Binary files /dev/null and b/LayoutTests/animations/suspend-transform-animation-expected.png differ
diff --git a/LayoutTests/animations/suspend-transform-animation-expected.txt b/LayoutTests/animations/suspend-transform-animation-expected.txt
new file mode 100644 (file)
index 0000000..7d8af70
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock {DIV} at (0,0) size 784x0
+layer at (0,0) size 100x100
+  RenderBlock (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF0000]
+layer at (100,0) size 300x100
+  RenderBlock (positioned) {DIV} at (100,0) size 300x100 [bgcolor=#008000]
diff --git a/LayoutTests/animations/suspend-transform-animation.html b/LayoutTests/animations/suspend-transform-animation.html
new file mode 100644 (file)
index 0000000..dd7b42a
--- /dev/null
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css" media="screen">
+    #box {
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100px;
+        width: 100px;
+        background-color: red;
+        -webkit-animation-duration: 0.2s;
+        -webkit-animation-timing-function: linear;
+    }
+    
+    .move {
+        -webkit-animation-name: move;
+    }
+
+    @-webkit-keyframes move {
+        from { -webkit-transform: translateX(100px) scale(1); }
+        to   { -webkit-transform: translateX(400px) scale(1); }
+    }
+    
+    #safezone {
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100px;
+        width: 300px;
+        left: 100px;
+        background-color: green;
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+    
+    function suspendAndWaitForCompletion()
+    {
+        if (window.layoutTestController)
+            layoutTestController.suspendAnimations();
+
+        window.setTimeout(function() {
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }, 250);
+    }
+    
+    function doTest()
+    {
+        document.getElementById('box').addEventListener('webkitAnimationStart', function() {
+            suspendAndWaitForCompletion();
+        }, false)
+
+        document.getElementById('box').className = 'move';
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+<!-- When suspended, the red box should be hidden by the green box. You should see no red. -->
+<div id="box"></div>
+<div id="safezone"></div>
+
+<div id="result"></div>
+
+</body>
+</html>
index 0957570..e6904ce 100644 (file)
   <script type="text/javascript" charset="utf-8">
     function checkRunning()
     {
+      if (!window.layoutTestController) {
+        document.getElementById('result').innerHTML = "This test must be run in DRT."
+        return;
+      }
+        
       var current = layoutTestController.numberOfActiveAnimations();
       if (current == 0)
         document.getElementById('result').innerHTML = "Number of active transitions is (0) as expected";
diff --git a/LayoutTests/transitions/suspend-transform-transition-expected.checksum b/LayoutTests/transitions/suspend-transform-transition-expected.checksum
new file mode 100644 (file)
index 0000000..129db12
--- /dev/null
@@ -0,0 +1 @@
+71e8c47597a07100ddc8ecd015fe21fb
\ No newline at end of file
diff --git a/LayoutTests/transitions/suspend-transform-transition-expected.png b/LayoutTests/transitions/suspend-transform-transition-expected.png
new file mode 100644 (file)
index 0000000..21da8c7
Binary files /dev/null and b/LayoutTests/transitions/suspend-transform-transition-expected.png differ
diff --git a/LayoutTests/transitions/suspend-transform-transition-expected.txt b/LayoutTests/transitions/suspend-transform-transition-expected.txt
new file mode 100644 (file)
index 0000000..7d8af70
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock {DIV} at (0,0) size 784x0
+layer at (0,0) size 100x100
+  RenderBlock (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#FF0000]
+layer at (100,0) size 300x100
+  RenderBlock (positioned) {DIV} at (100,0) size 300x100 [bgcolor=#008000]
diff --git a/LayoutTests/transitions/suspend-transform-transition.html b/LayoutTests/transitions/suspend-transform-transition.html
new file mode 100644 (file)
index 0000000..b862488
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css" media="screen">
+    #box {
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100px;
+        width: 100px;
+        background-color: red;
+        -webkit-transition: -webkit-transform 0.5s linear;
+        -webkit-transform: translateX(0) scale(1);
+    }
+    
+    #box.move {
+        -webkit-transform: translateX(400px) scale(1);
+    }
+
+    #safezone {
+        position: absolute;
+        left: 0;
+        top: 0;
+        height: 100px;
+        width: 300px;
+        left: 100px;
+        background-color: green;
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController)
+        layoutTestController.waitUntilDone();
+    
+    function suspendAndWaitForCompletion()
+    {
+        if (window.layoutTestController)
+            layoutTestController.suspendAnimations();
+
+        window.setTimeout(function() {
+            if (window.layoutTestController)
+                layoutTestController.notifyDone();
+        }, 250);
+    }
+    
+    function doTest()
+    {
+        document.getElementById('box').className = 'move';
+        window.setTimeout(function() {
+            // Wait for the box to animate into the safe zone (to test that it doesn't snap back to the start).
+            window.setTimeout(suspendAndWaitForCompletion, 250);
+        }, 0); // give the accelerated transition a chance to kick off.
+    }
+
+    window.addEventListener('load', doTest, false);
+  </script>
+</head>
+<body>
+
+<!-- When suspended, the red box should be hidden by the green box. You should see no red. -->
+<div id="box"></div>
+<div id="safezone"></div>
+
+<div id="result"></div>
+
+</body>
+</html>
index caa68af..cc14821 100644 (file)
@@ -1,3 +1,67 @@
+2010-09-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        Accelerated transitions do not suspend/resume properly.
+        https://bugs.webkit.org/show_bug.cgi?id=43792
+        
+        Fix suspending of accelerated transitions.
+        
+        GraphicsLayer changes unify the handling of transitions and animations
+        in GraphicsLayer. Both are now identified by name, so the code
+        now refers to "animationName" rather than "keyframesName". Transitions
+        use a dummy name which is not a valid keyframe identifier.
+
+        Tests: animations/suspend-transform-animation.html
+               transitions/suspend-transform-transition.html
+
+        * page/animation/ImplicitAnimation.h:
+        * page/animation/ImplicitAnimation.cpp:
+        (WebCore::ImplicitAnimation::pauseAnimation): Call down to the RenderLayerBacking
+        to tell it that an accelerated transition was paused.
+
+        * platform/graphics/GraphicsLayer.h:
+        * platform/graphics/GraphicsLayer.cpp:
+        (WebCore::GraphicsLayer::animationNameForTransition): Create a name
+        for the transition of the given property.
+        (WebCore::GraphicsLayer::addAnimation): Generalize "keyframe" to "animation" in the parameter names.
+        (WebCore::GraphicsLayer::pauseAnimation): ditto
+        (WebCore::GraphicsLayer::removeAnimation): ditto
+
+        * platform/graphics/mac/GraphicsLayerCA.h: Parameter renaming, and some method renames for clarity.
+        (WebCore::GraphicsLayerCA::animationIsRunning):
+        (WebCore::GraphicsLayerCA::LayerPropertyAnimation::LayerPropertyAnimation): struct rename for clarity.
+
+        * platform/graphics/mac/GraphicsLayerCA.mm:
+        (WebCore::animationIdentifier): the animationName already has the property baked in.
+        (WebCore::GraphicsLayerCA::moveOrCopyLayerAnimation): just deals with one animation now.
+        (WebCore::GraphicsLayerCA::moveOrCopyAnimationsForProperty): we have to trawl through
+        m_runningAnimations to get the identifiers for the animations that need to be copied.
+        (WebCore::GraphicsLayerCA::addAnimation): rename parameters.
+        (WebCore::GraphicsLayerCA::pauseAnimation): re-ordered methods here. member var renames.
+        (WebCore::GraphicsLayerCA::removeAnimation): ditto.
+        (WebCore::GraphicsLayerCA::updateLayerAnimations): no need to iterate over m_transitionPropertiesToRemove,
+        and no more divergence between transitions and animations.
+        (WebCore::GraphicsLayerCA::setCAAnimationOnLayer): renames for clarity.
+        (WebCore::GraphicsLayerCA::removeCAAnimationFromLayer): ditto
+        (WebCore::GraphicsLayerCA::pauseCAAnimationOnLayer): ditto
+        (WebCore::GraphicsLayerCA::createAnimationFromKeyframes): renames
+        (WebCore::GraphicsLayerCA::createTransformAnimationsFromKeyframes): renames
+        (WebCore::GraphicsLayerCA::suspendAnimations): whitespace.
+
+        * rendering/RenderLayerBacking.h: Group the transition and animation methods together.
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::animationPaused): Re-ordered methods for clarity.
+        (WebCore::RenderLayerBacking::animationFinished): ditto
+        (WebCore::RenderLayerBacking::startTransition): Use animationNameForTransition() to generate
+        the animation identifier.
+        (WebCore::RenderLayerBacking::transitionPaused): Call pauseAnimation, using animationNameForTransition()
+        to generate the animation identifier.
+        (WebCore::RenderLayerBacking::transitionFinished): Call removeAnimation, using animationNameForTransition()
+        to generate the animation identifier.
+        (WebCore::RenderLayerBacking::notifyAnimationStarted): Moved.
+        (WebCore::RenderLayerBacking::notifySyncRequired): Moved.
+
 2010-09-23  David Hyatt  <hyatt@apple.com>
 
         Reviewed by Sam Weinig.
index da0a810..34607f6 100644 (file)
@@ -120,6 +120,25 @@ bool ImplicitAnimation::startAnimation(double timeOffset)
     return false;
 }
 
+void ImplicitAnimation::pauseAnimation(double timeOffset)
+{
+    if (!m_object)
+        return;
+
+#if USE(ACCELERATED_COMPOSITING)
+    if (m_object->hasLayer()) {
+        RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+        if (layer->isComposited())
+            layer->backing()->transitionPaused(timeOffset, m_animatingProperty);
+    }
+#else
+    UNUSED_PARAM(timeOffset);
+#endif
+    // Restore the original (unanimated) style
+    if (!paused())
+        setNeedsStyleRecalc(m_object->node());
+}
+
 void ImplicitAnimation::endAnimation()
 {
 #if USE(ACCELERATED_COMPOSITING)
index be5c197..c40c00a 100644 (file)
@@ -48,7 +48,7 @@ public:
 
     virtual void onAnimationEnd(double elapsedTime);
     virtual bool startAnimation(double timeOffset);
-    virtual void pauseAnimation(double /*timeOffset*/) { }
+    virtual void pauseAnimation(double /*timeOffset*/);
     virtual void endAnimation();
 
     virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
index b0f529b..412f06d 100644 (file)
@@ -246,6 +246,12 @@ void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const I
         m_client->paintContents(this, context, m_paintingPhase, clip);
 }
 
+String GraphicsLayer::animationNameForTransition(AnimatedPropertyID property)
+{
+    // | is not a valid identifier character in CSS, so this can never conflict with a keyframe identifier.
+    return String::format("-|transition%c-", property);
+}
+
 void GraphicsLayer::suspendAnimations(double)
 {
 }
index 04899f2..ad4d056 100644 (file)
@@ -284,13 +284,16 @@ public:
     IntRect contentsRect() const { return m_contentsRect; }
     virtual void setContentsRect(const IntRect& r) { m_contentsRect = r; }
     
+    // Transitions are identified by a special animation name that cannot clash with a keyframe identifier.
+    static String animationNameForTransition(AnimatedPropertyID);
+    
     // 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 /*timeOffset*/) { return false; }
-    virtual void removeAnimationsForProperty(AnimatedPropertyID) { }
-    virtual void removeAnimationsForKeyframes(const String& /* keyframesName */) { }
-    virtual void pauseAnimation(const String& /* keyframesName */, double /*timeOffset*/) { }
-    
+    // These methods handle both transitions and keyframe animations.
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/)  { return false; }
+    virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { }
+    virtual void removeAnimation(const String& /*animationName*/) { }
+
     virtual void suspendAnimations(double time);
     virtual void resumeAnimations();
     
index 6ff3ff0..91d5de0 100644 (file)
@@ -96,11 +96,10 @@ public:
     virtual void suspendAnimations(double time);
     virtual void resumeAnimations();
 
-    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, double timeOffset);
-    
+    virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset);
+    virtual void pauseAnimation(const String& animationName, double timeOffset);
+    virtual void removeAnimation(const String& animationName);
+
     virtual void setContentsToImage(Image*);
     virtual void setContentsToMedia(PlatformLayer*);
     virtual void setContentsToCanvas(PlatformLayer*);
@@ -128,17 +127,17 @@ private:
     CALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
     CALayer* hostLayerForSublayers() const;
     CALayer* layerForSuperlayer() const;
-    CALayer* animatedLayer(AnimatedPropertyID property) const;
+    CALayer* animatedLayer(AnimatedPropertyID) const;
 
     typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree.
     static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
 
     typedef HashMap<CloneID, RetainPtr<CALayer> > LayerMap;
     LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); }
-    LayerMap* animatedLayerClones(AnimatedPropertyID property) const;
+    LayerMap* animatedLayerClones(AnimatedPropertyID) const;
 
-    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);
+    bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
+    bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
 
     // Return autoreleased animation (use RetainPtr?)
     CABasicAnimation* createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
@@ -153,9 +152,9 @@ private:
     bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, CABasicAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
     bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, CAKeyframeAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
     
-    bool animationIsRunning(const String& keyframesName) const
+    bool animationIsRunning(const String& animationName) const
     {
-        return m_runningKeyframeAnimations.find(keyframesName) != m_runningKeyframeAnimations.end();
+        return m_runningAnimations.find(animationName) != m_runningAnimations.end();
     }
 
     void commitLayerChangesBeforeSublayers();
@@ -271,13 +270,13 @@ private:
     void ensureStructuralLayer(StructuralLayerPurpose);
     StructuralLayerPurpose structuralLayerPurpose() const;
 
-    void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
-    bool removeAnimationFromLayer(AnimatedPropertyID, const String& keyframesName, int index);
-    void pauseAnimationOnLayer(AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
+    void setCAAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& animationName, int index, double timeOffset);
+    bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index);
+    void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, double timeOffset);
 
     enum MoveOrCopy { Move, Copy };
-    void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID property, CALayer * fromLayer, CALayer * toLayer);
-    static void moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer * fromLayer, CALayer * toLayer);
+    static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer);
+    void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID, CALayer * fromLayer, CALayer * toLayer);
     
     enum LayerChange {
         NoChange = 0,
@@ -335,29 +334,29 @@ private:
     RetainPtr<CGImageRef> m_uncorrectedContentsImage;
     RetainPtr<CGImageRef> m_pendingContentsImage;
     
-    struct LayerAnimation {
-        LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double timeOffset)
-        : m_animation(caAnim)
-        , m_keyframesName(keyframesName)
+    // This represents the animation of a single property. There may be multiple transform animations for
+    // a single transition or keyframe animation, so index is used to distinguish these.
+    struct LayerPropertyAnimation {
+        LayerPropertyAnimation(CAPropertyAnimation* caAnimation, const String& animationName, AnimatedPropertyID property, int index, double timeOffset)
+        : m_animation(caAnimation)
+        , m_name(animationName)
         , m_property(property)
         , m_index(index)
         , m_timeOffset(timeOffset)
         { }
 
         RetainPtr<CAPropertyAnimation*> m_animation;
-        String m_keyframesName;
+        String m_name;
         AnimatedPropertyID m_property;
         int m_index;
         double m_timeOffset;
     };
     
-    Vector<LayerAnimation> m_uncomittedAnimations;
-    
-    // Animations on the layer are identified by property + index.
-    typedef int AnimatedProperty;   // std containers choke on the AnimatedPropertyID enum
-    typedef pair<AnimatedProperty, int> AnimationPair;
+    // Uncommitted transitions and animations.
+    Vector<LayerPropertyAnimation> m_uncomittedAnimations;
 
-    HashSet<AnimatedProperty> m_transitionPropertiesToRemove;
+    typedef int AnimatedProperty; // std containers choke on the AnimatedPropertyID enum
+    typedef pair<AnimatedProperty, int> PropertyAnimationPair; // pair of property, index
     
     enum Action { Remove, Pause };
     struct AnimationProcessingAction {
@@ -367,15 +366,15 @@ private:
         {
         }
         Action action;
-        double timeOffset;      // only used for pause
+        double timeOffset; // only used for pause
     };
     typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
-    AnimationsToProcessMap m_keyframeAnimationsToProcess;
+    AnimationsToProcessMap m_animationsToProcess;
+
+    // Map of animation names to their associated lists of property animations, so we can remove/pause them.
+    typedef HashMap<String, Vector<PropertyAnimationPair> > AnimationsMap;
+    AnimationsMap m_runningAnimations;
 
-    // Map of keyframe names to their associated lists of animations for running animations, so we can remove/pause them.
-    typedef HashMap<String, Vector<AnimationPair> > KeyframeAnimationsMap;
-    KeyframeAnimationsMap m_runningKeyframeAnimations;
-    
     Vector<FloatRect> m_dirtyRects;
     
     LayerChangeFlags m_uncommittedChanges;
index 395a691..33f14e6 100644 (file)
@@ -197,7 +197,7 @@ static NSValue* getTransformFunctionValue(const TransformOperation* transformOp,
 }
 
 #if HAVE_MODERN_QUARTZCORE
-static NSStringgetValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
+static NSString *getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
 {
     // Use literal strings to avoid link-time dependency on those symbols.
     switch (transformType) {
@@ -247,17 +247,11 @@ static String propertyIdToString(AnimatedPropertyID property)
     return "";
 }
 
-static String animationIdentifier(AnimatedPropertyID property, const String& keyframesName, int index)
+static String animationIdentifier(const String& animationName, int index)
 {
     StringBuilder builder;
 
-    builder.append(propertyIdToString(property));
-    builder.append("_");
-
-    if (!keyframesName.isEmpty()) {
-        builder.append(keyframesName);
-        builder.append("_");
-    }
+    builder.append(animationName);
     builder.append("_");
     builder.append(String::number(index));
     return builder.toString();
@@ -550,39 +544,40 @@ void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
     noteLayerPropertyChanged(ChildrenTransformChanged);
 }
 
-void GraphicsLayerCA::moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer *fromLayer, CALayer *toLayer)
+void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer)
 {
-    for (int index = 0; ; ++index) {
-        String animName = animationIdentifier(property, keyframesName, index);
+    NSString *animationID = animationIdentifier;
+    CAAnimation *anim = [fromLayer animationForKey:animationID];
+    if (!anim)
+        return;
 
-        CAAnimation* anim = [fromLayer animationForKey:animName];
-        if (!anim)
+    switch (operation) {
+        case Move:
+            [anim retain];
+            [fromLayer removeAnimationForKey:animationID];
+            [toLayer addAnimation:anim forKey:animationID];
+            [anim release];
             break;
 
-        switch (operation) {
-            case Move:
-                [anim retain];
-                [fromLayer removeAnimationForKey:animName];
-                [toLayer addAnimation:anim forKey:animName];
-                [anim release];
-                break;
-
-            case Copy:
-                [toLayer addAnimation:anim forKey:animName];
-                break;
-        }
+        case Copy:
+            [toLayer addAnimation:anim forKey:animationID];
+            break;
     }
 }
 
 void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, CALayer *fromLayer, CALayer *toLayer)
 {
-    // Move transitions for this property.
-    moveOrCopyAllAnimationsForProperty(operation, property, "", fromLayer, toLayer);
-    
     // Look for running animations affecting this property.
-    KeyframeAnimationsMap::const_iterator end = m_runningKeyframeAnimations.end();
-    for (KeyframeAnimationsMap::const_iterator it = m_runningKeyframeAnimations.begin(); it != end; ++it)
-        moveOrCopyAllAnimationsForProperty(operation, property, it->first, fromLayer, toLayer);
+    AnimationsMap::const_iterator end = m_runningAnimations.end();
+    for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
+        const Vector<PropertyAnimationPair>& propertyAnimations = it->second;
+        size_t numAnimations = propertyAnimations.size();
+        for (size_t i = 0; i < numAnimations; ++i) {
+            const PropertyAnimationPair& currPair = propertyAnimations[i];
+            if (currPair.first == property)
+                moveOrCopyLayerAnimation(operation, animationIdentifier(it->first, currPair.second), fromLayer, toLayer);
+        }
+    }
 }
 
 void GraphicsLayerCA::setPreserves3D(bool preserves3D)
@@ -704,8 +699,10 @@ void GraphicsLayerCA::setContentsRect(const IntRect& rect)
     noteLayerPropertyChanged(ContentsRectChanged);
 }
 
-bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
+bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
 {
+    ASSERT(!animationName.isEmpty());
+
     if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
         return false;
 
@@ -723,9 +720,9 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
 
     bool createdAnimations = false;
     if (valueList.property() == AnimatedPropertyWebkitTransform)
-        createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, timeOffset, boxSize);
+        createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
     else
-        createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, timeOffset);
+        createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
 
     if (createdAnimations)
         noteLayerPropertyChanged(AnimationChanged);
@@ -733,41 +730,32 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
     return createdAnimations;
 }
 
-void GraphicsLayerCA::removeAnimationsForProperty(AnimatedPropertyID property)
-{
-    if (m_transitionPropertiesToRemove.find(property) != m_transitionPropertiesToRemove.end())
-        return;
-
-    m_transitionPropertiesToRemove.add(property);
-    noteLayerPropertyChanged(AnimationChanged);
-}
-
-void GraphicsLayerCA::removeAnimationsForKeyframes(const String& animationName)
+void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
 {
     if (!animationIsRunning(animationName))
         return;
 
-    m_keyframeAnimationsToProcess.add(animationName, AnimationProcessingAction(Remove));
-    noteLayerPropertyChanged(AnimationChanged);
-}
-
-void GraphicsLayerCA::pauseAnimation(const String& keyframesName, double timeOffset)
-{
-    if (!animationIsRunning(keyframesName))
-        return;
-
-    AnimationsToProcessMap::iterator it = m_keyframeAnimationsToProcess.find(keyframesName);
-    if (it != m_keyframeAnimationsToProcess.end()) {
+    AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
+    if (it != m_animationsToProcess.end()) {
         AnimationProcessingAction& processingInfo = it->second;
         // If an animation is scheduled to be removed, don't change the remove to a pause.
         if (processingInfo.action != Remove)
             processingInfo.action = Pause;
     } else
-        m_keyframeAnimationsToProcess.add(keyframesName, AnimationProcessingAction(Pause, timeOffset));
+        m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
 
     noteLayerPropertyChanged(AnimationChanged);
 }
 
+void GraphicsLayerCA::removeAnimation(const String& animationName)
+{
+    if (!animationIsRunning(animationName))
+        return;
+
+    m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
+    noteLayerPropertyChanged(AnimationChanged);
+}
+
 void GraphicsLayerCA::setContentsToImage(Image* image)
 {
     if (image) {
@@ -1496,68 +1484,49 @@ CALayer *GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
 
 void GraphicsLayerCA::updateLayerAnimations()
 {
-    if (m_transitionPropertiesToRemove.size()) {
-        HashSet<int>::const_iterator end = m_transitionPropertiesToRemove.end();
-        for (HashSet<AnimatedProperty>::const_iterator it = m_transitionPropertiesToRemove.begin(); it != end; ++it) {
-            AnimatedPropertyID currProperty = static_cast<AnimatedPropertyID>(*it);
-            // Remove all animations with this property in the key.
-            for (int index = 0; ; ++index) {
-                if (!removeAnimationFromLayer(currProperty, "", index))
-                    break;
-            }
-        }
-
-        m_transitionPropertiesToRemove.clear();
-    }
-
-    if (m_keyframeAnimationsToProcess.size()) {
-        AnimationsToProcessMap::const_iterator end = m_keyframeAnimationsToProcess.end();
-        for (AnimationsToProcessMap::const_iterator it = m_keyframeAnimationsToProcess.begin(); it != end; ++it) {
-            const String& currKeyframeName = it->first;
-            KeyframeAnimationsMap::iterator animationIt = m_runningKeyframeAnimations.find(currKeyframeName);
-            if (animationIt == m_runningKeyframeAnimations.end())
+    if (m_animationsToProcess.size()) {
+        AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
+        for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
+            const String& currAnimationName = it->first;
+            AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
+            if (animationIt == m_runningAnimations.end())
                 continue;
 
             const AnimationProcessingAction& processingInfo = it->second;
-            const Vector<AnimationPair>& animations = animationIt->second;
+            const Vector<PropertyAnimationPair>& animations = animationIt->second;
             for (size_t i = 0; i < animations.size(); ++i) {
-                const AnimationPair& currPair = animations[i];
+                const PropertyAnimationPair& currPair = animations[i];
                 switch (processingInfo.action) {
                     case Remove:
-                        removeAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second);
+                        removeCAAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currAnimationName, currPair.second);
                         break;
                     case Pause:
-                        pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second, processingInfo.timeOffset);
+                        pauseCAAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currAnimationName, currPair.second, processingInfo.timeOffset);
                         break;
                 }
             }
 
             if (processingInfo.action == Remove)
-                m_runningKeyframeAnimations.remove(currKeyframeName);
+                m_runningAnimations.remove(currAnimationName);
         }
     
-        m_keyframeAnimationsToProcess.clear();
+        m_animationsToProcess.clear();
     }
     
     size_t numAnimations;
     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_keyframesName, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
+            const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
+            setCAAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, 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,
-                // so we can remove the animations later if needed.
-                // For transitions, we can just generate animation names with property and index.
-                KeyframeAnimationsMap::iterator it = m_runningKeyframeAnimations.find(pendingAnimation.m_keyframesName);
-                if (it == m_runningKeyframeAnimations.end()) {
-                    Vector<AnimationPair> firstPair;
-                    firstPair.append(AnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
-                    m_runningKeyframeAnimations.add(pendingAnimation.m_keyframesName, firstPair);
-                } else {
-                    Vector<AnimationPair>& animPairs = it->second;
-                    animPairs.append(AnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
-                }
+            AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
+            if (it == m_runningAnimations.end()) {
+                Vector<PropertyAnimationPair> firstPair;
+                firstPair.append(PropertyAnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
+                m_runningAnimations.add(pendingAnimation.m_name, firstPair);
+            } else {
+                Vector<PropertyAnimationPair>& animPairs = it->second;
+                animPairs.append(PropertyAnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
             }
         }
         
@@ -1565,16 +1534,16 @@ void GraphicsLayerCA::updateLayerAnimations()
     }
 }
 
-void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
+void GraphicsLayerCA::setCAAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
 {
     PlatformLayer* layer = animatedLayer(property);
 
     [caAnim setTimeOffset:timeOffset];
     
-    String animationName = animationIdentifier(property, keyframesName, index);
+    String animationID = animationIdentifier(animationName, index);
     
-    [layer removeAnimationForKey:animationName];
-    [layer addAnimation:caAnim forKey:animationName];
+    [layer removeAnimationForKey:animationID];
+    [layer addAnimation:caAnim forKey:animationID];
 
     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
         LayerMap::const_iterator end = layerCloneMap->end();
@@ -1583,8 +1552,8 @@ void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedP
             if (m_replicaLayer && isReplicatedRootClone(it->first))
                 continue;
             CALayer *currLayer = it->second.get();
-            [currLayer removeAnimationForKey:animationName];
-            [currLayer addAnimation:caAnim forKey:animationName];
+            [currLayer removeAnimationForKey:animationID];
+            [currLayer addAnimation:caAnim forKey:animationID];
         }
     }
 }
@@ -1604,16 +1573,16 @@ static void bug7311367Workaround(CALayer* transformLayer, const TransformationMa
     [transformLayer setTransform:caTransform];
 }
 
-bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, const String& keyframesName, int index)
+bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
 {
     PlatformLayer* layer = animatedLayer(property);
 
-    String animationName = animationIdentifier(property, keyframesName, index);
+    String animationID = animationIdentifier(animationName, index);
 
-    if (![layer animationForKey:animationName])
+    if (![layer animationForKey:animationID])
         return false;
     
-    [layer removeAnimationForKey:animationName];
+    [layer removeAnimationForKey:animationID];
     bug7311367Workaround(m_structuralLayer.get(), m_transform);
 
     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
@@ -1624,7 +1593,7 @@ bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, cons
                 continue;
 
             CALayer *currLayer = it->second.get();
-            [currLayer removeAnimationForKey:animationName];
+            [currLayer removeAnimationForKey:animationID];
         }
     }
     return true;
@@ -1646,13 +1615,13 @@ static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimati
 #endif
 }
 
-void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
+void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
 {
     PlatformLayer* layer = animatedLayer(property);
 
-    String animationName = animationIdentifier(property, keyframesName, index);
+    String animationID = animationIdentifier(animationName, index);
 
-    CAAnimation* caAnim = [layer animationForKey:animationName];
+    CAAnimation *caAnim = [layer animationForKey:animationID];
     if (!caAnim)
         return;
 
@@ -1679,7 +1648,7 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const S
     [pausedAnim setSpeed:0];
     [pausedAnim setTimeOffset:timeOffset];
     
-    [layer addAnimation:pausedAnim forKey:animationName];  // This will replace the running animation.
+    [layer addAnimation:pausedAnim forKey:animationID];  // This will replace the running animation.
 
     // Pause the animations on the clones too.
     if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
@@ -1689,7 +1658,7 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const S
             if (m_replicaLayer && isReplicatedRootClone(it->first))
                 continue;
             CALayer *currLayer = it->second.get();
-            [currLayer addAnimation:pausedAnim forKey:animationName];
+            [currLayer addAnimation:pausedAnim forKey:animationID];
         }
     }
 }
@@ -1726,7 +1695,7 @@ void GraphicsLayerCA::updateContentsNeedsDisplay()
         [m_contentsLayer.get() setNeedsDisplay];
 }
 
-bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset)
+bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
 {
     ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
 
@@ -1752,14 +1721,14 @@ bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valu
     if (!valuesOK)
         return false;
 
-    m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
+    m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
     
     END_BLOCK_OBJC_EXCEPTIONS;
 
     return true;
 }
 
-bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset, const IntSize& boxSize)
+bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
 {
     ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
 
@@ -1810,7 +1779,7 @@ bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValue
         if (!validMatrices)
             break;
     
-        m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
+        m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
     }
 
     END_BLOCK_OBJC_EXCEPTIONS;
@@ -1844,7 +1813,7 @@ void GraphicsLayerCA::setupAnimation(CAPropertyAnimation* propertyAnim, const An
     else if (anim->direction() == Animation::AnimationDirectionAlternate)
         repeatCount /= 2;
 
-    NSStringfillMode = 0;
+    NSString *fillMode = 0;
     switch (anim->fillMode()) {
     case AnimationFillModeNone:
         fillMode = kCAFillModeForwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
@@ -1983,7 +1952,7 @@ bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& va
     [basicAnim setToValue:toValue];
 
 #if HAVE_MODERN_QUARTZCORE
-    if (NSStringvalueFunctionName = getValueFunctionNameForTransformOperation(transformOp))
+    if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOp))
         [basicAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
 #endif
 
@@ -2028,7 +1997,7 @@ bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& va
     [keyframeAnim setTimingFunctions:timingFunctions.get()];
 
 #if HAVE_MODERN_QUARTZCORE
-    if (NSStringvalueFunctionName = getValueFunctionNameForTransformOperation(transformOpType))
+    if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOpType))
         [keyframeAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
 #endif
     return true;
@@ -2045,7 +2014,7 @@ void GraphicsLayerCA::suspendAnimations(double time)
         LayerMap::const_iterator end = layerCloneMap->end();
         for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
             CALayer *currLayer = it->second.get();
-            [currLayer setSpeed:0 ];
+            [currLayer setSpeed:0];
             [currLayer setTimeOffset:t];
         }
     }
index 15a5b2f..f9e2367 100644 (file)
@@ -1160,6 +1160,16 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
     return runningAcceleratedAnimation;
 }
 
+void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
+{
+    m_graphicsLayer->pauseAnimation(animationName, timeOffset);
+}
+
+void RenderLayerBacking::animationFinished(const String& animationName)
+{
+    m_graphicsLayer->removeAnimation(animationName);
+}
+
 bool RenderLayerBacking::startTransition(double timeOffset, int property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
 {
     bool didAnimate = false;
@@ -1172,7 +1182,7 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
             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(), timeOffset)) {
+            if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
                 // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
                 updateLayerOpacity(toStyle);
                 didAnimate = true;
@@ -1186,7 +1196,7 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
             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(), timeOffset)) {
+            if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
                 // To ensure that the correct transform is visible when the animation ends, also set the final opacity.
                 updateLayerTransform(toStyle);
                 didAnimate = true;
@@ -1200,34 +1210,32 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
     return didAnimate;
 }
 
-void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
-{
-    renderer()->animation()->notifyAnimationStarted(renderer(), time);
-}
-
-void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*)
+void RenderLayerBacking::transitionPaused(double timeOffset, int property)
 {
-    if (!renderer()->documentBeingDestroyed())
-        compositor()->scheduleSync();
+    AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
+    if (animatedProperty != AnimatedPropertyInvalid)
+        m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransition(animatedProperty), timeOffset);
 }
 
-void RenderLayerBacking::animationFinished(const String& animationName)
+void RenderLayerBacking::transitionFinished(int property)
 {
-    m_graphicsLayer->removeAnimationsForKeyframes(animationName);
+    AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
+    if (animatedProperty != AnimatedPropertyInvalid)
+        m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransition(animatedProperty));
 }
 
-void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
+void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double time)
 {
-    m_graphicsLayer->pauseAnimation(animationName, timeOffset);
+    renderer()->animation()->notifyAnimationStarted(renderer(), time);
 }
 
-void RenderLayerBacking::transitionFinished(int property)
+void RenderLayerBacking::notifySyncRequired(const GraphicsLayer*)
 {
-    AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
-    if (animatedProperty != AnimatedPropertyInvalid)
-        m_graphicsLayer->removeAnimationsForProperty(animatedProperty);
+    if (!renderer()->documentBeingDestroyed())
+        compositor()->scheduleSync();
 }
 
+// This is used for the 'freeze' API, for testing only.
 void RenderLayerBacking::suspendAnimations(double time)
 {
     m_graphicsLayer->suspendAnimations(time);
index 808000b..fb3ab67 100644 (file)
@@ -105,12 +105,14 @@ public:
     void rendererContentChanged();
 
     // Interface to start, finish, suspend and resume animations and transitions
-    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(double timeOffset, const String& name);
+    void transitionPaused(double timeOffset, int property);
     void transitionFinished(int property);
 
+    bool startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes);
+    void animationPaused(double timeOffset, const String& name);
+    void animationFinished(const String& name);
+
     void suspendAnimations(double time = 0);
     void resumeAnimations();