diff -r 000000000000 -r 4f2f89ce4247 WebCore/page/animation/AnimationBase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebCore/page/animation/AnimationBase.h Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AnimationBase_h +#define AnimationBase_h + +#include "AtomicString.h" +#include + +namespace WebCore { + +class Animation; +class AnimationBase; +class AnimationController; +class CompositeAnimation; +class Element; +class Node; +class RenderObject; +class RenderStyle; +struct TimingFunction; + +class AnimationBase : public RefCounted { + friend class CompositeAnimation; + +public: + AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim); + virtual ~AnimationBase(); + + RenderObject* renderer() const { return m_object; } + void clearRenderer() { m_object = 0; } + + double duration() const; + + // Animations and Transitions go through the states below. When entering the STARTED state + // the animation is started. This may or may not require deferred response from the animator. + // If so, we stay in this state until that response is received (and it returns the start time). + // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping + // or AnimationStateEnding. + enum AnimState { + AnimationStateNew, // animation just created, animation not running yet + AnimationStateStartWaitTimer, // start timer running, waiting for fire + AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations + AnimationStateStartWaitResponse, // animation started, waiting for response + AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire + AnimationStateEnding, // received, animation running, end timer running, waiting for fire + AnimationStatePausedWaitTimer, // in pause mode when animation started + AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup + AnimationStatePausedWaitResponse, // animation paused when in STARTING state + AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state + AnimationStateDone, // end timer fired, animation finished and removed + AnimationStateFillingForwards // animation has ended and is retaining its final value + }; + + enum AnimStateInput { + AnimationStateInputMakeNew, // reset back to new from any state + AnimationStateInputStartAnimation, // animation requests a start + AnimationStateInputRestartAnimation, // force a restart from any state + AnimationStateInputStartTimerFired, // start timer fired + AnimationStateInputStyleAvailable, // style is setup, ready to start animating + AnimationStateInputStartTimeSet, // m_startTime was set + AnimationStateInputLoopTimerFired, // loop timer fired + AnimationStateInputEndTimerFired, // end timer fired + AnimationStateInputPauseOverride, // pause an animation due to override + AnimationStateInputResumeOverride, // resume an overridden animation + AnimationStateInputPlayStateRunning, // play state paused -> running + AnimationStateInputPlayStatePaused, // play state running -> paused + AnimationStateInputEndAnimation // force an end from any state + }; + + // Called when animation is in AnimationStateNew to start animation + void updateStateMachine(AnimStateInput, double param); + + // Animation has actually started, at passed time + void onAnimationStartResponse(double startTime) + { + updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime); + } + + // Called to change to or from paused state + void updatePlayState(bool running); + bool playStatePlaying() const; + + bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } + bool preActive() const + { + return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse; + } + + bool postActive() const { return m_animState == AnimationStateDone; } + bool active() const { return !postActive() && !preActive(); } + bool running() const { return !isNew() && !postActive(); } + bool paused() const { return m_pauseTime >= 0; } + bool isNew() const { return m_animState == AnimationStateNew; } + bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; } + bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; } + + // "animating" means that something is running that requires a timer to keep firing + // (e.g. a software animation) + void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; } + virtual double timeToNextService(); + + double progress(double scale, double offset, const TimingFunction*) const; + + virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr& /*animatedStyle*/) = 0; + virtual void getAnimatedStyle(RefPtr& /*animatedStyle*/) = 0; + + virtual bool shouldFireEvents() const { return false; } + + void fireAnimationEventsIfNeeded(); + + bool animationsMatch(const Animation*) const; + + void setAnimation(const Animation* anim) { m_animation = const_cast(anim); } + + // Return true if this animation is overridden. This will only be the case for + // ImplicitAnimations and is used to determine whether or not we should force + // set the start time. If an animation is overridden, it will probably not get + // back the AnimationStateInputStartTimeSet input. + virtual bool overridden() const { return false; } + + // Does this animation/transition involve the given property? + virtual bool affectsProperty(int /*property*/) const { return false; } + + bool isAnimatingProperty(int property, bool acceleratedOnly, bool isRunningNow) const + { + if (acceleratedOnly && !m_isAccelerated) + return false; + + if (isRunningNow) + return (!waitingToStart() && !postActive()) && affectsProperty(property); + + return !postActive() && affectsProperty(property); + } + + bool isTransformFunctionListValid() const { return m_transformFunctionListValid; } + + // Freeze the animation; used by DumpRenderTree. + void freezeAtTime(double t); + + double beginAnimationUpdateTime() const; + + double getElapsedTime() const; + + AnimationBase* next() const { return m_next; } + void setNext(AnimationBase* animation) { m_next = animation; } + + void styleAvailable() + { + ASSERT(waitingForStyleAvailable()); + updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1); + } + +#if USE(ACCELERATED_COMPOSITING) + static bool animationOfPropertyIsAccelerated(int prop); +#endif + +protected: + virtual void overrideAnimations() { } + virtual void resumeOverriddenAnimations() { } + + CompositeAnimation* compositeAnimation() { return m_compAnim; } + + // These are called when the corresponding timer fires so subclasses can do any extra work + virtual void onAnimationStart(double /*elapsedTime*/) { } + virtual void onAnimationIteration(double /*elapsedTime*/) { } + virtual void onAnimationEnd(double /*elapsedTime*/) { } + + // 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(); + + bool isAccelerated() const { return m_isAccelerated; } + + static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b); + static int getPropertyAtIndex(int, bool& isShorthand); + static int getNumProperties(); + + // Return true if we need to start software animation timers + static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress); + + static void setNeedsStyleRecalc(Node*); + + void getTimeToNextEvent(double& time, bool& isLooping) const; + + AnimState m_animState; + + bool m_isAnimating; // transition/animation requires continual timer firing + double m_startTime; + double m_pauseTime; + double m_requestedStartTime; + RenderObject* m_object; + + RefPtr m_animation; + CompositeAnimation* m_compAnim; + bool m_isAccelerated; + bool m_transformFunctionListValid; + double m_totalDuration, m_nextIterationDuration; + + AnimationBase* m_next; + +private: + static void ensurePropertyMap(); +}; + +} // namespace WebCore + +#endif // AnimationBase_h