/src/skia/modules/skottie/include/Skottie.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2017 Google Inc. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license that can be |
5 | | * found in the LICENSE file. |
6 | | */ |
7 | | |
8 | | #ifndef Skottie_DEFINED |
9 | | #define Skottie_DEFINED |
10 | | |
11 | | #include "include/core/SkRefCnt.h" |
12 | | #include "include/core/SkScalar.h" |
13 | | #include "include/core/SkSize.h" |
14 | | #include "include/core/SkString.h" |
15 | | #include "include/core/SkTypes.h" |
16 | | #include "modules/skresources/include/SkResources.h" |
17 | | |
18 | | // TODO(kjlubick) update clients and then remove the following: |
19 | | #include "include/core/SkFontMgr.h" // IWYU pragma: keep |
20 | | #include "modules/skottie/include/ExternalLayer.h" // IWYU pragma: keep |
21 | | #include "modules/skottie/include/SkottieProperty.h" // IWYU pragma: keep |
22 | | #include "modules/skottie/include/SlotManager.h" // IWYU pragma: keep |
23 | | |
24 | | #include <cstddef> |
25 | | #include <cstdint> |
26 | | #include <vector> |
27 | | |
28 | | class SkCanvas; |
29 | | class SkStream; |
30 | | struct SkRect; |
31 | | |
32 | | namespace sksg { |
33 | | |
34 | | class InvalidationController; |
35 | | class RenderNode; |
36 | | |
37 | | } // namespace sksg |
38 | | |
39 | | namespace SkShapers { class Factory; } |
40 | | |
41 | | namespace skottie { |
42 | | |
43 | | namespace internal { class Animator; } |
44 | | |
45 | | using ImageAsset = skresources::ImageAsset; |
46 | | using ResourceProvider = skresources::ResourceProvider; |
47 | | |
48 | | /** |
49 | | * A Logger subclass can be used to receive Animation::Builder parsing errors and warnings. |
50 | | */ |
51 | | class SK_API Logger : public SkRefCnt { |
52 | | public: |
53 | | enum class Level { |
54 | | kWarning, |
55 | | kError, |
56 | | }; |
57 | | |
58 | | virtual void log(Level, const char message[], const char* json = nullptr) = 0; |
59 | | }; |
60 | | |
61 | | // Evaluates AE expressions. |
62 | | template <class T> |
63 | | class SK_API ExpressionEvaluator : public SkRefCnt { |
64 | | public: |
65 | | // Evaluate the expression at the current time. |
66 | | virtual T evaluate(float t) = 0; |
67 | | }; |
68 | | |
69 | | /** |
70 | | * Creates ExpressionEvaluators to evaluate AE expressions and return the results. |
71 | | */ |
72 | | class SK_API ExpressionManager : public SkRefCnt { |
73 | | public: |
74 | | virtual sk_sp<ExpressionEvaluator<float>> createNumberExpressionEvaluator( |
75 | | const char expression[]) = 0; |
76 | | |
77 | | virtual sk_sp<ExpressionEvaluator<SkString>> createStringExpressionEvaluator( |
78 | | const char expression[]) = 0; |
79 | | |
80 | | virtual sk_sp<ExpressionEvaluator<std::vector<float>>> createArrayExpressionEvaluator( |
81 | | const char expression[]) = 0; |
82 | | }; |
83 | | |
84 | | /** |
85 | | * Interface for receiving AE composition markers at Animation build time. |
86 | | */ |
87 | | class SK_API MarkerObserver : public SkRefCnt { |
88 | | public: |
89 | | // t0,t1 are in the Animation::seek() domain. |
90 | | virtual void onMarker(const char name[], float t0, float t1) = 0; |
91 | | }; |
92 | | |
93 | | class SK_API Animation : public SkNVRefCnt<Animation> { |
94 | | public: |
95 | | class SK_API Builder final { |
96 | | public: |
97 | | enum Flags : uint32_t { |
98 | | kDeferImageLoading = 0x01, // Normally, all static image frames are resolved at |
99 | | // load time via ImageAsset::getFrame(0). With this flag, |
100 | | // frames are only resolved when needed, at seek() time. |
101 | | kPreferEmbeddedFonts = 0x02, // Attempt to use the embedded fonts (glyph paths, |
102 | | // normally used as fallback) over native Skia typefaces. |
103 | | }; |
104 | | |
105 | | explicit Builder(uint32_t flags = 0); |
106 | | Builder(const Builder&); |
107 | | Builder(Builder&&); |
108 | | ~Builder(); |
109 | | |
110 | | struct Stats { |
111 | | float fTotalLoadTimeMS = 0, // Total animation instantiation time. |
112 | | fJsonParseTimeMS = 0, // Time spent building a JSON DOM. |
113 | | fSceneParseTimeMS = 0; // Time spent constructing the animation scene graph. |
114 | | size_t fJsonSize = 0, // Input JSON size. |
115 | | fAnimatorCount = 0; // Number of dynamically animated properties. |
116 | | }; |
117 | | |
118 | | /** |
119 | | * Returns various animation build stats. |
120 | | * |
121 | | * @return Stats (see above). |
122 | | */ |
123 | 0 | const Stats& getStats() const { return fStats; } |
124 | | |
125 | | /** |
126 | | * Specify a loader for external resources (images, etc.). |
127 | | */ |
128 | | Builder& setResourceProvider(sk_sp<ResourceProvider>); |
129 | | |
130 | | /** |
131 | | * Specify a font manager for loading animation fonts. |
132 | | */ |
133 | | Builder& setFontManager(sk_sp<SkFontMgr>); |
134 | | |
135 | | /** |
136 | | * Specify a PropertyObserver to receive callbacks during parsing. |
137 | | * |
138 | | * See SkottieProperty.h for more details. |
139 | | * |
140 | | */ |
141 | | Builder& setPropertyObserver(sk_sp<PropertyObserver>); |
142 | | |
143 | | /** |
144 | | * Register a Logger with this builder. |
145 | | */ |
146 | | Builder& setLogger(sk_sp<Logger>); |
147 | | |
148 | | /** |
149 | | * Register a MarkerObserver with this builder. |
150 | | */ |
151 | | Builder& setMarkerObserver(sk_sp<MarkerObserver>); |
152 | | |
153 | | /** |
154 | | * Register a precomp layer interceptor. |
155 | | * This allows substituting precomp layers with custom/externally managed content. |
156 | | */ |
157 | | Builder& setPrecompInterceptor(sk_sp<PrecompInterceptor>); |
158 | | |
159 | | /** |
160 | | * Registers an ExpressionManager to evaluate AE expressions. |
161 | | * If unspecified, expressions in the animation JSON will be ignored. |
162 | | */ |
163 | | Builder& setExpressionManager(sk_sp<ExpressionManager>); |
164 | | |
165 | | /** |
166 | | * Registers a factory to be used when shaping text. |
167 | | * If unspecified, text will be shaped with primitive shaping. |
168 | | * See //modules/skshaper/utils/FactoryHelpers.h |
169 | | */ |
170 | | Builder& setTextShapingFactory(sk_sp<SkShapers::Factory>); |
171 | | |
172 | | /** |
173 | | * Animation factories. |
174 | | */ |
175 | | sk_sp<Animation> make(SkStream*); |
176 | | sk_sp<Animation> make(const char* data, size_t length); |
177 | | sk_sp<Animation> makeFromFile(const char path[]); |
178 | | |
179 | | /** |
180 | | * Get handle for SlotManager after animation is built. |
181 | | */ |
182 | 0 | const sk_sp<SlotManager>& getSlotManager() const {return fSlotManager;} |
183 | | |
184 | | private: |
185 | | const uint32_t fFlags; |
186 | | |
187 | | sk_sp<ResourceProvider> fResourceProvider; |
188 | | sk_sp<SkFontMgr> fFontMgr; |
189 | | sk_sp<PropertyObserver> fPropertyObserver; |
190 | | sk_sp<Logger> fLogger; |
191 | | sk_sp<MarkerObserver > fMarkerObserver; |
192 | | sk_sp<PrecompInterceptor> fPrecompInterceptor; |
193 | | sk_sp<ExpressionManager> fExpressionManager; |
194 | | sk_sp<SkShapers::Factory> fShapingFactory; |
195 | | sk_sp<SlotManager> fSlotManager; |
196 | | Stats fStats; |
197 | | }; |
198 | | |
199 | | /** |
200 | | * Animation factories. |
201 | | * |
202 | | * Use the Builder helper above for more options/control. |
203 | | */ |
204 | | static sk_sp<Animation> Make(const char* data, size_t length); |
205 | | static sk_sp<Animation> Make(SkStream*); |
206 | | static sk_sp<Animation> MakeFromFile(const char path[]); |
207 | | |
208 | | ~Animation(); |
209 | | |
210 | | enum RenderFlag : uint32_t { |
211 | | // When rendering into a known transparent buffer, clients can pass |
212 | | // this flag to avoid some unnecessary compositing overhead for |
213 | | // animations using layer blend modes. |
214 | | kSkipTopLevelIsolation = 0x01, |
215 | | // By default, content is clipped to the intrinsic animation |
216 | | // bounds (as determined by its size). If this flag is set, |
217 | | // then the animation can draw outside of the bounds. |
218 | | kDisableTopLevelClipping = 0x02, |
219 | | }; |
220 | | using RenderFlags = uint32_t; |
221 | | |
222 | | /** |
223 | | * Draws the current animation frame. |
224 | | * |
225 | | * It is undefined behavior to call render() on a newly created Animation |
226 | | * before specifying an initial frame via one of the seek() variants. |
227 | | * |
228 | | * @param canvas destination canvas |
229 | | * @param dst optional destination rect |
230 | | * @param flags optional RenderFlags |
231 | | */ |
232 | | void render(SkCanvas* canvas, const SkRect* dst = nullptr) const; |
233 | | void render(SkCanvas* canvas, const SkRect* dst, RenderFlags) const; |
234 | | |
235 | | /** |
236 | | * [Deprecated: use one of the other versions.] |
237 | | * |
238 | | * Updates the animation state for |t|. |
239 | | * |
240 | | * @param t normalized [0..1] frame selector (0 -> first frame, 1 -> final frame) |
241 | | * @param ic optional invalidation controller (dirty region tracking) |
242 | | * |
243 | | */ |
244 | 9.10k | void seek(SkScalar t, sksg::InvalidationController* ic = nullptr) { |
245 | 9.10k | this->seekFrameTime(t * this->duration(), ic); |
246 | 9.10k | } |
247 | | |
248 | | /** |
249 | | * Update the animation state to match |t|, specified as a frame index |
250 | | * i.e. relative to duration() * fps(). |
251 | | * |
252 | | * Fractional values are allowed and meaningful - e.g. |
253 | | * |
254 | | * 0.0 -> first frame |
255 | | * 1.0 -> second frame |
256 | | * 0.5 -> halfway between first and second frame |
257 | | */ |
258 | | void seekFrame(double t, sksg::InvalidationController* ic = nullptr); |
259 | | |
260 | | /** Update the animation state to match t, specifed in frame time |
261 | | * i.e. relative to duration(). |
262 | | */ |
263 | | void seekFrameTime(double t, sksg::InvalidationController* = nullptr); |
264 | | |
265 | | /** |
266 | | * Returns the animation duration in seconds. |
267 | | */ |
268 | 9.10k | double duration() const { return fDuration; } |
269 | | |
270 | | /** |
271 | | * Returns the animation frame rate (frames / second). |
272 | | */ |
273 | 0 | double fps() const { return fFPS; } |
274 | | |
275 | | /** |
276 | | * Animation in point, in frame index units. |
277 | | */ |
278 | 0 | double inPoint() const { return fInPoint; } |
279 | | |
280 | | /** |
281 | | * Animation out point, in frame index units. |
282 | | */ |
283 | 0 | double outPoint() const { return fOutPoint; } |
284 | | |
285 | 0 | const SkString& version() const { return fVersion; } |
286 | 0 | const SkSize& size() const { return fSize; } |
287 | | |
288 | | private: |
289 | | enum Flags : uint32_t { |
290 | | kRequiresTopLevelIsolation = 1 << 0, // Needs to draw into a layer due to layer blending. |
291 | | }; |
292 | | |
293 | | Animation(sk_sp<sksg::RenderNode>, |
294 | | std::vector<sk_sp<internal::Animator>>&&, |
295 | | SkString ver, const SkSize& size, |
296 | | double inPoint, double outPoint, double duration, double fps, uint32_t flags); |
297 | | |
298 | | const sk_sp<sksg::RenderNode> fSceneRoot; |
299 | | const std::vector<sk_sp<internal::Animator>> fAnimators; |
300 | | const SkString fVersion; |
301 | | const SkSize fSize; |
302 | | const double fInPoint, |
303 | | fOutPoint, |
304 | | fDuration, |
305 | | fFPS; |
306 | | const uint32_t fFlags; |
307 | | |
308 | | using INHERITED = SkNVRefCnt<Animation>; |
309 | | }; |
310 | | |
311 | | } // namespace skottie |
312 | | |
313 | | #endif // Skottie_DEFINED |