Backed out 2 changesets (bug 1539720) for causing caret related failures. CLOSED...
[gecko.git] / dom / animation / EffectSet.h
blobc7436767940446c9472278d31e80b67bb69a384b
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 mMayHaveOpacityAnim(false),
36 mMayHaveTransformAnim(false) {
37 MOZ_COUNT_CTOR(EffectSet);
40 ~EffectSet() {
41 MOZ_ASSERT(!IsBeingEnumerated(),
42 "Effect set should not be destroyed while it is being "
43 "enumerated");
44 MOZ_COUNT_DTOR(EffectSet);
47 // Methods for supporting cycle-collection
48 void Traverse(nsCycleCollectionTraversalCallback& aCallback);
50 static EffectSet* Get(const dom::Element* aElement,
51 PseudoStyleType aPseudoType);
52 static EffectSet* GetOrCreate(dom::Element* aElement,
53 PseudoStyleType aPseudoType);
55 static EffectSet* GetForFrame(const nsIFrame* aFrame,
56 const nsCSSPropertyIDSet& aProperties);
57 static EffectSet* GetForFrame(const nsIFrame* aFrame,
58 DisplayItemType aDisplayItemType);
59 // Gets the EffectSet associated with the specified frame's content.
61 // Typically the specified frame should be a "style frame".
63 // That is because display:table content:
65 // - makes a distinction between the primary frame and style frame,
66 // - associates the EffectSet with the style frame's content,
67 // - applies transform animations to the primary frame.
69 // In such a situation, passing in the primary frame here will return nullptr
70 // despite the fact that it has a transform animation applied to it.
72 // GetForFrame, above, handles this by automatically looking up the
73 // EffectSet on the corresponding style frame when querying transform
74 // properties. Unless you are sure you know what you are doing, you should
75 // try using GetForFrame first.
77 // If you decide to use this, consider documenting why you are sure it is ok
78 // to use this.
79 static EffectSet* GetForStyleFrame(const nsIFrame* aStyleFrame);
81 static EffectSet* GetForEffect(const dom::KeyframeEffect* aEffect);
83 static void DestroyEffectSet(dom::Element* aElement,
84 PseudoStyleType aPseudoType);
86 void AddEffect(dom::KeyframeEffect& aEffect);
87 void RemoveEffect(dom::KeyframeEffect& aEffect);
89 void SetMayHaveOpacityAnimation() { mMayHaveOpacityAnim = true; }
90 bool MayHaveOpacityAnimation() const { return mMayHaveOpacityAnim; }
91 void SetMayHaveTransformAnimation() { mMayHaveTransformAnim = true; }
92 bool MayHaveTransformAnimation() const { return mMayHaveTransformAnim; }
94 private:
95 using OwningEffectSet = nsTHashSet<nsRefPtrHashKey<dom::KeyframeEffect>>;
97 public:
98 // A simple iterator to support iterating over the effects in this object in
99 // range-based for loops.
101 // This allows us to avoid exposing mEffects directly and saves the
102 // caller from having to dereference hashtable iterators using
103 // the rather complicated: iter.Get()->GetKey().
105 // XXX Except for the active iterator checks, this could be replaced by the
106 // STL-style iterators of nsTHashSet directly now.
107 class Iterator {
108 public:
109 explicit Iterator(EffectSet& aEffectSet)
110 : Iterator(aEffectSet, aEffectSet.mEffects.begin()) {}
112 Iterator() = delete;
113 Iterator(const Iterator&) = delete;
114 Iterator(Iterator&&) = delete;
115 Iterator& operator=(const Iterator&) = delete;
116 Iterator& operator=(Iterator&&) = delete;
118 static Iterator EndIterator(EffectSet& aEffectSet) {
119 return {aEffectSet, aEffectSet.mEffects.end()};
122 #ifdef DEBUG
123 ~Iterator() {
124 MOZ_ASSERT(mEffectSet.mActiveIterators > 0);
125 mEffectSet.mActiveIterators--;
127 #endif
129 bool operator!=(const Iterator& aOther) const {
130 return mHashIterator != aOther.mHashIterator;
133 Iterator& operator++() {
134 ++mHashIterator;
135 return *this;
138 dom::KeyframeEffect* operator*() { return *mHashIterator; }
140 private:
141 Iterator(EffectSet& aEffectSet,
142 OwningEffectSet::const_iterator aHashIterator)
144 #ifdef DEBUG
145 mEffectSet(aEffectSet),
146 #endif
147 mHashIterator(std::move(aHashIterator)) {
148 #ifdef DEBUG
149 mEffectSet.mActiveIterators++;
150 #endif
153 #ifdef DEBUG
154 EffectSet& mEffectSet;
155 #endif
156 OwningEffectSet::const_iterator mHashIterator;
159 friend class Iterator;
161 Iterator begin() { return Iterator(*this); }
162 Iterator end() { return Iterator::EndIterator(*this); }
163 #ifdef DEBUG
164 bool IsBeingEnumerated() const { return mActiveIterators != 0; }
165 #endif
167 bool IsEmpty() const { return mEffects.IsEmpty(); }
169 size_t Count() const { return mEffects.Count(); }
171 const TimeStamp& LastOverflowAnimationSyncTime() const {
172 return mLastOverflowAnimationSyncTime;
174 void UpdateLastOverflowAnimationSyncTime(const TimeStamp& aRefreshTime) {
175 mLastOverflowAnimationSyncTime = aRefreshTime;
178 bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
179 void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
180 void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
182 void UpdateAnimationGeneration(nsPresContext* aPresContext);
183 uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
185 const nsCSSPropertyIDSet& PropertiesWithImportantRules() const {
186 return mPropertiesWithImportantRules;
188 nsCSSPropertyIDSet& PropertiesWithImportantRules() {
189 return mPropertiesWithImportantRules;
191 nsCSSPropertyIDSet PropertiesForAnimationsLevel() const {
192 return mPropertiesForAnimationsLevel;
194 nsCSSPropertyIDSet& PropertiesForAnimationsLevel() {
195 return mPropertiesForAnimationsLevel;
198 private:
199 OwningEffectSet mEffects;
201 // Refresh driver timestamp from the moment when the animations which produce
202 // overflow change hints in this effect set were last updated.
204 // This is used for animations whose main-thread restyling is throttled either
205 // because they are running on the compositor or because they are not visible.
206 // We still need to update them on the main thread periodically, however (e.g.
207 // so scrollbars can be updated), so this tracks the last time we did that.
208 TimeStamp mLastOverflowAnimationSyncTime;
210 // RestyleManager keeps track of the number of animation restyles.
211 // 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
212 // mAnimationGeneration is the sequence number of the last flush where a
213 // transition/animation changed. We keep a similar count on the
214 // corresponding layer so we can check that the layer is up to date with
215 // the animation manager.
216 uint64_t mAnimationGeneration = 0;
218 // Specifies the compositor-animatable properties that are overridden by
219 // !important rules.
220 nsCSSPropertyIDSet mPropertiesWithImportantRules;
221 // Specifies the properties for which the result will be added to the
222 // animations level of the cascade and hence should be skipped when we are
223 // composing the animation style for the transitions level of the cascede.
224 nsCSSPropertyIDSet mPropertiesForAnimationsLevel;
226 #ifdef DEBUG
227 // Track how many iterators are referencing this effect set when we are
228 // destroyed, we can assert that nothing is still pointing to us.
229 uint64_t mActiveIterators = 0;
230 #endif
232 // Dirty flag to represent when the mPropertiesWithImportantRules and
233 // mPropertiesForAnimationsLevel on effects in this set might need to be
234 // updated.
236 // Set to true any time the set of effects is changed or when
237 // one the effects goes in or out of the "in effect" state.
238 bool mCascadeNeedsUpdate = false;
240 bool mMayHaveOpacityAnim = false;
241 bool mMayHaveTransformAnim = false;
244 } // namespace mozilla
246 #endif // mozilla_EffectSet_h