/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 |