Title: [105925] trunk/Source/WebCore
Revision
105925
Author
[email protected]
Date
2012-01-25 14:13:29 -0800 (Wed, 25 Jan 2012)

Log Message

[Texmap] Divide TextureMapperNode.cpp to 3 files.
https://bugs.webkit.org/show_bug.cgi?id=76660

 Reviewed by Kenneth Rohde Christiansen.

 Split the animation part of TextureMapperNode out to a separate file, called
 TextureMapperAnimation.
 Provide a clean interface for that class, that allows separating the internals of the scene
 painting from the internals of the animation interpolation.

 No new tests. Existing animation tests cover this.

 * GNUmakefile.list.am:

* Target.pri:
* WebCore.gypi:
* platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
(WebCore::GraphicsLayerTextureMapper::addAnimation):
(WebCore::GraphicsLayerTextureMapper::pauseAnimation):
(WebCore::GraphicsLayerTextureMapper::removeAnimation):
* platform/graphics/texmap/GraphicsLayerTextureMapper.h:
(GraphicsLayerTextureMapper):
* platform/graphics/texmap/TextureMapperNode.cpp:
(WebCore::TextureMapperNode::syncCompositingStateSelf):
(WebCore::TextureMapperNode::descendantsOrSelfHaveRunningAnimations):
(WebCore::TextureMapperNode::syncAnimations):
(WebCore::TextureMapperNode::syncAnimationsRecursively):
(WebCore::TextureMapperNode::syncCompositingState):
* platform/graphics/texmap/TextureMapperNode.h:
(TextureMapperNode):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (105924 => 105925)


--- trunk/Source/WebCore/ChangeLog	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/ChangeLog	2012-01-25 22:13:29 UTC (rev 105925)
@@ -1,3 +1,35 @@
+2012-01-25  No'am Rosenthal  <[email protected]>
+
+        [Texmap] Divide TextureMapperNode.cpp to 3 files.
+        https://bugs.webkit.org/show_bug.cgi?id=76660
+
+         Reviewed by Kenneth Rohde Christiansen.
+
+         Split the animation part of TextureMapperNode out to a separate file, called
+         TextureMapperAnimation.
+         Provide a clean interface for that class, that allows separating the internals of the scene
+         painting from the internals of the animation interpolation.
+
+         No new tests. Existing animation tests cover this.
+
+         * GNUmakefile.list.am:
+        * Target.pri:
+        * WebCore.gypi:
+        * platform/graphics/texmap/GraphicsLayerTextureMapper.cpp:
+        (WebCore::GraphicsLayerTextureMapper::addAnimation):
+        (WebCore::GraphicsLayerTextureMapper::pauseAnimation):
+        (WebCore::GraphicsLayerTextureMapper::removeAnimation):
+        * platform/graphics/texmap/GraphicsLayerTextureMapper.h:
+        (GraphicsLayerTextureMapper):
+        * platform/graphics/texmap/TextureMapperNode.cpp:
+        (WebCore::TextureMapperNode::syncCompositingStateSelf):
+        (WebCore::TextureMapperNode::descendantsOrSelfHaveRunningAnimations):
+        (WebCore::TextureMapperNode::syncAnimations):
+        (WebCore::TextureMapperNode::syncAnimationsRecursively):
+        (WebCore::TextureMapperNode::syncCompositingState):
+        * platform/graphics/texmap/TextureMapperNode.h:
+        (TextureMapperNode):
+
 2012-01-25  Hajime Morita  <[email protected]>
 
         ENABLE_SHADOW_DOM should be available via build-webkit --shadow-dom

Modified: trunk/Source/WebCore/GNUmakefile.list.am (105924 => 105925)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-01-25 22:13:29 UTC (rev 105925)
@@ -5726,6 +5726,8 @@
 	Source/WebCore/platform/graphics/texmap/LayerTransform.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapper.cpp \
 	Source/WebCore/platform/graphics/texmap/TextureMapper.h \
+	Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp \
+	Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp \
 	Source/WebCore/platform/graphics/texmap/TextureMapperNode.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
@@ -5744,6 +5746,8 @@
 	Source/WebCore/platform/graphics/texmap/LayerTransform.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapper.cpp \
 	Source/WebCore/platform/graphics/texmap/TextureMapper.h \
