Home | History | Annotate | Download | only in animation
      1 /*
      2  * Copyright (C) 2007 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef AnimationBase_h
     30 #define AnimationBase_h
     31 
     32 #include "AtomicString.h"
     33 #include <wtf/HashMap.h>
     34 
     35 namespace WebCore {
     36 
     37 class Animation;
     38 class AnimationBase;
     39 class AnimationController;
     40 class CompositeAnimation;
     41 class Element;
     42 class Node;
     43 class RenderObject;
     44 class RenderStyle;
     45 class TimingFunction;
     46 
     47 class AnimationBase : public RefCounted<AnimationBase> {
     48     friend class CompositeAnimation;
     49 
     50 public:
     51     AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim);
     52     virtual ~AnimationBase();
     53 
     54     RenderObject* renderer() const { return m_object; }
     55     void clearRenderer() { m_object = 0; }
     56 
     57     double duration() const;
     58 
     59     // Animations and Transitions go through the states below. When entering the STARTED state
     60     // the animation is started. This may or may not require deferred response from the animator.
     61     // If so, we stay in this state until that response is received (and it returns the start time).
     62     // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
     63     // or AnimationStateEnding.
     64     enum AnimState {
     65         AnimationStateNew,                  // animation just created, animation not running yet
     66         AnimationStateStartWaitTimer,       // start timer running, waiting for fire
     67         AnimationStateStartWaitStyleAvailable,   // waiting for style setup so we can start animations
     68         AnimationStateStartWaitResponse,    // animation started, waiting for response
     69         AnimationStateLooping,              // response received, animation running, loop timer running, waiting for fire
     70         AnimationStateEnding,               // received, animation running, end timer running, waiting for fire
     71         AnimationStatePausedWaitTimer,      // in pause mode when animation started
     72         AnimationStatePausedWaitResponse,   // animation paused when in STARTING state
     73         AnimationStatePausedRun,            // animation paused when in LOOPING or ENDING state
     74         AnimationStateDone                  // end timer fired, animation finished and removed
     75     };
     76 
     77     enum AnimStateInput {
     78         AnimationStateInputMakeNew,           // reset back to new from any state
     79         AnimationStateInputStartAnimation,    // animation requests a start
     80         AnimationStateInputRestartAnimation,  // force a restart from any state
     81         AnimationStateInputStartTimerFired,   // start timer fired
     82         AnimationStateInputStyleAvailable,    // style is setup, ready to start animating
     83         AnimationStateInputStartTimeSet,      // m_startTime was set
     84         AnimationStateInputLoopTimerFired,    // loop timer fired
     85         AnimationStateInputEndTimerFired,     // end timer fired
     86         AnimationStateInputPauseOverride,     // pause an animation due to override
     87         AnimationStateInputResumeOverride,    // resume an overridden animation
     88         AnimationStateInputPlayStateRunnning, // play state paused -> running
     89         AnimationStateInputPlayStatePaused,   // play state running -> paused
     90         AnimationStateInputEndAnimation       // force an end from any state
     91     };
     92 
     93     // Called when animation is in AnimationStateNew to start animation
     94     void updateStateMachine(AnimStateInput, double param);
     95 
     96     // Animation has actually started, at passed time
     97     void onAnimationStartResponse(double startTime)
     98     {
     99         updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime);
    100     }
    101 
    102     // Called to change to or from paused state
    103     void updatePlayState(bool running);
    104     bool playStatePlaying() const;
    105 
    106     bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
    107     bool preActive() const
    108     {
    109         return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
    110     }
    111 
    112     bool postActive() const { return m_animState == AnimationStateDone; }
    113     bool active() const { return !postActive() && !preActive(); }
    114     bool running() const { return !isNew() && !postActive(); }
    115     bool paused() const { return m_pauseTime >= 0; }
    116     bool isNew() const { return m_animState == AnimationStateNew; }
    117     bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
    118     bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
    119 
    120     // "animating" means that something is running that requires a timer to keep firing
    121     // (e.g. a software animation)
    122     void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; }
    123     virtual double timeToNextService();
    124 
    125     double progress(double scale, double offset, const TimingFunction*) const;
    126 
    127     virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
    128     virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
    129 
    130     virtual bool shouldFireEvents() const { return false; }
    131 
    132     void fireAnimationEventsIfNeeded();
    133 
    134     bool animationsMatch(const Animation*) const;
    135 
    136     void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); }
    137 
    138     // Return true if this animation is overridden. This will only be the case for
    139     // ImplicitAnimations and is used to determine whether or not we should force
    140     // set the start time. If an animation is overridden, it will probably not get
    141     // back the AnimationStateInputStartTimeSet input.
    142     virtual bool overridden() const { return false; }
    143 
    144     // Does this animation/transition involve the given property?
    145     virtual bool affectsProperty(int /*property*/) const { return false; }
    146     bool isAnimatingProperty(int property, bool isRunningNow) const
    147     {
    148         if (m_fallbackAnimating)
    149             return false;
    150 
    151         if (isRunningNow)
    152             return (!waitingToStart() && !postActive()) && affectsProperty(property);
    153 
    154         return !postActive() && affectsProperty(property);
    155     }
    156 
    157     bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
    158 
    159     // Freeze the animation; used by DumpRenderTree.
    160     void freezeAtTime(double t);
    161 
    162     double beginAnimationUpdateTime() const;
    163 
    164     double getElapsedTime() const;
    165 
    166     AnimationBase* next() const { return m_next; }
    167     void setNext(AnimationBase* animation) { m_next = animation; }
    168 
    169     void styleAvailable()
    170     {
    171         ASSERT(waitingForStyleAvailable());
    172         updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
    173     }
    174 
    175 #if USE(ACCELERATED_COMPOSITING)
    176     static bool animationOfPropertyIsAccelerated(int prop);
    177 #endif
    178 
    179 protected:
    180     virtual void overrideAnimations() { }
    181     virtual void resumeOverriddenAnimations() { }
    182 
    183     CompositeAnimation* compositeAnimation() { return m_compAnim; }
    184 
    185     // These are called when the corresponding timer fires so subclasses can do any extra work
    186     virtual void onAnimationStart(double /*elapsedTime*/) { }
    187     virtual void onAnimationIteration(double /*elapsedTime*/) { }
    188     virtual void onAnimationEnd(double /*elapsedTime*/) { }
    189 
    190     // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
    191     // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
    192     virtual bool startAnimation(double /*timeOffset*/) { return false; }
    193     // timeOffset is the time at which the animation is being paused.
    194     virtual void pauseAnimation(double /*timeOffset*/) { }
    195     virtual void endAnimation() { }
    196 
    197     void goIntoEndingOrLoopingState();
    198 
    199     bool isFallbackAnimating() const { return m_fallbackAnimating; }
    200 
    201     static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
    202     static int getPropertyAtIndex(int, bool& isShorthand);
    203     static int getNumProperties();
    204 
    205     // Return true if we need to start software animation timers
    206     static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
    207 
    208     static void setNeedsStyleRecalc(Node*);
    209 
    210     void getTimeToNextEvent(double& time, bool& isLooping) const;
    211 
    212     AnimState m_animState;
    213 
    214     bool m_isAnimating;       // transition/animation requires continual timer firing
    215     double m_startTime;
    216     double m_pauseTime;
    217     double m_requestedStartTime;
    218     RenderObject* m_object;
    219 
    220     RefPtr<Animation> m_animation;
    221     CompositeAnimation* m_compAnim;
    222     bool m_fallbackAnimating;       // true when animating an accelerated property but have to fall back to software
    223     bool m_transformFunctionListValid;
    224     double m_totalDuration, m_nextIterationDuration;
    225 
    226     AnimationBase* m_next;
    227 };
    228 
    229 } // namespace WebCore
    230 
    231 #endif // AnimationBase_h
    232