1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_PendingAnimationTracker_h
8 #define mozilla_dom_PendingAnimationTracker_h
10 #include "mozilla/dom/Animation.h"
11 #include "mozilla/dom/Document.h"
12 #include "mozilla/TypedEnumBits.h"
13 #include "nsCycleCollectionParticipant.h"
14 #include "nsTHashtable.h"
24 class PendingAnimationTracker final
{
26 explicit PendingAnimationTracker(dom::Document
* aDocument
)
27 : mDocument(aDocument
) {}
29 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PendingAnimationTracker
)
30 NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PendingAnimationTracker
)
32 void AddPlayPending(dom::Animation
& aAnimation
) {
33 // We'd like to assert here that IsWaitingToPause(aAnimation) is false but
34 // if |aAnimation| was tracked here as a pause-pending animation when it was
35 // removed from |mDocument|, then re-attached to |mDocument|, and then
36 // played again, we could end up here with IsWaitingToPause returning true.
38 // However, that should be harmless since all it means is that we'll call
39 // Animation::TriggerOnNextTick or Animation::TriggerNow twice, both of
40 // which will handle the redundant call gracefully.
41 AddPending(aAnimation
, mPlayPendingSet
);
42 mHasPlayPendingGeometricAnimations
= CheckState::Indeterminate
;
44 void RemovePlayPending(dom::Animation
& aAnimation
) {
45 RemovePending(aAnimation
, mPlayPendingSet
);
46 mHasPlayPendingGeometricAnimations
= CheckState::Indeterminate
;
48 bool IsWaitingToPlay(const dom::Animation
& aAnimation
) const {
49 return IsWaiting(aAnimation
, mPlayPendingSet
);
52 void AddPausePending(dom::Animation
& aAnimation
) {
53 // As with AddPausePending, we'd like to assert that
54 // IsWaitingToPlay(aAnimation) is false but there are some circumstances
55 // where this can be true. Fortunately adding the animation to both pending
56 // sets should be harmless.
57 AddPending(aAnimation
, mPausePendingSet
);
59 void RemovePausePending(dom::Animation
& aAnimation
) {
60 RemovePending(aAnimation
, mPausePendingSet
);
62 bool IsWaitingToPause(const dom::Animation
& aAnimation
) const {
63 return IsWaiting(aAnimation
, mPausePendingSet
);
66 void TriggerPendingAnimationsOnNextTick(const TimeStamp
& aReadyTime
);
67 void TriggerPendingAnimationsNow();
68 bool HasPendingAnimations() const {
69 return mPlayPendingSet
.Count() > 0 || mPausePendingSet
.Count() > 0;
73 * Looks amongst the set of play-pending animations, and, if there are
74 * animations that affect geometric properties, notifies all play-pending
75 * animations so that they can be synchronized, if needed.
77 void MarkAnimationsThatMightNeedSynchronization();
80 ~PendingAnimationTracker() = default;
82 void EnsurePaintIsScheduled();
84 typedef nsTHashtable
<nsRefPtrHashKey
<dom::Animation
>> AnimationSet
;
86 void AddPending(dom::Animation
& aAnimation
, AnimationSet
& aSet
);
87 void RemovePending(dom::Animation
& aAnimation
, AnimationSet
& aSet
);
88 bool IsWaiting(const dom::Animation
& aAnimation
,
89 const AnimationSet
& aSet
) const;
91 AnimationSet mPlayPendingSet
;
92 AnimationSet mPausePendingSet
;
93 RefPtr
<dom::Document
> mDocument
;
96 enum class CheckState
{
99 AnimationsPresent
= 1 << 1,
100 TransitionsPresent
= 1 << 2,
104 CheckState mHasPlayPendingGeometricAnimations
= CheckState::Indeterminate
;
107 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PendingAnimationTracker::CheckState
)
109 } // namespace mozilla
111 #endif // mozilla_dom_PendingAnimationTracker_h