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