Bug 1698238 return default dictionary from GetUserMediaRequest#getConstraints() if...
[gecko.git] / dom / animation / EffectSet.h
blob8073503f572c0428e719f7fd2ddf7864815d0fab
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_EffectSet_h
8 #define mozilla_EffectSet_h
10 #include "mozilla/DebugOnly.h"
11 #include "mozilla/EffectCompositor.h"
12 #include "mozilla/EnumeratedArray.h"
13 #include "mozilla/TimeStamp.h"
14 #include "mozilla/dom/KeyframeEffect.h"
15 #include "nsHashKeys.h" // For nsPtrHashKey
16 #include "nsTHashSet.h"
18 class nsPresContext;
19 enum class DisplayItemType : uint8_t;
21 namespace mozilla {
23 namespace dom {
24 class Element;
25 } // namespace dom
27 enum class PseudoStyleType : uint8_t;
29 // A wrapper around a hashset of AnimationEffect objects to handle
30 // storing the set as a property of an element.
31 class EffectSet {
32 public:
33 EffectSet()
34 : mCascadeNeedsUpdate(false),
35 mAnimationGeneration(0)
36 #ifdef DEBUG
38 mActiveIterators(0),
39 mCalledPropertyDtor(false)
40 #endif
42 mMayHaveOpacityAnim(false),
43 mMayHaveTransformAnim(false) {
44 MOZ_COUNT_CTOR(EffectSet);
47 ~EffectSet() {
48 MOZ_ASSERT(mCalledPropertyDtor,
49 "must call destructor through element property dtor");
50 MOZ_ASSERT(mActiveIterators == 0,
51 "Effect set should not be destroyed while it is being "
52 "enumerated");
53 MOZ_COUNT_DTOR(EffectSet);
55 static void PropertyDtor(void* aObject, nsAtom* aPropertyName,
56 void* aPropertyValue, void* aData);
58 // Methods for supporting cycle-collection
59 void Traverse(nsCycleCollectionTraversalCallback& aCallback);
61 static EffectSet* GetEffectSet(const dom::Element* aElement,
62 PseudoStyleType aPseudoType);
63 static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
64 PseudoStyleType aPseudoType);
66 static EffectSet* GetEffectSetForFrame(const nsIFrame* aFrame,
67 const nsCSSPropertyIDSet& aProperties);
68 static EffectSet* GetEffectSetForFrame(const nsIFrame* aFrame,
69 DisplayItemType aDisplayItemType);
70 // Gets the EffectSet associated with the specified frame's content.
72 // Typically the specified frame should be a "style frame".
74 // That is because display:table content:
76 // - makes a distinction between the primary frame and style frame,
77 // - associates the EffectSet with the style frame's content,
78 // - applies transform animations to the primary frame.
80 // In such a situation, passing in the primary frame here will return nullptr
81 // despite the fact that it has a transform animation applied to it.
83 // GetEffectSetForFrame, above, handles this by automatically looking up the
84 // EffectSet on the corresponding style frame when querying transform
85 // properties. Unless you are sure you know what you are doing, you should
86 // try using GetEffectSetForFrame first.
88 // If you decide to use this, consider documenting why you are sure it is ok
89 // to use this.
90 static EffectSet* GetEffectSetForStyleFrame(const nsIFrame* aStyleFrame);
92 static EffectSet* GetEffectSetForEffect(const dom::KeyframeEffect* aEffect);
94 static void DestroyEffectSet(dom::Element* aElement,
95 PseudoStyleType aPseudoType);
97 void AddEffect(dom::KeyframeEffect& aEffect);
98 void RemoveEffect(dom::KeyframeEffect& aEffect);
100 void SetMayHaveOpacityAnimation() { mMayHaveOpacityAnim = true; }
101 bool MayHaveOpacityAnimation() const { return mMayHaveOpacityAnim; }
102 void SetMayHaveTransformAnimation() { mMayHaveTransformAnim = true; }
103 bool MayHaveTransformAnimation() const { return mMayHaveTransformAnim; }
105 private:
106 typedef nsTHashSet<nsRefPtrHashKey<dom::KeyframeEffect>> OwningEffectSet;
108 public:
109 // A simple iterator to support iterating over the effects in this object in
110 // range-based for loops.
112 // This allows us to avoid exposing mEffects directly and saves the
113 // caller from having to dereference hashtable iterators using
114 // the rather complicated: iter.Get()->GetKey().
116 // XXX Except for the active iterator checks, this could be replaced by the
117 // STL-style iterators of nsTHashSet directly now.
118 class Iterator {
119 public:
120 explicit Iterator(EffectSet& aEffectSet)
121 : Iterator(aEffectSet, aEffectSet.mEffects.begin()) {}
123 Iterator() = delete;
124 Iterator(const Iterator&) = delete;
125 Iterator(Iterator&&) = delete;
126 Iterator& operator=(const Iterator&) = delete;
127 Iterator& operator=(Iterator&&) = delete;
129 static Iterator EndIterator(EffectSet& aEffectSet) {
130 return {aEffectSet, aEffectSet.mEffects.end()};
133 #ifdef DEBUG
134 ~Iterator() {
135 MOZ_ASSERT(mEffectSet.mActiveIterators > 0);
136 mEffectSet.mActiveIterators--;
138 #endif
140 bool operator!=(const Iterator& aOther) const {
141 return mHashIterator != aOther.mHashIterator;
144 Iterator& operator++() {
145 ++mHashIterator;
146 return *this;
149 dom::KeyframeEffect* operator*() { return *mHashIterator; }
151 private:
152 Iterator(EffectSet& aEffectSet,
153 OwningEffectSet::const_iterator aHashIterator)
155 #ifdef DEBUG
156 mEffectSet(aEffectSet),
157 #endif
158 mHashIterator(std::move(aHashIterator)) {
159 #ifdef DEBUG
160 mEffectSet.mActiveIterators++;
161 #endif
164 #ifdef DEBUG
165 EffectSet& mEffectSet;
166 #endif
167 OwningEffectSet::const_iterator mHashIterator;
170 friend class Iterator;
172 Iterator begin() { return Iterator(*this); }
173 Iterator end() { return Iterator::EndIterator(*this); }
174 #ifdef DEBUG
175 bool IsBeingEnumerated() const { return mActiveIterators != 0; }
176 #endif
178 bool IsEmpty() const { return mEffects.IsEmpty(); }
180 size_t Count() const { return mEffects.Count(); }
182 const TimeStamp& LastOverflowAnimationSyncTime() const {
183 return mLastOverflowAnimationSyncTime;
185 void UpdateLastOverflowAnimationSyncTime(const TimeStamp& aRefreshTime) {
186 mLastOverflowAnimationSyncTime = aRefreshTime;
189 bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
190 void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
191 void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
193 void UpdateAnimationGeneration(nsPresContext* aPresContext);
194 uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
196 static nsAtom** GetEffectSetPropertyAtoms();
198 const nsCSSPropertyIDSet& PropertiesWithImportantRules() const {
199 return mPropertiesWithImportantRules;
201 nsCSSPropertyIDSet& PropertiesWithImportantRules() {
202 return mPropertiesWithImportantRules;
204 nsCSSPropertyIDSet& PropertiesForAnimationsLevel() {
205 return mPropertiesForAnimationsLevel;
207 nsCSSPropertyIDSet PropertiesForAnimationsLevel() const {
208 return mPropertiesForAnimationsLevel;
211 private:
212 static nsAtom* GetEffectSetPropertyAtom(PseudoStyleType aPseudoType);
214 OwningEffectSet mEffects;
216 // Refresh driver timestamp from the moment when the animations which produce
217 // overflow change hints in this effect set were last updated.
219 // This is used for animations whose main-thread restyling is throttled either
220 // because they are running on the compositor or because they are not visible.
221 // We still need to update them on the main thread periodically, however (e.g.
222 // so scrollbars can be updated), so this tracks the last time we did that.
223 TimeStamp mLastOverflowAnimationSyncTime;
225 // Dirty flag to represent when the mPropertiesWithImportantRules and
226 // mPropertiesForAnimationsLevel on effects in this set might need to be
227 // updated.
229 // Set to true any time the set of effects is changed or when
230 // one the effects goes in or out of the "in effect" state.
231 bool mCascadeNeedsUpdate;
233 // RestyleManager keeps track of the number of animation restyles.
234 // 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
235 // mAnimationGeneration is the sequence number of the last flush where a
236 // transition/animation changed. We keep a similar count on the
237 // corresponding layer so we can check that the layer is up to date with
238 // the animation manager.
239 uint64_t mAnimationGeneration;
241 // Specifies the compositor-animatable properties that are overridden by
242 // !important rules.
243 nsCSSPropertyIDSet mPropertiesWithImportantRules;
244 // Specifies the properties for which the result will be added to the
245 // animations level of the cascade and hence should be skipped when we are
246 // composing the animation style for the transitions level of the cascede.
247 nsCSSPropertyIDSet mPropertiesForAnimationsLevel;
249 #ifdef DEBUG
250 // Track how many iterators are referencing this effect set when we are
251 // destroyed, we can assert that nothing is still pointing to us.
252 uint64_t mActiveIterators;
254 bool mCalledPropertyDtor;
255 #endif
257 bool mMayHaveOpacityAnim;
258 bool mMayHaveTransformAnim;
261 } // namespace mozilla
263 #endif // mozilla_EffectSet_h