+	Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp \
+	Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp \
 	Source/WebCore/platform/graphics/texmap/TextureMapperNode.h \
 	Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h

Modified: trunk/Source/WebCore/Target.pri (105924 => 105925)


--- trunk/Source/WebCore/Target.pri	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/Target.pri	2012-01-25 22:13:29 UTC (rev 105925)
@@ -3933,6 +3933,7 @@
         platform/graphics/texmap/GraphicsLayerTextureMapper.h \
         platform/graphics/texmap/LayerTransform.h \
         platform/graphics/texmap/TextureMapper.h \
+        platform/graphics/texmap/TextureMapperAnimation.h \
         platform/graphics/texmap/TextureMapperNode.h \
         platform/graphics/texmap/TextureMapperPlatformLayer.h
 
@@ -3940,6 +3941,7 @@
         platform/graphics/qt/TextureMapperQt.cpp \
         platform/graphics/texmap/LayerTransform.cpp \
         platform/graphics/texmap/TextureMapper.cpp \
+        platform/graphics/texmap/TextureMapperAnimation.cpp \
         platform/graphics/texmap/TextureMapperNode.cpp \
         platform/graphics/texmap/GraphicsLayerTextureMapper.cpp
 

Modified: trunk/Source/WebCore/WebCore.gypi (105924 => 105925)


--- trunk/Source/WebCore/WebCore.gypi	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/WebCore.gypi	2012-01-25 22:13:29 UTC (rev 105925)
@@ -3573,6 +3573,8 @@
             'platform/graphics/texmap/LayerTransform.h',
             'platform/graphics/texmap/TextureMapper.cpp',
             'platform/graphics/texmap/TextureMapper.h',
+            'platform/graphics/texmap/TextureMapperAnimation.cpp',
+            'platform/graphics/texmap/TextureMapperAnimation.h',
             'platform/graphics/texmap/TextureMapperNode.cpp',
             'platform/graphics/texmap/TextureMapperNode.h',
             'platform/graphics/texmap/TextureMapperPlatformLayer.h',

Modified: trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp (105924 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp	2012-01-25 22:13:29 UTC (rev 105925)
@@ -365,59 +365,27 @@
     if (!anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2 || (valueList.property() != AnimatedPropertyWebkitTransform && valueList.property() != AnimatedPropertyOpacity))
         return false;
 
-    for (size_t i = 0; i < m_animations.size(); ++i) {
-        // The same animation name can be used for two animations with different properties.
-        if (m_animations[i]->name != keyframesName || m_animations[i]->keyframes.property() != valueList.property())
-            continue;
+    bool listsMatch;
+    bool hasBigRotation;
+    Vector<TransformOperation::OperationType> functionList;
 
-        // We already have a copy of this animation, that means that we're resuming it rather than adding it.
-        RefPtr<TextureMapperAnimation>& animation = m_animations[i];
-        animation->animation = Animation::create(anim);
-        animation->paused = false;
-        animation->startTime = WTF::currentTime() - timeOffset;
-        notifyChange(TextureMapperNode::AnimationChange);
-        m_animationStartedTimer.startOneShot(0);
-        return true;
-    }
+    if (valueList.property() == AnimatedPropertyWebkitTransform)
+        fetchTransformOperationList(valueList, functionList, listsMatch, hasBigRotation);
 
-    RefPtr<TextureMapperAnimation> animation = TextureMapperAnimation::create(valueList);
-    animation->boxSize = boxSize;
-    animation->name = keyframesName;
-    animation->animation = Animation::create(anim);
-    animation->paused = false;
-    animation->startTime = WTF::currentTime() - timeOffset;
-
-    if (valueList.property() == AnimatedPropertyWebkitTransform) {
-        bool hasBigRotation; // Not used, but required as a pointer parameter for the function.
-        fetchTransformOperationList(valueList, animation->functionList, animation->listsMatch, hasBigRotation);
-    }
-
-    m_animations.append(animation);
+    m_animations.add(keyframesName, TextureMapperAnimation(valueList, boxSize, anim, timeOffset, functionList, listsMatch));
     notifyChange(TextureMapperNode::AnimationChange);
     m_animationStartedTimer.startOneShot(0);
-
     return true;
 }
 
 void GraphicsLayerTextureMapper::pauseAnimation(const String& animationName, double timeOffset)
 {
-    for (size_t i = 0; i < m_animations.size(); ++i) {
-        if (m_animations[i]->name != animationName)
-            continue;
-        m_animations[i]->paused = true;
-        notifyChange(TextureMapperNode::AnimationChange);
-    }
+    m_animations.pause(animationName, timeOffset);
 }
 
 void GraphicsLayerTextureMapper::removeAnimation(const String& animationName)
 {
-    for (int i = m_animations.size() - 1; i >= 0; --i) {
-        // The same animation name can be used for two animations with different properties. We should remove both.
-        if (m_animations[i]->name != animationName)
-            continue;
-        m_animations.remove(i);
-        notifyChange(TextureMapperNode::AnimationChange);
-    }
+    m_animations.remove(animationName);
 }
 
 void GraphicsLayerTextureMapper::animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*)

