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