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 renderer()54 RenderObject* renderer() const { return m_object; } clearRenderer()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 onAnimationStartResponse(double startTime)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 waitingToStart()106 bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; } preActive()107 bool preActive() const 108 { 109 return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse; 110 } 111 postActive()112 bool postActive() const { return m_animState == AnimationStateDone; } active()113 bool active() const { return !postActive() && !preActive(); } running()114 bool running() const { return !isNew() && !postActive(); } paused()115 bool paused() const { return m_pauseTime >= 0; } isNew()116 bool isNew() const { return m_animState == AnimationStateNew; } waitingForStartTime()117 bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; } waitingForStyleAvailable()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 shouldFireEvents()130 virtual bool shouldFireEvents() const { return false; } 131 132 void fireAnimationEventsIfNeeded(); 133 134 bool animationsMatch(const Animation*) const; 135 setAnimation(const Animation * anim)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. overridden()142 virtual bool overridden() const { return false; } 143 144 // Does this animation/transition involve the given property? affectsProperty(int)145 virtual bool affectsProperty(int /*property*/) const { return false; } isAnimatingProperty(int property,bool isRunningNow)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 isTransformFunctionListValid()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 next()166 AnimationBase* next() const { return m_next; } setNext(AnimationBase * animation)167 void setNext(AnimationBase* animation) { m_next = animation; } 168 styleAvailable()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: overrideAnimations()180 virtual void overrideAnimations() { } resumeOverriddenAnimations()181 virtual void resumeOverriddenAnimations() { } 182 compositeAnimation()183 CompositeAnimation* compositeAnimation() { return m_compAnim; } 184 185 // These are called when the corresponding timer fires so subclasses can do any extra work onAnimationStart(double)186 virtual void onAnimationStart(double /*elapsedTime*/) { } onAnimationIteration(double)187 virtual void onAnimationIteration(double /*elapsedTime*/) { } onAnimationEnd(double)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. startAnimation(double)192 virtual bool startAnimation(double /*timeOffset*/) { return false; } 193 // timeOffset is the time at which the animation is being paused. pauseAnimation(double)194 virtual void pauseAnimation(double /*timeOffset*/) { } endAnimation()195 virtual void endAnimation() { } 196 197 void goIntoEndingOrLoopingState(); 198 isFallbackAnimating()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