Modified: trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h (105924 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.h	2012-01-25 22:13:29 UTC (rev 105925)
@@ -95,7 +95,7 @@
     bool m_syncQueued;
     int m_changeMask;
     TextureMapperNode::ContentData m_pendingContent;
-    Vector<RefPtr<TextureMapperAnimation> > m_animations;
+    TextureMapperAnimations m_animations;
     void animationStartedTimerFired(Timer<GraphicsLayerTextureMapper>*);
     Timer<GraphicsLayerTextureMapper> m_animationStartedTimer;
 };

Added: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp (0 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.cpp	2012-01-25 22:13:29 UTC (rev 105925)
@@ -0,0 +1,256 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "TextureMapperAnimation.h"
+
+#include "CurrentTime.h"
+#include "UnitBezier.h"
+
+#if USE(TEXTURE_MAPPER)
+namespace WebCore {
+
+static double normalizedAnimationValue(double runningTime, double duration, bool alternate)
+{
+    if (!duration)
+        return 0;
+
+    const int loopCount = runningTime / duration;
+    const double lastFullLoop = duration * double(loopCount);
+    const double remainder = runningTime - lastFullLoop;
+    const double normalized = remainder / duration;
+    return (loopCount % 2 && alternate) ? (1 - normalized) : normalized;
+}
+
+static float applyOpacityAnimation(float fromOpacity, float toOpacity, double progress)
+{
+    // Optimization: special case the edge values (0 and 1).
+    if (progress == 1.0)
+        return toOpacity;
+
+    if (!progress)
+        return fromOpacity;
+
+    return fromOpacity + progress * (toOpacity - fromOpacity);
+}
+
+static inline double solveEpsilon(double duration)
+{
+    return 1.0 / (200.0 * duration);
+}
+
+static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration)
+{
+    return UnitBezier(p1x, p1y, p2x, p2y).solve(t, solveEpsilon(duration));
+}
+
+static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t)
+{
+    if (stepAtStart)
+        return std::min(1.0, (floor(numSteps * t) + 1) / numSteps);
+    return floor(numSteps * t) / numSteps;
+}
+
+static inline float applyTimingFunction(const TimingFunction* timingFunction, float progress, double duration)
+{
+    if (!timingFunction)
+        return progress;
+
+    if (timingFunction->isCubicBezierTimingFunction()) {
+        const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
+        return solveCubicBezierFunction(ctf->x1(), ctf->y1(), ctf->x2(), ctf->y2(), progress, duration);
+    }
+
+    if (timingFunction->isStepsTimingFunction()) {
+        const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(timingFunction);
+        return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), double(progress));
+    }
+
+    return progress;
+}
+
+static TransformationMatrix applyTransformAnimation(const TransformOperations* from, const TransformOperations* to, double progress, const IntSize& boxSize, const Vector<TransformOperation::OperationType> functionList, bool listsMatch)
+{
+    TransformationMatrix matrix;
+
+    // First frame of an animation.
+    if (!progress) {
+        from->apply(boxSize, matrix);
+        return matrix;
+    }
+
+    // Last frame of an animation.
+    if (progress == 1) {
+        to->apply(boxSize, matrix);
+        return matrix;
+    }
+
+    // If we have incompatible operation lists, we blend the resulting matrices.
+    if (!listsMatch) {
+        TransformationMatrix fromMatrix;
+        to->apply(boxSize, matrix);
+        from->apply(boxSize, fromMatrix);
+        matrix.blend(fromMatrix, progress);
+        return matrix;
+    }
+
+    // Animation to "-webkit-transform: none".
+    if (!to->size()) {
+        TransformOperations blended(*to);
+        for (size_t i = 0; i < blended.operations().size(); ++i)
+            blended.operations()[i]->blend(0, progress, true)->apply(matrix, boxSize);
+        return matrix;
+    }
+
+    // Animation from "-webkit-transform: none".
+    if (!from->size()) {
+        TransformOperations blended(*from);
+        for (size_t i = 0; i < blended.operations().size(); ++i)
+            blended.operations()[i]->blend(0, 1. - progress, true)->apply(matrix, boxSize);
+        return matrix;
+    }
+
+    // Normal animation with a matching operation list.
+    TransformOperations blended(*to);
+    for (size_t i = 0; i < blended.operations().size(); ++i)
+        blended.operations()[i]->blend(from->at(i), progress, !from->at(i))->apply(matrix, boxSize);
+    return matrix;
+}
+
+
+TextureMapperAnimation::TextureMapperAnimation(const KeyframeValueList& keyframes, const IntSize& boxSize, const Animation* animation, double timeOffset, const Vector<TransformOperation::OperationType>& functionList, bool listsMatch)
+    : m_keyframes(keyframes)
+    , m_boxSize(boxSize)
+    , m_animation(Animation::create(animation))
+    , m_functionList(functionList)
+    , m_listsMatch(listsMatch)
+    , m_startTime(WTF::currentTime() - timeOffset)
+    , m_pauseTime(0)
+    , m_state(PlayingState)
+{
+}
+
+void TextureMapperAnimation::applyInternal(TextureMapperAnimationClient* client, const AnimationValue* from, const AnimationValue* to, float progress)
+{
+    switch (m_keyframes.property()) {
+    case AnimatedPropertyOpacity:
+        client->setOpacity(applyOpacityAnimation((static_cast<const FloatAnimationValue*>(from)->value()), (static_cast<const FloatAnimationValue*>(to)->value()), progress));
+        return;
+    case AnimatedPropertyWebkitTransform:
+        client->setTransform(applyTransformAnimation(static_cast<const TransformAnimationValue*>(from)->value(), static_cast<const TransformAnimationValue*>(to)->value(), progress, m_boxSize, m_functionList, m_listsMatch));
+        return;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+
+bool TextureMapperAnimation::isActive() const
+{
+    if (state() != StoppedState)
+        return true;
+
+    return m_animation->fillsForwards();
+}
+
+bool TextureMapperAnimations::hasActiveAnimationsOfType(AnimatedPropertyID type) const
+{
+    HashMap<String, TextureMapperAnimation>::const_iterator end = m_animations.end();
+    for (HashMap<String, TextureMapperAnimation>::const_iterator it = m_animations.begin(); it != end; ++it) {
+        const TextureMapperAnimation& animation = it->second;
+        if (animation.isActive() && animation.property() == type)
+            return true;
+    }
+    return false;
+}
+
+bool TextureMapperAnimations::hasRunningAnimations() const
+{
+    HashMap<String, TextureMapperAnimation>::const_iterator end = m_animations.end();
+    for (HashMap<String, TextureMapperAnimation>::const_iterator it = m_animations.begin(); it != end; ++it) {
+        const TextureMapperAnimation& animation = it->second;
+        if (animation.state() == TextureMapperAnimation::PlayingState)
+            return true;
+    }
+
+    return false;
+}
+
+void TextureMapperAnimation::apply(TextureMapperAnimationClient* client)
+{
+    if (state() == StoppedState)
+        return;
+
+    double totalRunningTime = m_state == PausedState ? m_pauseTime : WTF::currentTime() - m_startTime;
+    double normalizedValue = normalizedAnimationValue(totalRunningTime, m_animation->duration(), m_animation->direction());
+
+    if (m_animation->iterationCount() != Animation::IterationCountInfinite && totalRunningTime >= m_animation->duration() * m_animation->iterationCount())
+        setState(StoppedState);
+
+    if (!normalizedValue) {
+        applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), 0);
+        return;
+    }
+
+    if (normalizedValue == 1.0) {
+        applyInternal(client, m_keyframes.at(m_keyframes.size() - 2), m_keyframes.at(m_keyframes.size() - 1), 1);
+        return;
+    }
+    if (m_keyframes.size() == 2) {
+        normalizedValue = applyTimingFunction(m_animation->timingFunction().get(), normalizedValue, m_animation->duration());
+        applyInternal(client, m_keyframes.at(0), m_keyframes.at(1), normalizedValue);
+        return;
+    }
+
+    for (size_t i = 0; i < m_keyframes.size() - 1; ++i) {
+        const AnimationValue* from = m_keyframes.at(i);
+        const AnimationValue* to = m_keyframes.at(i + 1);
+        if (from->keyTime() > normalizedValue || to->keyTime() < normalizedValue)
+            continue;
+
+        normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime());
+        normalizedValue = applyTimingFunction(from->timingFunction(), normalizedValue, m_animation->duration());
+        applyInternal(client, from, to, normalizedValue);
+        break;
+    }
+}
+
+void TextureMapperAnimation::pause(double offset)
+{
+    // FIXME: should apply offset here.
+    setState(PausedState);
+    m_pauseTime = WTF::currentTime() - offset;
+}
+
+void TextureMapperAnimations::pause(const String& name, double offset)
+{
+    HashMap<String, TextureMapperAnimation>::iterator it = m_animations.find(name);
+    if (it == m_animations.end())
+        return;
+    it->second.pause(offset);
+}
+
+void TextureMapperAnimations::apply(TextureMapperAnimationClient* client)
+{
+    HashMap<String, TextureMapperAnimation>::iterator end = m_animations.end();
+    for (HashMap<String, TextureMapperAnimation>::iterator it = m_animations.begin(); it != end; ++it)
+        it->second.apply(client);
+}
+
+}
+#endif

