summaryrefslogtreecommitdiffstats
path: root/WebCore/page/animation
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page/animation')
-rw-r--r--WebCore/page/animation/AnimationBase.cpp48
-rw-r--r--WebCore/page/animation/AnimationBase.h9
-rw-r--r--WebCore/page/animation/AnimationController.cpp2
-rw-r--r--WebCore/page/animation/AnimationControllerPrivate.h2
-rw-r--r--WebCore/page/animation/CompositeAnimation.cpp15
-rw-r--r--WebCore/page/animation/ImplicitAnimation.cpp14
-rw-r--r--WebCore/page/animation/ImplicitAnimation.h5
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp56
-rw-r--r--WebCore/page/animation/KeyframeAnimation.h5
9 files changed, 104 insertions, 52 deletions
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index f1ee750..2a2ab4b 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -92,10 +92,17 @@ static inline Color blendFunc(const AnimationBase* anim, const Color& from, cons
if (progress == 1 && !to.isValid())
return Color();
- return Color(blendFunc(anim, from.red(), to.red(), progress),
- blendFunc(anim, from.green(), to.green(), progress),
- blendFunc(anim, from.blue(), to.blue(), progress),
- blendFunc(anim, from.alpha(), to.alpha(), progress));
+ // Contrary to the name, RGBA32 actually stores ARGB, so we can initialize Color directly from premultipliedARGBFromColor().
+ // Also, premultipliedARGBFromColor() bails on zero alpha, so special-case that.
+ Color premultFrom = from.alpha() ? premultipliedARGBFromColor(from) : 0;
+ Color premultTo = to.alpha() ? premultipliedARGBFromColor(to) : 0;
+
+ Color premultBlended(blendFunc(anim, premultFrom.red(), premultTo.red(), progress),
+ blendFunc(anim, premultFrom.green(), premultTo.green(), progress),
+ blendFunc(anim, premultFrom.blue(), premultTo.blue(), progress),
+ blendFunc(anim, premultFrom.alpha(), premultTo.alpha(), progress));
+
+ return Color(colorFromPremultipliedARGB(premultBlended.rgb()));
}
static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress)
@@ -407,7 +414,7 @@ public:
};
template <typename T>
-class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase {
+class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase, public Noncopyable {
public:
FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
: m_getter(getter)
@@ -863,7 +870,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_pauseTime = -1;
m_requestedStartTime = 0;
m_nextIterationDuration = -1;
- endAnimation(false);
+ endAnimation();
return;
}
@@ -875,7 +882,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_pauseTime = -1;
m_requestedStartTime = 0;
m_nextIterationDuration = -1;
- endAnimation(false);
+ endAnimation();
if (!paused())
updateStateMachine(AnimationStateInputStartAnimation, -1);
@@ -886,7 +893,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->animationController()->removeFromStyleAvailableWaitList(this);
m_animState = AnimationStateDone;
- endAnimation(true);
+ endAnimation();
return;
}
@@ -894,7 +901,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (m_animState == AnimationStateStartWaitResponse) {
// If we are in AnimationStateStartWaitResponse, the animation will get canceled before
// we get a response, so move to the next state.
- endAnimation(false);
+ endAnimation();
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
return;
@@ -903,7 +910,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (input == AnimationStateInputResumeOverride) {
if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
// Start the animation
- startAnimation(m_startTime);
+ startAnimation(beginAnimationUpdateTime() - m_startTime);
}
return;
}
@@ -956,7 +963,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
else {
- bool started = startAnimation(0);
+ double timeOffset = 0;
+ // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
+ if (m_animation->delay() < 0)
+ timeOffset = -m_animation->delay();
+ bool started = startAnimation(timeOffset);
+
m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started);
m_fallbackAnimating = !started;
}
@@ -967,8 +979,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (input == AnimationStateInputStartTimeSet) {
ASSERT(param >= 0);
// We have a start time, set it, unless the startTime is already set
- if (m_startTime <= 0)
+ if (m_startTime <= 0) {
m_startTime = param;
+ // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
+ if (m_animation->delay() < 0)
+ m_startTime += m_animation->delay();
+ }
// Decide whether to go into looping or ending state
goIntoEndingOrLoopingState();
@@ -980,7 +996,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
m_pauseTime = -1;
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedWaitResponse;
}
break;
@@ -997,7 +1013,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedRun;
}
break;
@@ -1020,7 +1036,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedRun;
}
// |this| may be deleted here
@@ -1072,7 +1088,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
m_fallbackAnimating = true;
} else {
- bool started = startAnimation(m_startTime);
+ bool started = startAnimation(beginAnimationUpdateTime() - m_startTime);
m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started);
m_fallbackAnimating = !started;
}
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
index 3482f65..c367e0a 100644
--- a/WebCore/page/animation/AnimationBase.h
+++ b/WebCore/page/animation/AnimationBase.h
@@ -186,8 +186,13 @@ protected:
virtual void onAnimationStart(double /*elapsedTime*/) { }
virtual void onAnimationIteration(double /*elapsedTime*/) { }
virtual void onAnimationEnd(double /*elapsedTime*/) { }
- virtual bool startAnimation(double /*beginTime*/) { return false; }
- virtual void endAnimation(bool /*reset*/) { }
+
+ // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
+ // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
+ virtual bool startAnimation(double /*timeOffset*/) { return false; }
+ // timeOffset is the time at which the animation is being paused.
+ virtual void pauseAnimation(double /*timeOffset*/) { }
+ virtual void endAnimation() { }
void goIntoEndingOrLoopingState();
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index aa5de2c..422c154 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -484,7 +484,7 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
m_data->updateAnimationTimer();
if (blendedStyle != newStyle) {
- // If the animations/transitions change opacity or transform, we neeed to update
+ // If the animations/transitions change opacity or transform, we need to update
// the style to impose the stacking rules. Note that this is also
// done in CSSStyleSelector::adjustRenderStyle().
if (blendedStyle->hasAutoZIndex() && (blendedStyle->opacity() < 1.0f || blendedStyle->hasTransform()))
diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h
index 7db3803..682dd75 100644
--- a/WebCore/page/animation/AnimationControllerPrivate.h
+++ b/WebCore/page/animation/AnimationControllerPrivate.h
@@ -49,7 +49,7 @@ class Node;
class RenderObject;
class RenderStyle;
-class AnimationControllerPrivate {
+class AnimationControllerPrivate : public Noncopyable {
public:
AnimationControllerPrivate(Frame*);
~AnimationControllerPrivate();
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
index 8946d80..34f03c7 100644
--- a/WebCore/page/animation/CompositeAnimation.cpp
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -57,6 +57,7 @@ void CompositeAnimation::clearRenderer()
}
}
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* anim = it->second.get();
@@ -186,6 +187,8 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render
if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
return;
+ m_keyframeAnimations.checkConsistency();
+
AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
@@ -262,6 +265,7 @@ PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, Rend
// We don't do any transitions if we don't have a currentStyle (on startup).
updateTransitions(renderer, currentStyle, targetStyle);
updateKeyframeAnimations(renderer, currentStyle, targetStyle);
+ m_keyframeAnimations.checkConsistency();
if (currentStyle) {
// Now that we have transition objects ready, let them know about the new goal state. We want them
@@ -295,6 +299,8 @@ PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
implicitAnimation->getAnimatedStyle(resultStyle);
}
+ m_keyframeAnimations.checkConsistency();
+
for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
if (keyframeAnimation)
@@ -315,6 +321,7 @@ void CompositeAnimation::setAnimating(bool animating)
}
}
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* anim = it->second.get();
@@ -341,6 +348,7 @@ double CompositeAnimation::timeToNextService() const
}
}
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* animation = it->second.get();
@@ -362,6 +370,7 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr
// We want to send back the last animation with the property if there are multiples.
// So we need to iterate through all animations
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
RefPtr<KeyframeAnimation> anim = it->second;
@@ -381,6 +390,7 @@ void CompositeAnimation::suspendAnimations()
m_isSuspended = true;
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
if (KeyframeAnimation* anim = it->second.get())
@@ -405,6 +415,7 @@ void CompositeAnimation::resumeAnimations()
m_isSuspended = false;
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* anim = it->second.get();
@@ -450,6 +461,7 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property)
bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const
{
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* anim = it->second.get();
@@ -474,6 +486,8 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t
if (!name)
return false;
+ m_keyframeAnimations.checkConsistency();
+
RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl());
if (!keyframeAnim || !keyframeAnim->running())
return false;
@@ -509,6 +523,7 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const
unsigned count = 0;
if (!m_keyframeAnimations.isEmpty()) {
+ m_keyframeAnimations.checkConsistency();
AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
KeyframeAnimation* anim = it->second.get();
diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp
index 50fc781..328fe0e 100644
--- a/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/WebCore/page/animation/ImplicitAnimation.cpp
@@ -55,7 +55,7 @@ ImplicitAnimation::~ImplicitAnimation()
{
// // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
if (!postActive())
- endAnimation(true);
+ endAnimation();
}
bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const
@@ -106,21 +106,21 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
}
-bool ImplicitAnimation::startAnimation(double beginTime)
+bool ImplicitAnimation::startAnimation(double timeOffset)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
if (layer->isComposited())
- return layer->backing()->startTransition(beginTime, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+ return layer->backing()->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
}
#else
- UNUSED_PARAM(beginTime);
+ UNUSED_PARAM(timeOffset);
#endif
return false;
}
-void ImplicitAnimation::endAnimation(bool /*reset*/)
+void ImplicitAnimation::endAnimation()
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
@@ -143,7 +143,7 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime)
keyframeAnim->setUnanimatedStyle(m_toStyle);
sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime);
- endAnimation(true);
+ endAnimation();
}
bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
@@ -161,7 +161,7 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl
if (m_object->node() && m_object->node()->isElementNode())
element = static_cast<Element*>(m_object->node());
- ASSERT(!element || element->document() && !element->document()->inPageCache());
+ ASSERT(!element || (element->document() && !element->document()->inPageCache()));
if (!element)
return false;
diff --git a/WebCore/page/animation/ImplicitAnimation.h b/WebCore/page/animation/ImplicitAnimation.h
index 7e286d2..be5c197 100644
--- a/WebCore/page/animation/ImplicitAnimation.h
+++ b/WebCore/page/animation/ImplicitAnimation.h
@@ -47,8 +47,9 @@ public:
int animatingProperty() const { return m_animatingProperty; }
virtual void onAnimationEnd(double elapsedTime);
- virtual bool startAnimation(double beginTime);
- virtual void endAnimation(bool reset);
+ virtual bool startAnimation(double timeOffset);
+ virtual void pauseAnimation(double /*timeOffset*/) { }
+ virtual void endAnimation();
virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index 500bf6f..c5e3660 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -59,7 +59,7 @@ KeyframeAnimation::~KeyframeAnimation()
{
// Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
if (!postActive())
- endAnimation(true);
+ endAnimation();
}
void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
@@ -192,40 +192,54 @@ bool KeyframeAnimation::hasAnimationForProperty(int property) const
return false;
}
-bool KeyframeAnimation::startAnimation(double beginTime)
+bool KeyframeAnimation::startAnimation(double timeOffset)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
if (layer->isComposited())
- return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes);
+ return layer->backing()->startAnimation(timeOffset, m_animation.get(), m_keyframes);
}
#else
- UNUSED_PARAM(beginTime);
+ UNUSED_PARAM(timeOffset);
#endif
return false;
}
-void KeyframeAnimation::endAnimation(bool reset)
+void KeyframeAnimation::pauseAnimation(double timeOffset)
{
- if (m_object) {
+ if (!m_object)
+ return;
+
#if USE(ACCELERATED_COMPOSITING)
- if (m_object->hasLayer()) {
- RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
- if (layer->isComposited()) {
- if (reset)
- layer->backing()->animationFinished(m_keyframes.animationName());
- else
- layer->backing()->animationPaused(m_keyframes.animationName());
- }
- }
+ if (m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->animationPaused(timeOffset, m_keyframes.animationName());
+ }
#else
- UNUSED_PARAM(reset);
+ UNUSED_PARAM(timeOffset);
#endif
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
+ // Restore the original (unanimated) style
+ if (!paused())
+ setNeedsStyleRecalc(m_object->node());
+}
+
+void KeyframeAnimation::endAnimation()
+{
+ if (!m_object)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->animationFinished(m_keyframes.animationName());
}
+#endif
+ // Restore the original (unanimated) style
+ if (!paused())
+ setNeedsStyleRecalc(m_object->node());
}
bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
@@ -246,7 +260,7 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime)
void KeyframeAnimation::onAnimationEnd(double elapsedTime)
{
sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime);
- endAnimation(true);
+ endAnimation();
}
bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
@@ -267,7 +281,7 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
if (m_object->node() && m_object->node()->isElementNode())
element = static_cast<Element*>(m_object->node());
- ASSERT(!element || element->document() && !element->document()->inPageCache());
+ ASSERT(!element || (element->document() && !element->document()->inPageCache()));
if (!element)
return false;
diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h
index e3b8f53..fab0ae8 100644
--- a/WebCore/page/animation/KeyframeAnimation.h
+++ b/WebCore/page/animation/KeyframeAnimation.h
@@ -64,8 +64,9 @@ protected:
virtual void onAnimationStart(double elapsedTime);
virtual void onAnimationIteration(double elapsedTime);
virtual void onAnimationEnd(double elapsedTime);
- virtual bool startAnimation(double beginTime);
- virtual void endAnimation(bool reset);
+ virtual bool startAnimation(double timeOffset);
+ virtual void pauseAnimation(double timeOffset);
+ virtual void endAnimation();
virtual void overrideAnimations();
virtual void resumeOverriddenAnimations();