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_layers_CompositorAnimationStorage_h
8 #define mozilla_layers_CompositorAnimationStorage_h
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"
17 #include <unordered_map>
18 #include <unordered_set>
24 class CompositorBridgeParent
;
27 typedef nsTArray
<layers::Animation
> AnimationArray
;
29 struct AnimationTransform
{
31 * This transform is calculated from sampleanimation in device pixel
32 * and used for layers (i.e. non WebRender)
34 gfx::Matrix4x4 mTransformInDevSpace
;
36 * This transform is calculated from frame used for WebRender and used by
37 * getOMTAStyle() for OMTA testing.
39 gfx::Matrix4x4 mFrameTransform
;
43 struct AnimatedValue final
{
44 typedef Variant
<AnimationTransform
, float, nscolor
> AnimatedValueType
;
46 const AnimatedValueType
& Value() const { return mValue
; }
47 const AnimationTransform
& Transform() const {
48 return mValue
.as
<AnimationTransform
>();
50 const float& Opacity() const { return mValue
.as
<float>(); }
51 const nscolor
& Color() const { return mValue
.as
<nscolor
>(); }
54 return mValue
.is
<T
>();
57 AnimatedValue(const gfx::Matrix4x4
& aTransformInDevSpace
,
58 const gfx::Matrix4x4
& aFrameTransform
,
59 const TransformData
& aData
)
60 : mValue(AsVariant(AnimationTransform
{aTransformInDevSpace
,
61 aFrameTransform
, aData
})) {}
63 explicit AnimatedValue(const float& aValue
) : mValue(AsVariant(aValue
)) {}
65 explicit AnimatedValue(nscolor aValue
) : mValue(AsVariant(aValue
)) {}
67 void SetTransform(const gfx::Matrix4x4
& aFrameTransform
,
68 const TransformData
& aData
) {
69 MOZ_ASSERT(mValue
.is
<AnimationTransform
>());
70 AnimationTransform
& previous
= mValue
.as
<AnimationTransform
>();
71 previous
.mFrameTransform
= aFrameTransform
;
72 if (previous
.mData
!= aData
) {
73 previous
.mData
= aData
;
76 void SetOpacity(float aOpacity
) {
77 MOZ_ASSERT(mValue
.is
<float>());
78 mValue
.as
<float>() = aOpacity
;
80 void SetColor(nscolor aColor
) {
81 MOZ_ASSERT(mValue
.is
<nscolor
>());
82 mValue
.as
<nscolor
>() = aColor
;
86 AnimatedValueType mValue
;
90 nsTArray
<wr::WrOpacityProperty
> mOpacityArrays
;
91 nsTArray
<wr::WrTransformProperty
> mTransformArrays
;
92 nsTArray
<wr::WrColorProperty
> mColorArrays
;
95 // CompositorAnimationStorage stores the animations and animated values
96 // keyed by a CompositorAnimationsId. The "animations" are a representation of
97 // an entire animation over time, while the "animated values" are values sampled
98 // from the animations at a particular point in time.
100 // There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
101 // one per browser window), and the CompositorAnimationsId key is unique within
102 // a particular CompositorAnimationStorage instance.
104 // Each layer which has animations gets a CompositorAnimationsId key, and reuses
105 // that key during its lifetime. Likewise, in layers-free webrender, a display
106 // item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
107 // key and reuses that key (it persists the key via the frame user-data
109 class CompositorAnimationStorage final
{
110 typedef nsClassHashtable
<nsUint64HashKey
, AnimatedValue
> AnimatedValueTable
;
111 typedef std::unordered_map
<uint64_t, std::unique_ptr
<AnimationStorageData
>>
114 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage
)
116 explicit CompositorAnimationStorage(CompositorBridgeParent
* aCompositorBridge
)
117 : mLock("CompositorAnimationStorage::mLock"),
118 mCompositorBridge(aCompositorBridge
) {}
120 OMTAValue
GetOMTAValue(const uint64_t& aId
) const;
123 * Collect all animations in this class as WebRender type properties.
125 WrAnimations
CollectWebRenderAnimations() const;
128 * Set the animations based on the unique id
130 void SetAnimations(uint64_t aId
, const LayersId
& aLayersId
,
131 const AnimationArray
& aAnimations
);
134 * Sample animation based the given timestamps and store them in this
135 * CompositorAnimationStorage. The animated values after sampling will be
136 * stored in CompositorAnimationStorage as well.
138 * Returns true if there is any animation.
139 * Note that even if there are only in-delay phase animations (i.e. not
140 * visually effective), this function returns true to ensure we composite
141 * again on the next tick.
143 * Note: This is called only by WebRender.
145 bool SampleAnimations(const OMTAController
* aOMTAController
,
146 TimeStamp aPreviousFrameTime
,
147 TimeStamp aCurrentFrameTime
);
149 bool HasAnimations() const;
152 * Clear AnimatedValues and Animations data
154 void ClearById(const uint64_t& aId
);
157 ~CompositorAnimationStorage() = default;
160 * Return the animated value if a given id can map to its animated value
162 AnimatedValue
* GetAnimatedValue(const uint64_t& aId
) const;
165 * Set the animation transform based on the unique id and also
166 * set up |aFrameTransform| and |aData| for OMTA testing.
167 * If |aPreviousValue| is not null, the animation transform replaces the value
168 * in the |aPreviousValue|.
169 * NOTE: |aPreviousValue| should be the value for the |aId|.
171 void SetAnimatedValue(uint64_t aId
, AnimatedValue
* aPreviousValue
,
172 const gfx::Matrix4x4
& aFrameTransform
,
173 const TransformData
& aData
);
176 * Similar to above but for opacity.
178 void SetAnimatedValue(uint64_t aId
, AnimatedValue
* aPreviousValue
,
182 * Similar to above but for color.
184 void SetAnimatedValue(uint64_t aId
, AnimatedValue
* aPreviousValue
,
187 using JankedAnimationMap
=
188 std::unordered_map
<LayersId
, nsTArray
<uint64_t>, LayersId::HashFn
>;
191 * Store the animated values from |aAnimationValues|.
193 void StoreAnimatedValue(
194 nsCSSPropertyID aProperty
, uint64_t aId
,
195 const std::unique_ptr
<AnimationStorageData
>& aAnimationStorageData
,
196 const AutoTArray
<RefPtr
<StyleAnimationValue
>, 1>& aAnimationValues
,
197 const MutexAutoLock
& aProofOfMapLock
,
198 const RefPtr
<APZSampler
>& aApzSampler
, AnimatedValue
* aAnimatedValueEntry
,
199 JankedAnimationMap
& aJankedAnimationMap
);
202 AnimatedValueTable mAnimatedValues
;
203 AnimationsTable mAnimations
;
204 std::unordered_set
<uint64_t> mNewAnimations
;
205 mutable Mutex mLock MOZ_UNANNOTATED
;
206 // CompositorBridgeParent owns this CompositorAnimationStorage instance.
207 CompositorBridgeParent
* MOZ_NON_OWNING_REF mCompositorBridge
;
210 } // namespace layers
211 } // namespace mozilla
213 #endif // mozilla_layers_CompositorAnimationStorage_h