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;
};