1/*
2 * Copyright (C) 2013 Google 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 are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef AnimationPlayer_h
32#define AnimationPlayer_h
33
34#include "core/animation/AnimationNode.h"
35#include "core/dom/ActiveDOMObject.h"
36#include "core/events/EventTarget.h"
37#include "wtf/RefPtr.h"
38
39namespace blink {
40
41class AnimationTimeline;
42class ExceptionState;
43
44class AnimationPlayer FINAL : public RefCountedWillBeGarbageCollectedFinalized<AnimationPlayer>
45    , public ActiveDOMObject
46    , public EventTargetWithInlineData {
47    DEFINE_WRAPPERTYPEINFO();
48    REFCOUNTED_EVENT_TARGET(AnimationPlayer);
49    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AnimationPlayer);
50public:
51    enum AnimationPlayState {
52        Idle,
53        Pending,
54        Running,
55        Paused,
56        Finished
57    };
58
59    ~AnimationPlayer();
60    static PassRefPtrWillBeRawPtr<AnimationPlayer> create(ExecutionContext*, AnimationTimeline&, AnimationNode*);
61
62    // Returns whether the player is finished.
63    bool update(TimingUpdateReason);
64
65    // timeToEffectChange returns:
66    //  infinity  - if this player is no longer in effect
67    //  0         - if this player requires an update on the next frame
68    //  n         - if this player requires an update after 'n' units of time
69    double timeToEffectChange();
70
71    void cancel();
72
73    double currentTime(bool& isNull);
74    double currentTime();
75    void setCurrentTime(double newCurrentTime);
76
77    double calculateCurrentTime() const;
78    double currentTimeInternal();
79    void setCurrentTimeInternal(double newCurrentTime, TimingUpdateReason = TimingUpdateOnDemand);
80
81    bool paused() const { return m_paused && !m_isPausedForTesting; }
82    String playState();
83    AnimationPlayState playStateInternal();
84
85    void pause();
86    void play();
87    void reverse();
88    void finish(ExceptionState&);
89    bool finished() { return !m_idle && limited(currentTimeInternal()); }
90    bool playing() { return !(finished() || m_paused || m_isPausedForTesting || m_idle); }
91    // FIXME: Resolve whether finished() should just return the flag, and
92    // remove this method.
93    bool finishedInternal() const { return m_finished; }
94
95    DEFINE_ATTRIBUTE_EVENT_LISTENER(finish);
96
97    virtual const AtomicString& interfaceName() const OVERRIDE;
98    virtual ExecutionContext* executionContext() const OVERRIDE;
99    virtual bool hasPendingActivity() const OVERRIDE;
100    virtual void stop() OVERRIDE;
101    virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
102
103    double playbackRate() const;
104    void setPlaybackRate(double);
105    const AnimationTimeline* timeline() const { return m_timeline; }
106    AnimationTimeline* timeline() { return m_timeline; }
107
108#if !ENABLE(OILPAN)
109    void timelineDestroyed() { m_timeline = nullptr; }
110#endif
111
112    double calculateStartTime(double currentTime) const;
113    bool hasStartTime() const { return !isNull(m_startTime); }
114    double startTime(bool& isNull) const;
115    double startTime() const;
116    double startTimeInternal() const { return m_startTime; }
117    void setStartTime(double);
118    void setStartTimeInternal(double);
119
120    const AnimationNode* source() const { return m_content.get(); }
121    AnimationNode* source() { return m_content.get(); }
122    void setSource(AnimationNode*);
123
124    // Pausing via this method is not reflected in the value returned by
125    // paused() and must never overlap with pausing via pause().
126    void pauseForTesting(double pauseTime);
127    // This should only be used for CSS
128    void unpause();
129
130    void setOutdated();
131    bool outdated() { return m_outdated; }
132
133    bool canStartAnimationOnCompositor();
134    bool maybeStartAnimationOnCompositor();
135    void cancelAnimationOnCompositor();
136    bool hasActiveAnimationsOnCompositor();
137    void setCompositorPending(bool sourceChanged = false);
138    void notifyCompositorStartTime(double timelineTime);
139
140
141    void preCommit(bool startOnCompositor);
142    void postCommit(double timelineTime);
143
144    unsigned sequenceNumber() const { return m_sequenceNumber; }
145
146    static bool hasLowerPriority(AnimationPlayer* player1, AnimationPlayer* player2)
147    {
148        return player1->sequenceNumber() < player2->sequenceNumber();
149    }
150
151#if !ENABLE(OILPAN)
152    // Checks if the AnimationStack is the last reference holder to the Player.
153    // This won't be needed when AnimationPlayer is moved to Oilpan.
154    bool canFree() const;
155#endif
156
157    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
158
159    virtual void trace(Visitor*) OVERRIDE;
160
161private:
162    AnimationPlayer(ExecutionContext*, AnimationTimeline&, AnimationNode*);
163    double sourceEnd() const;
164    bool limited(double currentTime) const;
165    void setPlaybackRateInternal(double);
166    void updateCurrentTimingState(TimingUpdateReason);
167    void unpauseInternal();
168    void uncancel();
169    void setFinished(bool);
170
171    double m_playbackRate;
172
173    double m_startTime;
174    double m_holdTime;
175
176    unsigned m_sequenceNumber;
177
178    RefPtrWillBeMember<AnimationNode> m_content;
179    RawPtrWillBeMember<AnimationTimeline> m_timeline;
180    // Reflects all pausing, including via pauseForTesting().
181    bool m_paused;
182    bool m_held;
183    bool m_isPausedForTesting;
184
185    // This indicates timing information relevant to the player's effect
186    // has changed by means other than the ordinary progression of time
187    bool m_outdated;
188
189    bool m_finished;
190    // Holds a 'finished' event queued for asynchronous dispatch via the
191    // ScriptedAnimationController. This object remains active until the
192    // event is actually dispatched.
193    RefPtrWillBeMember<Event> m_pendingFinishedEvent;
194
195    enum CompositorAction {
196        None,
197        Pause,
198        Start,
199        PauseThenStart
200    };
201
202    class CompositorState {
203    public:
204        CompositorState(AnimationPlayer& player)
205            : startTime(player.m_startTime)
206            , holdTime(player.m_holdTime)
207            , playbackRate(player.m_playbackRate)
208            , sourceChanged(false)
209            , pendingAction(Start)
210        { }
211        double startTime;
212        double holdTime;
213        double playbackRate;
214        bool sourceChanged;
215        CompositorAction pendingAction;
216    };
217
218    // This mirrors the known compositor state. It is created when a compositor
219    // animation is started. Updated once the start time is known and each time
220    // modifications are pushed to the compositor.
221    OwnPtr<CompositorState> m_compositorState;
222    bool m_compositorPending;
223    bool m_currentTimePending;
224    bool m_idle;
225};
226
227} // namespace blink
228
229#endif
230