• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "RenderStyleConstants.h"
33 #include <wtf/HashMap.h>
34 #include <wtf/HashSet.h>
35 #include <wtf/text/AtomicString.h>
36 
37 namespace WebCore {
38 
39 class Animation;
40 class AnimationBase;
41 class AnimationController;
42 class CompositeAnimation;
43 class Element;
44 class Node;
45 class RenderObject;
46 class RenderStyle;
47 class TimingFunction;
48 
49 class AnimationBase : public RefCounted<AnimationBase> {
50     friend class CompositeAnimation;
51 
52 public:
53     AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim);
~AnimationBase()54     virtual ~AnimationBase() { }
55 
renderer()56     RenderObject* renderer() const { return m_object; }
clear()57     void clear() { m_object = 0; m_compAnim = 0; }
58 
59     double duration() const;
60 
61     // Animations and Transitions go through the states below. When entering the STARTED state
62     // the animation is started. This may or may not require deferred response from the animator.
63     // If so, we stay in this state until that response is received (and it returns the start time).
64     // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
65     // or AnimationStateEnding.
66     enum AnimState {
67         AnimationStateNew,                  // animation just created, animation not running yet
68         AnimationStateStartWaitTimer,       // start timer running, waiting for fire
69         AnimationStateStartWaitStyleAvailable,   // waiting for style setup so we can start animations
70         AnimationStateStartWaitResponse,    // animation started, waiting for response
71         AnimationStateLooping,              // response received, animation running, loop timer running, waiting for fire
72         AnimationStateEnding,               // received, animation running, end timer running, waiting for fire
73         AnimationStatePausedWaitTimer,      // in pause mode when animation started
74         AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup
75         AnimationStatePausedWaitResponse,   // animation paused when in STARTING state
76         AnimationStatePausedRun,            // animation paused when in LOOPING or ENDING state
77         AnimationStateDone,                 // end timer fired, animation finished and removed
78         AnimationStateFillingForwards       // animation has ended and is retaining its final value
79     };
80 
81     enum AnimStateInput {
82         AnimationStateInputMakeNew,           // reset back to new from any state
83         AnimationStateInputStartAnimation,    // animation requests a start
84         AnimationStateInputRestartAnimation,  // force a restart from any state
85         AnimationStateInputStartTimerFired,   // start timer fired
86         AnimationStateInputStyleAvailable,    // style is setup, ready to start animating
87         AnimationStateInputStartTimeSet,      // m_startTime was set
88         AnimationStateInputLoopTimerFired,    // loop timer fired
89         AnimationStateInputEndTimerFired,     // end timer fired
90         AnimationStateInputPauseOverride,     // pause an animation due to override
91         AnimationStateInputResumeOverride,    // resume an overridden animation
92         AnimationStateInputPlayStateRunning,  // play state paused -> running
93         AnimationStateInputPlayStatePaused,   // play state running -> paused
94         AnimationStateInputEndAnimation       // force an end from any state
95     };
96 
97     // Called when animation is in AnimationStateNew to start animation
98     void updateStateMachine(AnimStateInput, double param);
99 
100     // Animation has actually started, at passed time
onAnimationStartResponse(double startTime)101     void onAnimationStartResponse(double startTime)
102     {
103         updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime);
104     }
105 
106     // Called to change to or from paused state
107     void updatePlayState(EAnimPlayState);
108     bool playStatePlaying() const;
109 
waitingToStart()110     bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
preActive()111     bool preActive() const
112     {
113         return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
114     }
115 
postActive()116     bool postActive() const { return m_animState == AnimationStateDone; }
active()117     bool active() const { return !postActive() && !preActive(); }
running()118     bool running() const { return !isNew() && !postActive(); }
paused()119     bool paused() const { return m_pauseTime >= 0; }
isNew()120     bool isNew() const { return m_animState == AnimationStateNew; }
waitingForStartTime()121     bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
waitingForStyleAvailable()122     bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
123 
124     // "animating" means that something is running that requires a timer to keep firing
125     // (e.g. a software animation)
126     void setAnimating(bool inAnimating = true) { m_isAnimating = inAnimating; }
127     virtual double timeToNextService();
128 
129     double progress(double scale, double offset, const TimingFunction*) const;
130 
131     virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
132     virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
133 
shouldFireEvents()134     virtual bool shouldFireEvents() const { return false; }
135 
136     void fireAnimationEventsIfNeeded();
137 
138     bool animationsMatch(const Animation*) const;
139 
setAnimation(const Animation * anim)140     void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); }
141 
142     // Return true if this animation is overridden. This will only be the case for
143     // ImplicitAnimations and is used to determine whether or not we should force
144     // set the start time. If an animation is overridden, it will probably not get
145     // back the AnimationStateInputStartTimeSet input.
overridden()146     virtual bool overridden() const { return false; }
147 
148     // Does this animation/transition involve the given property?
affectsProperty(int)149     virtual bool affectsProperty(int /*property*/) const { return false; }
150 
isAnimatingProperty(int property,bool acceleratedOnly,bool isRunningNow)151     bool isAnimatingProperty(int property, bool acceleratedOnly, bool isRunningNow) const
152     {
153         if (acceleratedOnly && !m_isAccelerated)
154             return false;
155 
156         if (isRunningNow)
157             return (!waitingToStart() && !postActive()) && affectsProperty(property);
158 
159         return !postActive() && affectsProperty(property);
160     }
161 
isTransformFunctionListValid()162     bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
163 
164     // Freeze the animation; used by DumpRenderTree.
165     void freezeAtTime(double t);
166 
167     // Play and pause API
168     void play();
169     void pause();
170 
171     double beginAnimationUpdateTime() const;
172 
173     double getElapsedTime() const;
174     // Setting the elapsed time will adjust the start time and possibly pause time.
175     void setElapsedTime(double);
176 
styleAvailable()177     void styleAvailable()
178     {
179         ASSERT(waitingForStyleAvailable());
180         updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
181     }
182 
183 #if USE(ACCELERATED_COMPOSITING)
184     static bool animationOfPropertyIsAccelerated(int prop);
185 #endif
186 
187     static HashSet<int> animatableShorthandsAffectingProperty(int property);
188 
animation()189     const Animation* animation() const { return m_animation.get(); }
190 
191 protected:
overrideAnimations()192     virtual void overrideAnimations() { }
resumeOverriddenAnimations()193     virtual void resumeOverriddenAnimations() { }
194 
compositeAnimation()195     CompositeAnimation* compositeAnimation() { return m_compAnim; }
196 
197     // These are called when the corresponding timer fires so subclasses can do any extra work
onAnimationStart(double)198     virtual void onAnimationStart(double /*elapsedTime*/) { }
onAnimationIteration(double)199     virtual void onAnimationIteration(double /*elapsedTime*/) { }
onAnimationEnd(double)200     virtual void onAnimationEnd(double /*elapsedTime*/) { }
201 
202     // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
203     // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
startAnimation(double)204     virtual bool startAnimation(double /*timeOffset*/) { return false; }
205     // timeOffset is the time at which the animation is being paused.
pauseAnimation(double)206     virtual void pauseAnimation(double /*timeOffset*/) { }
endAnimation()207     virtual void endAnimation() { }
208 
209     void goIntoEndingOrLoopingState();
210 
isAccelerated()211     bool isAccelerated() const { return m_isAccelerated; }
212 
213     static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
214     static int getPropertyAtIndex(int, bool& isShorthand);
215     static int getNumProperties();
216 
217     // Return true if we need to start software animation timers
218     static bool blendProperties(const AnimationBase* anim, int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
219 
220     static void setNeedsStyleRecalc(Node*);
221 
222     void getTimeToNextEvent(double& time, bool& isLooping) const;
223 
224     AnimState m_animState;
225 
226     bool m_isAnimating;       // transition/animation requires continual timer firing
227     double m_startTime;
228     double m_pauseTime;
229     double m_requestedStartTime;
230     RenderObject* m_object;
231 
232     RefPtr<Animation> m_animation;
233     CompositeAnimation* m_compAnim;
234     bool m_isAccelerated;
235     bool m_transformFunctionListValid;
236     double m_totalDuration, m_nextIterationDuration;
237 
238 private:
239     static void ensurePropertyMap();
240 };
241 
242 } // namespace WebCore
243 
244 #endif // AnimationBase_h
245