1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkPicture.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,338 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2007 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkPicture_DEFINED 1.14 +#define SkPicture_DEFINED 1.15 + 1.16 +#include "SkBitmap.h" 1.17 +#include "SkImageDecoder.h" 1.18 +#include "SkRefCnt.h" 1.19 + 1.20 +class SkBBoxHierarchy; 1.21 +class SkCanvas; 1.22 +class SkDrawPictureCallback; 1.23 +class SkData; 1.24 +class SkPicturePlayback; 1.25 +class SkPictureRecord; 1.26 +class SkStream; 1.27 +class SkWStream; 1.28 + 1.29 +struct SkPictInfo; 1.30 + 1.31 +/** \class SkPicture 1.32 + 1.33 + The SkPicture class records the drawing commands made to a canvas, to 1.34 + be played back at a later time. 1.35 +*/ 1.36 +class SK_API SkPicture : public SkRefCnt { 1.37 +public: 1.38 + SK_DECLARE_INST_COUNT(SkPicture) 1.39 + 1.40 + // AccelData provides a base class for device-specific acceleration 1.41 + // data. It is added to the picture via a call to a device's optimize 1.42 + // method. 1.43 + class AccelData : public SkRefCnt { 1.44 + public: 1.45 + typedef uint8_t Domain; 1.46 + typedef uint32_t Key; 1.47 + 1.48 + AccelData(Key key) : fKey(key) { } 1.49 + 1.50 + const Key& getKey() const { return fKey; } 1.51 + 1.52 + // This entry point allows user's to get a unique domain prefix 1.53 + // for their keys 1.54 + static Domain GenerateDomain(); 1.55 + private: 1.56 + Key fKey; 1.57 + 1.58 + typedef SkRefCnt INHERITED; 1.59 + }; 1.60 + 1.61 + /** The constructor prepares the picture to record. 1.62 + @param width the width of the virtual device the picture records. 1.63 + @param height the height of the virtual device the picture records. 1.64 + */ 1.65 + SkPicture(); 1.66 + /** Make a copy of the contents of src. If src records more drawing after 1.67 + this call, those elements will not appear in this picture. 1.68 + */ 1.69 + SkPicture(const SkPicture& src); 1.70 + 1.71 + /** PRIVATE / EXPERIMENTAL -- do not call */ 1.72 + void EXPERIMENTAL_addAccelData(const AccelData* data) { 1.73 + SkRefCnt_SafeAssign(fAccelData, data); 1.74 + } 1.75 + /** PRIVATE / EXPERIMENTAL -- do not call */ 1.76 + const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const { 1.77 + if (NULL != fAccelData && fAccelData->getKey() == key) { 1.78 + return fAccelData; 1.79 + } 1.80 + return NULL; 1.81 + } 1.82 + 1.83 + /** 1.84 + * Function signature defining a function that sets up an SkBitmap from encoded data. On 1.85 + * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set. 1.86 + * If the installed pixelref has decoded the data into pixels, then the src buffer need not be 1.87 + * copied. If the pixelref defers the actual decode until its lockPixels() is called, then it 1.88 + * must make a copy of the src buffer. 1.89 + * @param src Encoded data. 1.90 + * @param length Size of the encoded data, in bytes. 1.91 + * @param dst SkBitmap to install the pixel ref on. 1.92 + * @param bool Whether or not a pixel ref was successfully installed. 1.93 + */ 1.94 + typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst); 1.95 + 1.96 + /** 1.97 + * Recreate a picture that was serialized into a stream. 1.98 + * @param SkStream Serialized picture data. 1.99 + * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the 1.100 + * encoded bitmap data from the stream. 1.101 + * @return A new SkPicture representing the serialized data, or NULL if the stream is 1.102 + * invalid. 1.103 + */ 1.104 + static SkPicture* CreateFromStream(SkStream*, 1.105 + InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory); 1.106 + 1.107 + /** 1.108 + * Recreate a picture that was serialized into a buffer. If the creation requires bitmap 1.109 + * decoding, the decoder must be set on the SkReadBuffer parameter by calling 1.110 + * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer(). 1.111 + * @param SkReadBuffer Serialized picture data. 1.112 + * @return A new SkPicture representing the serialized data, or NULL if the buffer is 1.113 + * invalid. 1.114 + */ 1.115 + static SkPicture* CreateFromBuffer(SkReadBuffer&); 1.116 + 1.117 + virtual ~SkPicture(); 1.118 + 1.119 + /** 1.120 + * Swap the contents of the two pictures. Guaranteed to succeed. 1.121 + */ 1.122 + void swap(SkPicture& other); 1.123 + 1.124 + /** 1.125 + * Creates a thread-safe clone of the picture that is ready for playback. 1.126 + */ 1.127 + SkPicture* clone() const; 1.128 + 1.129 + /** 1.130 + * Creates multiple thread-safe clones of this picture that are ready for 1.131 + * playback. The resulting clones are stored in the provided array of 1.132 + * SkPictures. 1.133 + */ 1.134 + void clone(SkPicture* pictures, int count) const; 1.135 + 1.136 + enum RecordingFlags { 1.137 + /* This flag specifies that when clipPath() is called, the path will 1.138 + be faithfully recorded, but the recording canvas' current clip will 1.139 + only see the path's bounds. This speeds up the recording process 1.140 + without compromising the fidelity of the playback. The only side- 1.141 + effect for recording is that calling getTotalClip() or related 1.142 + clip-query calls will reflect the path's bounds, not the actual 1.143 + path. 1.144 + */ 1.145 + kUsePathBoundsForClip_RecordingFlag = 0x01, 1.146 + /* This flag causes the picture to compute bounding boxes and build 1.147 + up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas' 1.148 + usually stack-based clip/etc state. This requires an increase in 1.149 + recording time (often ~2x; likely more for very complex pictures), 1.150 + but allows us to perform much faster culling at playback time, and 1.151 + completely avoid some unnecessary clips and other operations. This 1.152 + is ideal for tiled rendering, or any other situation where you're 1.153 + drawing a fraction of a large scene into a smaller viewport. 1.154 + 1.155 + In most cases the record cost is offset by the playback improvement 1.156 + after a frame or two of tiled rendering (and complex pictures that 1.157 + induce the worst record times will generally get the largest 1.158 + speedups at playback time). 1.159 + 1.160 + Note: Currently this is not serializable, the bounding data will be 1.161 + discarded if you serialize into a stream and then deserialize. 1.162 + */ 1.163 + kOptimizeForClippedPlayback_RecordingFlag = 0x02, 1.164 + }; 1.165 + 1.166 + /** Returns the canvas that records the drawing commands. 1.167 + @param width the base width for the picture, as if the recording 1.168 + canvas' bitmap had this width. 1.169 + @param height the base width for the picture, as if the recording 1.170 + canvas' bitmap had this height. 1.171 + @param recordFlags optional flags that control recording. 1.172 + @return the picture canvas. 1.173 + */ 1.174 + SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0); 1.175 + 1.176 + /** Returns the recording canvas if one is active, or NULL if recording is 1.177 + not active. This does not alter the refcnt on the canvas (if present). 1.178 + */ 1.179 + SkCanvas* getRecordingCanvas() const; 1.180 + /** Signal that the caller is done recording. This invalidates the canvas 1.181 + returned by beginRecording/getRecordingCanvas, and prepares the picture 1.182 + for drawing. Note: this happens implicitly the first time the picture 1.183 + is drawn. 1.184 + */ 1.185 + void endRecording(); 1.186 + 1.187 + /** Replays the drawing commands on the specified canvas. This internally 1.188 + calls endRecording() if that has not already been called. 1.189 + @param canvas the canvas receiving the drawing commands. 1.190 + */ 1.191 + void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL); 1.192 + 1.193 + /** Return the width of the picture's recording canvas. This 1.194 + value reflects what was passed to setSize(), and does not necessarily 1.195 + reflect the bounds of what has been recorded into the picture. 1.196 + @return the width of the picture's recording canvas 1.197 + */ 1.198 + int width() const { return fWidth; } 1.199 + 1.200 + /** Return the height of the picture's recording canvas. This 1.201 + value reflects what was passed to setSize(), and does not necessarily 1.202 + reflect the bounds of what has been recorded into the picture. 1.203 + @return the height of the picture's recording canvas 1.204 + */ 1.205 + int height() const { return fHeight; } 1.206 + 1.207 + /** 1.208 + * Function to encode an SkBitmap to an SkData. A function with this 1.209 + * signature can be passed to serialize() and SkWriteBuffer. 1.210 + * Returning NULL will tell the SkWriteBuffer to use 1.211 + * SkBitmap::flatten() to store the bitmap. 1.212 + * 1.213 + * @param pixelRefOffset DEPRECATED -- caller assumes it will return 0. 1.214 + * @return SkData If non-NULL, holds encoded data representing the passed 1.215 + * in bitmap. The caller is responsible for calling unref(). 1.216 + */ 1.217 + typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm); 1.218 + 1.219 + /** 1.220 + * Serialize to a stream. If non NULL, encoder will be used to encode 1.221 + * any bitmaps in the picture. 1.222 + * encoder will never be called with a NULL pixelRefOffset. 1.223 + */ 1.224 + void serialize(SkWStream*, EncodeBitmap encoder = NULL) const; 1.225 + 1.226 + /** 1.227 + * Serialize to a buffer. 1.228 + */ 1.229 + void flatten(SkWriteBuffer&) const; 1.230 + 1.231 + /** 1.232 + * Returns true if any bitmaps may be produced when this SkPicture 1.233 + * is replayed. 1.234 + * Returns false if called while still recording. 1.235 + */ 1.236 + bool willPlayBackBitmaps() const; 1.237 + 1.238 +#ifdef SK_BUILD_FOR_ANDROID 1.239 + /** Signals that the caller is prematurely done replaying the drawing 1.240 + commands. This can be called from a canvas virtual while the picture 1.241 + is drawing. Has no effect if the picture is not drawing. 1.242 + @deprecated preserving for legacy purposes 1.243 + */ 1.244 + void abortPlayback(); 1.245 +#endif 1.246 + 1.247 + /** Return true if the SkStream/Buffer represents a serialized picture, and 1.248 + fills out SkPictInfo. After this function returns, the data source is not 1.249 + rewound so it will have to be manually reset before passing to 1.250 + CreateFromStream or CreateFromBuffer. Note, CreateFromStream and 1.251 + CreateFromBuffer perform this check internally so these entry points are 1.252 + intended for stand alone tools. 1.253 + If false is returned, SkPictInfo is unmodified. 1.254 + */ 1.255 + static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*); 1.256 + static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*); 1.257 + 1.258 + /** Enable/disable all the picture recording optimizations (i.e., 1.259 + those in SkPictureRecord). It is mainly intended for testing the 1.260 + existing optimizations (i.e., to actually have the pattern 1.261 + appear in an .skp we have to disable the optimization). Call right 1.262 + after 'beginRecording'. 1.263 + */ 1.264 + void internalOnly_EnableOpts(bool enableOpts); 1.265 + 1.266 +protected: 1.267 + // V2 : adds SkPixelRef's generation ID. 1.268 + // V3 : PictInfo tag at beginning, and EOF tag at the end 1.269 + // V4 : move SkPictInfo to be the header 1.270 + // V5 : don't read/write FunctionPtr on cross-process (we can detect that) 1.271 + // V6 : added serialization of SkPath's bounds (and packed its flags tighter) 1.272 + // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect) 1.273 + // V8 : Add an option for encoding bitmaps 1.274 + // V9 : Allow the reader and writer of an SKP disagree on whether to support 1.275 + // SK_SUPPORT_HINTING_SCALE_FACTOR 1.276 + // V10: add drawRRect, drawOval, clipRRect 1.277 + // V11: modify how readBitmap and writeBitmap store their info. 1.278 + // V12: add conics to SkPath, use new SkPathRef flattening 1.279 + // V13: add flag to drawBitmapRectToRect 1.280 + // parameterize blurs by sigma rather than radius 1.281 + // V14: Add flags word to PathRef serialization 1.282 + // V15: Remove A1 bitmpa config (and renumber remaining configs) 1.283 + // V16: Move SkPath's isOval flag to SkPathRef 1.284 + // V17: SkPixelRef now writes SkImageInfo 1.285 + // V18: SkBitmap now records x,y for its pixelref origin, instead of offset. 1.286 + // V19: encode matrices and regions into the ops stream 1.287 + // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization) 1.288 + // V21: add pushCull, popCull 1.289 + // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes 1.290 + 1.291 + // Note: If the picture version needs to be increased then please follow the 1.292 + // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw 1.293 + 1.294 + // Only SKPs within the min/current picture version range (inclusive) can be read. 1.295 + static const uint32_t MIN_PICTURE_VERSION = 19; 1.296 + static const uint32_t CURRENT_PICTURE_VERSION = 22; 1.297 + 1.298 + // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to 1.299 + // install their own SkPicturePlayback-derived players,SkPictureRecord-derived 1.300 + // recorders and set the picture size 1.301 + SkPicturePlayback* fPlayback; 1.302 + SkPictureRecord* fRecord; 1.303 + int fWidth, fHeight; 1.304 + const AccelData* fAccelData; 1.305 + 1.306 + // Create a new SkPicture from an existing SkPicturePlayback. Ref count of 1.307 + // playback is unchanged. 1.308 + SkPicture(SkPicturePlayback*, int width, int height); 1.309 + 1.310 + // For testing. Derived classes may instantiate an alternate 1.311 + // SkBBoxHierarchy implementation 1.312 + virtual SkBBoxHierarchy* createBBoxHierarchy() const; 1.313 +private: 1.314 + void createHeader(SkPictInfo* info) const; 1.315 + static bool IsValidPictInfo(const SkPictInfo& info); 1.316 + 1.317 + friend class SkFlatPicture; 1.318 + friend class SkPicturePlayback; 1.319 + 1.320 + typedef SkRefCnt INHERITED; 1.321 +}; 1.322 + 1.323 +/** 1.324 + * Subclasses of this can be passed to canvas.drawPicture. During the drawing 1.325 + * of the picture, this callback will periodically be invoked. If its 1.326 + * abortDrawing() returns true, then picture playback will be interrupted. 1.327 + * 1.328 + * The resulting drawing is undefined, as there is no guarantee how often the 1.329 + * callback will be invoked. If the abort happens inside some level of nested 1.330 + * calls to save(), restore will automatically be called to return the state 1.331 + * to the same level it was before the drawPicture call was made. 1.332 + */ 1.333 +class SK_API SkDrawPictureCallback { 1.334 +public: 1.335 + SkDrawPictureCallback() {} 1.336 + virtual ~SkDrawPictureCallback() {} 1.337 + 1.338 + virtual bool abortDrawing() = 0; 1.339 +}; 1.340 + 1.341 +#endif