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"
19 enum class DisplayItemType
: uint8_t;
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.
34 : mCascadeNeedsUpdate(false),
35 mAnimationGeneration(0)
39 mCalledPropertyDtor(false)
42 mMayHaveOpacityAnim(false),
43 mMayHaveTransformAnim(false) {
44 MOZ_COUNT_CTOR(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 "
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
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
; }
106 typedef nsTHashSet
<nsRefPtrHashKey
<dom::KeyframeEffect
>> OwningEffectSet
;
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.
120 explicit Iterator(EffectSet
& aEffectSet
)
121 : Iterator(aEffectSet
, aEffectSet
.mEffects
.begin()) {}
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()};
135 MOZ_ASSERT(mEffectSet
.mActiveIterators
> 0);
136 mEffectSet
.mActiveIterators
--;
140 bool operator!=(const Iterator
& aOther
) const {
141 return mHashIterator
!= aOther
.mHashIterator
;
144 Iterator
& operator++() {
149 dom::KeyframeEffect
* operator*() { return *mHashIterator
; }
152 Iterator(EffectSet
& aEffectSet
,
153 OwningEffectSet::const_iterator aHashIterator
)
156 mEffectSet(aEffectSet
),
158 mHashIterator(std::move(aHashIterator
)) {
160 mEffectSet
.mActiveIterators
++;
165 EffectSet
& mEffectSet
;
167 OwningEffectSet::const_iterator mHashIterator
;
170 friend class Iterator
;
172 Iterator
begin() { return Iterator(*this); }
173 Iterator
end() { return Iterator::EndIterator(*this); }
175 bool IsBeingEnumerated() const { return mActiveIterators
!= 0; }
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
;
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
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
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
;
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
;
257 bool mMayHaveOpacityAnim
;
258 bool mMayHaveTransformAnim
;
261 } // namespace mozilla
263 #endif // mozilla_EffectSet_h