354da40446ad0c7f0968818a9a97ada1f2bc7565
[WebKit-https.git] / Source / WebCore / page / animation / AnimationBase.h
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 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 "Animation.h"
33 #include "CSSPropertyNames.h"
34 #include "RenderStyleConstants.h"
35 #include <wtf/HashMap.h>
36 #include <wtf/HashSet.h>
37 #include <wtf/RefCounted.h>
38 #include <wtf/text/AtomicString.h>
39
40 namespace WebCore {
41
42 class CompositeAnimation;
43 class Element;
44 class FloatRect;
45 class LayoutRect;
46 class RenderElement;
47 class RenderStyle;
48 class TimingFunction;
49
50 class AnimationBase : public RefCounted<AnimationBase> {
51     friend class CompositeAnimation;
52     friend class CSSPropertyAnimation;
53     WTF_MAKE_FAST_ALLOCATED;
54 public:
55     AnimationBase(Animation& transition, RenderElement*, CompositeAnimation*);
56     virtual ~AnimationBase() { }
57
58     RenderElement* renderer() const { return m_object; }
59     void clear()
60     {
61         endAnimation();
62         m_object = nullptr;
63         m_compositeAnimation = nullptr;
64     }
65
66     double duration() const;
67
68     // Animations and Transitions go through the states below. When entering the STARTED state
69     // the animation is started. This may or may not require deferred response from the animator.
70     // If so, we stay in this state until that response is received (and it returns the start time).
71     // Otherwise, we use the current time as the start time and go immediately to AnimationState::Looping
72     // or AnimationState::Ending.
73     enum class AnimationState {
74         New,                        // animation just created, animation not running yet
75         StartWaitTimer,             // start timer running, waiting for fire
76         StartWaitStyleAvailable,    // waiting for style setup so we can start animations
77         StartWaitResponse,          // animation started, waiting for response
78         Looping,                    // response received, animation running, loop timer running, waiting for fire
79         Ending,                     // received, animation running, end timer running, waiting for fire
80         PausedNew,                  // in pause mode when animation was created
81         PausedWaitTimer,            // in pause mode when animation started
82         PausedWaitStyleAvailable,   // in pause mode when waiting for style setup
83         PausedWaitResponse,         // animation paused when in STARTING state
84         PausedRun,                  // animation paused when in LOOPING or ENDING state
85         Done,                       // end timer fired, animation finished and removed
86         FillingForwards             // animation has ended and is retaining its final value
87     };
88
89     enum class AnimationStateInput {
90         MakeNew,           // reset back to new from any state
91         StartAnimation,    // animation requests a start
92         RestartAnimation,  // force a restart from any state
93         StartTimerFired,   // start timer fired
94         StyleAvailable,    // style is setup, ready to start animating
95         StartTimeSet,      // m_startTime was set
96         LoopTimerFired,    // loop timer fired
97         EndTimerFired,     // end timer fired
98         PauseOverride,     // pause an animation due to override
99         ResumeOverride,    // resume an overridden animation
100         PlayStateRunning,  // play state paused -> running
101         PlayStatePaused,   // play state running -> paused
102         EndAnimation       // force an end from any state
103     };
104
105     // Called when animation is in AnimationState::New to start animation
106     void updateStateMachine(AnimationStateInput, double param);
107
108     // Animation has actually started, at passed time
109     void onAnimationStartResponse(double startTime)
110     {
111         updateStateMachine(AnimationStateInput::StartTimeSet, startTime);
112     }
113
114     // Called to change to or from paused state
115     void updatePlayState(EAnimPlayState);
116     bool playStatePlaying() const;
117
118     bool waitingToStart() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::PausedNew; }
119     bool preActive() const
120     {
121         return m_animationState == AnimationState::New || m_animationState == AnimationState::StartWaitTimer || m_animationState == AnimationState::StartWaitStyleAvailable || m_animationState == AnimationState::StartWaitResponse;
122     }
123
124     bool postActive() const { return m_animationState == AnimationState::Done; }
125     bool fillingForwards() const { return m_animationState == AnimationState::FillingForwards; }
126     bool active() const { return !postActive() && !preActive(); }
127     bool running() const { return !isNew() && !postActive(); }
128     bool paused() const { return m_pauseTime >= 0 || m_animationState == AnimationState::PausedNew; }
129     bool inPausedState() const { return m_animationState >= AnimationState::PausedNew && m_animationState <= AnimationState::PausedRun; }
130     bool isNew() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::PausedNew; }
131     bool waitingForStartTime() const { return m_animationState == AnimationState::StartWaitResponse; }
132     bool waitingForStyleAvailable() const { return m_animationState == AnimationState::StartWaitStyleAvailable; }
133
134     virtual double timeToNextService();
135
136     double progress(double scale, double offset, const TimingFunction*) const;
137
138     virtual void animate(CompositeAnimation*, RenderElement*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
139     virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
140
141     virtual bool computeExtentOfTransformAnimation(LayoutRect&) const = 0;
142
143     virtual bool shouldFireEvents() const { return false; }
144
145     void fireAnimationEventsIfNeeded();
146
147     bool animationsMatch(const Animation&) const;
148
149     const Animation& animation() const { return m_animation; }
150     void setAnimation(Animation& animation) { m_animation = animation; }
151
152     // Return true if this animation is overridden. This will only be the case for
153     // ImplicitAnimations and is used to determine whether or not we should force
154     // set the start time. If an animation is overridden, it will probably not get
155     // back the AnimationStateInput::StartTimeSet input.
156     virtual bool overridden() const { return false; }
157
158     // Does this animation/transition involve the given property?
159     virtual bool affectsProperty(CSSPropertyID /*property*/) const { return false; }
160
161     enum RunningStates {
162         Delaying = 1 << 0,
163         Paused = 1 << 1,
164         Running = 1 << 2,
165         FillingFowards = 1 << 3
166     };
167     typedef unsigned RunningState;
168     bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, RunningState runningState) const
169     {
170         if (acceleratedOnly && !m_isAccelerated)
171             return false;
172
173         if (!affectsProperty(property))
174             return false;
175
176         if ((runningState & Delaying) && preActive())
177             return true;
178
179         if ((runningState & Paused) && inPausedState())
180             return true;
181
182         if ((runningState & Running) && !inPausedState() && (m_animationState >= AnimationState::StartWaitStyleAvailable && m_animationState <= AnimationState::Done))
183             return true;
184
185         if ((runningState & FillingFowards) && m_animationState == AnimationState::FillingForwards)
186             return true;
187
188         return false;
189     }
190
191     // FIXME: rename this using the "lists match" terminology.
192     bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
193     bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; }
194
195     // Freeze the animation; used by DumpRenderTree.
196     void freezeAtTime(double t);
197
198     // Play and pause API
199     void play();
200     void pause();
201     
202     double beginAnimationUpdateTime() const;
203     
204     double getElapsedTime() const;
205     // Setting the elapsed time will adjust the start time and possibly pause time.
206     void setElapsedTime(double);
207     
208     void styleAvailable() 
209     {
210         ASSERT(waitingForStyleAvailable());
211         updateStateMachine(AnimationStateInput::StyleAvailable, -1);
212     }
213
214 protected:
215     virtual void overrideAnimations() { }
216     virtual void resumeOverriddenAnimations() { }
217
218     CompositeAnimation* compositeAnimation() { return m_compositeAnimation; }
219
220     // These are called when the corresponding timer fires so subclasses can do any extra work
221     virtual void onAnimationStart(double /*elapsedTime*/) { }
222     virtual void onAnimationIteration(double /*elapsedTime*/) { }
223     virtual void onAnimationEnd(double /*elapsedTime*/) { }
224     
225     // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
226     // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
227     virtual bool startAnimation(double /*timeOffset*/) { return false; }
228     // timeOffset is the time at which the animation is being paused.
229     virtual void pauseAnimation(double /*timeOffset*/) { }
230     virtual void endAnimation() { }
231
232     void goIntoEndingOrLoopingState();
233
234     bool isAccelerated() const { return m_isAccelerated; }
235
236     static void setNeedsStyleRecalc(Element*);
237     
238     void getTimeToNextEvent(double& time, bool& isLooping) const;
239
240     double fractionalTime(double scale, double elapsedTime, double offset) const;
241
242     // These return true if we can easily compute a bounding box by applying the style's transform to the bounds rect.
243     bool computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;
244     bool computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle&, LayoutRect& bounds) const;
245
246     RenderElement* m_object;
247     CompositeAnimation* m_compositeAnimation; // Ideally this would be a reference, but it has to be cleared if an animation is destroyed inside an event callback.
248     Ref<Animation> m_animation;
249
250     double m_startTime { 0 };
251     double m_pauseTime { -1 };
252     double m_requestedStartTime { 0 };
253     double m_totalDuration { -1 };
254     double m_nextIterationDuration { -1 };
255
256     AnimationState m_animationState { AnimationState::New };
257     bool m_isAccelerated { false };
258     bool m_transformFunctionListValid { false };
259     bool m_filterFunctionListsMatch { false };
260 };
261
262 } // namespace WebCore
263
264 #endif // AnimationBase_h