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 "SkRefCnt.h" 12 #include "SkRect.h" 13 #include "SkTypes.h" 14 15 class GrContext; 16 class SkBigPicture; 17 class SkBitmap; 18 class SkCanvas; 19 class SkData; 20 class SkImage; 21 class SkImageDeserializer; 22 class SkPath; 23 class SkPictureData; 24 class SkPixelSerializer; 25 class SkReadBuffer; 26 class SkRefCntSet; 27 class SkStream; 28 class SkTypefacePlayback; 29 class SkWStream; 30 class SkWriteBuffer; 31 struct SkPictInfo; 32 33 /** \class SkPicture 34 35 An SkPicture records drawing commands made to a canvas to be played back at a later time. 36 This base class handles serialization and a few other miscellany. 37 */ 38 class SK_API SkPicture : public SkRefCnt { 39 public: 40 virtual ~SkPicture(); 41 42 /** 43 * Function signature defining a function that sets up an SkBitmap from encoded data. On 44 * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set. 45 * If the installed pixelref has decoded the data into pixels, then the src buffer need not be 46 * copied. If the pixelref defers the actual decode until its lockPixels() is called, then it 47 * must make a copy of the src buffer. 48 * @param src Encoded data. 49 * @param length Size of the encoded data, in bytes. 50 * @param dst SkBitmap to install the pixel ref on. 51 * @param bool Whether or not a pixel ref was successfully installed. 52 */ 53 typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst); 54 55 #ifdef SK_SUPPORT_LEGACY_PICTUREINSTALLPIXELREF 56 /** 57 * Recreate a picture that was serialized into a stream. 58 * @param SkStream Serialized picture data. Ownership is unchanged by this call. 59 * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the 60 * encoded bitmap data from the stream. 61 * @return A new SkPicture representing the serialized data, or NULL if the stream is 62 * invalid. 63 */ 64 static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc proc); 65 static sk_sp<SkPicture> MakeFromStream(SkStream* stream, std::nullptr_t) { 66 return MakeFromStream(stream); 67 } 68 #endif 69 70 /** 71 * Recreate a picture that was serialized into a stream. 72 * 73 * Any serialized images in the stream will be passed the image-deserializer, or if that is 74 * null, to the default deserializer that will call SkImage::MakeFromEncoded(). 75 */ 76 static sk_sp<SkPicture> MakeFromStream(SkStream*, SkImageDeserializer*); 77 static sk_sp<SkPicture> MakeFromStream(SkStream*); 78 static sk_sp<SkPicture> MakeFromData(const void* data, size_t size, 79 SkImageDeserializer* = nullptr); 80 static sk_sp<SkPicture> MakeFromData(const SkData* data, SkImageDeserializer* = nullptr); 81 82 /** 83 * Recreate a picture that was serialized into a buffer. If the creation requires bitmap 84 * decoding, the decoder must be set on the SkReadBuffer parameter by calling 85 * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer(). 86 * @param SkReadBuffer Serialized picture data. 87 * @return A new SkPicture representing the serialized data, or NULL if the buffer is 88 * invalid. 89 */ 90 static sk_sp<SkPicture> MakeFromBuffer(SkReadBuffer&); 91 92 /** 93 * Subclasses of this can be passed to playback(). During the playback 94 * of the picture, this callback will periodically be invoked. If its 95 * abort() returns true, then picture playback will be interrupted. 96 * 97 * The resulting drawing is undefined, as there is no guarantee how often the 98 * callback will be invoked. If the abort happens inside some level of nested 99 * calls to save(), restore will automatically be called to return the state 100 * to the same level it was before the playback call was made. 101 */ 102 class SK_API AbortCallback { 103 public: 104 AbortCallback() {} 105 virtual ~AbortCallback() {} 106 virtual bool abort() = 0; 107 }; 108 109 /** Replays the drawing commands on the specified canvas. Note that 110 this has the effect of unfurling this picture into the destination 111 canvas. Using the SkCanvas::drawPicture entry point gives the destination 112 canvas the option of just taking a ref. 113 @param canvas the canvas receiving the drawing commands. 114 @param callback a callback that allows interruption of playback 115 */ 116 virtual void playback(SkCanvas*, AbortCallback* = NULL) const = 0; 117 118 /** Return a cull rect for this picture. 119 Ops recorded into this picture that attempt to draw outside the cull might not be drawn. 120 */ 121 virtual SkRect cullRect() const = 0; 122 123 /** Returns a non-zero value unique among all pictures. */ 124 uint32_t uniqueID() const; 125 126 /** 127 * Serialize the picture to SkData. If non nullptr, pixel-serializer will be used to 128 * customize how images reference by the picture are serialized/compressed. 129 */ 130 sk_sp<SkData> serialize(SkPixelSerializer* = nullptr) const; 131 132 /** 133 * Serialize to a stream. If non nullptr, pixel-serializer will be used to 134 * customize how images reference by the picture are serialized/compressed. 135 */ 136 void serialize(SkWStream*, SkPixelSerializer* = nullptr) const; 137 138 /** 139 * Serialize to a buffer. 140 */ 141 void flatten(SkWriteBuffer&) const; 142 143 /** 144 * Returns true if any bitmaps may be produced when this SkPicture 145 * is replayed. 146 */ 147 virtual bool willPlayBackBitmaps() const = 0; 148 149 /** Return the approximate number of operations in this picture. This 150 * number may be greater or less than the number of SkCanvas calls 151 * recorded: some calls may be recorded as more than one operation, or some 152 * calls may be optimized away. 153 */ 154 virtual int approximateOpCount() const = 0; 155 156 /** Returns the approximate byte size of this picture, not including large ref'd objects. */ 157 virtual size_t approximateBytesUsed() const = 0; 158 159 /** Return true if the SkStream/Buffer represents a serialized picture, and 160 fills out SkPictInfo. After this function returns, the data source is not 161 rewound so it will have to be manually reset before passing to 162 CreateFromStream or CreateFromBuffer. Note, CreateFromStream and 163 CreateFromBuffer perform this check internally so these entry points are 164 intended for stand alone tools. 165 If false is returned, SkPictInfo is unmodified. 166 */ 167 static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*); 168 static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*); 169 170 #ifdef SK_SUPPORT_LEGACY_PICTURE_GPUVETO 171 /** Return true if the picture is suitable for rendering on the GPU. */ 172 bool suitableForGpuRasterization(GrContext*, const char** whyNot = NULL) const; 173 #endif 174 175 // Sent via SkMessageBus from destructor. 176 struct DeletionMessage { int32_t fUniqueID; }; // TODO: -> uint32_t? 177 178 // Returns NULL if this is not an SkBigPicture. 179 virtual const SkBigPicture* asSkBigPicture() const { return NULL; } 180 181 // Global setting to enable or disable security precautions for serialization. 182 static void SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set); 183 static bool PictureIOSecurityPrecautionsEnabled(); 184 185 #ifdef SK_SUPPORT_LEGACY_PICTURE_PTR 186 static SkPicture* CreateFromStream(SkStream* stream, InstallPixelRefProc proc) { 187 return MakeFromStream(stream, proc).release(); 188 } 189 static SkPicture* CreateFromStream(SkStream* stream) { 190 return MakeFromStream(stream).release(); 191 } 192 static SkPicture* CreateFromBuffer(SkReadBuffer& rbuf) { 193 return MakeFromBuffer(rbuf).release(); 194 } 195 #endif 196 197 private: 198 // Subclass whitelist. 199 SkPicture(); 200 friend class SkBigPicture; 201 friend class SkEmptyPicture; 202 template <typename> friend class SkMiniPicture; 203 204 void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet* typefaces) const; 205 static sk_sp<SkPicture> MakeFromStream(SkStream*, SkImageDeserializer*, SkTypefacePlayback*); 206 friend class SkPictureData; 207 208 virtual int numSlowPaths() const = 0; 209 friend class SkPictureGpuAnalyzer; 210 friend struct SkPathCounter; 211 212 // V35: Store SkRect (rather then width & height) in header 213 // V36: Remove (obsolete) alphatype from SkColorTable 214 // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR) 215 // V38: Added PictureResolution option to SkPictureImageFilter 216 // V39: Added FilterLevel option to SkPictureImageFilter 217 // V40: Remove UniqueID serialization from SkImageFilter. 218 // V41: Added serialization of SkBitmapSource's filterQuality parameter 219 // V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture? 220 // V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data 221 // V44: Move annotations from paint to drawAnnotation 222 // V45: Add invNormRotation to SkLightingShader. 223 // V46: Add drawTextRSXform 224 // V47: Add occluder rect to SkBlurMaskFilter 225 // V48: Read and write extended SkTextBlobs. 226 // V49: Gradients serialized as SkColor4f + SkColorSpace 227 // V50: SkXfermode -> SkBlendMode 228 229 // Only SKPs within the min/current picture version range (inclusive) can be read. 230 static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39. 231 static const uint32_t CURRENT_PICTURE_VERSION = 50; 232 233 static_assert(MIN_PICTURE_VERSION <= 41, 234 "Remove kFontFileName and related code from SkFontDescriptor.cpp."); 235 236 static_assert(MIN_PICTURE_VERSION <= 42, 237 "Remove COMMENT API handlers from SkPicturePlayback.cpp"); 238 239 static_assert(MIN_PICTURE_VERSION <= 43, 240 "Remove SkBitmapSourceDeserializer."); 241 242 static_assert(MIN_PICTURE_VERSION <= 45, 243 "Remove decoding of old SkTypeface::Style from SkFontDescriptor.cpp."); 244 245 static_assert(MIN_PICTURE_VERSION <= 48, 246 "Remove legacy gradient deserialization code from SkGradientShader.cpp."); 247 248 static bool IsValidPictInfo(const SkPictInfo& info); 249 static sk_sp<SkPicture> Forwardport(const SkPictInfo&, 250 const SkPictureData*, 251 SkReadBuffer* buffer); 252 253 SkPictInfo createHeader() const; 254 SkPictureData* backport() const; 255 256 mutable uint32_t fUniqueID; 257 }; 258 259 #endif 260