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 39 namespace blink { 40 41 class AnimationTimeline; 42 class ExceptionState; 43 44 class 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); 50 public: 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 161 private: 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