diff options
Diffstat (limited to 'WebCore/page/animation')
-rw-r--r-- | WebCore/page/animation/AnimationBase.cpp | 48 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationBase.h | 9 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationController.cpp | 2 | ||||
-rw-r--r-- | WebCore/page/animation/AnimationControllerPrivate.h | 2 | ||||
-rw-r--r-- | WebCore/page/animation/CompositeAnimation.cpp | 15 | ||||
-rw-r--r-- | WebCore/page/animation/ImplicitAnimation.cpp | 14 | ||||
-rw-r--r-- | WebCore/page/animation/ImplicitAnimation.h | 5 | ||||
-rw-r--r-- | WebCore/page/animation/KeyframeAnimation.cpp | 56 | ||||
-rw-r--r-- | WebCore/page/animation/KeyframeAnimation.h | 5 |
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(); |