summaryrefslogtreecommitdiffstats
path: root/dom/animation/EffectSet.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/animation/EffectSet.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/animation/EffectSet.h')
-rw-r--r--dom/animation/EffectSet.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/dom/animation/EffectSet.h b/dom/animation/EffectSet.h
new file mode 100644
index 000000000..9ba31ef91
--- /dev/null
+++ b/dom/animation/EffectSet.h
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_EffectSet_h
+#define mozilla_EffectSet_h
+
+#include "mozilla/AnimValuesStyleRule.h"
+#include "mozilla/DebugOnly.h"
+#include "mozilla/EffectCompositor.h"
+#include "mozilla/EnumeratedArray.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/dom/KeyframeEffectReadOnly.h"
+#include "nsHashKeys.h" // For nsPtrHashKey
+#include "nsTHashtable.h" // For nsTHashtable
+
+class nsPresContext;
+
+namespace mozilla {
+
+namespace dom {
+class Element;
+} // namespace dom
+
+enum class CSSPseudoElementType : uint8_t;
+
+// A wrapper around a hashset of AnimationEffect objects to handle
+// storing the set as a property of an element.
+class EffectSet
+{
+public:
+ EffectSet()
+ : mCascadeNeedsUpdate(false)
+ , mAnimationGeneration(0)
+#ifdef DEBUG
+ , mActiveIterators(0)
+ , mCalledPropertyDtor(false)
+#endif
+ {
+ MOZ_COUNT_CTOR(EffectSet);
+ }
+
+ ~EffectSet()
+ {
+ MOZ_ASSERT(mCalledPropertyDtor,
+ "must call destructor through element property dtor");
+ MOZ_ASSERT(mActiveIterators == 0,
+ "Effect set should not be destroyed while it is being "
+ "enumerated");
+ MOZ_COUNT_DTOR(EffectSet);
+ }
+ static void PropertyDtor(void* aObject, nsIAtom* aPropertyName,
+ void* aPropertyValue, void* aData);
+
+ // Methods for supporting cycle-collection
+ void Traverse(nsCycleCollectionTraversalCallback& aCallback);
+
+ static EffectSet* GetEffectSet(dom::Element* aElement,
+ CSSPseudoElementType aPseudoType);
+ static EffectSet* GetEffectSet(const nsIFrame* aFrame);
+ static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
+ CSSPseudoElementType aPseudoType);
+ static void DestroyEffectSet(dom::Element* aElement,
+ CSSPseudoElementType aPseudoType);
+
+ void AddEffect(dom::KeyframeEffectReadOnly& aEffect);
+ void RemoveEffect(dom::KeyframeEffectReadOnly& aEffect);
+
+private:
+ typedef nsTHashtable<nsRefPtrHashKey<dom::KeyframeEffectReadOnly>>
+ OwningEffectSet;
+
+public:
+ // A simple iterator to support iterating over the effects in this object in
+ // range-based for loops.
+ //
+ // This allows us to avoid exposing mEffects directly and saves the
+ // caller from having to dereference hashtable iterators using
+ // the rather complicated: iter.Get()->GetKey().
+ class Iterator
+ {
+ public:
+ explicit Iterator(EffectSet& aEffectSet)
+ : mEffectSet(aEffectSet)
+ , mHashIterator(mozilla::Move(aEffectSet.mEffects.Iter()))
+ , mIsEndIterator(false)
+ {
+#ifdef DEBUG
+ mEffectSet.mActiveIterators++;
+#endif
+ }
+
+ Iterator(Iterator&& aOther)
+ : mEffectSet(aOther.mEffectSet)
+ , mHashIterator(mozilla::Move(aOther.mHashIterator))
+ , mIsEndIterator(aOther.mIsEndIterator)
+ {
+#ifdef DEBUG
+ mEffectSet.mActiveIterators++;
+#endif
+ }
+
+ static Iterator EndIterator(EffectSet& aEffectSet)
+ {
+ Iterator result(aEffectSet);
+ result.mIsEndIterator = true;
+ return result;
+ }
+
+ ~Iterator()
+ {
+#ifdef DEBUG
+ MOZ_ASSERT(mEffectSet.mActiveIterators > 0);
+ mEffectSet.mActiveIterators--;
+#endif
+ }
+
+ bool operator!=(const Iterator& aOther) const {
+ if (Done() || aOther.Done()) {
+ return Done() != aOther.Done();
+ }
+ return mHashIterator.Get() != aOther.mHashIterator.Get();
+ }
+
+ Iterator& operator++() {
+ MOZ_ASSERT(!Done());
+ mHashIterator.Next();
+ return *this;
+ }
+
+ dom::KeyframeEffectReadOnly* operator* ()
+ {
+ MOZ_ASSERT(!Done());
+ return mHashIterator.Get()->GetKey();
+ }
+
+ private:
+ Iterator() = delete;
+ Iterator(const Iterator&) = delete;
+ Iterator& operator=(const Iterator&) = delete;
+ Iterator& operator=(const Iterator&&) = delete;
+
+ bool Done() const {
+ return mIsEndIterator || mHashIterator.Done();
+ }
+
+ EffectSet& mEffectSet;
+ OwningEffectSet::Iterator mHashIterator;
+ bool mIsEndIterator;
+ };
+
+ friend class Iterator;
+
+ Iterator begin() { return Iterator(*this); }
+ Iterator end() { return Iterator::EndIterator(*this); }
+#ifdef DEBUG
+ bool IsBeingEnumerated() const { return mActiveIterators != 0; }
+#endif
+
+ bool IsEmpty() const { return mEffects.IsEmpty(); }
+
+ size_t Count() const { return mEffects.Count(); }
+
+ RefPtr<AnimValuesStyleRule>& AnimationRule(EffectCompositor::CascadeLevel
+ aCascadeLevel)
+ {
+ return mAnimationRule[aCascadeLevel];
+ }
+
+ const TimeStamp& AnimationRuleRefreshTime(EffectCompositor::CascadeLevel
+ aCascadeLevel) const
+ {
+ return mAnimationRuleRefreshTime[aCascadeLevel];
+ }
+ void UpdateAnimationRuleRefreshTime(EffectCompositor::CascadeLevel
+ aCascadeLevel,
+ const TimeStamp& aRefreshTime)
+ {
+ mAnimationRuleRefreshTime[aCascadeLevel] = aRefreshTime;
+ }
+
+ bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
+ void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
+ void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
+
+ void UpdateAnimationGeneration(nsPresContext* aPresContext);
+ uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
+
+ static nsIAtom** GetEffectSetPropertyAtoms();
+
+ nsCSSPropertyIDSet& PropertiesWithImportantRules()
+ {
+ return mPropertiesWithImportantRules;
+ }
+ nsCSSPropertyIDSet& PropertiesForAnimationsLevel()
+ {
+ return mPropertiesForAnimationsLevel;
+ }
+
+private:
+ static nsIAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType);
+
+ OwningEffectSet mEffects;
+
+ // These style rules contain the style data for currently animating
+ // values. They only match when styling with animation. When we
+ // style without animation, we need to not use them so that we can
+ // detect any new changes; if necessary we restyle immediately
+ // afterwards with animation.
+ EnumeratedArray<EffectCompositor::CascadeLevel,
+ EffectCompositor::CascadeLevel(
+ EffectCompositor::kCascadeLevelCount),
+ RefPtr<AnimValuesStyleRule>> mAnimationRule;
+
+ // A parallel array to mAnimationRule that records the refresh driver
+ // timestamp when the rule was last updated. This is used for certain
+ // animations which are updated only periodically (e.g. transform animations
+ // running on the compositor that affect the scrollable overflow region).
+ EnumeratedArray<EffectCompositor::CascadeLevel,
+ EffectCompositor::CascadeLevel(
+ EffectCompositor::kCascadeLevelCount),
+ TimeStamp> mAnimationRuleRefreshTime;
+
+ // Dirty flag to represent when the mPropertiesWithImportantRules and
+ // mPropertiesForAnimationsLevel on effects in this set might need to be
+ // updated.
+ //
+ // Set to true any time the set of effects is changed or when
+ // one the effects goes in or out of the "in effect" state.
+ bool mCascadeNeedsUpdate;
+
+ // RestyleManager keeps track of the number of animation restyles.
+ // 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
+ // mAnimationGeneration is the sequence number of the last flush where a
+ // transition/animation changed. We keep a similar count on the
+ // corresponding layer so we can check that the layer is up to date with
+ // the animation manager.
+ uint64_t mAnimationGeneration;
+
+ // Specifies the compositor-animatable properties that are overridden by
+ // !important rules.
+ nsCSSPropertyIDSet mPropertiesWithImportantRules;
+ // Specifies the properties for which the result will be added to the
+ // animations level of the cascade and hence should be skipped when we are
+ // composing the animation style for the transitions level of the cascede.
+ nsCSSPropertyIDSet mPropertiesForAnimationsLevel;
+
+#ifdef DEBUG
+ // Track how many iterators are referencing this effect set when we are
+ // destroyed, we can assert that nothing is still pointing to us.
+ uint64_t mActiveIterators;
+
+ bool mCalledPropertyDtor;
+#endif
+};
+
+} // namespace mozilla
+
+#endif // mozilla_EffectSet_h