Coverage Report

Created: 2024-05-20 07:14

/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