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 | 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 | @param procs custom serial data encoders; may be nullptr |
166 | @return storage containing serialized SkPicture |
167 | |
168 | example: https://fiddle.skia.org/c/@Picture_serialize |
169 | */ |
170 | sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const; |
171 | |
172 | /** Writes picture to stream, using optional custom encoders. |
173 | |
174 | procs->fPictureProc permits supplying a custom function to encode SkPicture. |
175 | If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx |
176 | may be used to provide user context to procs->fPictureProc; procs->fPictureProc |
177 | is called with a pointer to SkPicture and user context. |
178 | |
179 | @param stream writable serial data stream |
180 | @param procs custom serial data encoders; may be nullptr |
181 | |
182 | example: https://fiddle.skia.org/c/@Picture_serialize_2 |
183 | */ |
184 | void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const; |
185 | |
186 | /** Returns a placeholder SkPicture. Result does not draw, and contains only |
187 | cull SkRect, a hint of its bounds. Result is immutable; it cannot be changed |
188 | later. Result identifier is unique. |
189 | |
190 | Returned placeholder can be intercepted during playback to insert other |
191 | commands into SkCanvas draw stream. |
192 | |
193 | @param cull placeholder dimensions |
194 | @return placeholder with unique identifier |
195 | |
196 | example: https://fiddle.skia.org/c/@Picture_MakePlaceholder |
197 | */ |
198 | static sk_sp<SkPicture> MakePlaceholder(SkRect cull); |
199 | |
200 | /** Returns the approximate number of operations in SkPicture. Returned value |
201 | may be greater or less than the number of SkCanvas calls |
202 | recorded: some calls may be recorded as more than one operation, other |
203 | calls may be optimized away. |
204 | |
205 | @param nested if true, include the op-counts of nested pictures as well, else |
206 | just return count the ops in the top-level picture. |
207 | @return approximate operation count |
208 | |
209 | example: https://fiddle.skia.org/c/@Picture_approximateOpCount |
210 | */ |
211 | virtual int approximateOpCount(bool nested = false) const = 0; |
212 | |
213 | /** Returns the approximate byte size of SkPicture. Does not include large objects |
214 | referenced by SkPicture. |
215 | |
216 | @return approximate size |
217 | |
218 | example: https://fiddle.skia.org/c/@Picture_approximateBytesUsed |
219 | */ |
220 | virtual size_t approximateBytesUsed() const = 0; |
221 | |
222 | /** Return a new shader that will draw with this picture. |
223 | * |
224 | * @param tmx The tiling mode to use when sampling in the x-direction. |
225 | * @param tmy The tiling mode to use when sampling in the y-direction. |
226 | * @param mode How to filter the tiles |
227 | * @param localMatrix Optional matrix used when sampling |
228 | * @param tile The tile rectangle in picture coordinates: this represents the subset |
229 | * (or superset) of the picture used when building a tile. It is not |
230 | * affected by localMatrix and does not imply scaling (only translation |
231 | * and cropping). If null, the tile rect is considered equal to the picture |
232 | * bounds. |
233 | * @return Returns a new shader object. Note: this function never returns null. |
234 | */ |
235 | sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode, |
236 | const SkMatrix* localMatrix, const SkRect* tileRect) const; |
237 | |
238 | sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const { |
239 | return this->makeShader(tmx, tmy, mode, localMatrix: nullptr, tileRect: nullptr); |
240 | } |
241 | |
242 | private: |
243 | // Allowed subclasses. |
244 | SkPicture(); |
245 | friend class SkBigPicture; |
246 | friend class SkEmptyPicture; |
247 | friend class SkPicturePriv; |
248 | |
249 | void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces, |
250 | bool textBlobsOnly=false) const; |
251 | static sk_sp<SkPicture> MakeFromStreamPriv(SkStream*, const SkDeserialProcs*, |
252 | class SkTypefacePlayback*, |
253 | int recursionLimit); |
254 | friend class SkPictureData; |
255 | |
256 | /** Return true if the SkStream/Buffer represents a serialized picture, and |
257 | fills out SkPictInfo. After this function returns, the data source is not |
258 | rewound so it will have to be manually reset before passing to |
259 | MakeFromStream or MakeFromBuffer. Note, MakeFromStream and |
260 | MakeFromBuffer perform this check internally so these entry points are |
261 | intended for stand alone tools. |
262 | If false is returned, SkPictInfo is unmodified. |
263 | */ |
264 | static bool StreamIsSKP(SkStream*, struct SkPictInfo*); |
265 | static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*); |
266 | friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*); |
267 | |
268 | // Returns NULL if this is not an SkBigPicture. |
269 | virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; } |
270 | |
271 | static bool IsValidPictInfo(const struct SkPictInfo& info); |
272 | static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&, |
273 | const class SkPictureData*, |
274 | class SkReadBuffer* buffer); |
275 | |
276 | struct SkPictInfo () const; |
277 | class SkPictureData* backport() const; |
278 | |
279 | uint32_t fUniqueID; |
280 | mutable std::atomic<bool> fAddedToCache{false}; |
281 | }; |
282 | |
283 | #endif |
284 | |