forked from mirrors/gecko-dev
		
	 b2d4c86823
			
		
	
	
		b2d4c86823
		
	
	
	
	
		
			
			--HG-- extra : rebase_source : 56f2cc017632bf27115490ae05254019108c6179 extra : amend_source : 98ea6c3c02a9f7650d2cf65deaf5085cf9a2efa4
		
			
				
	
	
		
			262 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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_layers_AnimationHelper_h
 | |
| #define mozilla_layers_AnimationHelper_h
 | |
| 
 | |
| #include "mozilla/dom/Nullable.h"
 | |
| #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
 | |
| #include "mozilla/layers/LayersMessages.h" // for TransformData, etc
 | |
| #include "mozilla/TimeStamp.h"          // for TimeStamp
 | |
| #include "mozilla/TimingParams.h"
 | |
| #include "X11UndefineNone.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| struct AnimationValue;
 | |
| namespace layers {
 | |
| class Animation;
 | |
| 
 | |
| typedef InfallibleTArray<layers::Animation> AnimationArray;
 | |
| 
 | |
| struct AnimData {
 | |
|   InfallibleTArray<RefPtr<RawServoAnimationValue>> mStartValues;
 | |
|   InfallibleTArray<RefPtr<RawServoAnimationValue>> mEndValues;
 | |
|   InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
 | |
|   TimingParams mTiming;
 | |
|   // These two variables correspond to the variables of the same name in
 | |
|   // KeyframeEffectReadOnly and are used for the same purpose: to skip composing
 | |
|   // animations whose progress has not changed.
 | |
|   dom::Nullable<double> mProgressOnLastCompose;
 | |
|   uint64_t mCurrentIterationOnLastCompose = 0;
 | |
|   // These two variables are used for a similar optimization above but are
 | |
|   // applied to the timing function in each keyframe.
 | |
|   uint32_t mSegmentIndexOnLastCompose = 0;
 | |
|   dom::Nullable<double> mPortionInSegmentOnLastCompose;
 | |
| };
 | |
| 
 | |
| struct AnimationTransform {
 | |
|   /*
 | |
|    * This transform is calculated from sampleanimation in device pixel
 | |
|    * and used by compositor.
 | |
|    */
 | |
|   gfx::Matrix4x4 mTransformInDevSpace;
 | |
|   /*
 | |
|    * This transform is calculated from frame and used by getOMTAStyle()
 | |
|    * for OMTA testing.
 | |
|    */
 | |
|   gfx::Matrix4x4 mFrameTransform;
 | |
|   TransformData mData;
 | |
| };
 | |
| 
 | |
| struct AnimatedValue {
 | |
|   enum {
 | |
|     TRANSFORM,
 | |
|     OPACITY,
 | |
|     NONE
 | |
|   } mType {NONE};
 | |
| 
 | |
|   union {
 | |
|     AnimationTransform mTransform;
 | |
|     float mOpacity;
 | |
|   };
 | |
| 
 | |
|   AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
 | |
|                 gfx::Matrix4x4&& aFrameTransform,
 | |
|                 const TransformData& aData)
 | |
|     : mType(AnimatedValue::TRANSFORM)
 | |
|     , mOpacity(0.0)
 | |
|   {
 | |
|     mTransform.mTransformInDevSpace = std::move(aTransformInDevSpace);
 | |
|     mTransform.mFrameTransform = std::move(aFrameTransform);
 | |
|     mTransform.mData = aData;
 | |
|   }
 | |
| 
 | |
|   explicit AnimatedValue(const float& aValue)
 | |
|     : mType(AnimatedValue::OPACITY)
 | |
|     , mOpacity(aValue)
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   ~AnimatedValue() {}
 | |
| 
 | |
| private:
 | |
|   AnimatedValue() = delete;
 | |
| };
 | |
| 
 | |
| // CompositorAnimationStorage stores the animations and animated values
 | |
| // keyed by a CompositorAnimationsId. The "animations" are a representation of
 | |
| // an entire animation over time, while the "animated values" are values sampled
 | |
| // from the animations at a particular point in time.
 | |
| //
 | |
| // There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
 | |
| // one per browser window), and the CompositorAnimationsId key is unique within
 | |
| // a particular CompositorAnimationStorage instance.
 | |
| //
 | |
| // Each layer which has animations gets a CompositorAnimationsId key, and reuses
 | |
| // that key during its lifetime. Likewise, in layers-free webrender, a display
 | |
| // item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
 | |
| // key and reuses that key (it persists the key via the frame user-data
 | |
| // mechanism).
 | |
| class CompositorAnimationStorage final
 | |
