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