blob: e17a0d4bd3f0367d7d55a1b98b2b1f6901517d95 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@android.com8a1c16f2008-12-17 15:59:43 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2007 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#ifndef SkPicture_DEFINED
11#define SkPicture_DEFINED
12
scroggo@google.comf8d7d272013-02-22 21:38:35 +000013#include "SkBitmap.h"
scroggo@google.comf1754ec2013-06-28 21:32:00 +000014#include "SkImageDecoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015#include "SkRefCnt.h"
16
commit-bot@chromium.orgeb9547c2014-03-19 21:24:25 +000017#if SK_SUPPORT_GPU
18class GrContext;
19#endif
20
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +000021class SkBBHFactory;
junov@chromium.org35ac0482012-11-01 17:10:32 +000022class SkBBoxHierarchy;
reed@android.com8a1c16f2008-12-17 15:59:43 +000023class SkCanvas;
reed@google.com74babdf2013-05-20 17:02:41 +000024class SkDrawPictureCallback;
scroggo@google.com1b1bcc32013-05-21 20:31:23 +000025class SkData;
commit-bot@chromium.org8f831f22014-04-23 22:35:42 +000026class SkPathHeap;
reed@android.com8a1c16f2008-12-17 15:59:43 +000027class SkPicturePlayback;
28class SkPictureRecord;
29class SkStream;
30class SkWStream;
31
scroggo@google.comf1754ec2013-06-28 21:32:00 +000032struct SkPictInfo;
33
reed@android.com8a1c16f2008-12-17 15:59:43 +000034/** \class SkPicture
35
36 The SkPicture class records the drawing commands made to a canvas, to
37 be played back at a later time.
38*/
reed@google.com1a32d4a2011-04-25 20:02:38 +000039class SK_API SkPicture : public SkRefCnt {
reed@android.com8a1c16f2008-12-17 15:59:43 +000040public:
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +000041 SK_DECLARE_INST_COUNT(SkPicture)
42
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000043 // AccelData provides a base class for device-specific acceleration
skia.committer@gmail.comeb849e52014-03-17 03:02:17 +000044 // data. It is added to the picture via a call to a device's optimize
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000045 // method.
46 class AccelData : public SkRefCnt {
47 public:
48 typedef uint8_t Domain;
49 typedef uint32_t Key;
50
51 AccelData(Key key) : fKey(key) { }
52
53 const Key& getKey() const { return fKey; }
54
55 // This entry point allows user's to get a unique domain prefix
56 // for their keys
57 static Domain GenerateDomain();
58 private:
59 Key fKey;
60
61 typedef SkRefCnt INHERITED;
62 };
63
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 SkPicture();
65 /** Make a copy of the contents of src. If src records more drawing after
66 this call, those elements will not appear in this picture.
67 */
68 SkPicture(const SkPicture& src);
scroggo@google.comf8d7d272013-02-22 21:38:35 +000069
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000070 /** PRIVATE / EXPERIMENTAL -- do not call */
skia.committer@gmail.comeb849e52014-03-17 03:02:17 +000071 void EXPERIMENTAL_addAccelData(const AccelData* data) {
72 SkRefCnt_SafeAssign(fAccelData, data);
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000073 }
74 /** PRIVATE / EXPERIMENTAL -- do not call */
skia.committer@gmail.comeb849e52014-03-17 03:02:17 +000075 const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const {
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000076 if (NULL != fAccelData && fAccelData->getKey() == key) {
skia.committer@gmail.comeb849e52014-03-17 03:02:17 +000077 return fAccelData;
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000078 }
79 return NULL;
80 }
81
reed@google.com34342f62012-06-25 14:36:28 +000082 /**
scroggo@google.comf8d7d272013-02-22 21:38:35 +000083 * Function signature defining a function that sets up an SkBitmap from encoded data. On
84 * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
85 * If the installed pixelref has decoded the data into pixels, then the src buffer need not be
86 * copied. If the pixelref defers the actual decode until its lockPixels() is called, then it
87 * must make a copy of the src buffer.
88 * @param src Encoded data.
89 * @param length Size of the encoded data, in bytes.
90 * @param dst SkBitmap to install the pixel ref on.
91 * @param bool Whether or not a pixel ref was successfully installed.
92 */
93 typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
94
95 /**
96 * Recreate a picture that was serialized into a stream.
97 * @param SkStream Serialized picture data.
scroggo@google.comf8d7d272013-02-22 21:38:35 +000098 * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
99 * encoded bitmap data from the stream.
scroggo@google.comf1754ec2013-06-28 21:32:00 +0000100 * @return A new SkPicture representing the serialized data, or NULL if the stream is
101 * invalid.
scroggo@google.comf8d7d272013-02-22 21:38:35 +0000102 */
scroggo@google.comf1754ec2013-06-28 21:32:00 +0000103 static SkPicture* CreateFromStream(SkStream*,
104 InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
scroggo@google.comf8d7d272013-02-22 21:38:35 +0000105
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000106 /**
107 * Recreate a picture that was serialized into a buffer. If the creation requires bitmap
108 * decoding, the decoder must be set on the SkReadBuffer parameter by calling
109 * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
110 * @param SkReadBuffer Serialized picture data.
111 * @return A new SkPicture representing the serialized data, or NULL if the buffer is
112 * invalid.
113 */
114 static SkPicture* CreateFromBuffer(SkReadBuffer&);
115
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116 virtual ~SkPicture();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000117
reed@android.com8a1c16f2008-12-17 15:59:43 +0000118 /**
119 * Swap the contents of the two pictures. Guaranteed to succeed.
120 */
121 void swap(SkPicture& other);
skia.committer@gmail.coma27096b2012-08-30 14:38:00 +0000122
djsollen@google.comc9ab9872012-08-29 18:52:07 +0000123 /**
124 * Creates a thread-safe clone of the picture that is ready for playback.
125 */
126 SkPicture* clone() const;
127
128 /**
129 * Creates multiple thread-safe clones of this picture that are ready for
130 * playback. The resulting clones are stored in the provided array of
131 * SkPictures.
132 */
133 void clone(SkPicture* pictures, int count) const;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000134
reed@android.comae814c82009-02-13 14:56:09 +0000135 enum RecordingFlags {
136 /* This flag specifies that when clipPath() is called, the path will
137 be faithfully recorded, but the recording canvas' current clip will
138 only see the path's bounds. This speeds up the recording process
139 without compromising the fidelity of the playback. The only side-
140 effect for recording is that calling getTotalClip() or related
141 clip-query calls will reflect the path's bounds, not the actual
142 path.
143 */
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000144 kUsePathBoundsForClip_RecordingFlag = 0x01
145 };
146
147#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
148 // TODO: once kOptimizeForClippedPlayback_RecordingFlag is hidden from
149 // all external consumers, SkPicture::createBBoxHierarchy can also be
150 // cleaned up.
151private:
152#endif
153 enum Deprecated_RecordingFlags {
rileya@google.com8515e792012-09-13 21:41:51 +0000154 /* This flag causes the picture to compute bounding boxes and build
155 up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
156 usually stack-based clip/etc state. This requires an increase in
157 recording time (often ~2x; likely more for very complex pictures),
158 but allows us to perform much faster culling at playback time, and
159 completely avoid some unnecessary clips and other operations. This
160 is ideal for tiled rendering, or any other situation where you're
skia.committer@gmail.com1d225f22012-09-14 02:01:10 +0000161 drawing a fraction of a large scene into a smaller viewport.
rileya@google.com8515e792012-09-13 21:41:51 +0000162
163 In most cases the record cost is offset by the playback improvement
164 after a frame or two of tiled rendering (and complex pictures that
165 induce the worst record times will generally get the largest
166 speedups at playback time).
167
168 Note: Currently this is not serializable, the bounding data will be
169 discarded if you serialize into a stream and then deserialize.
170 */
robertphillips@google.comad7d4812013-04-12 15:13:35 +0000171 kOptimizeForClippedPlayback_RecordingFlag = 0x02,
reed@android.comae814c82009-02-13 14:56:09 +0000172 };
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000173#ifndef SK_SUPPORT_DEPRECATED_RECORD_FLAGS
174public:
175#endif
reed@android.comae814c82009-02-13 14:56:09 +0000176
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000177#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
178private:
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000179#endif
180
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000181#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
182
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183 /** Returns the canvas that records the drawing commands.
reed@android.comae814c82009-02-13 14:56:09 +0000184 @param width the base width for the picture, as if the recording
185 canvas' bitmap had this width.
186 @param height the base width for the picture, as if the recording
187 canvas' bitmap had this height.
188 @param recordFlags optional flags that control recording.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189 @return the picture canvas.
190 */
reed@android.comae814c82009-02-13 14:56:09 +0000191 SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000192#endif
reed@android.comae814c82009-02-13 14:56:09 +0000193
reed@android.com8a1c16f2008-12-17 15:59:43 +0000194 /** Returns the recording canvas if one is active, or NULL if recording is
195 not active. This does not alter the refcnt on the canvas (if present).
196 */
197 SkCanvas* getRecordingCanvas() const;
198 /** Signal that the caller is done recording. This invalidates the canvas
199 returned by beginRecording/getRecordingCanvas, and prepares the picture
200 for drawing. Note: this happens implicitly the first time the picture
201 is drawn.
202 */
203 void endRecording();
junov@chromium.org4866cc02012-06-01 21:23:07 +0000204
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000205#ifndef SK_SUPPORT_LEGACY_PICTURE_CAN_RECORD
206public:
207#endif
208
reed@android.com8a1c16f2008-12-17 15:59:43 +0000209 /** Replays the drawing commands on the specified canvas. This internally
210 calls endRecording() if that has not already been called.
reed@google.com74babdf2013-05-20 17:02:41 +0000211 @param canvas the canvas receiving the drawing commands.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000212 */
reed@google.com74babdf2013-05-20 17:02:41 +0000213 void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000214
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 /** Return the width of the picture's recording canvas. This
216 value reflects what was passed to setSize(), and does not necessarily
217 reflect the bounds of what has been recorded into the picture.
218 @return the width of the picture's recording canvas
219 */
220 int width() const { return fWidth; }
221
222 /** Return the height of the picture's recording canvas. This
223 value reflects what was passed to setSize(), and does not necessarily
224 reflect the bounds of what has been recorded into the picture.
225 @return the height of the picture's recording canvas
226 */
227 int height() const { return fHeight; }
228
skia.committer@gmail.coma9157722014-04-03 03:04:26 +0000229 /** Return a non-zero, unique value representing the picture. This call is
230 only valid when not recording. Between a beginRecording/endRecording
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000231 pair it will just return 0 (the invalid ID). Each beginRecording/
robertphillips@google.comd5500882014-04-02 23:51:13 +0000232 endRecording pair will cause a different generation ID to be returned.
233 */
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000234 uint32_t uniqueID() const;
robertphillips@google.comd5500882014-04-02 23:51:13 +0000235
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000236 /**
scroggo@google.com1b1bcc32013-05-21 20:31:23 +0000237 * Function to encode an SkBitmap to an SkData. A function with this
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +0000238 * signature can be passed to serialize() and SkWriteBuffer.
239 * Returning NULL will tell the SkWriteBuffer to use
scroggo@google.com1b1bcc32013-05-21 20:31:23 +0000240 * SkBitmap::flatten() to store the bitmap.
reed@google.com672588b2014-01-08 15:42:01 +0000241 *
242 * @param pixelRefOffset DEPRECATED -- caller assumes it will return 0.
scroggo@google.com1b1bcc32013-05-21 20:31:23 +0000243 * @return SkData If non-NULL, holds encoded data representing the passed
244 * in bitmap. The caller is responsible for calling unref().
scroggo@google.com32ef1312013-02-22 22:04:19 +0000245 */
scroggo@google.com1b1bcc32013-05-21 20:31:23 +0000246 typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm);
scroggo@google.com32ef1312013-02-22 22:04:19 +0000247
248 /**
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000249 * Serialize to a stream. If non NULL, encoder will be used to encode
250 * any bitmaps in the picture.
scroggo@google.com1b1bcc32013-05-21 20:31:23 +0000251 * encoder will never be called with a NULL pixelRefOffset.
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000252 */
scroggo@google.com32ef1312013-02-22 22:04:19 +0000253 void serialize(SkWStream*, EncodeBitmap encoder = NULL) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000254
tomhudson@google.com381010e2013-10-24 11:12:47 +0000255 /**
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000256 * Serialize to a buffer.
257 */
258 void flatten(SkWriteBuffer&) const;
259
260 /**
tomhudson@google.com381010e2013-10-24 11:12:47 +0000261 * Returns true if any bitmaps may be produced when this SkPicture
262 * is replayed.
263 * Returns false if called while still recording.
264 */
265 bool willPlayBackBitmaps() const;
266
djsollen@google.comd9b0f482013-02-01 16:18:09 +0000267#ifdef SK_BUILD_FOR_ANDROID
reed@android.com8a1c16f2008-12-17 15:59:43 +0000268 /** Signals that the caller is prematurely done replaying the drawing
269 commands. This can be called from a canvas virtual while the picture
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000270 is drawing. Has no effect if the picture is not drawing.
djsollen@google.comd9b0f482013-02-01 16:18:09 +0000271 @deprecated preserving for legacy purposes
reed@android.com8a1c16f2008-12-17 15:59:43 +0000272 */
273 void abortPlayback();
djsollen@google.comd9b0f482013-02-01 16:18:09 +0000274#endif
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000275
commit-bot@chromium.org6f4fb0f2014-03-03 19:18:39 +0000276 /** Return true if the SkStream/Buffer represents a serialized picture, and
277 fills out SkPictInfo. After this function returns, the data source is not
skia.committer@gmail.comade9a342014-03-04 03:02:32 +0000278 rewound so it will have to be manually reset before passing to
commit-bot@chromium.org6f4fb0f2014-03-03 19:18:39 +0000279 CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
280 CreateFromBuffer perform this check internally so these entry points are
281 intended for stand alone tools.
282 If false is returned, SkPictInfo is unmodified.
283 */
284 static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
285 static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*);
286
commit-bot@chromium.orge494dbd2014-03-04 19:08:57 +0000287 /** Enable/disable all the picture recording optimizations (i.e.,
288 those in SkPictureRecord). It is mainly intended for testing the
289 existing optimizations (i.e., to actually have the pattern
290 appear in an .skp we have to disable the optimization). Call right
291 after 'beginRecording'.
292 */
293 void internalOnly_EnableOpts(bool enableOpts);
294
commit-bot@chromium.orgeb9547c2014-03-19 21:24:25 +0000295 /** Return true if the picture is suitable for rendering on the GPU.
296 */
297
298#if SK_SUPPORT_GPU
299 bool suitableForGpuRasterization(GrContext*) const;
300#endif
301
scroggo@google.com2983ddd2013-05-07 14:45:40 +0000302protected:
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000303 // V2 : adds SkPixelRef's generation ID.
304 // V3 : PictInfo tag at beginning, and EOF tag at the end
305 // V4 : move SkPictInfo to be the header
306 // V5 : don't read/write FunctionPtr on cross-process (we can detect that)
307 // V6 : added serialization of SkPath's bounds (and packed its flags tighter)
308 // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect)
309 // V8 : Add an option for encoding bitmaps
310 // V9 : Allow the reader and writer of an SKP disagree on whether to support
311 // SK_SUPPORT_HINTING_SCALE_FACTOR
reed@google.com4ed0fb72012-12-12 20:48:18 +0000312 // V10: add drawRRect, drawOval, clipRRect
scroggo@google.com74b7ffd2013-04-30 02:32:41 +0000313 // V11: modify how readBitmap and writeBitmap store their info.
reed@google.com277c3f82013-05-31 15:17:50 +0000314 // V12: add conics to SkPath, use new SkPathRef flattening
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +0000315 // V13: add flag to drawBitmapRectToRect
robertphillips@google.com7ce661d2013-08-27 16:14:03 +0000316 // parameterize blurs by sigma rather than radius
robertphillips@google.comca0c8382013-09-26 12:18:23 +0000317 // V14: Add flags word to PathRef serialization
robertphillips@google.comd5500882014-04-02 23:51:13 +0000318 // V15: Remove A1 bitmap config (and renumber remaining configs)
robertphillips@google.com466310d2013-12-03 16:43:54 +0000319 // V16: Move SkPath's isOval flag to SkPathRef
reed@google.come132f502013-12-13 19:58:46 +0000320 // V17: SkPixelRef now writes SkImageInfo
reed@google.com672588b2014-01-08 15:42:01 +0000321 // V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
commit-bot@chromium.orgfed2ab62014-01-23 15:16:05 +0000322 // V19: encode matrices and regions into the ops stream
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000323 // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
commit-bot@chromium.org210ae2a2014-02-27 17:40:13 +0000324 // V21: add pushCull, popCull
commit-bot@chromium.orgdcb8e542014-03-05 18:25:20 +0000325 // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
commit-bot@chromium.org85faf502014-04-16 12:58:02 +0000326 // V23: SkPaint::FilterLevel became a real enum
commit-bot@chromium.org44d83c12014-04-21 13:10:25 +0000327 // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
commit-bot@chromium.orgaec14382014-04-22 15:21:18 +0000328 // V25: SkDashPathEffect now only writes phase and interval array when flattening
commit-bot@chromium.org76a3b2a2014-04-24 16:54:46 +0000329 // V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
commit-bot@chromium.orgd281c922014-02-18 22:08:16 +0000330
331 // Note: If the picture version needs to be increased then please follow the
332 // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
commit-bot@chromium.orge8d96142014-02-25 02:16:10 +0000333
334 // Only SKPs within the min/current picture version range (inclusive) can be read.
335 static const uint32_t MIN_PICTURE_VERSION = 19;
commit-bot@chromium.org3339ac52014-05-22 02:55:59 +0000336 static const uint32_t CURRENT_PICTURE_VERSION = 26;
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000337
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000338 mutable uint32_t fUniqueID;
robertphillips@google.comd5500882014-04-02 23:51:13 +0000339
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000340 // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
skia.committer@gmail.comfbb0ed92012-11-13 21:46:06 +0000341 // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000342 // recorders and set the picture size
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000343 SkPicturePlayback* fPlayback;
344 SkPictureRecord* fRecord;
345 int fWidth, fHeight;
346 const AccelData* fAccelData;
robertphillips@google.com63f11272012-10-24 19:30:41 +0000347
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000348 void needsNewGenID() { fUniqueID = SK_InvalidGenID; }
robertphillips@google.comd5500882014-04-02 23:51:13 +0000349
scroggo@google.comf1754ec2013-06-28 21:32:00 +0000350 // Create a new SkPicture from an existing SkPicturePlayback. Ref count of
351 // playback is unchanged.
352 SkPicture(SkPicturePlayback*, int width, int height);
353
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000354#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
junov@chromium.org35ac0482012-11-01 17:10:32 +0000355 // For testing. Derived classes may instantiate an alternate
356 // SkBBoxHierarchy implementation
357 virtual SkBBoxHierarchy* createBBoxHierarchy() const;
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000358#endif
359
360 SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000361
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362private:
commit-bot@chromium.org8f831f22014-04-23 22:35:42 +0000363 friend class SkPictureRecord;
364 friend class SkPictureTester; // for unit testing
365
366 SkAutoTUnref<SkPathHeap> fPathHeap; // reference counted
367
commit-bot@chromium.orge2cb12a2014-04-24 21:53:13 +0000368 // ContentInfo is not serialized! It is intended solely for use
369 // with suitableForGpuRasterization.
370 class ContentInfo {
371 public:
372 ContentInfo() { this->reset(); }
373
374 ContentInfo(const ContentInfo& src) { this->set(src); }
375
376 void set(const ContentInfo& src) {
377 fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
378 fNumAAConcavePaths = src.fNumAAConcavePaths;
379 fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
380 }
381
382 void reset() {
383 fNumPaintWithPathEffectUses = 0;
384 fNumAAConcavePaths = 0;
385 fNumAAHairlineConcavePaths = 0;
386 }
387
388 void swap(ContentInfo* other) {
389 SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
390 SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
391 SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
392 }
393
394 // This field is incremented every time a paint with a path effect is
395 // used (i.e., it is not a de-duplicated count)
396 int fNumPaintWithPathEffectUses;
skia.committer@gmail.comcc9dbfb2014-04-25 03:05:58 +0000397 // This field is incremented every time an anti-aliased drawPath call is
commit-bot@chromium.orge2cb12a2014-04-24 21:53:13 +0000398 // issued with a concave path
399 int fNumAAConcavePaths;
400 // This field is incremented every time a drawPath call is
401 // issued for a hairline stroked concave path.
402 int fNumAAHairlineConcavePaths;
403 };
404
405 ContentInfo fContentInfo;
406
407 void incPaintWithPathEffectUses() {
408 ++fContentInfo.fNumPaintWithPathEffectUses;
409 }
410 int numPaintWithPathEffectUses() const {
411 return fContentInfo.fNumPaintWithPathEffectUses;
412 }
413
414 void incAAConcavePaths() {
415 ++fContentInfo.fNumAAConcavePaths;
416 }
417 int numAAConcavePaths() const {
418 return fContentInfo.fNumAAConcavePaths;
419 }
420
421 void incAAHairlineConcavePaths() {
422 ++fContentInfo.fNumAAHairlineConcavePaths;
423 SkASSERT(fContentInfo.fNumAAHairlineConcavePaths <= fContentInfo.fNumAAConcavePaths);
424 }
425 int numAAHairlineConcavePaths() const {
426 return fContentInfo.fNumAAHairlineConcavePaths;
427 }
428
commit-bot@chromium.org8f831f22014-04-23 22:35:42 +0000429 const SkPath& getPath(int index) const;
430 int addPathToHeap(const SkPath& path);
431
432 void flattenToBuffer(SkWriteBuffer& buffer) const;
433 bool parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size);
434
435 static void WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size);
436 static void WriteTagSize(SkWStream* stream, uint32_t tag, size_t size);
437
438 void initForPlayback() const;
439 void dumpSize() const;
440
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000441 // An OperationList encapsulates a set of operation offsets into the picture byte
442 // stream along with the CTMs needed for those operation.
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +0000443 class OperationList : ::SkNoncopyable {
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000444 public:
445 virtual ~OperationList() {}
446
447 // If valid returns false then there is no optimization data
448 // present. All the draw operations need to be issued.
449 virtual bool valid() const { return false; }
450
451 // The following three entry points should only be accessed if
452 // 'valid' returns true.
453 virtual int numOps() const { SkASSERT(false); return 0; };
454 // The offset in the picture of the operation to execute.
455 virtual uint32_t offset(int index) const { SkASSERT(false); return 0; };
456 // The CTM that must be installed for the operation to behave correctly
457 virtual const SkMatrix& matrix(int index) const { SkASSERT(false); return SkMatrix::I(); }
458
459 static const OperationList& InvalidList();
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000460 };
461
462 /** PRIVATE / EXPERIMENTAL -- do not call
463 Return the operations required to render the content inside 'queryRect'.
464 */
465 const OperationList& EXPERIMENTAL_getActiveOps(const SkIRect& queryRect);
466
commit-bot@chromium.org75cf29b2014-03-24 19:40:49 +0000467 /** PRIVATE / EXPERIMENTAL -- do not call
468 Return the ID of the operation currently being executed when playing
469 back. 0 indicates no call is active.
470 */
471 size_t EXPERIMENTAL_curOpID() const;
472
commit-bot@chromium.org9e5f85e2014-03-12 14:46:41 +0000473 void createHeader(SkPictInfo* info) const;
474 static bool IsValidPictInfo(const SkPictInfo& info);
commit-bot@chromium.org2ee3c2c2014-05-19 12:36:15 +0000475 static SkPicturePlayback* FakeEndRecording(const SkPicture* resourceSrc,
476 const SkPictureRecord& record,
477 bool deepCopy);
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000478
reed@android.com8a1c16f2008-12-17 15:59:43 +0000479 friend class SkFlatPicture;
480 friend class SkPicturePlayback;
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000481 friend class SkPictureRecorder;
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000482 friend class SkGpuDevice;
robertphillips@google.combeb1af22014-05-07 21:31:09 +0000483 friend class GrGatherCanvas;
commit-bot@chromium.org75cf29b2014-03-24 19:40:49 +0000484 friend class GrGatherDevice;
485 friend class SkDebugCanvas;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000486
487 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000488};
489
reed@google.com74babdf2013-05-20 17:02:41 +0000490/**
491 * Subclasses of this can be passed to canvas.drawPicture. During the drawing
492 * of the picture, this callback will periodically be invoked. If its
493 * abortDrawing() returns true, then picture playback will be interrupted.
494 *
495 * The resulting drawing is undefined, as there is no guarantee how often the
496 * callback will be invoked. If the abort happens inside some level of nested
497 * calls to save(), restore will automatically be called to return the state
498 * to the same level it was before the drawPicture call was made.
499 */
commit-bot@chromium.orgbe879bc2013-05-22 21:11:42 +0000500class SK_API SkDrawPictureCallback {
reed@google.com74babdf2013-05-20 17:02:41 +0000501public:
502 SkDrawPictureCallback() {}
503 virtual ~SkDrawPictureCallback() {}
skia.committer@gmail.com3e50e992013-05-21 07:01:40 +0000504
reed@google.com74babdf2013-05-20 17:02:41 +0000505 virtual bool abortDrawing() = 0;
506};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000507
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000508#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
509
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000510class SkPictureFactory : public SkRefCnt {
511public:
512 /**
513 * Allocate a new SkPicture. Return NULL on failure.
514 */
515 virtual SkPicture* create(int width, int height) = 0;
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000516
517private:
518 typedef SkRefCnt INHERITED;
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000519};
520
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000521#endif
522
robertphillips@google.com770963f2014-04-18 18:04:41 +0000523#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
524#include "SkPictureRecorder.h"
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000525#endif
526
reed@android.com8a1c16f2008-12-17 15:59:43 +0000527#endif