CompositorAnimationStorage.h (8134B)
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_layers_CompositorAnimationStorage_h 8 #define mozilla_layers_CompositorAnimationStorage_h 9 10 #include "mozilla/layers/AnimationStorageData.h" 11 #include "mozilla/layers/LayersMessages.h" // for TransformData, etc 12 #include "mozilla/webrender/webrender_ffi.h" 13 #include "mozilla/Variant.h" 14 #include "nsClassHashtable.h" 15 #include "X11UndefineNone.h" 16 #include <memory> 17 #include <unordered_map> 18 #include <unordered_set> 19 20 namespace mozilla { 21 namespace layers { 22 class APZSampler; 23 class Animation; 24 class CompositorBridgeParent; 25 class OMTAController; 26 27 using AnimationArray = nsTArray<layers::Animation>; 28 using SampledAnimationArray = AutoTArray<RefPtr<StyleAnimationValue>, 1>; 29 30 struct AnimationTransform { 31 /* 32 * This transform is calculated from frame used for WebRender and used by 33 * getOMTAStyle() for OMTA testing. 34 */ 35 gfx::Matrix4x4 mFrameTransform; 36 TransformData mData; 37 38 /* 39 * Store the previous sampled transform-like animation values. 40 * It's unfortunate we have to keep the previous sampled animation value for 41 * replacing the running transition, because we can not re-create the 42 * AnimationValues from the matrix. 43 * Note: We expect the length is one in most cases. 44 */ 45 SampledAnimationArray mAnimationValues; 46 }; 47 48 struct AnimatedValue final { 49 typedef Variant<AnimationTransform, float, nscolor> AnimatedValueType; 50 51 const AnimatedValueType& Value() const { return mValue; } 52 const AnimationTransform& Transform() const { 53 return mValue.as<AnimationTransform>(); 54 } 55 const float& Opacity() const { return mValue.as<float>(); } 56 const nscolor& Color() const { return mValue.as<nscolor>(); } 57 template <typename T> 58 bool Is() const { 59 return mValue.is<T>(); 60 } 61 62 AnimatedValue(const gfx::Matrix4x4& aFrameTransform, 63 const TransformData& aData, SampledAnimationArray&& aValue) 64 : mValue(AsVariant( 65 AnimationTransform{aFrameTransform, aData, std::move(aValue)})) {} 66 67 explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {} 68 69 explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {} 70 71 // Note: Only transforms need to store the sampled AnimationValue because it's 72 // impossible to re-create the AnimationValue from the matrix. 73 void SetTransform(const gfx::Matrix4x4& aFrameTransform, 74 const TransformData& aData, 75 SampledAnimationArray&& aValue) { 76 MOZ_ASSERT(mValue.is<AnimationTransform>()); 77 AnimationTransform& previous = mValue.as<AnimationTransform>(); 78 previous.mFrameTransform = aFrameTransform; 79 if (previous.mData != aData) { 80 previous.mData = aData; 81 } 82 previous.mAnimationValues = std::move(aValue); 83 } 84 void SetOpacity(float aOpacity) { 85 MOZ_ASSERT(mValue.is<float>()); 86 mValue.as<float>() = aOpacity; 87 } 88 void SetColor(nscolor aColor) { 89 MOZ_ASSERT(mValue.is<nscolor>()); 90 mValue.as<nscolor>() = aColor; 91 } 92 93 already_AddRefed<StyleAnimationValue> AsAnimationValue( 94 NonCustomCSSPropertyId) const; 95 96 private: 97 AnimatedValueType mValue; 98 }; 99 100 struct WrAnimations { 101 nsTArray<wr::WrOpacityProperty> mOpacityArrays; 102 nsTArray<wr::WrTransformProperty> mTransformArrays; 103 nsTArray<wr::WrColorProperty> mColorArrays; 104 }; 105 106 // CompositorAnimationStorage stores the animations and animated values 107 // keyed by a CompositorAnimationsId. The "animations" are a representation of 108 // an entire animation over time, while the "animated values" are values sampled 109 // from the animations at a particular point in time. 110 // 111 // There is one CompositorAnimationStorage per CompositorBridgeParent (i.e. 112 // one per browser window), and the CompositorAnimationsId key is unique within 113 // a particular CompositorAnimationStorage instance. 114 // 115 // Each layer which has animations gets a CompositorAnimationsId key, and reuses 116 // that key during its lifetime. Likewise, in layers-free webrender, a display 117 // item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId 118 // key and reuses that key (it persists the key via the frame user-data 119 // mechanism). 120 class CompositorAnimationStorage final { 121 typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable; 122 typedef std::unordered_map<uint64_t, std::unique_ptr<AnimationStorageData>> 123 AnimationsTable; 124 125 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage) 126 public: 127 explicit CompositorAnimationStorage(CompositorBridgeParent* aCompositorBridge) 128 : mLock("CompositorAnimationStorage::mLock"), 129 mCompositorBridge(aCompositorBridge) {} 130 131 OMTAValue GetOMTAValue(const uint64_t& aId) const; 132 133 /** 134 * Collect all animations in this class as WebRender type properties. 135 */ 136 WrAnimations CollectWebRenderAnimations() const; 137 138 /** 139 * Set the animations based on the unique id 140 */ 141 void SetAnimations(uint64_t aId, const LayersId& aLayersId, 142 const AnimationArray& aAnimations, 143 const TimeStamp& aPreviousSampleTime); 144 145 /** 146 * Sample animation based the given timestamps and store them in this 147 * CompositorAnimationStorage. The animated values after sampling will be 148 * stored in CompositorAnimationStorage as well. 149 * 150 * Returns true if there is any animation. 151 * Note that even if there are only in-delay phase animations (i.e. not 152 * visually effective), this function returns true to ensure we composite 153 * again on the next tick. 154 * 155 * Note: This is called only by WebRender. 156 */ 157 bool SampleAnimations(const OMTAController* aOMTAController, 158 TimeStamp aPreviousFrameTime, 159 TimeStamp aCurrentFrameTime); 160 161 bool HasAnimations() const; 162 163 /** 164 * Clear AnimatedValues and Animations data 165 */ 166 void ClearById(const uint64_t& aId); 167 168 /** 169 * Return the animated value if a given id can map to its animated value 170 */ 171 AnimatedValue* GetAnimatedValue(const uint64_t& aId) const; 172 173 private: 174 ~CompositorAnimationStorage() = default; 175 176 /** 177 * Set the animation transform based on the unique id and also 178 * set up |aFrameTransform| and |aData| for OMTA testing. 179 * If |aPreviousValue| is not null, the animation transform replaces the value 180 * in the |aPreviousValue|. 181 * NOTE: |aPreviousValue| should be the value for the |aId|. 182 */ 183 void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue, 184 const gfx::Matrix4x4& aFrameTransform, 185 const TransformData& aData, 186 SampledAnimationArray&& aValue); 187 188 /** 189 * Similar to above but for opacity. 190 */ 191 void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue, 192 float aOpacity); 193 194 /** 195 * Similar to above but for color. 196 */ 197 void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue, 198 nscolor aColor); 199 200 using JankedAnimationMap = 201 std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn>; 202 203 /* 204 * Store the animated values from |aAnimationValues|. 205 */ 206 void StoreAnimatedValue( 207 NonCustomCSSPropertyId aProperty, uint64_t aId, 208 const std::unique_ptr<AnimationStorageData>& aAnimationStorageData, 209 SampledAnimationArray&& aAnimationValues, 210 const MutexAutoLock& aProofOfMapLock, 211 const RefPtr<APZSampler>& aApzSampler, AnimatedValue* aAnimatedValueEntry, 212 JankedAnimationMap& aJankedAnimationMap); 213 214 private: 215 AnimatedValueTable mAnimatedValues; 216 AnimationsTable mAnimations; 217 std::unordered_set<uint64_t> mNewAnimations; 218 mutable Mutex mLock MOZ_UNANNOTATED; 219 // CompositorBridgeParent owns this CompositorAnimationStorage instance. 220 CompositorBridgeParent* MOZ_NON_OWNING_REF mCompositorBridge; 221 }; 222 223 } // namespace layers 224 } // namespace mozilla 225 226 #endif // mozilla_layers_CompositorAnimationStorage_h