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