Index: Source/core/animation/Animation.h |
diff --git a/Source/core/animation/Animation.h b/Source/core/animation/Animation.h |
index 3f8937196673096f8227cd98ddb856eafc8197c5..9433247fc0d0123e040addddd974c88df979471b 100644 |
--- a/Source/core/animation/Animation.h |
+++ b/Source/core/animation/Animation.h |
@@ -31,92 +31,257 @@ |
#ifndef Animation_h |
#define Animation_h |
+#include "bindings/core/v8/ScriptPromise.h" |
+#include "bindings/core/v8/ScriptPromiseProperty.h" |
+#include "core/CSSPropertyNames.h" |
#include "core/CoreExport.h" |
#include "core/animation/AnimationEffect.h" |
-#include "core/animation/AnimationNode.h" |
-#include "core/animation/EffectInput.h" |
-#include "core/animation/TimingInput.h" |
+#include "core/dom/ActiveDOMObject.h" |
+#include "core/dom/DOMException.h" |
+#include "core/events/EventTarget.h" |
#include "platform/heap/Handle.h" |
+#include "public/platform/WebCompositorAnimationDelegate.h" |
+#include "public/platform/WebCompositorAnimationPlayerClient.h" |
#include "wtf/RefPtr.h" |
namespace blink { |
-class AnimationTimingProperties; |
-class Dictionary; |
+class AnimationTimeline; |
class Element; |
class ExceptionState; |
-class PropertyHandle; |
-class SampledEffect; |
+class WebCompositorAnimationPlayer; |
-class CORE_EXPORT Animation final : public AnimationNode { |
+class CORE_EXPORT Animation final |
+ : public EventTargetWithInlineData |
+ , public RefCountedWillBeNoBase<Animation> |
+ , public ActiveDOMObject |
+ , public WebCompositorAnimationDelegate |
+ , public WebCompositorAnimationPlayerClient { |
DEFINE_WRAPPERTYPEINFO(); |
+ REFCOUNTED_EVENT_TARGET(Animation); |
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Animation); |
public: |
- enum Priority { DefaultPriority, TransitionPriority }; |
+ enum AnimationPlayState { |
+ Idle, |
+ Pending, |
+ Running, |
+ Paused, |
+ Finished |
+ }; |
- static PassRefPtrWillBeRawPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority = DefaultPriority, PassOwnPtrWillBeRawPtr<EventDelegate> = nullptr); |
- // Web Animations API Bindings constructors. |
- static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, double duration, ExceptionState&); |
- static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, const AnimationTimingProperties& timingInput, ExceptionState&); |
- static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState&); |
+ ~Animation(); |
+ static PassRefPtrWillBeRawPtr<Animation> create(AnimationEffect*, AnimationTimeline*); |
- virtual ~Animation(); |
+ // Returns whether the animation is finished. |
+ bool update(TimingUpdateReason); |
- virtual bool isAnimation() const override { return true; } |
+ // timeToEffectChange returns: |
+ // infinity - if this animation is no longer in effect |
+ // 0 - if this animation requires an update on the next frame |
+ // n - if this animation requires an update after 'n' units of time |
+ double timeToEffectChange(); |
- bool affects(PropertyHandle) const; |
- const AnimationEffect* effect() const { return m_effect.get(); } |
- AnimationEffect* effect() { return m_effect.get(); } |
- void setEffect(PassRefPtrWillBeRawPtr<AnimationEffect> effect) { m_effect = effect; } |
- Priority priority() const { return m_priority; } |
- Element* target() const { return m_target; } |
+ void cancel(); |
+ |
+ double currentTime(bool& isNull); |
+ double currentTime(); |
+ void setCurrentTime(double newCurrentTime); |
+ |
+ double currentTimeInternal() const; |
+ double unlimitedCurrentTimeInternal() const; |
+ |
+ void setCurrentTimeInternal(double newCurrentTime, TimingUpdateReason = TimingUpdateOnDemand); |
+ bool paused() const { return m_paused && !m_isPausedForTesting; } |
+ static const char* playStateString(AnimationPlayState); |
+ String playState() const { return playStateString(playStateInternal()); } |
+ AnimationPlayState playStateInternal() const; |
+ |
+ void pause(); |
+ void play(); |
+ void reverse(); |
+ void finish(ExceptionState&); |
+ |
+ ScriptPromise finished(ScriptState*); |
+ ScriptPromise ready(ScriptState*); |
+ |
+ bool playing() const { return !(playStateInternal() == Idle || limited() || m_paused || m_isPausedForTesting); } |
+ bool limited() const { return limited(currentTimeInternal()); } |
+ bool finishedInternal() const { return m_finished; } |
+ |
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(finish); |
+ |
+ virtual const AtomicString& interfaceName() const override; |
+ virtual ExecutionContext* executionContext() const override; |
+ virtual bool hasPendingActivity() const override; |
+ virtual void stop() override; |
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) override; |
+ |
+ double playbackRate() const; |
+ void setPlaybackRate(double); |
+ const AnimationTimeline* timeline() const { return m_timeline; } |
+ AnimationTimeline* timeline() { return m_timeline; } |
#if !ENABLE(OILPAN) |
- void notifyElementDestroyed(); |
+ void detachFromTimeline(); |
#endif |
- bool isCandidateForAnimationOnCompositor(double playerPlaybackRate) const; |
- // Must only be called once. |
- bool maybeStartAnimationOnCompositor(int group, double startTime, double timeOffset, double playerPlaybackRate); |
- bool hasActiveAnimationsOnCompositor() const; |
- bool hasActiveAnimationsOnCompositor(CSSPropertyID) const; |
- bool cancelAnimationOnCompositor(); |
+ double calculateStartTime(double currentTime) const; |
+ bool hasStartTime() const { return !isNull(m_startTime); } |
+ double startTime(bool& isNull) const; |
+ double startTime() const; |
+ double startTimeInternal() const { return m_startTime; } |
+ void setStartTime(double); |
+ void setStartTimeInternal(double); |
+ |
+ const AnimationEffect* source() const { return m_content.get(); } |
+ AnimationEffect* source() { return m_content.get(); } |
+ void setSource(AnimationEffect*); |
+ |
+ // Pausing via this method is not reflected in the value returned by |
+ // paused() and must never overlap with pausing via pause(). |
+ void pauseForTesting(double pauseTime); |
+ // This should only be used for CSS |
+ void unpause(); |
+ |
+ void setOutdated(); |
+ bool outdated() { return m_outdated; } |
+ |
+ bool canStartAnimationOnCompositor() const; |
+ bool isCandidateForAnimationOnCompositor() const; |
+ bool maybeStartAnimationOnCompositor(); |
+ void cancelAnimationOnCompositor(); |
void restartAnimationOnCompositor(); |
void cancelIncompatibleAnimationsOnCompositor(); |
- void pauseAnimationForTestingOnCompositor(double pauseTime); |
+ bool hasActiveAnimationsOnCompositor(); |
+ void setCompositorPending(bool sourceChanged = false); |
+ void notifyCompositorStartTime(double timelineTime); |
+ void notifyStartTime(double timelineTime); |
+ // WebCompositorAnimationPlayerClient implementation. |
+ WebCompositorAnimationPlayer* compositorPlayer() const override { return m_compositorPlayer.get(); } |
- bool canAttachCompositedLayers() const; |
- void attachCompositedLayers(); |
+ bool affects(const Element&, CSSPropertyID) const; |
- void setCompositorAnimationIdsForTesting(const Vector<int>& compositorAnimationIds) { m_compositorAnimationIds = compositorAnimationIds; } |
+ void preCommit(int compositorGroup, bool startOnCompositor); |
+ void postCommit(double timelineTime); |
- DECLARE_VIRTUAL_TRACE(); |
+ unsigned sequenceNumber() const { return m_sequenceNumber; } |
+ int compositorGroup() const { return m_compositorGroup; } |
- void downgradeToNormalAnimation() { m_priority = DefaultPriority; } |
+ static bool hasLowerPriority(const Animation* animation1, const Animation* animation2) |
+ { |
+ return animation1->sequenceNumber() < animation2->sequenceNumber(); |
+ } |
-protected: |
- void applyEffects(); |
- void clearEffects(); |
- virtual void updateChildrenAndEffects() const override; |
- virtual void attach(AnimationPlayer*) override; |
- virtual void detach() override; |
- virtual void specifiedTimingChanged() override; |
- virtual double calculateTimeToEffectChange(bool forwards, double inheritedTime, double timeToNextIteration) const override; |
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) override; |
+ |
+ DECLARE_VIRTUAL_TRACE(); |
private: |
- Animation(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority, PassOwnPtrWillBeRawPtr<EventDelegate>); |
+ Animation(ExecutionContext*, AnimationTimeline&, AnimationEffect*); |
- RawPtrWillBeMember<Element> m_target; |
- RefPtrWillBeMember<AnimationEffect> m_effect; |
- RawPtrWillBeMember<SampledEffect> m_sampledEffect; |
+ double sourceEnd() const; |
+ bool limited(double currentTime) const; |
- Priority m_priority; |
+ AnimationPlayState calculatePlayState(); |
+ double calculateCurrentTime() const; |
- Vector<int> m_compositorAnimationIds; |
+ void unpauseInternal(); |
+ void setPlaybackRateInternal(double); |
+ void updateCurrentTimingState(TimingUpdateReason); |
- friend class AnimationAnimationV8Test; |
-}; |
+ void beginUpdatingState(); |
+ void endUpdatingState(); |
+ |
+ void createCompositorPlayer(); |
+ void destroyCompositorPlayer(); |
+ void attachCompositorTimeline(); |
+ void detachCompositorTimeline(); |
+ void attachCompositedLayers(); |
+ void detachCompositedLayers(); |
+ // WebCompositorAnimationDelegate implementation. |
+ void notifyAnimationStarted(double monotonicTime, int group) override; |
+ void notifyAnimationFinished(double monotonicTime, int group) override { } |
+ |
+ AnimationPlayState m_playState; |
+ double m_playbackRate; |
+ double m_startTime; |
+ double m_holdTime; |
+ |
+ unsigned m_sequenceNumber; |
+ |
+ typedef ScriptPromiseProperty<RawPtrWillBeMember<Animation>, RawPtrWillBeMember<Animation>, Member<DOMException>> AnimationPromise; |
+ PersistentWillBeMember<AnimationPromise> m_finishedPromise; |
+ PersistentWillBeMember<AnimationPromise> m_readyPromise; |
+ |
+ RefPtrWillBeMember<AnimationEffect> m_content; |
+ RawPtrWillBeMember<AnimationTimeline> m_timeline; |
+ // Reflects all pausing, including via pauseForTesting(). |
+ bool m_paused; |
+ bool m_held; |
+ bool m_isPausedForTesting; |
+ |
+ // This indicates timing information relevant to the animation's effect |
+ // has changed by means other than the ordinary progression of time |
+ bool m_outdated; |
-DEFINE_TYPE_CASTS(Animation, AnimationNode, animationNode, animationNode->isAnimation(), animationNode.isAnimation()); |
+ bool m_finished; |
+ // Holds a 'finished' event queued for asynchronous dispatch via the |
+ // ScriptedAnimationController. This object remains active until the |
+ // event is actually dispatched. |
+ RefPtrWillBeMember<Event> m_pendingFinishedEvent; |
+ |
+ enum CompositorAction { |
+ None, |
+ Pause, |
+ Start, |
+ PauseThenStart |
+ }; |
+ |
+ class CompositorState { |
+ public: |
+ CompositorState(Animation& animation) |
+ : startTime(animation.m_startTime) |
+ , holdTime(animation.m_holdTime) |
+ , playbackRate(animation.m_playbackRate) |
+ , sourceChanged(false) |
+ , pendingAction(Start) |
+ { } |
+ double startTime; |
+ double holdTime; |
+ double playbackRate; |
+ bool sourceChanged; |
+ CompositorAction pendingAction; |
+ }; |
+ |
+ enum CompositorPendingChange { |
+ SetCompositorPending, |
+ SetCompositorPendingWithSourceChanged, |
+ DoNotSetCompositorPending, |
+ }; |
+ |
+ class PlayStateUpdateScope { |
+ STACK_ALLOCATED(); |
+ public: |
+ PlayStateUpdateScope(Animation&, TimingUpdateReason, CompositorPendingChange = SetCompositorPending); |
+ ~PlayStateUpdateScope(); |
+ private: |
+ RawPtrWillBeMember<Animation> m_animation; |
+ AnimationPlayState m_initialPlayState; |
+ CompositorPendingChange m_compositorPendingChange; |
+ }; |
+ |
+ // This mirrors the known compositor state. It is created when a compositor |
+ // animation is started. Updated once the start time is known and each time |
+ // modifications are pushed to the compositor. |
+ OwnPtr<CompositorState> m_compositorState; |
+ bool m_compositorPending; |
+ int m_compositorGroup; |
+ |
+ OwnPtr<WebCompositorAnimationPlayer> m_compositorPlayer; |
+ |
+ bool m_currentTimePending; |
+ bool m_stateIsBeingUpdated; |
+}; |
} // namespace blink |