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_layers_AnimationHelper_h
8 : #define mozilla_layers_AnimationHelper_h
9 :
10 : #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
11 : #include "mozilla/layers/LayersMessages.h" // for TransformData, etc
12 : #include "mozilla/TimeStamp.h" // for TimeStamp
13 :
14 :
15 : namespace mozilla {
16 : class StyleAnimationValue;
17 : namespace layers {
18 : class Animation;
19 :
20 : typedef InfallibleTArray<layers::Animation> AnimationArray;
21 :
22 0 : struct AnimData {
23 : InfallibleTArray<mozilla::StyleAnimationValue> mStartValues;
24 : InfallibleTArray<mozilla::StyleAnimationValue> mEndValues;
25 : InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
26 : };
27 :
28 : struct AnimationTransform {
29 : /*
30 : * This transform is calculated from sampleanimation in device pixel
31 : * and used by compositor.
32 : */
33 : gfx::Matrix4x4 mTransformInDevSpace;
34 : /*
35 : * This transform is calculated from frame and used by getOMTAStyle()
36 : * for OMTA testing.
37 : */
38 : gfx::Matrix4x4 mFrameTransform;
39 : TransformData mData;
40 : };
41 :
42 : struct AnimatedValue {
43 : enum {
44 : TRANSFORM,
45 : OPACITY,
46 : NONE
47 : } mType {NONE};
48 :
49 : union {
50 : AnimationTransform mTransform;
51 : float mOpacity;
52 : };
53 :
54 0 : AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
55 : gfx::Matrix4x4&& aFrameTransform,
56 : const TransformData& aData)
57 0 : : mType(AnimatedValue::TRANSFORM)
58 : {
59 0 : mTransform.mTransformInDevSpace = Move(aTransformInDevSpace);
60 0 : mTransform.mFrameTransform = Move(aFrameTransform);
61 0 : mTransform.mData = aData;
62 0 : }
63 :
64 0 : explicit AnimatedValue(const float& aValue)
65 0 : : mType(AnimatedValue::OPACITY)
66 0 : , mOpacity(aValue)
67 : {
68 0 : }
69 :
70 0 : ~AnimatedValue() {}
71 :
72 : private:
73 : AnimatedValue() = delete;
74 : };
75 :
76 : // CompositorAnimationStorage stores the layer animations and animated value
77 : // after sampling based on an unique id (CompositorAnimationsId)
78 1 : class CompositorAnimationStorage final
79 : {
80 : typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
81 : typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable;
82 :
83 3 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
84 : public:
85 :
86 : /**
87 : * Set the animation transform based on the unique id and also
88 : * set up |aFrameTransform| and |aData| for OMTA testing
89 : */
90 : void SetAnimatedValue(uint64_t aId,
91 : gfx::Matrix4x4&& aTransformInDevSpace,
92 : gfx::Matrix4x4&& aFrameTransform,
93 : const TransformData& aData);
94 :
95 : /**
96 : * Set the animation transform in device pixel based on the unique id
97 : */
98 : void SetAnimatedValue(uint64_t aId,
99 : gfx::Matrix4x4&& aTransformInDevSpace);
100 :
101 : /**
102 : * Set the animation opacity based on the unique id
103 : */
104 : void SetAnimatedValue(uint64_t aId, const float& aOpacity);
105 :
106 : /**
107 : * Return the animated value if a given id can map to its animated value
108 : */
109 : AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
110 :
111 : /**
112 : * Like GetAnimatedValue(), but ensures the value is an opacity and returns
113 : * the float value if possible, or Nothing() otherwise.
114 : */
115 : Maybe<float> GetAnimationOpacity(const uint64_t& aId) const;
116 :
117 : /**
118 : * Like GetAnimatedValue(), but ensures the value is a transform and returns
119 : * the transform matrix if possible, or Nothing() otherwise. It also does
120 : * some post-processing on the transform matrix as well. See the comments
121 : * inside the function for details.
122 : */
123 : Maybe<gfx::Matrix4x4> GetAnimationTransform(const uint64_t& aId) const;
124 :
125 : /**
126 : * Return the iterator of animated value table
127 : */
128 0 : AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const
129 : {
130 0 : return mAnimatedValues.ConstIter();
131 : }
132 :
133 0 : uint32_t AnimatedValueCount() const
134 : {
135 0 : return mAnimatedValues.Count();
136 : }
137 :
138 : /**
139 : * Set the animations based on the unique id
140 : */
141 : void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
142 :
143 : /**
144 : * Return the animations if a given id can map to its animations
145 : */
146 : AnimationArray* GetAnimations(const uint64_t& aId) const;
147 :
148 : /**
149 : * Return the iterator of animations table
150 : */
151 0 : AnimationsTable::Iterator ConstAnimationsTableIter() const
152 : {
153 0 : return mAnimations.ConstIter();
154 : }
155 :
156 0 : uint32_t AnimationsCount() const
157 : {
158 0 : return mAnimations.Count();
159 : }
160 :
161 : /**
162 : * Clear AnimatedValues and Animations data
163 : */
164 : void Clear();
165 :
166 : void ClearById(const uint64_t& aId);
167 : private:
168 0 : ~CompositorAnimationStorage() { };
169 :
170 : private:
171 : AnimatedValueTable mAnimatedValues;
172 : AnimationsTable mAnimations;
173 : };
174 :
175 : class AnimationHelper
176 : {
177 : public:
178 :
179 :
180 : /*
181 : * TODO Bug 1356509 Once we decouple the compositor animations and layers
182 : * in parent side, the API will be called inside SampleAnimations.
183 : * Before this, we expose this API for AsyncCompositionManager.
184 : *
185 : * Sample animations based on a given time stamp for a element(layer) with
186 : * its animation data.
187 : * Returns true if there exists compositor animation, and stores corresponding
188 : * animated value in |aAnimationValue|.
189 : */
190 : static bool
191 : SampleAnimationForEachNode(TimeStamp aTime,
192 : AnimationArray& aAnimations,
193 : InfallibleTArray<AnimData>& aAnimationData,
194 : StyleAnimationValue& aAnimationValue,
195 : bool& aHasInEffectAnimations);
196 : /*
197 : * TODO Bug 1356509 Once we decouple the compositor animations and layers
198 : * in parent side, the API will be called inside SampleAnimations.
199 : * Before this, we expose this API for AsyncCompositionManager.
200 : *
201 : * Populates AnimData stuctures into |aAnimData| based on |aAnimations|
202 : */
203 : static void
204 : SetAnimations(AnimationArray& aAnimations,
205 : InfallibleTArray<AnimData>& aAnimData,
206 : StyleAnimationValue& aBaseAnimationStyle);
207 :
208 : /*
209 : * Get a unique id to represent the compositor animation between child
210 : * and parent side. This id will be used as a key to store animation
211 : * data in the CompositorAnimationStorage per compositor.
212 : * Each layer on the content side calls this when it gets new animation
213 : * data.
214 : */
215 : static uint64_t GetNextCompositorAnimationsId();
216 :
217 : /*
218 : * Sample animation based a given time stamp |aTime| and the animation
219 : * data inside CompositorAnimationStorage |aStorage|. The animated values
220 : * after sampling will be stored in CompositorAnimationStorage as well.
221 : */
222 : static void
223 : SampleAnimations(CompositorAnimationStorage* aStorage,
224 : TimeStamp aTime);
225 : };
226 :
227 : } // namespace layers
228 : } // namespace mozilla
229 :
230 : #endif // mozilla_layers_AnimationHelper_h
|