Added: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h (0 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperAnimation.h	2012-01-25 22:13:29 UTC (rev 105925)
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TextureMapperAnimation_h
+#define TextureMapperAnimation_h
+
+#include "GraphicsLayer.h"
+#include "HashMap.h"
+#include "TransformationMatrix.h"
+#include <wtf/text/StringHash.h>
+
+#if USE(TEXTURE_MAPPER)
+namespace WebCore {
+
+class TextureMapperAnimationClient {
+public:
+    virtual void setTransform(const TransformationMatrix&) = 0;
+    virtual void setOpacity(float) = 0;
+};
+
+class TextureMapperAnimation {
+public:
+    enum AnimationState { PlayingState, PausedState, StoppedState };
+
+    TextureMapperAnimation()
+        : m_keyframes(AnimatedPropertyInvalid)
+    { }
+    TextureMapperAnimation(const KeyframeValueList&, const IntSize&, const Animation*, double, const Vector<TransformOperation::OperationType>&, bool);
+    void apply(TextureMapperAnimationClient*);
+    void pause(double);
+    AnimationState state() const { return m_state; }
+    void setState(AnimationState s) { m_state = s; }
+    AnimatedPropertyID property() const { return m_keyframes.property(); }
+    bool isActive() const;
+
+private:
+    void applyInternal(TextureMapperAnimationClient*, const AnimationValue* from, const AnimationValue* to, float progress);
+    KeyframeValueList m_keyframes;
+    IntSize m_boxSize;
+    RefPtr<Animation> m_animation;
+    String m_name;
+    Vector<TransformOperation::OperationType> m_functionList;
+    bool m_listsMatch;
+    bool m_hasBigRotation;
+    double m_startTime;
+    double m_pauseTime;
+    AnimationState m_state;
+};
+
+class TextureMapperAnimations {
+public:
+    TextureMapperAnimations() { }
+
+    void add(const String& name, const TextureMapperAnimation& animation) { m_animations.add(name, animation); }
+    void remove(const String& name) { m_animations.remove(name); }
+    void pause(const String&, double);
+    void apply(TextureMapperAnimationClient*);
+    bool isEmpty() const { return m_animations.isEmpty(); }
+
+    bool hasRunningAnimations() const;
+    bool hasActiveAnimationsOfType(AnimatedPropertyID type) const;
+
+private:
+    HashMap<String, TextureMapperAnimation> m_animations;
+};
+
+}
+#endif // USE(TEXTURE_MAPPER)
+
+#endif // TextureMapperAnimation_h

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp (105924 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.cpp	2012-01-25 22:13:29 UTC (rev 105925)
@@ -585,11 +585,8 @@
            layer->m_effectTarget = this;
     }
 
-    if (changeMask & AnimationChange) {
-        m_animations.clear();
-        for (size_t i = 0; i < graphicsLayer->m_animations.size(); ++i)
-            m_animations.append(graphicsLayer->m_animations[i]);
-    }
+    if (changeMask & AnimationChange)
+        m_animations = graphicsLayer->m_animations;
 
     m_state.maskLayer = toTextureMapperNode(graphicsLayer->maskLayer());
     m_state.replicaLayer = toTextureMapperNode(graphicsLayer->replicaLayer());
@@ -614,11 +611,6 @@
     if (!m_currentContent.needsDisplay)
         m_currentContent.needsDisplayRect.unite(pendingContent.needsDisplayRect);
 
-    if (!hasOpacityAnimation())
-        m_opacity = m_state.opacity;
-    if (!hasTransformAnimation())
-        m_transform.setLocalTransform(m_state.transform);
-
     m_transform.setPosition(m_state.pos);
     m_transform.setAnchorPoint(m_state.anchorPoint);
     m_transform.setSize(m_state.size);
@@ -628,10 +620,8 @@
 
 bool TextureMapperNode::descendantsOrSelfHaveRunningAnimations() const
 {
-    for (size_t i = 0; i < m_animations.size(); ++i) {
-        if (!m_animations[i]->paused)
-            return true;
-    }
+    if (m_animations.hasRunningAnimations())
+        return true;
 
     for (size_t i = 0; i < m_children.size(); ++i) {
         if (m_children[i]->descendantsOrSelfHaveRunningAnimations())
@@ -641,197 +631,18 @@
     return false;
 }
 
-static double normalizedAnimationValue(double runningTime, double duration, bool alternate)
+void TextureMapperNode::syncAnimations()
 {
-    if (!duration)
-        return 0;
-    const int loopCount = runningTime / duration;
-    const double lastFullLoop = duration * double(loopCount);
-    const double remainder = runningTime - lastFullLoop;
-    const double normalized = remainder / duration;
-    return (loopCount % 2 && alternate) ? (1 - normalized) : normalized;
+    m_animations.apply(this);
+    if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyWebkitTransform))
+        setTransform(m_state.transform);
+    if (!m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity))
+        setOpacity(m_state.opacity);
 }
 
