/work/obj-fuzz/dist/include/mozilla/layers/AnimationHelper.h
Line | Count | Source (jump to first uncovered line) |
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/dom/Nullable.h" |
11 | | #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction |
12 | | #include "mozilla/layers/LayersMessages.h" // for TransformData, etc |
13 | | #include "mozilla/TimeStamp.h" // for TimeStamp |
14 | | #include "mozilla/TimingParams.h" |
15 | | #include "X11UndefineNone.h" |
16 | | |
17 | | namespace mozilla { |
18 | | struct AnimationValue; |
19 | | namespace layers { |
20 | | class Animation; |
21 | | |
22 | | typedef InfallibleTArray<layers::Animation> AnimationArray; |
23 | | |
24 | | struct AnimData { |
25 | | InfallibleTArray<RefPtr<RawServoAnimationValue>> mStartValues; |
26 | | InfallibleTArray<RefPtr<RawServoAnimationValue>> mEndValues; |
27 | | InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions; |
28 | | TimingParams mTiming; |
29 | | // These two variables correspond to the variables of the same name in |
30 | | // KeyframeEffectReadOnly and are used for the same purpose: to skip composing |
31 | | // animations whose progress has not changed. |
32 | | dom::Nullable<double> mProgressOnLastCompose; |
33 | | uint64_t mCurrentIterationOnLastCompose = 0; |
34 | | // These two variables are used for a similar optimization above but are |
35 | | // applied to the timing function in each keyframe. |
36 | | uint32_t mSegmentIndexOnLastCompose = 0; |
37 | | dom::Nullable<double> mPortionInSegmentOnLastCompose; |
38 | | }; |
39 | | |
40 | | struct AnimationTransform { |
41 | | /* |
42 | | * This transform is calculated from sampleanimation in device pixel |
43 | | * and used by compositor. |
44 | | */ |
45 | | gfx::Matrix4x4 mTransformInDevSpace; |
46 | | /* |
47 | | * This transform is calculated from frame and used by getOMTAStyle() |
48 | | * for OMTA testing. |
49 | | */ |
50 | | gfx::Matrix4x4 mFrameTransform; |
51 | | TransformData mData; |
52 | | }; |
53 | | |
54 | | struct AnimatedValue { |
55 | | enum { |
56 | | TRANSFORM, |
57 | | OPACITY, |
58 | | NONE |
59 | | } mType {NONE}; |
60 | | |
61 | | union { |
62 | | AnimationTransform mTransform; |
63 | | float mOpacity; |
64 | | }; |
65 | | |
66 | | AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace, |
67 | | gfx::Matrix4x4&& aFrameTransform, |
68 | | const TransformData& aData) |
69 | | : mType(AnimatedValue::TRANSFORM) |
70 | | , mOpacity(0.0) |
71 | 0 | { |
72 | 0 | mTransform.mTransformInDevSpace = std::move(aTransformInDevSpace); |
73 | 0 | mTransform.mFrameTransform = std::move(aFrameTransform); |
74 | 0 | mTransform.mData = aData; |
75 | 0 | } |
76 | | |
77 | | explicit AnimatedValue(const float& aValue) |
78 | | : mType(AnimatedValue::OPACITY) |
79 | | , mOpacity(aValue) |
80 | 0 | { |
81 | 0 | } |
82 | | |
83 | 0 | ~AnimatedValue() {} |
84 | | |
85 | | private: |
86 | | AnimatedValue() = delete; |
87 | | }; |
88 | | |
89 | | // CompositorAnimationStorage stores the animations and animated values |
90 | | // keyed by a CompositorAnimationsId. The "animations" are a representation of |
91 | | // an entire animation over time, while the "animated values" are values sampled |
92 | | // from the animations at a particular point in time. |
93 | | // |
94 | | // There is one CompositorAnimationStorage per CompositorBridgeParent (i.e. |
95 | | // one per browser window), and the CompositorAnimationsId key is unique within |
96 | | // a particular CompositorAnimationStorage instance. |
97 | | // |
98 | | // Each layer which has animations gets a CompositorAnimationsId key, and reuses |
99 | | // that key during its lifetime. Likewise, in layers-free webrender, a display |
100 | | // item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId |
101 | | // key and reuses that key (it persists the key via the frame user-data |
102 | | // mechanism). |
103 | | class CompositorAnimationStorage final |
104 | | { |
105 | | typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable; |
106 | | typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable; |
107 | | |
108 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage) |
109 | | public: |
110 | | |
111 | | /** |
112 | | * Set the animation transform based on the unique id and also |
113 | | * set up |aFrameTransform| and |aData| for OMTA testing |
114 | | */ |
115 | | void SetAnimatedValue(uint64_t aId, |
116 | | gfx::Matrix4x4&& aTransformInDevSpace, |
117 | | gfx::Matrix4x4&& aFrameTransform, |
118 | | const TransformData& aData); |
119 | | |
120 | | /** |
121 | | * Set the animation transform in device pixel based on the unique id |
122 | | */ |
123 | | void SetAnimatedValue(uint64_t aId, |
124 | | gfx::Matrix4x4&& aTransformInDevSpace); |
125 | | |
126 | | /** |
127 | | * Set the animation opacity based on the unique id |
128 | | */ |
129 | | void SetAnimatedValue(uint64_t aId, const float& aOpacity); |
130 | | |
131 | | /** |
132 | | * Return the animated value if a given id can map to its animated value |
133 | | */ |
134 | | AnimatedValue* GetAnimatedValue(const uint64_t& aId) const; |
135 | | |
136 | | OMTAValue GetOMTAValue(const uint64_t& aId) const; |
137 | | |
138 | | /** |
139 | | * Return the iterator of animated value table |
140 | | */ |
141 | | AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const |
142 | 0 | { |
143 | 0 | return mAnimatedValues.ConstIter(); |
144 | 0 | } |
145 | | |
146 | | uint32_t AnimatedValueCount() const |
147 | 0 | { |
148 | 0 | return mAnimatedValues.Count(); |
149 | 0 | } |
150 | | |
151 | | /** |
152 | | * Set the animations based on the unique id |
153 | | */ |
154 | | void SetAnimations(uint64_t aId, const AnimationArray& aAnimations); |
155 | | |
156 | | /** |
157 | | * Return the animations if a given id can map to its animations |
158 | | */ |
159 | | AnimationArray* GetAnimations(const uint64_t& aId) const; |
160 | | |
161 | | /** |
162 | | * Return the iterator of animations table |
163 | | */ |
164 | | AnimationsTable::Iterator ConstAnimationsTableIter() const |
165 | 0 | { |
166 | 0 | return mAnimations.ConstIter(); |
167 | 0 | } |
168 | | |
169 | | uint32_t AnimationsCount() const |
170 | 0 | { |
171 | 0 | return mAnimations.Count(); |
172 | 0 | } |
173 | | |
174 | | /** |
175 | | * Clear AnimatedValues and Animations data |
176 | | */ |
177 | | void Clear(); |
178 | | void ClearById(const uint64_t& aId); |
179 | | |
180 | | private: |
181 | 0 | ~CompositorAnimationStorage() { }; |
182 | | |
183 | | private: |
184 | | AnimatedValueTable mAnimatedValues; |
185 | | AnimationsTable mAnimations; |
186 | | }; |
187 | | |
188 | | /** |
189 | | * This utility class allows reusing code between the webrender and |
190 | | * non-webrender compositor-side implementations. It provides |
191 | | * utility functions for sampling animations at particular timestamps. |
192 | | */ |
193 | | class AnimationHelper |
194 | | { |
195 | | public: |
196 | | |
197 | | enum class SampleResult { |
198 | | None, |
199 | | Skipped, |
200 | | Sampled |
201 | | }; |
202 | | |
203 | | /** |
204 | | * Sample animations based on a given time stamp for a element(layer) with |
205 | | * its animation data. |
206 | | * Generally |aPreviousFrameTimeStamp| is used for the sampling if it's |
207 | | * supplied to make the animation more in sync with other animations on the |
208 | | * main-thread. But in the case where the animation just started at the time |
209 | | * when the animation was sent to the compositor, |aCurrentTime| is used for |
210 | | * the sampling instead to avoid flickering the animation. |
211 | | * |
212 | | * Returns SampleResult::None if none of the animations are producing a result |
213 | | * (e.g. they are in the delay phase with no backwards fill), |
214 | | * SampleResult::Skipped if the animation output did not change since the last |
215 | | * call of this function, |
216 | | * SampleResult::Sampled if the animation output was updated. |
217 | | */ |
218 | | static SampleResult |
219 | | SampleAnimationForEachNode(TimeStamp aPreviousFrameTime, |
220 | | TimeStamp aCurrentFrameTime, |
221 | | AnimationArray& aAnimations, |
222 | | InfallibleTArray<AnimData>& aAnimationData, |
223 | | RefPtr<RawServoAnimationValue>& aAnimationValue, |
224 | | const AnimatedValue* aPreviousValue); |
225 | | /** |
226 | | * Populates AnimData stuctures into |aAnimData| and |aBaseAnimationStyle| |
227 | | * based on |aAnimations|. |
228 | | */ |
229 | | static void |
230 | | SetAnimations(AnimationArray& aAnimations, |
231 | | InfallibleTArray<AnimData>& aAnimData, |
232 | | RefPtr<RawServoAnimationValue>& aBaseAnimationStyle); |
233 | | |
234 | | /** |
235 | | * Get a unique id to represent the compositor animation between child |
236 | | * and parent side. This id will be used as a key to store animation |
237 | | * data in the CompositorAnimationStorage per compositor. |
238 | | * Each layer on the content side calls this when it gets new animation |
239 | | * data. |
240 | | */ |
241 | | static uint64_t GetNextCompositorAnimationsId(); |
242 | | |
243 | | /** |
244 | | * Sample animation based a given time stamp |aTime| and the animation |
245 | | * data inside CompositorAnimationStorage |aStorage|. The animated values |
246 | | * after sampling will be stored in CompositorAnimationStorage as well. |
247 | | * |
248 | | * Returns true if there is any animation. |
249 | | * Note that even if there are only in-delay phase animations (i.e. not |
250 | | * visually effective), this function returns true to ensure we composite |
251 | | * again on the next tick. |
252 | | */ |
253 | | static bool |
254 | | SampleAnimations(CompositorAnimationStorage* aStorage, |
255 | | TimeStamp aPreviousFrameTime, |
256 | | TimeStamp aCurrentFrameTime); |
257 | | }; |
258 | | |
259 | | } // namespace layers |
260 | | } // namespace mozilla |
261 | | |
262 | | #endif // mozilla_layers_AnimationHelper_h |