xref: /aosp_15_r20/external/skia/include/core/SkPicture.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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     */
uniqueID()155     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 
makeShader(SkTileMode tmx,SkTileMode tmy,SkFilterMode mode)246     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const {
247         return this->makeShader(tmx, tmy, mode, nullptr, nullptr);
248     }
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.
asSkBigPicture()277     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
292