Bug 1634779 - pt 2. Partially revert Bug 1603006 r=kmag
[gecko.git] / dom / animation / PendingAnimationTracker.h
blobf91810aaffa26abcd64b30f0399d2cd1a215b211
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"
16 class nsIFrame;
18 namespace mozilla {
20 namespace dom {
21 class Document;
24 class PendingAnimationTracker final {
25 public:
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;
72 /**
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();
79 private:
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;
95 public:
96 enum class CheckState {
97 Indeterminate = 0,
98 Absent = 1 << 0,
99 AnimationsPresent = 1 << 1,
100 TransitionsPresent = 1 << 2,
103 private:
104 CheckState mHasPlayPendingGeometricAnimations = CheckState::Indeterminate;
107 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PendingAnimationTracker::CheckState)
109 } // namespace mozilla
111 #endif // mozilla_dom_PendingAnimationTracker_h