blob: 44681ea7e619ba8b7d0e5c0383a33cf24e617faa [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.org83f23d82014-05-22 12:27:41 +0000330 // V27: Remove SkUnitMapper from gradients (and skia).
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000331 // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.
commit-bot@chromium.orgd281c922014-02-18 22:08:16 +0000332
333 // Note: If the picture version needs to be increased then please follow the
334 // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
commit-bot@chromium.orge8d96142014-02-25 02:16:10 +0000335
336 // Only SKPs within the min/current picture version range (inclusive) can be read.
337 static const uint32_t MIN_PICTURE_VERSION = 19;
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000338 static const uint32_t CURRENT_PICTURE_VERSION = 28;
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000339
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000340 mutable uint32_t fUniqueID;
robertphillips@google.comd5500882014-04-02 23:51:13 +0000341
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000342 // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
skia.committer@gmail.comfbb0ed92012-11-13 21:46:06 +0000343 // install their own SkPicturePlayback-derived players,SkPictureRecord-derived
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000344 // recorders and set the picture size
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +0000345 SkPicturePlayback* fPlayback;
346 SkPictureRecord* fRecord;
347 int fWidth, fHeight;
348 const AccelData* fAccelData;
robertphillips@google.com63f11272012-10-24 19:30:41 +0000349
commit-bot@chromium.org2b4e3702014-04-07 18:26:22 +0000350 void needsNewGenID() { fUniqueID = SK_InvalidGenID; }
robertphillips@google.comd5500882014-04-02 23:51:13 +0000351
scroggo@google.comf1754ec2013-06-28 21:32:00 +0000352 // Create a new SkPicture from an existing SkPicturePlayback. Ref count of
353 // playback is unchanged.
354 SkPicture(SkPicturePlayback*, int width, int height);
355
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000356#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
junov@chromium.org35ac0482012-11-01 17:10:32 +0000357 // For testing. Derived classes may instantiate an alternate
358 // SkBBoxHierarchy implementation
359 virtual SkBBoxHierarchy* createBBoxHierarchy() const;
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000360#endif
361
362 SkCanvas* beginRecording(int width, int height, SkBBHFactory* factory, uint32_t recordFlags);
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000363
reed@android.com8a1c16f2008-12-17 15:59:43 +0000364private:
commit-bot@chromium.org8f831f22014-04-23 22:35:42 +0000365 friend class SkPictureRecord;
366 friend class SkPictureTester; // for unit testing
367
368 SkAutoTUnref<SkPathHeap> fPathHeap; // reference counted
369
commit-bot@chromium.orge2cb12a2014-04-24 21:53:13 +0000370 // ContentInfo is not serialized! It is intended solely for use
371 // with suitableForGpuRasterization.
372 class ContentInfo {
373 public:
374 ContentInfo() { this->reset(); }
375
376 ContentInfo(const ContentInfo& src) { this->set(src); }
377
378 void set(const ContentInfo& src) {
379 fNumPaintWithPathEffectUses = src.fNumPaintWithPathEffectUses;
380 fNumAAConcavePaths = src.fNumAAConcavePaths;
381 fNumAAHairlineConcavePaths = src.fNumAAHairlineConcavePaths;
382 }
383
384 void reset() {
385 fNumPaintWithPathEffectUses = 0;
386 fNumAAConcavePaths = 0;
387 fNumAAHairlineConcavePaths = 0;
388 }
389
390 void swap(ContentInfo* other) {
391 SkTSwap(fNumPaintWithPathEffectUses, other->fNumPaintWithPathEffectUses);
392 SkTSwap(fNumAAConcavePaths, other->fNumAAConcavePaths);
393 SkTSwap(fNumAAHairlineConcavePaths, other->fNumAAHairlineConcavePaths);
394 }
395
396 // This field is incremented every time a paint with a path effect is
397 // used (i.e., it is not a de-duplicated count)
398 int fNumPaintWithPathEffectUses;
skia.committer@gmail.comcc9dbfb2014-04-25 03:05:58 +0000399 // This field is incremented every time an anti-aliased drawPath call is
commit-bot@chromium.orge2cb12a2014-04-24 21:53:13 +0000400 // issued with a concave path
401 int fNumAAConcavePaths;
402 // This field is incremented every time a drawPath call is
403 // issued for a hairline stroked concave path.
404 int fNumAAHairlineConcavePaths;
405 };
406
407 ContentInfo fContentInfo;
408
409 void incPaintWithPathEffectUses() {
410 ++fContentInfo.fNumPaintWithPathEffectUses;
411 }
412 int numPaintWithPathEffectUses() const {
413 return fContentInfo.fNumPaintWithPathEffectUses;
414 }
415
416 void incAAConcavePaths() {
417 ++fContentInfo.fNumAAConcavePaths;
418 }
419 int numAAConcavePaths() const {
420 return fContentInfo.fNumAAConcavePaths;
421 }
422
423 void incAAHairlineConcavePaths() {
424 ++fContentInfo.fNumAAHairlineConcavePaths;
425 SkASSERT(fContentInfo.fNumAAHairlineConcavePaths <= fContentInfo.fNumAAConcavePaths);
426 }
427 int numAAHairlineConcavePaths() const {
428 return fContentInfo.fNumAAHairlineConcavePaths;
429 }
430
commit-bot@chromium.org8f831f22014-04-23 22:35:42 +0000431 const SkPath& getPath(int index) const;
432 int addPathToHeap(const SkPath& path);
433
434 void flattenToBuffer(SkWriteBuffer& buffer) const;
435 bool parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size);
436
437 static void WriteTagSize(SkWriteBuffer& buffer, uint32_t tag, size_t size);
438 static void WriteTagSize(SkWStream* stream, uint32_t tag, size_t size);
439
440 void initForPlayback() const;
441 void dumpSize() const;
442
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000443 // An OperationList encapsulates a set of operation offsets into the picture byte
444 // stream along with the CTMs needed for those operation.
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +0000445 class OperationList : ::SkNoncopyable {
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000446 public:
447 virtual ~OperationList() {}
448
449 // If valid returns false then there is no optimization data
450 // present. All the draw operations need to be issued.
451 virtual bool valid() const { return false; }
452
453 // The following three entry points should only be accessed if
454 // 'valid' returns true.
455 virtual int numOps() const { SkASSERT(false); return 0; };
456 // The offset in the picture of the operation to execute.
457 virtual uint32_t offset(int index) const { SkASSERT(false); return 0; };
458 // The CTM that must be installed for the operation to behave correctly
459 virtual const SkMatrix& matrix(int index) const { SkASSERT(false); return SkMatrix::I(); }
460
461 static const OperationList& InvalidList();
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000462 };
463
464 /** PRIVATE / EXPERIMENTAL -- do not call
465 Return the operations required to render the content inside 'queryRect'.
466 */
467 const OperationList& EXPERIMENTAL_getActiveOps(const SkIRect& queryRect);
468
commit-bot@chromium.org75cf29b2014-03-24 19:40:49 +0000469 /** PRIVATE / EXPERIMENTAL -- do not call
470 Return the ID of the operation currently being executed when playing
471 back. 0 indicates no call is active.
472 */
473 size_t EXPERIMENTAL_curOpID() const;
474
commit-bot@chromium.org9e5f85e2014-03-12 14:46:41 +0000475 void createHeader(SkPictInfo* info) const;
476 static bool IsValidPictInfo(const SkPictInfo& info);
commit-bot@chromium.org2ee3c2c2014-05-19 12:36:15 +0000477 static SkPicturePlayback* FakeEndRecording(const SkPicture* resourceSrc,
478 const SkPictureRecord& record,
479 bool deepCopy);
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000480
reed@android.com8a1c16f2008-12-17 15:59:43 +0000481 friend class SkFlatPicture;
482 friend class SkPicturePlayback;
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000483 friend class SkPictureRecorder;
commit-bot@chromium.org70512af2014-03-18 17:45:32 +0000484 friend class SkGpuDevice;
robertphillips@google.combeb1af22014-05-07 21:31:09 +0000485 friend class GrGatherCanvas;
commit-bot@chromium.org75cf29b2014-03-24 19:40:49 +0000486 friend class GrGatherDevice;
487 friend class SkDebugCanvas;
robertphillips@google.com15e9d3e2012-06-21 20:25:03 +0000488
489 typedef SkRefCnt INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000490};
491
reed@google.com74babdf2013-05-20 17:02:41 +0000492/**
493 * Subclasses of this can be passed to canvas.drawPicture. During the drawing
494 * of the picture, this callback will periodically be invoked. If its
495 * abortDrawing() returns true, then picture playback will be interrupted.
496 *
497 * The resulting drawing is undefined, as there is no guarantee how often the
498 * callback will be invoked. If the abort happens inside some level of nested
499 * calls to save(), restore will automatically be called to return the state
500 * to the same level it was before the drawPicture call was made.
501 */
commit-bot@chromium.orgbe879bc2013-05-22 21:11:42 +0000502class SK_API SkDrawPictureCallback {
reed@google.com74babdf2013-05-20 17:02:41 +0000503public:
504 SkDrawPictureCallback() {}
505 virtual ~SkDrawPictureCallback() {}
skia.committer@gmail.com3e50e992013-05-21 07:01:40 +0000506
reed@google.com74babdf2013-05-20 17:02:41 +0000507 virtual bool abortDrawing() = 0;
508};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000509
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000510#ifdef SK_SUPPORT_LEGACY_DERIVED_PICTURE_CLASSES
511
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000512class SkPictureFactory : public SkRefCnt {
513public:
514 /**
515 * Allocate a new SkPicture. Return NULL on failure.
516 */
517 virtual SkPicture* create(int width, int height) = 0;
commit-bot@chromium.orgd393b172014-04-16 16:02:10 +0000518
519private:
520 typedef SkRefCnt INHERITED;
robertphillips@google.com84b18c72014-04-13 19:09:42 +0000521};
522
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000523#endif
524
robertphillips@google.com770963f2014-04-18 18:04:41 +0000525#ifdef SK_SUPPORT_LEGACY_PICTURE_HEADERS
526#include "SkPictureRecorder.h"
commit-bot@chromium.org5fb2ce32014-04-17 23:35:06 +0000527#endif
528
reed@android.com8a1c16f2008-12-17 15:59:43 +0000529#endif