blob: 8a6216e1aa14092a9ed12b1b9c0c095bb01b2a89 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2007 The Android Open Source Project
reed@android.com8a1c16f2008-12-17 15:59:43 +00003 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00004 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@android.com8a1c16f2008-12-17 15:59:43 +00006 */
7
epoger@google.comec3ed6a2011-07-28 14:26:00 +00008
reed@android.com8a1c16f2008-12-17 15:59:43 +00009#ifndef SkPicture_DEFINED
10#define SkPicture_DEFINED
11
scroggo@google.comf1754ec2013-06-28 21:32:00 +000012#include "SkImageDecoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013#include "SkRefCnt.h"
robertphillips3afef1f2014-07-08 06:12:22 -070014#include "SkTDArray.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015
commit-bot@chromium.orgeb9547c2014-03-19 21:24:25 +000016#if SK_SUPPORT_GPU
17class GrContext;
18#endif
19
robertphillips783fe162015-01-07 07:28:41 -080020class SkBitmap;
junov@chromium.org35ac0482012-11-01 17:10:32 +000021class SkBBoxHierarchy;
reed@android.com8a1c16f2008-12-17 15:59:43 +000022class SkCanvas;
scroggo@google.com1b1bcc32013-05-21 20:31:23 +000023class SkData;
robertphillipsdb539902014-07-01 08:47:04 -070024class SkPictureData;
scroggo895c43b2014-12-11 10:53:58 -080025class SkPixelSerializer;
reed@android.com8a1c16f2008-12-17 15:59:43 +000026class SkStream;
27class SkWStream;
28
scroggo@google.comf1754ec2013-06-28 21:32:00 +000029struct SkPictInfo;
30
Mike Klein744fb732014-06-23 15:13:26 -040031class SkRecord;
32
robertphillipsd8aa7b72014-10-30 16:45:02 -070033namespace SkRecords {
34 class CollectLayers;
35};
36
reed@android.com8a1c16f2008-12-17 15:59:43 +000037/** \class SkPicture
38
39 The SkPicture class records the drawing commands made to a canvas, to
40 be played back at a later time.
41*/
mtklein08d1fcc2014-11-20 09:18:31 -080042class SK_API SkPicture : public SkNVRefCnt<SkPicture> {
reed@android.com8a1c16f2008-12-17 15:59:43 +000043public:
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000044 // AccelData provides a base class for device-specific acceleration
robertphillips82365912014-11-12 09:32:34 -080045 // data. It is added to the picture via EXPERIMENTAL_addAccelData.
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000046 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;
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000060 };
61
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000062 /** PRIVATE / EXPERIMENTAL -- do not call */
Mike Klein744fb732014-06-23 15:13:26 -040063 void EXPERIMENTAL_addAccelData(const AccelData*) const;
64
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000065 /** PRIVATE / EXPERIMENTAL -- do not call */
Mike Klein744fb732014-06-23 15:13:26 -040066 const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key) const;
commit-bot@chromium.org145d1c02014-03-16 19:46:36 +000067
reed@google.com34342f62012-06-25 14:36:28 +000068 /**
scroggo@google.comf8d7d272013-02-22 21:38:35 +000069 * Function signature defining a function that sets up an SkBitmap from encoded data. On
70 * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
71 * If the installed pixelref has decoded the data into pixels, then the src buffer need not be
72 * copied. If the pixelref defers the actual decode until its lockPixels() is called, then it
73 * must make a copy of the src buffer.
74 * @param src Encoded data.
75 * @param length Size of the encoded data, in bytes.
76 * @param dst SkBitmap to install the pixel ref on.
77 * @param bool Whether or not a pixel ref was successfully installed.
78 */
79 typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
80
81 /**
82 * Recreate a picture that was serialized into a stream.
scroggoa1193e42015-01-21 12:09:53 -080083 * @param SkStream Serialized picture data. Ownership is unchanged by this call.
scroggo@google.comf8d7d272013-02-22 21:38:35 +000084 * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
85 * encoded bitmap data from the stream.
scroggo@google.comf1754ec2013-06-28 21:32:00 +000086 * @return A new SkPicture representing the serialized data, or NULL if the stream is
87 * invalid.
scroggo@google.comf8d7d272013-02-22 21:38:35 +000088 */
scroggo@google.comf1754ec2013-06-28 21:32:00 +000089 static SkPicture* CreateFromStream(SkStream*,
90 InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
scroggo@google.comf8d7d272013-02-22 21:38:35 +000091
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000092 /**
93 * Recreate a picture that was serialized into a buffer. If the creation requires bitmap
94 * decoding, the decoder must be set on the SkReadBuffer parameter by calling
95 * SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
96 * @param SkReadBuffer Serialized picture data.
97 * @return A new SkPicture representing the serialized data, or NULL if the buffer is
98 * invalid.
99 */
100 static SkPicture* CreateFromBuffer(SkReadBuffer&);
101
mtklein08d1fcc2014-11-20 09:18:31 -0800102 ~SkPicture();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000103
robertphillips783fe162015-01-07 07:28:41 -0800104 /**
105 * Subclasses of this can be passed to playback(). During the playback
106 * of the picture, this callback will periodically be invoked. If its
107 * abort() returns true, then picture playback will be interrupted.
108 *
109 * The resulting drawing is undefined, as there is no guarantee how often the
110 * callback will be invoked. If the abort happens inside some level of nested
111 * calls to save(), restore will automatically be called to return the state
112 * to the same level it was before the playback call was made.
113 */
114 class SK_API AbortCallback {
115 public:
116 AbortCallback() {}
117 virtual ~AbortCallback() {}
118
119 virtual bool abort() = 0;
120 };
121
robertphillipsc5ba71d2014-09-04 08:42:50 -0700122 /** Replays the drawing commands on the specified canvas. Note that
123 this has the effect of unfurling this picture into the destination
124 canvas. Using the SkCanvas::drawPicture entry point gives the destination
125 canvas the option of just taking a ref.
reed@google.com74babdf2013-05-20 17:02:41 +0000126 @param canvas the canvas receiving the drawing commands.
robertphillipsc5ba71d2014-09-04 08:42:50 -0700127 @param callback a callback that allows interruption of playback
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128 */
robertphillips783fe162015-01-07 07:28:41 -0800129 void playback(SkCanvas* canvas, AbortCallback* = NULL) const;
robertphillipsc5ba71d2014-09-04 08:42:50 -0700130
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700131 /** Return the cull rect used when creating this picture: { 0, 0, cullWidth, cullHeight }.
132 It does not necessarily reflect the bounds of what has been recorded into the picture.
133 @return the cull rect used to create this picture
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 */
reed78e27682014-11-19 08:04:34 -0800135 SkRect cullRect() const { return fCullRect; }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136
reed41d2c2e2014-11-21 08:07:41 -0800137 /** Return a non-zero, unique value representing the picture.
138 */
mtkleine35268e2015-04-07 06:34:05 -0700139 uint32_t uniqueID() const;
robertphillips@google.comd5500882014-04-02 23:51:13 +0000140
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000141 /**
scroggo895c43b2014-12-11 10:53:58 -0800142 * Serialize to a stream. If non NULL, serializer will be used to serialize
143 * any bitmaps in the picture.
144 *
145 * TODO: Use serializer to serialize SkImages as well.
146 */
147 void serialize(SkWStream*, SkPixelSerializer* serializer = NULL) const;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000148
tomhudson@google.com381010e2013-10-24 11:12:47 +0000149 /**
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000150 * Serialize to a buffer.
151 */
152 void flatten(SkWriteBuffer&) const;
153
154 /**
tomhudson@google.com381010e2013-10-24 11:12:47 +0000155 * Returns true if any bitmaps may be produced when this SkPicture
156 * is replayed.
tomhudson@google.com381010e2013-10-24 11:12:47 +0000157 */
158 bool willPlayBackBitmaps() const;
159
commit-bot@chromium.org6f4fb0f2014-03-03 19:18:39 +0000160 /** Return true if the SkStream/Buffer represents a serialized picture, and
161 fills out SkPictInfo. After this function returns, the data source is not
skia.committer@gmail.comade9a342014-03-04 03:02:32 +0000162 rewound so it will have to be manually reset before passing to
commit-bot@chromium.org6f4fb0f2014-03-03 19:18:39 +0000163 CreateFromStream or CreateFromBuffer. Note, CreateFromStream and
164 CreateFromBuffer perform this check internally so these entry points are
165 intended for stand alone tools.
166 If false is returned, SkPictInfo is unmodified.
167 */
168 static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700169 static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*);
commit-bot@chromium.org6f4fb0f2014-03-03 19:18:39 +0000170
commit-bot@chromium.orgeb9547c2014-03-19 21:24:25 +0000171 /** Return true if the picture is suitable for rendering on the GPU.
172 */
173
174#if SK_SUPPORT_GPU
commit-bot@chromium.orga1ff26a2014-05-30 21:52:52 +0000175 bool suitableForGpuRasterization(GrContext*, const char ** = NULL) const;
commit-bot@chromium.orgeb9547c2014-03-19 21:24:25 +0000176#endif
177
mtklein5a246bb2014-08-14 19:17:18 -0700178 /** Return the approximate number of operations in this picture. This
179 * number may be greater or less than the number of SkCanvas calls
180 * recorded: some calls may be recorded as more than one operation, or some
181 * calls may be optimized away.
182 */
183 int approximateOpCount() const;
184
ajuma750ae262014-08-18 12:59:55 -0700185 /** Return true if this picture contains text.
186 */
187 bool hasText() const;
188
mtklein19ac7672014-11-21 12:20:35 -0800189 // An array of refcounted const SkPicture pointers.
190 class SnapshotArray : ::SkNoncopyable {
191 public:
reed735f5482014-11-23 18:37:14 -0800192 SnapshotArray(const SkPicture* pics[], int count) : fPics(pics), fCount(count) {}
193 ~SnapshotArray() { for (int i = 0; i < fCount; i++) { fPics[i]->unref(); } }
mtkleinb7ee3492014-11-21 11:06:04 -0800194
195 const SkPicture* const* begin() const { return fPics; }
reed735f5482014-11-23 18:37:14 -0800196 int count() const { return fCount; }
mtkleinb7ee3492014-11-21 11:06:04 -0800197 private:
198 SkAutoTMalloc<const SkPicture*> fPics;
reed735f5482014-11-23 18:37:14 -0800199 int fCount;
mtkleinb7ee3492014-11-21 11:06:04 -0800200 };
201
mtklein04c96952014-11-24 08:20:57 -0800202 // Sent via SkMessageBus from destructor.
203 struct DeletionMessage { int32_t fUniqueID; };
204
robertphillips6daadc72014-07-08 08:38:18 -0700205private:
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000206 // V2 : adds SkPixelRef's generation ID.
207 // V3 : PictInfo tag at beginning, and EOF tag at the end
208 // V4 : move SkPictInfo to be the header
209 // V5 : don't read/write FunctionPtr on cross-process (we can detect that)
210 // V6 : added serialization of SkPath's bounds (and packed its flags tighter)
211 // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect)
212 // V8 : Add an option for encoding bitmaps
213 // V9 : Allow the reader and writer of an SKP disagree on whether to support
214 // SK_SUPPORT_HINTING_SCALE_FACTOR
reed@google.com4ed0fb72012-12-12 20:48:18 +0000215 // V10: add drawRRect, drawOval, clipRRect
scroggo@google.com74b7ffd2013-04-30 02:32:41 +0000216 // V11: modify how readBitmap and writeBitmap store their info.
reed@google.com277c3f82013-05-31 15:17:50 +0000217 // V12: add conics to SkPath, use new SkPathRef flattening
commit-bot@chromium.orgeed779d2013-08-16 10:24:37 +0000218 // V13: add flag to drawBitmapRectToRect
robertphillips@google.com7ce661d2013-08-27 16:14:03 +0000219 // parameterize blurs by sigma rather than radius
robertphillips@google.comca0c8382013-09-26 12:18:23 +0000220 // V14: Add flags word to PathRef serialization
robertphillips@google.comd5500882014-04-02 23:51:13 +0000221 // V15: Remove A1 bitmap config (and renumber remaining configs)
robertphillips@google.com466310d2013-12-03 16:43:54 +0000222 // V16: Move SkPath's isOval flag to SkPathRef
reed@google.come132f502013-12-13 19:58:46 +0000223 // V17: SkPixelRef now writes SkImageInfo
reed@google.com672588b2014-01-08 15:42:01 +0000224 // V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
commit-bot@chromium.orgfed2ab62014-01-23 15:16:05 +0000225 // V19: encode matrices and regions into the ops stream
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000226 // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
commit-bot@chromium.org210ae2a2014-02-27 17:40:13 +0000227 // V21: add pushCull, popCull
commit-bot@chromium.orgdcb8e542014-03-05 18:25:20 +0000228 // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
commit-bot@chromium.org85faf502014-04-16 12:58:02 +0000229 // V23: SkPaint::FilterLevel became a real enum
commit-bot@chromium.org44d83c12014-04-21 13:10:25 +0000230 // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
commit-bot@chromium.orgaec14382014-04-22 15:21:18 +0000231 // V25: SkDashPathEffect now only writes phase and interval array when flattening
commit-bot@chromium.org76a3b2a2014-04-24 16:54:46 +0000232 // V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
commit-bot@chromium.org83f23d82014-05-22 12:27:41 +0000233 // V27: Remove SkUnitMapper from gradients (and skia).
commit-bot@chromium.org968edca2014-05-23 13:21:55 +0000234 // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.
Florin Malita5f6102d2014-06-30 10:13:28 -0400235 // V29: Removed SaveFlags parameter from save().
scroggoc870d492014-07-11 10:42:12 -0700236 // V30: Remove redundant SkMatrix from SkLocalMatrixShader.
senorblanco55b6d8b2014-07-30 11:26:46 -0700237 // V31: Add a serialized UniqueID to SkImageFilter.
djsollen3b625542014-08-14 06:29:02 -0700238 // V32: Removed SkPaintOptionsAndroid from SkPaint
fmalitab7425172014-08-26 07:56:44 -0700239 // V33: Serialize only public API of effects.
240 // V34: Add SkTextBlob serialization.
robertphillipsa8d7f0b2014-08-29 08:03:56 -0700241 // V35: Store SkRect (rather then width & height) in header
reedc5e15a12014-09-29 12:10:27 -0700242 // V36: Remove (obsolete) alphatype from SkColorTable
reed8eddfb52014-12-04 07:50:14 -0800243 // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR)
junovf3c78cc2014-12-09 13:07:22 -0800244 // V38: Added PictureResolution option to SkPictureImageFilter
245 // V39: Added FilterLevel option to SkPictureImageFilter
senorblanco4a22a432015-03-18 13:14:54 -0700246 // V40: Remove UniqueID serialization from SkImageFilter.
robertphillips25c40d22015-04-10 08:39:58 -0700247 // V41: Added serialization of SkBitmapSource's filterQuality parameter
commit-bot@chromium.orgd281c922014-02-18 22:08:16 +0000248
249 // Note: If the picture version needs to be increased then please follow the
250 // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
commit-bot@chromium.orge8d96142014-02-25 02:16:10 +0000251
252 // Only SKPs within the min/current picture version range (inclusive) can be read.
mtklein88fd0fb2014-12-01 06:56:38 -0800253 static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
robertphillips25c40d22015-04-10 08:39:58 -0700254 static const uint32_t CURRENT_PICTURE_VERSION = 41;
robertphillips@google.com9a5b5702012-11-13 20:41:18 +0000255
bungeman9d911d52015-04-17 11:00:06 -0700256 static_assert(MIN_PICTURE_VERSION <= 41,
257 "Remove kFontFileName and related code from SkFontDescriptor.cpp.");
258
commit-bot@chromium.org9e5f85e2014-03-12 14:46:41 +0000259 void createHeader(SkPictInfo* info) const;
260 static bool IsValidPictInfo(const SkPictInfo& info);
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000261
mtklein19ac7672014-11-21 12:20:35 -0800262 // Takes ownership of the SkRecord and (optional) SnapshotArray, refs the (optional) BBH.
mtkleinb7ee3492014-11-21 11:06:04 -0800263 SkPicture(const SkRect& cullRect, SkRecord*, SnapshotArray*, SkBBoxHierarchy*);
mtklein5ad6ee12014-08-11 08:08:43 -0700264
mtkleinc6ad9ee2014-11-17 06:45:18 -0800265 static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*);
reed6be2aa92014-11-18 11:08:05 -0800266 static SkPictureData* Backport(const SkRecord&, const SkPictInfo&,
267 SkPicture const* const drawablePics[], int drawableCount);
mtkleinc6ad9ee2014-11-17 06:45:18 -0800268
mtklein08d1fcc2014-11-20 09:18:31 -0800269 // uint32_t fRefCnt; from SkNVRefCnt<SkPicture>
mtkleine35268e2015-04-07 06:34:05 -0700270 mutable uint32_t fUniqueID;
reed78e27682014-11-19 08:04:34 -0800271 const SkRect fCullRect;
mtkleinc6ad9ee2014-11-17 06:45:18 -0800272 mutable SkAutoTUnref<const AccelData> fAccelData;
reed1bdfd3f2014-11-24 14:41:51 -0800273 SkAutoTUnref<const SkRecord> fRecord;
274 SkAutoTUnref<const SkBBoxHierarchy> fBBH;
275 SkAutoTDelete<const SnapshotArray> fDrawablePicts;
reed6be2aa92014-11-18 11:08:05 -0800276
277 // helpers for fDrawablePicts
278 int drawableCount() const;
279 // will return NULL if drawableCount() returns 0
280 SkPicture const* const* drawablePicts() const;
281
282 struct PathCounter;
283
tomhudson3a0f2792014-08-20 05:29:41 -0700284 struct Analysis {
mtkleinc551d9f2014-08-20 08:09:46 -0700285 Analysis() {} // Only used by SkPictureData codepath.
286 explicit Analysis(const SkRecord&);
tomhudson3a0f2792014-08-20 05:29:41 -0700287
288 bool suitableForGpuRasterization(const char** reason, int sampleCount) const;
289
290 bool fWillPlaybackBitmaps;
mtkleinc551d9f2014-08-20 08:09:46 -0700291 bool fHasText;
tomhudson3a0f2792014-08-20 05:29:41 -0700292 int fNumPaintWithPathEffectUses;
293 int fNumFastPathDashEffects;
294 int fNumAAConcavePaths;
295 int fNumAAHairlineConcavePaths;
jvanverthf7007b02014-11-04 07:59:01 -0800296 int fNumAADFEligibleConcavePaths;
mtkleinc551d9f2014-08-20 08:09:46 -0700297 } fAnalysis;
mtkleinc6ad9ee2014-11-17 06:45:18 -0800298
mtkleinc6ad9ee2014-11-17 06:45:18 -0800299 friend class SkPictureRecorder; // SkRecord-based constructor.
300 friend class GrLayerHoister; // access to fRecord
301 friend class ReplaceDraw;
tomhudson158fcaa2014-11-19 10:41:14 -0800302 friend class SkPictureUtils;
reed1bdfd3f2014-11-24 14:41:51 -0800303 friend class SkRecordedDrawable;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000304};
mtklein08d1fcc2014-11-20 09:18:31 -0800305SK_COMPILE_ASSERT(sizeof(SkPicture) <= 96, SkPictureSize);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000306
reed@android.com8a1c16f2008-12-17 15:59:43 +0000307#endif