File: SkResources.h

package info (click to toggle)
webkit2gtk 2.48.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 429,764 kB
  • sloc: cpp: 3,697,587; javascript: 194,444; ansic: 169,997; python: 46,499; asm: 19,295; ruby: 18,528; perl: 16,602; xml: 4,650; yacc: 2,360; sh: 2,098; java: 1,993; lex: 1,327; pascal: 366; makefile: 298
file content (291 lines) | stat: -rw-r--r-- 10,243 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
 * Copyright 2019 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkResources_DEFINED
#define SkResources_DEFINED

#include "include/core/SkData.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkMutex.h"
#include "src/core/SkTHash.h"

#include <memory>

class SkAnimCodecPlayer;
class SkCodec;
class SkImage;

namespace skresources {

/**
 * Image asset proxy interface.
 */
class SK_API ImageAsset : public SkRefCnt {
public:
    /**
     * Returns true if the image asset is animated.
     */
    virtual bool isMultiFrame() = 0;

    /**
     * DEPRECATED: override getFrameData() instead.
     *
     * Returns the SkImage for a given frame.
     *
     * If the image asset is static, getFrame() is only called once, at animation load time.
     * Otherwise, this gets invoked every time the animation time is adjusted (on every seek).
     *
     * Embedders should cache and serve the same SkImage whenever possible, for efficiency.
     *
     * @param t   Frame time code, in seconds, relative to the image layer timeline origin
     *            (in-point).
     */
    virtual sk_sp<SkImage> getFrame(float t);

    // Describes how the frame image is to be scaled to the animation-declared asset size.
    enum class SizeFit {
        // See SkMatrix::ScaleToFit
        kFill   = SkMatrix::kFill_ScaleToFit,
        kStart  = SkMatrix::kStart_ScaleToFit,
        kCenter = SkMatrix::kCenter_ScaleToFit,
        kEnd    = SkMatrix::kEnd_ScaleToFit,

        // No scaling.
        kNone,
    };

    struct FrameData {
        // SkImage payload.
        sk_sp<SkImage>    image;
        // Resampling parameters.
        SkSamplingOptions sampling;
        // Additional image transform to be applied before AE scaling rules.
        SkMatrix          matrix = SkMatrix::I();
        // Strategy for image size -> AE asset size scaling.
        SizeFit           scaling = SizeFit::kCenter;
    };

    /**
     * Returns the payload for a given frame.
     *
     * If the image asset is static, getFrameData() is only called once, at animation load time.
     * Otherwise, this gets invoked every time the animation time is adjusted (on every seek).
     *
     * Embedders should cache and serve the same SkImage whenever possible, for efficiency.
     *
     * @param t   Frame time code, in seconds, relative to the image layer timeline origin
     *            (in-point).
     */
    virtual FrameData getFrameData(float t);
};

enum class ImageDecodeStrategy {
    // Images are decoded on-the-fly, at rasterization time.
    // Large images may cause jank as decoding is expensive (and can thrash internal caches).
    kLazyDecode,
    // Force-decode all images upfront, at the cost of potentially more RAM and slower
    // animation build times.
    kPreDecode,
};

class MultiFrameImageAsset final : public ImageAsset {
public:
    // Clients must call SkCodec::Register() to load the required decoding image codecs before
    // calling Make. For example:
    //     SkCodec::Register(SkPngDecoder::Decoder());
    static sk_sp<MultiFrameImageAsset> Make(sk_sp<SkData>,
                                            ImageDecodeStrategy = ImageDecodeStrategy::kLazyDecode);
    // If the client has already decoded the data, they can use this constructor.
    static sk_sp<MultiFrameImageAsset> Make(std::unique_ptr<SkCodec>,
                                            ImageDecodeStrategy = ImageDecodeStrategy::kLazyDecode);

    bool isMultiFrame() override;

    // Animation duration, in ms.
    float duration() const;

    sk_sp<SkImage> getFrame(float t) override;

private:
    explicit MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer>, ImageDecodeStrategy);

    sk_sp<SkImage> generateFrame(float t);

    std::unique_ptr<SkAnimCodecPlayer> fPlayer;
    sk_sp<SkImage>                     fCachedFrame;
    ImageDecodeStrategy fStrategy;

    using INHERITED = ImageAsset;
};

/**
 * External track (e.g. audio playback) interface.
 *
 * Used to wrap data payload and playback controllers.
 */
class ExternalTrackAsset : public SkRefCnt {
public:
    /**
     * Playback control callback, emitted for each corresponding Animation::seek().
     *
     * @param t  Frame time code, in seconds, relative to the layer's timeline origin
     *           (in-point).
     *
     * Negative |t| values are used to signal off state (stop playback outside layer span).
     */
    virtual void seek(float t) = 0;
};

