Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/core/SkPicture.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2007 The Android Open Source Project
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 SkPicture_DEFINED
9
#define SkPicture_DEFINED
10
11
#include "include/core/SkRect.h"
12
#include "include/core/SkRefCnt.h"
13
#include "include/core/SkShader.h"  // IWYU pragma: keep
14
#include "include/core/SkTypes.h"
15
16
#include <atomic>
17
#include <cstddef>
18
#include <cstdint>
19
20
class SkCanvas;
21
class SkData;
22
class SkMatrix;
23
class SkStream;
24
class SkWStream;
25
enum class SkFilterMode;
26
struct SkDeserialProcs;
27
struct SkSerialProcs;
28
29
// TODO(kjlubick) Remove this after cleaning up clients
30
#include "include/core/SkTileMode.h"  // IWYU pragma: keep
31
32
/** \class SkPicture
33
    SkPicture records drawing commands made to SkCanvas. The command stream may be
34
    played in whole or in part at a later time.
35
36
    SkPicture is an abstract class. SkPicture may be generated by SkPictureRecorder
37
    or SkDrawable, or from SkPicture previously saved to SkData or SkStream.
38
39
    SkPicture may contain any SkCanvas drawing command, as well as one or more
40
    SkCanvas matrix or SkCanvas clip. SkPicture has a cull SkRect, which is used as
41
    a bounding box hint. To limit SkPicture bounds, use SkCanvas clip when
42
    recording or drawing SkPicture.
43
*/
44
class SK_API SkPicture : public SkRefCnt {
45
public:
46
    ~SkPicture() override;
47
48
    /** Recreates SkPicture that was serialized into a stream. Returns constructed SkPicture
49
        if successful; otherwise, returns nullptr. Fails if data does not permit
50
        constructing valid SkPicture.
51
52
        procs->fPictureProc permits supplying a custom function to decode SkPicture.
53
        If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
54
        may be used to provide user context to procs->fPictureProc; procs->fPictureProc
55
        is called with a pointer to data, data byte length, and user context.
56
57
        @param stream  container for serial data
58
        @param procs   custom serial data decoders; may be nullptr
59
        @return        SkPicture constructed from stream data
60
    */
61
    static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
62
                                           const SkDeserialProcs* procs = nullptr);
63
64
    /** Recreates SkPicture that was serialized into data. Returns constructed SkPicture
65
        if successful; otherwise, returns nullptr. Fails if data does not permit
66
        constructing valid SkPicture.
67
68
        procs->fPictureProc permits supplying a custom function to decode SkPicture.
69
        If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
70
        may be used to provide user context to procs->fPictureProc; procs->fPictureProc
71
        is called with a pointer to data, data byte length, and user context.
72
73
        @param data   container for serial data
74
        @param procs  custom serial data decoders; may be nullptr
75
        @return       SkPicture constructed from data
76
    */
77
    static sk_sp<SkPicture> MakeFromData(const SkData* data,
78
                                         const SkDeserialProcs* procs = nullptr);
79
80
    /**
81
82
        @param data   pointer to serial data
83
        @param size   size of data
84
        @param procs  custom serial data decoders; may be nullptr
85
        @return       SkPicture constructed from data
86
    */
87
    static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
88
                                         const SkDeserialProcs* procs = nullptr);
89
90
    /** \class SkPicture::AbortCallback
91
        AbortCallback is an abstract class. An implementation of AbortCallback may
92
        passed as a parameter to SkPicture::playback, to stop it before all drawing
93
        commands have been processed.
94
95
        If AbortCallback::abort returns true, SkPicture::playback is interrupted.
96
    */
97
    class SK_API AbortCallback {
98
    public:
99
        /** Has no effect.
100
        */
101
        virtual ~AbortCallback() = default;
102
103
        /** Stops SkPicture playback when some condition is met. A subclass of
104
            AbortCallback provides an override for abort() that can stop SkPicture::playback.
105
106
            The part of SkPicture drawn when aborted is undefined. SkPicture instantiations are
107
            free to stop drawing at different points during playback.
108
109
            If the abort happens inside one or more calls to SkCanvas::save(), stack
110
            of SkCanvas matrix and SkCanvas clip values is restored to its state before
111
            SkPicture::playback was called.
112
113
            @return  true to stop playback
114
115
        example: https://fiddle.skia.org/c/@Picture_AbortCallback_abort
116
        */
117
        virtual bool abort() = 0;
118
119
    protected:
120
        AbortCallback() = default;
121
        AbortCallback(const AbortCallback&) = delete;
122
        AbortCallback& operator=(const AbortCallback&) = delete;
123
    };
124
125
    /** Replays the drawing commands on the specified canvas. In the case that the
126
        commands are recorded, each command in the SkPicture is sent separately to canvas.
127
128
        To add a single command to draw SkPicture to recording canvas, call
129
        SkCanvas::drawPicture instead.
130
131
        @param canvas    receiver of drawing commands
132
        @param callback  allows interruption of playback
133
134
        example: https://fiddle.skia.org/c/@Picture_playback
135
    */
136
    virtual void playback(SkCanvas* canvas, AbortCallback* callback = nullptr) const = 0;
137
138
    /** Returns cull SkRect for this picture, passed in when SkPicture was created.
139
        Returned SkRect does not specify clipping SkRect for SkPicture; cull is hint
140
        of SkPicture bounds.
141
142
        SkPicture is free to discard recorded drawing commands that fall outside
143
        cull.
144
145
        @return  bounds passed when SkPicture was created
146
147
        example: https://fiddle.skia.org/c/@Picture_cullRect
148
    */
149
    virtual SkRect cullRect() const = 0;
