LCOV - code coverage report
Current view: top level - dom/animation - EffectSet.h (source / functions) Hit Total Coverage
Test: output.info Lines: 56 63 88.9 %
Date: 2017-07-14 16:53:18 Functions: 24 27 88.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : #ifndef mozilla_EffectSet_h
       8             : #define mozilla_EffectSet_h
       9             : 
      10             : #include "mozilla/AnimValuesStyleRule.h"
      11             : #include "mozilla/DebugOnly.h"
      12             : #include "mozilla/EffectCompositor.h"
      13             : #include "mozilla/EnumeratedArray.h"
      14             : #include "mozilla/TimeStamp.h"
      15             : #include "mozilla/dom/KeyframeEffectReadOnly.h"
      16             : #include "nsHashKeys.h" // For nsPtrHashKey
      17             : #include "nsTHashtable.h" // For nsTHashtable
      18             : 
      19             : class nsPresContext;
      20             : 
      21             : namespace mozilla {
      22             : 
      23             : namespace dom {
      24             : class Element;
      25             : } // namespace dom
      26             : 
      27             : enum class CSSPseudoElementType : uint8_t;
      28             : 
      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             : {
      33             : public:
      34           2 :   EffectSet()
      35           2 :     : mCascadeNeedsUpdate(false)
      36             :     , mAnimationGeneration(0)
      37             : #ifdef DEBUG
      38             :     , mActiveIterators(0)
      39             :     , mCalledPropertyDtor(false)
      40             : #endif
      41             :     , mMayHaveOpacityAnim(false)
      42           2 :     , mMayHaveTransformAnim(false)
      43             :   {
      44           2 :     MOZ_COUNT_CTOR(EffectSet);
      45           2 :   }
      46             : 
      47           2 :   ~EffectSet()
      48           2 :   {
      49           2 :     MOZ_ASSERT(mCalledPropertyDtor,
      50             :                "must call destructor through element property dtor");
      51           2 :     MOZ_ASSERT(mActiveIterators == 0,
      52             :                "Effect set should not be destroyed while it is being "
      53             :                "enumerated");
      54           2 :     MOZ_COUNT_DTOR(EffectSet);
      55           2 :   }
      56             :   static void PropertyDtor(void* aObject, nsIAtom* aPropertyName,
      57             :                            void* aPropertyValue, void* aData);
      58             : 
      59             :   // Methods for supporting cycle-collection
      60             :   void Traverse(nsCycleCollectionTraversalCallback& aCallback);
      61             : 
      62             :   static EffectSet* GetEffectSet(const dom::Element* aElement,
      63             :                                  CSSPseudoElementType aPseudoType);
      64             :   static EffectSet* GetEffectSet(const nsIFrame* aFrame);
      65             :   static EffectSet* GetOrCreateEffectSet(dom::Element* aElement,
      66             :                                          CSSPseudoElementType aPseudoType);
      67             :   static void DestroyEffectSet(dom::Element* aElement,
      68             :                                CSSPseudoElementType aPseudoType);
      69             : 
      70             :   void AddEffect(dom::KeyframeEffectReadOnly& aEffect);
      71             :   void RemoveEffect(dom::KeyframeEffectReadOnly& aEffect);
      72             : 
      73           2 :   void SetMayHaveOpacityAnimation() { mMayHaveOpacityAnim = true; }
      74          14 :   bool MayHaveOpacityAnimation() const { return mMayHaveOpacityAnim; }
      75           0 :   void SetMayHaveTransformAnimation() { mMayHaveTransformAnim = true; }
      76          15 :   bool MayHaveTransformAnimation() const { return mMayHaveTransformAnim; }
      77             : 
      78             : private:
      79             :   typedef nsTHashtable<nsRefPtrHashKey<dom::KeyframeEffectReadOnly>>
      80             :     OwningEffectSet;
      81             : 
      82             : public:
      83             :   // A simple iterator to support iterating over the effects in this object in
      84             :   // range-based for loops.
      85             :   //
      86             :   // This allows us to avoid exposing mEffects directly and saves the
      87             :   // caller from having to dereference hashtable iterators using
      88             :   // the rather complicated: iter.Get()->GetKey().
      89             :   class Iterator
      90             :   {
      91             :   public:
      92          80 :     explicit Iterator(EffectSet& aEffectSet)
      93          80 :       : mEffectSet(aEffectSet)
      94         160 :       , mHashIterator(mozilla::Move(aEffectSet.mEffects.Iter()))
      95         240 :       , mIsEndIterator(false)
      96             :     {
      97             : #ifdef DEBUG
      98          80 :       mEffectSet.mActiveIterators++;
      99             : #endif
     100          80 :     }
     101             : 
     102             :     Iterator(Iterator&& aOther)
     103             :       : mEffectSet(aOther.mEffectSet)
     104             :       , mHashIterator(mozilla::Move(aOther.mHashIterator))
     105             :       , mIsEndIterator(aOther.mIsEndIterator)
     106             :     {
     107             : #ifdef DEBUG
     108             :       mEffectSet.mActiveIterators++;
     109             : #endif
     110             :     }
     111             : 
     112          40 :     static Iterator EndIterator(EffectSet& aEffectSet)
     113             :     {
     114          40 :       Iterator result(aEffectSet);
     115          40 :       result.mIsEndIterator = true;
     116          40 :       return result;
     117             :     }
     118             : 
     119          80 :     ~Iterator()
     120          80 :     {
     121             : #ifdef DEBUG
     122          80 :       MOZ_ASSERT(mEffectSet.mActiveIterators > 0);
     123          80 :       mEffectSet.mActiveIterators--;
     124             : #endif
     125          80 :     }
     126             : 
     127          66 :     bool operator!=(const Iterator& aOther) const {
     128          66 :       if (Done() || aOther.Done()) {
     129          66 :         return Done() != aOther.Done();
     130             :       }
     131           0 :       return mHashIterator.Get() != aOther.mHashIterator.Get();
     132             :     }
     133             : 
     134          26 :     Iterator& operator++() {
     135          26 :       MOZ_ASSERT(!Done());
     136          26 :       mHashIterator.Next();
     137          26 :       return *this;
     138             :     }
     139             : 
     140          40 :     dom::KeyframeEffectReadOnly* operator* ()
     141             :     {
     142          40 :       MOZ_ASSERT(!Done());
     143          40 :       return mHashIterator.Get()->GetKey();
     144             :     }
     145             : 
     146             :   private:
     147             :     Iterator() = delete;
     148             :     Iterator(const Iterator&) = delete;
     149             :     Iterator& operator=(const Iterator&) = delete;
     150             :     Iterator& operator=(const Iterator&&) = delete;
     151             : 
     152         304 :     bool Done() const {
     153         304 :       return mIsEndIterator || mHashIterator.Done();
     154             :     }
     155             : 
     156             :     EffectSet& mEffectSet;
     157             :     OwningEffectSet::Iterator mHashIterator;
     158             :     bool mIsEndIterator;
     159             :   };
     160             : 
     161             :   friend class Iterator;
     162             : 
     163          40 :   Iterator begin() { return Iterator(*this); }
     164          40 :   Iterator end() { return Iterator::EndIterator(*this); }
     165             : #ifdef DEBUG
     166           2 :   bool IsBeingEnumerated() const { return mActiveIterators != 0; }
     167             : #endif
     168             : 
     169          10 :   bool IsEmpty() const { return mEffects.IsEmpty(); }
     170             : 
     171          12 :   size_t Count() const { return mEffects.Count(); }
     172             : 
     173             :   RefPtr<AnimValuesStyleRule>&
     174          30 :   AnimationRule(EffectCompositor::CascadeLevel aCascadeLevel)
     175             :   {
     176          30 :     return mAnimationRule[aCascadeLevel];
     177             :   }
     178             : 
     179           0 :   const TimeStamp& LastTransformSyncTime() const
     180             :   {
     181           0 :     return mLastTransformSyncTime;
     182             :   }
     183           0 :   void UpdateLastTransformSyncTime(const TimeStamp& aRefreshTime)
     184             :   {
     185           0 :     mLastTransformSyncTime = aRefreshTime;
     186           0 :   }
     187             : 
     188          44 :   bool CascadeNeedsUpdate() const { return mCascadeNeedsUpdate; }
     189          12 :   void MarkCascadeNeedsUpdate() { mCascadeNeedsUpdate = true; }
     190           8 :   void MarkCascadeUpdated() { mCascadeNeedsUpdate = false; }
     191             : 
     192             :   void UpdateAnimationGeneration(nsPresContext* aPresContext);
     193          14 :   uint64_t GetAnimationGeneration() const { return mAnimationGeneration; }
     194             : 
     195             :   static nsIAtom** GetEffectSetPropertyAtoms();
     196             : 
     197          26 :   nsCSSPropertyIDSet& PropertiesWithImportantRules()
     198             :   {
     199          26 :     return mPropertiesWithImportantRules;
     200             :   }
     201          12 :   nsCSSPropertyIDSet& PropertiesForAnimationsLevel()
     202             :   {
     203          12 :     return mPropertiesForAnimationsLevel;
     204             :   }
     205             :   nsCSSPropertyIDSet PropertiesForAnimationsLevel() const
     206             :   {
     207             :     return mPropertiesForAnimationsLevel;
     208             :   }
     209             : 
     210             : private:
     211             :   static nsIAtom* GetEffectSetPropertyAtom(CSSPseudoElementType aPseudoType);
     212             : 
     213             :   OwningEffectSet mEffects;
     214             : 
     215             :   // These style rules contain the style data for currently animating
     216             :   // values.  They only match when styling with animation.  When we
     217             :   // style without animation, we need to not use them so that we can
     218             :   // detect any new changes; if necessary we restyle immediately
     219             :   // afterwards with animation.
     220             :   EnumeratedArray<EffectCompositor::CascadeLevel,
     221             :                   EffectCompositor::CascadeLevel(
     222             :                     EffectCompositor::kCascadeLevelCount),
     223             :                   RefPtr<AnimValuesStyleRule>> mAnimationRule;
     224             : 
     225             :   // Refresh driver timestamp from the moment when transform animations in this
     226             :   // effect set were last updated and sent to the compositor. This is used for
     227             :   // transform animations that run on the compositor but need to be updated on
     228             :   // the main thread periodically (e.g. so scrollbars can be updated).
     229             :   TimeStamp mLastTransformSyncTime;
     230             : 
     231             :   // Dirty flag to represent when the mPropertiesWithImportantRules and
     232             :   // mPropertiesForAnimationsLevel on effects in this set might need to be
     233             :   // updated.
     234             :   //
     235             :   // Set to true any time the set of effects is changed or when
     236             :   // one the effects goes in or out of the "in effect" state.
     237             :   bool mCascadeNeedsUpdate;
     238             : 
     239             :   // RestyleManager keeps track of the number of animation restyles.
     240             :   // 'mini-flushes' (see nsTransitionManager::UpdateAllThrottledStyles()).
     241             :   // mAnimationGeneration is the sequence number of the last flush where a
     242             :   // transition/animation changed.  We keep a similar count on the
     243             :   // corresponding layer so we can check that the layer is up to date with
     244             :   // the animation manager.
     245             :   uint64_t mAnimationGeneration;
     246             : 
     247             :   // Specifies the compositor-animatable properties that are overridden by
     248             :   // !important rules.
     249             :   nsCSSPropertyIDSet mPropertiesWithImportantRules;
     250             :   // Specifies the properties for which the result will be added to the
     251             :   // animations level of the cascade and hence should be skipped when we are
     252             :   // composing the animation style for the transitions level of the cascede.
     253             :   nsCSSPropertyIDSet mPropertiesForAnimationsLevel;
     254             : 
     255             : #ifdef DEBUG
     256             :   // Track how many iterators are referencing this effect set when we are
     257             :   // destroyed, we can assert that nothing is still pointing to us.
     258             :   uint64_t mActiveIterators;
     259             : 
     260             :   bool mCalledPropertyDtor;
     261             : #endif
     262             : 
     263             :   bool mMayHaveOpacityAnim;
     264             :   bool mMayHaveTransformAnim;
     265             : };
     266             : 
     267             : } // namespace mozilla
     268             : 
     269             : #endif // mozilla_EffectSet_h

Generated by: LCOV version 1.13