/**
 * ResourceProvider is an interface that lets rich-content modules defer loading of external
 * resources (images, fonts, etc.) to embedding clients.
 */
class SK_API ResourceProvider : public SkRefCnt {
public:
    /**
     * Load a generic resource (currently only nested animations) specified by |path| + |name|,
     * and return as an SkData.
     */
    virtual sk_sp<SkData> load(const char[] /* resource_path */,
                               const char[] /* resource_name */) const {
        return nullptr;
    }

    /**
     * Load an image asset specified by |path| + |name|, and returns the corresponding
     * ImageAsset proxy.
     */
    virtual sk_sp<ImageAsset> loadImageAsset(const char[] /* resource_path */,
                                             const char[] /* resource_name */,
                                             const char[] /* resource_id   */) const {
        return nullptr;
    }

    /**
     * Load an external audio track specified by |path|/|name|/|id|.
     */
    virtual sk_sp<ExternalTrackAsset> loadAudioAsset(const char[] /* resource_path */,
                                                     const char[] /* resource_name */,
                                                     const char[] /* resource_id   */) {
        return nullptr;
    }

    /**
     * DEPRECATED: implement loadTypeface() instead.
     *
     * Load an external font and return as SkData.
     *
     * @param name  font name    ("fName" Lottie property)
     * @param url   web font URL ("fPath" Lottie property)
     *
     * -- Note --
     *
     *   This mechanism assumes monolithic fonts (single data blob).  Some web font providers may
     *   serve multiple font blobs, segmented for various unicode ranges, depending on user agent
     *   capabilities (woff, woff2).  In that case, the embedder would need to advertise no user
     *   agent capabilities when fetching the URL, in order to receive full font data.
     */
    virtual sk_sp<SkData> loadFont(const char[] /* name */,
                                   const char[] /* url  */) const {
        return nullptr;
    }

    /**
     * Load an external font and return as SkTypeface.
     *
     * @param name  font name
     * @param url   web font URL
     */
    virtual sk_sp<SkTypeface> loadTypeface(const char[] /* name */,
                                           const char[] /* url  */) const {
        return nullptr;
    }
};

class FileResourceProvider final : public ResourceProvider {
public:
    // To decode images, clients must call SkCodecs::Register() before calling Make.
    static sk_sp<FileResourceProvider> Make(SkString base_dir,
                                            ImageDecodeStrategy = ImageDecodeStrategy::kLazyDecode);

    sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override;

    sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;

private:
    FileResourceProvider(SkString, ImageDecodeStrategy);

    const SkString fDir;
    const ImageDecodeStrategy fStrategy;

    using INHERITED = ResourceProvider;
};

class ResourceProviderProxyBase : public ResourceProvider {
protected:
    explicit ResourceProviderProxyBase(sk_sp<ResourceProvider>);

    sk_sp<SkData> load(const char[], const char[]) const override;
    sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
    sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override;
    sk_sp<SkData> loadFont(const char[], const char[]) const override;
    sk_sp<ExternalTrackAsset> loadAudioAsset(const char[], const char[], const char[]) override;

protected:
    const sk_sp<ResourceProvider> fProxy;
};

class SK_API CachingResourceProvider final : public ResourceProviderProxyBase {
public:
    static sk_sp<CachingResourceProvider> Make(sk_sp<ResourceProvider> rp) {
        return rp ? sk_sp<CachingResourceProvider>(new CachingResourceProvider(std::move(rp)))
                  : nullptr;
    }

private:
    explicit CachingResourceProvider(sk_sp<ResourceProvider>);

    sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;

    mutable SkMutex                                             fMutex;
    mutable skia_private::THashMap<SkString, sk_sp<ImageAsset>> fImageCache;

    using INHERITED = ResourceProviderProxyBase;
};

class SK_API DataURIResourceProviderProxy final : public ResourceProviderProxyBase {
public:
    // If font data is supplied via base64 encoding, this needs a provided SkFontMgr to process
    // that font data into an SkTypeface. To decode images, clients must call SkCodecs::Register()
    // before calling Make.
    static sk_sp<DataURIResourceProviderProxy> Make(
            sk_sp<ResourceProvider> rp,
            ImageDecodeStrategy = ImageDecodeStrategy::kLazyDecode,
            sk_sp<const SkFontMgr> fontMgr = nullptr);

private:
    DataURIResourceProviderProxy(sk_sp<ResourceProvider>,
                                 ImageDecodeStrategy,
                                 sk_sp<const SkFontMgr> fontMgr);

    sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
    sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override;

    const ImageDecodeStrategy fStrategy;
    sk_sp<const SkFontMgr> fFontMgr;

    using INHERITED = ResourceProviderProxyBase;
};

} // namespace skresources

#endif // SkResources_DEFINED