-void TextureMapperNode::applyOpacityAnimation(float fromOpacity, float toOpacity, double progress)
-{
-    // Optimization: special case the edge values (0 and 1).
-    if (progress == 1.0)
-        setOpacity(toOpacity);
-    else if (!progress)
-        setOpacity(fromOpacity);
-    else
-        setOpacity(fromOpacity + progress * (toOpacity - fromOpacity));
-}
-
-static inline double solveEpsilon(double duration)
-{
-    return 1.0 / (200.0 * duration);
-}
-
-static inline double solveCubicBezierFunction(double p1x, double p1y, double p2x, double p2y, double t, double duration)
-{
-    UnitBezier bezier(p1x, p1y, p2x, p2y);
-    return bezier.solve(t, solveEpsilon(duration));
-}
-
-static inline double solveStepsFunction(int numSteps, bool stepAtStart, double t)
-{
-    if (stepAtStart)
-        return std::min(1.0, (floor(numSteps * t) + 1) / numSteps);
-    return floor(numSteps * t) / numSteps;
-}
-
-static inline float applyTimingFunction(const TimingFunction* timingFunction, float progress, double duration)
-{
-    if (!timingFunction)
-        return progress;
-
-    if (timingFunction->isCubicBezierTimingFunction()) {
-        const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
-        return solveCubicBezierFunction(ctf->x1(),
-                                        ctf->y1(),
-                                        ctf->x2(),
-                                        ctf->y2(),
-                                        progress, duration);
-    }
-
-    if (timingFunction->isStepsTimingFunction()) {
-        const StepsTimingFunction* stf = static_cast<const StepsTimingFunction*>(timingFunction);
-        return solveStepsFunction(stf->numberOfSteps(), stf->stepAtStart(), double(progress));
-    }
-
-    return progress;
-}
-
-void TextureMapperNode::applyTransformAnimation(const TextureMapperAnimation& animation, const TransformOperations* from, const TransformOperations* to, double progress)
-{
-    // Optimization: special case the edge values (0 and 1).
-    if (progress == 1.0 || !progress) {
-        TransformationMatrix matrix;
-        const TransformOperations* ops = progress ? to : from;
-        ops->apply(animation.boxSize, matrix);
-        setTransform(matrix);
-    }
-
-    if (!animation.listsMatch) {
-        TransformationMatrix toMatrix, fromMatrix;
-        to->apply(animation.boxSize, toMatrix);
-        from->apply(animation.boxSize, fromMatrix);
-        toMatrix.blend(fromMatrix, progress);
-        setTransform(toMatrix);
-        return;
-    }
-
-    TransformationMatrix matrix;
-
-    if (!to->size()) {
-        const TransformOperations* swap = to;
-        to = from;
-        from = swap;
-    } else if (!from->size())
-        progress = 1.0 - progress;
-
-    TransformOperations blended(*to);
-    for (size_t i = 0; i < animation.functionList.size(); ++i)
-        blended.operations()[i]->blend(from->at(i), progress, !from->at(i))->apply(matrix, animation.boxSize);
-
-    setTransform(matrix);
-}
-
-void TextureMapperNode::applyAnimationFrame(const TextureMapperAnimation& animation, const AnimationValue* from, const AnimationValue* to, float progress)
-{
-    switch (animation.keyframes.property()) {
-    case AnimatedPropertyOpacity:
-        applyOpacityAnimation((static_cast<const FloatAnimationValue*>(from)->value()), (static_cast<const FloatAnimationValue*>(to)->value()), progress);
-        return;
-    case AnimatedPropertyWebkitTransform:
-        applyTransformAnimation(animation, static_cast<const TransformAnimationValue*>(from)->value(), static_cast<const TransformAnimationValue*>(to)->value(), progress);
-        return;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-}
-
-void TextureMapperNode::applyAnimation(const TextureMapperAnimation& animation, double normalizedValue)
-{
-    // Optimization: special case the edge values (0 and 1).
-    if (!normalizedValue) {
-        applyAnimationFrame(animation, animation.keyframes.at(0), animation.keyframes.at(1), 0);
-        return;
-    }
-    if (normalizedValue == 1.0) {
-        applyAnimationFrame(animation, animation.keyframes.at(animation.keyframes.size() - 2), animation.keyframes.at(animation.keyframes.size() - 1), 1);
-        return;
-    }
-    if (animation.keyframes.size() == 2) {
-        normalizedValue = applyTimingFunction(animation.animation->timingFunction().get(), normalizedValue, animation.animation->duration());
-        applyAnimationFrame(animation, animation.keyframes.at(0), animation.keyframes.at(1), normalizedValue);
-        return;
-    }
-
-    for (size_t i = 0; i < animation.keyframes.size() - 1; ++i) {
-        const AnimationValue* from = animation.keyframes.at(i);
-        const AnimationValue* to = animation.keyframes.at(i + 1);
-        if (from->keyTime() > normalizedValue || to->keyTime() < normalizedValue)
-            continue;
-
-        normalizedValue = (normalizedValue - from->keyTime()) / (to->keyTime() - from->keyTime());
-        normalizedValue = applyTimingFunction(from->timingFunction(), normalizedValue, animation.animation->duration());
-        applyAnimationFrame(animation, from, to, normalizedValue);
-        break;
-    }
-}
-
-bool TextureMapperNode::hasOpacityAnimation() const
-{
-    for (size_t i = 0; i < m_animations.size(); ++i) {
-        const TextureMapperAnimation& animation = *m_animations[i].get();
-        if (animation.keyframes.property() == AnimatedPropertyOpacity)
-            return true;
-    }
-    return false;
-}
-
-bool TextureMapperNode::hasTransformAnimation() const
-{
-    for (size_t i = 0; i < m_animations.size(); ++i) {
-        const TextureMapperAnimation& animation = *m_animations[i].get();
-        if (animation.keyframes.property() == AnimatedPropertyWebkitTransform)
-            return true;
-    }
-    return false;
-}
-
-void TextureMapperNode::syncAnimations(GraphicsLayerTextureMapper* layer)
-{
-    for (int i = m_animations.size() - 1; i >= 0; --i) {
-        RefPtr<TextureMapperAnimation> animation = m_animations[i];
-
-        double totalRunningTime = WTF::currentTime() - animation->startTime;
-        RefPtr<Animation> anim = animation->animation;
-        double normalizedValue = normalizedAnimationValue(totalRunningTime, anim->duration(), anim->direction());
-
-        if (anim->iterationCount() != Animation::IterationCountInfinite && totalRunningTime >= anim->duration() * anim->iterationCount()) {
-            // We apply an animation that very close to the edge, so that the final frame is applied, oterwise we might get, for example, an opacity of 0.01 which is still visible.
-            if (anim->fillsForwards()) {
-                if (animation->keyframes.property() == AnimatedPropertyWebkitTransform)
-                    setTransform(m_state.transform);
-                else if (animation->keyframes.property() == AnimatedPropertyOpacity)
-                    setOpacity(m_state.opacity);
-            }
-
-            m_animations.remove(i);
-            continue;
-        }
-
-        if (!animation->paused)
-            applyAnimation(*animation.get(), normalizedValue);
-    }
-}
-
 void TextureMapperNode::syncAnimationsRecursively()
 {
-    syncAnimations(0);
+    syncAnimations();
 
     for (int i = m_children.size() - 1; i >= 0; --i)
         m_children[i]->syncAnimationsRecursively();
@@ -855,8 +666,7 @@
     if (m_state.replicaLayer)
         m_state.replicaLayer->syncCompositingState(toGraphicsLayerTextureMapper(graphicsLayer->replicaLayer()), textureMapper);
 
-    syncAnimations(graphicsLayer);
-
+    syncAnimations();
     computeTiles();
 
     if (graphicsLayer)
@@ -879,11 +689,5 @@
     }
 }
 