150
151
    /** Returns a non-zero value unique among SkPicture in Skia process.
152
153
        @return  identifier for SkPicture
154
    */
155
3.99k
    uint32_t uniqueID() const { return fUniqueID; }
156
157
    /** Returns storage containing SkData describing SkPicture, using optional custom
158
        encoders.
159
160
        procs->fPictureProc permits supplying a custom function to encode SkPicture.
161
        If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
162
        may be used to provide user context to procs->fPictureProc; procs->fPictureProc
163
        is called with a pointer to SkPicture and user context.
164
165
        The default behavior for serializing SkImages is to encode a nullptr. Should
166
        clients want to, for example, encode these SkImages as PNGs so they can be
167
        deserialized, they must provide SkSerialProcs with the fImageProc set to do so.
168
169
        @param procs  custom serial data encoders; may be nullptr
170
        @return       storage containing serialized SkPicture
171
172
        example: https://fiddle.skia.org/c/@Picture_serialize
173
    */
174
    sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const;
175
176
    /** Writes picture to stream, using optional custom encoders.
177
178
        procs->fPictureProc permits supplying a custom function to encode SkPicture.
179
        If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
180
        may be used to provide user context to procs->fPictureProc; procs->fPictureProc
181
        is called with a pointer to SkPicture and user context.
182
183
        The default behavior for serializing SkImages is to encode a nullptr. Should
184
        clients want to, for example, encode these SkImages as PNGs so they can be
185
        deserialized, they must provide SkSerialProcs with the fImageProc set to do so.
186
187
        @param stream  writable serial data stream
188
        @param procs   custom serial data encoders; may be nullptr
189
190
        example: https://fiddle.skia.org/c/@Picture_serialize_2
191
    */
192
    void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const;
193
194
    /** Returns a placeholder SkPicture. Result does not draw, and contains only
195
        cull SkRect, a hint of its bounds. Result is immutable; it cannot be changed
196
        later. Result identifier is unique.
197
198
        Returned placeholder can be intercepted during playback to insert other
199
        commands into SkCanvas draw stream.
200
201
        @param cull  placeholder dimensions
202
        @return      placeholder with unique identifier
203
204
        example: https://fiddle.skia.org/c/@Picture_MakePlaceholder
205
    */
206
    static sk_sp<SkPicture> MakePlaceholder(SkRect cull);
207
208
    /** Returns the approximate number of operations in SkPicture. Returned value
209
        may be greater or less than the number of SkCanvas calls
210
        recorded: some calls may be recorded as more than one operation, other
211
        calls may be optimized away.
212
213
        @param nested  if true, include the op-counts of nested pictures as well, else
214
                       just return count the ops in the top-level picture.
215
        @return  approximate operation count
216
217
        example: https://fiddle.skia.org/c/@Picture_approximateOpCount
218
    */
219
    virtual int approximateOpCount(bool nested = false) const = 0;
220
221
    /** Returns the approximate byte size of SkPicture. Does not include large objects
222
        referenced by SkPicture.
223
224
        @return  approximate size
225
226
        example: https://fiddle.skia.org/c/@Picture_approximateBytesUsed
227
    */
228
    virtual size_t approximateBytesUsed() const = 0;
229
230
    /** Return a new shader that will draw with this picture.
231
     *
232
     *  @param tmx  The tiling mode to use when sampling in the x-direction.
233
     *  @param tmy  The tiling mode to use when sampling in the y-direction.
234
     *  @param mode How to filter the tiles
235
     *  @param localMatrix Optional matrix used when sampling
236
     *  @param tileRect The tile rectangle in picture coordinates: this represents the subset
237
     *                  (or superset) of the picture used when building a tile. It is not
238
     *                  affected by localMatrix and does not imply scaling (only translation
239
     *                  and cropping). If null, the tile rect is considered equal to the picture
240
     *                  bounds.
241
     *  @return     Returns a new shader object. Note: this function never returns null.
242
     */
243
    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode,
244
                               const SkMatrix* localMatrix, const SkRect* tileRect) const;
245
246
0
    sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const {
247
0
        return this->makeShader(tmx, tmy, mode, nullptr, nullptr);
248
0
    }
249
250
private:
251
    // Allowed subclasses.
252
    SkPicture();
253
    friend class SkBigPicture;
254
    friend class SkEmptyPicture;
255
    friend class SkPicturePriv;
256
257
    void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces,
258
        bool textBlobsOnly=false) const;
259
    static sk_sp<SkPicture> MakeFromStreamPriv(SkStream*, const SkDeserialProcs*,
260
                                               class SkTypefacePlayback*,
261
                                               int recursionLimit);
262
    friend class SkPictureData;
263
264
    /** Return true if the SkStream/Buffer represents a serialized picture, and
265
     fills out SkPictInfo. After this function returns, the data source is not
266
     rewound so it will have to be manually reset before passing to
267
     MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
268
     MakeFromBuffer perform this check internally so these entry points are
269
     intended for stand alone tools.
270
     If false is returned, SkPictInfo is unmodified.
271
     */
272
    static bool StreamIsSKP(SkStream*, struct SkPictInfo*);
273
    static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*);
274
    friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*);
275
276
    // Returns NULL if this is not an SkBigPicture.
277
0
    virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; }
278
279
    static bool IsValidPictInfo(const struct SkPictInfo& info);
280
    static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&,
281
                                        const class SkPictureData*,
282
                                        class SkReadBuffer* buffer);
283
284
    struct SkPictInfo createHeader() const;
285
    class SkPictureData* backport() const;
286
287
    uint32_t fUniqueID;
288
    mutable std::atomic<bool> fAddedToCache{false};
289
};
290
291
#endif