| {
 | |
|   typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
 | |
|   typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable;
 | |
| 
 | |
|   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
 | |
| public:
 | |
| 
 | |
|   /**
 | |
|    * Set the animation transform based on the unique id and also
 | |
|    * set up |aFrameTransform| and |aData| for OMTA testing
 | |
|    */
 | |
|   void SetAnimatedValue(uint64_t aId,
 | |
|                         gfx::Matrix4x4&& aTransformInDevSpace,
 | |
|                         gfx::Matrix4x4&& aFrameTransform,
 | |
|                         const TransformData& aData);
 | |
| 
 | |
|   /**
 | |
|    * Set the animation transform in device pixel based on the unique id
 | |
|    */
 | |
|   void SetAnimatedValue(uint64_t aId,
 | |
|                         gfx::Matrix4x4&& aTransformInDevSpace);
 | |
| 
 | |
|   /**
 | |
|    * Set the animation opacity based on the unique id
 | |
|    */
 | |
|   void SetAnimatedValue(uint64_t aId, const float& aOpacity);
 | |
| 
 | |
|   /**
 | |
|    * Return the animated value if a given id can map to its animated value
 | |
|    */
 | |
|   AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
 | |
| 
 | |
|   OMTAValue GetOMTAValue(const uint64_t& aId) const;
 | |
| 
 | |
|   /**
 | |
|    * Return the iterator of animated value table
 | |
|    */
 | |
|   AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const
 | |
|   {
 | |
|     return mAnimatedValues.ConstIter();
 | |
|   }
 | |
| 
 | |
|   uint32_t AnimatedValueCount() const
 | |
|   {
 | |
|     return mAnimatedValues.Count();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Set the animations based on the unique id
 | |
|    */
 | |
|   void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
 | |
| 
 | |
|   /**
 | |
|    * Return the animations if a given id can map to its animations
 | |
|    */
 | |
|   AnimationArray* GetAnimations(const uint64_t& aId) const;
 | |
| 
 | |
|   /**
 | |
|    * Return the iterator of animations table
 | |
|    */
 | |
|   AnimationsTable::Iterator ConstAnimationsTableIter() const
 | |
|   {
 | |
|     return mAnimations.ConstIter();
 | |
|   }
 | |
| 
 | |
|   uint32_t AnimationsCount() const
 | |
|   {
 | |
|     return mAnimations.Count();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Clear AnimatedValues and Animations data
 | |
|    */
 | |
|   void Clear();
 | |
|   void ClearById(const uint64_t& aId);
 | |
| 
 | |
| private:
 | |
|   ~CompositorAnimationStorage() { };
 | |
| 
 | |
| private:
 | |
|   AnimatedValueTable mAnimatedValues;
 | |
|   AnimationsTable mAnimations;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * This utility class allows reusing code between the webrender and
 | |
|  * non-webrender compositor-side implementations. It provides
 | |
|  * utility functions for sampling animations at particular timestamps.
 | |
|  */
 | |
| class AnimationHelper
 | |
| {
 | |
| public:
 | |
| 
 | |
|   enum class SampleResult {
 | |
|     None,
 | |
|     Skipped,
 | |
|     Sampled
 | |
|   };
 | |
| 
 | |
|   /**
 | |
|    * Sample animations based on a given time stamp for a element(layer) with
 | |
|    * its animation data.
 | |
|    * Generally |aPreviousFrameTimeStamp| is used for the sampling if it's
 | |
|    * supplied to make the animation more in sync with other animations on the
 | |
|    * main-thread.  But in the case where the animation just started at the time
 | |
|    * when the animation was sent to the compositor, |aCurrentTime| is used for
 | |
|    * the sampling instead to avoid flickering the animation.
 | |
|    *
 | |
|    * Returns SampleResult::None if none of the animations are producing a result
 | |
|    * (e.g. they are in the delay phase with no backwards fill),
 | |
|    * SampleResult::Skipped if the animation output did not change since the last
 | |
|    * call of this function,
 | |
|    * SampleResult::Sampled if the animation output was updated.
 | |
|    */
 | |
|   static SampleResult
 | |
|   SampleAnimationForEachNode(TimeStamp aPreviousFrameTime,
 | |
|                              TimeStamp aCurrentFrameTime,
 | |
|                              AnimationArray& aAnimations,
 | |
|                              InfallibleTArray<AnimData>& aAnimationData,
 | |
|                              RefPtr<RawServoAnimationValue>& aAnimationValue,
 | |
|                              const AnimatedValue* aPreviousValue);
 | |
|   /**
 | |
|    * Populates AnimData stuctures into |aAnimData| and |aBaseAnimationStyle|
 | |
|    * based on |aAnimations|.
 | |
|    */
 | |
|   static void
 | |
|   SetAnimations(AnimationArray& aAnimations,
 | |
|                 InfallibleTArray<AnimData>& aAnimData,
 | |
|                 RefPtr<RawServoAnimationValue>& aBaseAnimationStyle);
 | |
| 
 | |
|   /**
 | |
|    * Get a unique id to represent the compositor animation between child
 | |
|    * and parent side. This id will be used as a key to store animation
 | |
|    * data in the CompositorAnimationStorage per compositor.
 | |
|    * Each layer on the content side calls this when it gets new animation
 | |
|    * data.
 | |
|    */
 | |
|   static uint64_t GetNextCompositorAnimationsId();
 | |
| 
 | |
|   /**
 | |
|    * Sample animation based a given time stamp |aTime| and the animation
 | |
|    * data inside CompositorAnimationStorage |aStorage|. The animated values
 | |
|    * after sampling will be stored in CompositorAnimationStorage as well.
 | |
|    *
 | |
|    * Returns true if there is any animation.
 | |
|    * Note that even if there are only in-delay phase animations (i.e. not
 | |
|    * visually effective), this function returns true to ensure we composite
 | |
|    * again on the next tick.
 | |
|    */
 | |
|   static bool
 | |
|   SampleAnimations(CompositorAnimationStorage* aStorage,
 | |
|                    TimeStamp aPreviousFrameTime,
 | |
|                    TimeStamp aCurrentFrameTime);
 | |
| };
 | |
| 
 | |
| } // namespace layers
 | |
| } // namespace mozilla
 | |
| 
 | |
| #endif // mozilla_layers_AnimationHelper_h
 |