Coverage Report

Created: 2018-09-25 14:53

/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