-TextureMapperAnimation::TextureMapperAnimation(const KeyframeValueList& values)
-    : keyframes(values)
-{
 }
-
-}
-
 #endif

Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h (105924 => 105925)


--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h	2012-01-25 22:11:40 UTC (rev 105924)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperNode.h	2012-01-25 22:13:29 UTC (rev 105925)
@@ -27,10 +27,9 @@
 #include "IntPointHash.h"
 #include "LayerTransform.h"
 #include "TextureMapper.h"
+#include "TextureMapperAnimation.h"
 #include "Timer.h"
 #include "TransformOperations.h"
-#include "TranslateTransformOperation.h"
-#include "UnitBezier.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/HashMap.h>
 #include <wtf/RefCounted.h>
@@ -57,23 +56,8 @@
     { }
 };
 
-class TextureMapperAnimation : public RefCounted<TextureMapperAnimation> {
-public:
-    String name;
-    KeyframeValueList keyframes;
-    IntSize boxSize;
-    RefPtr<Animation> animation;
-    bool paused;
-    Vector<TransformOperation::OperationType> functionList;
-    bool listsMatch;
-    bool hasBigRotation;
-    double startTime;
-    TextureMapperAnimation(const KeyframeValueList&);
-    static PassRefPtr<TextureMapperAnimation> create(const KeyframeValueList& values) { return adoptRef(new TextureMapperAnimation(values)); }
-};
+class TextureMapperNode : public TextureMapperAnimationClient {
 
-class TextureMapperNode {
-
 public:
     // This set of flags help us defer which properties of the layer have been
     // modified by the compositor, so we can know what to look for in the next flush.
@@ -198,13 +182,7 @@
     void paintSelfAndChildrenWithReplica(const TextureMapperPaintOptions&);
     void renderContent(TextureMapper*, GraphicsLayer*);
 
-    void syncAnimations(GraphicsLayerTextureMapper*);
-    void applyAnimation(const TextureMapperAnimation&, double runningTime);
-    void applyAnimationFrame(const TextureMapperAnimation&, const AnimationValue* from, const AnimationValue* to, float progress);
-    void applyOpacityAnimation(float fromOpacity, float toOpacity, double);
-    void applyTransformAnimation(const TextureMapperAnimation&, const TransformOperations* start, const TransformOperations* end, double);
-    bool hasOpacityAnimation() const;
-    bool hasTransformAnimation() const;
+    void syncAnimations();
     bool isVisible() const;
     bool shouldPaintToIntermediateSurface() const;
 
@@ -315,8 +293,7 @@
 
     State m_state;
     TextureMapper* m_textureMapper;
-
-    Vector<RefPtr<TextureMapperAnimation> > m_animations;
+    TextureMapperAnimations m_animations;
 };
 
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to