blob: 909276f41baf8669a4d6af0be439e02c32b56e14 [file] [log] [blame]
reed54dc4872016-09-13 08:09:45 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkCanvas.h"
Mike Reed7c9c9e42018-01-03 09:23:34 -05009#include "SkCanvasPriv.h"
reed54dc4872016-09-13 08:09:45 -070010#include "SkDeduper.h"
Mike Reed7c9c9e42018-01-03 09:23:34 -050011#include "SkDrawShadowInfo.h"
reed54dc4872016-09-13 08:09:45 -070012#include "SkPicture.h"
13#include "SkPictureRecorder.h"
14#include "SkPipe.h"
15#include "SkPipeFormat.h"
16#include "SkReadBuffer.h"
17#include "SkRefSet.h"
18#include "SkRSXform.h"
Cary Clark53c87692018-07-17 08:59:34 -040019#include "SkTextBlobPriv.h"
reed54dc4872016-09-13 08:09:45 -070020#include "SkTypeface.h"
Mike Reed887cdf12017-04-03 11:11:09 -040021#include "SkVertices.h"
reed54dc4872016-09-13 08:09:45 -070022
23class SkPipeReader;
24
25static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex = nullptr);
26
27///////////////////////////////////////////////////////////////////////////////////////////////////
28
29class SkPipeInflator : public SkInflator {
30public:
31 SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures,
32 SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Factory>* factories,
Mike Reedc0cec872017-12-14 10:45:27 -050033 const SkDeserialProcs& procs)
reed54dc4872016-09-13 08:09:45 -070034 : fImages(images)
35 , fPictures(pictures)
36 , fTypefaces(typefaces)
37 , fFactories(factories)
Mike Reedc0cec872017-12-14 10:45:27 -050038 , fProcs(procs)
reed54dc4872016-09-13 08:09:45 -070039 {}
Ben Wagner63fd7602017-10-09 15:45:33 -040040
reed54dc4872016-09-13 08:09:45 -070041 SkImage* getImage(int index) override {
42 return index ? fImages->get(index - 1) : nullptr;
43 }
44 SkPicture* getPicture(int index) override {
45 return index ? fPictures->get(index - 1) : nullptr;
46 }
47 SkTypeface* getTypeface(int index) override {
48 return fTypefaces->get(index - 1);
49 }
50 SkFlattenable::Factory getFactory(int index) override {
51 return index ? fFactories->getAt(index - 1) : nullptr;
52 }
53
Ben Wagner36fe60d2018-07-10 17:38:12 -040054 bool setImage(int index, sk_sp<SkImage> img) {
55 return fImages->set(index - 1, std::move(img));
reed54dc4872016-09-13 08:09:45 -070056 }
Ben Wagner36fe60d2018-07-10 17:38:12 -040057 bool setPicture(int index, sk_sp<SkPicture> pic) {
58 return fPictures->set(index - 1, std::move(pic));
reed54dc4872016-09-13 08:09:45 -070059 }
Ben Wagner36fe60d2018-07-10 17:38:12 -040060 bool setTypeface(int index, sk_sp<SkTypeface> face) {
61 return fTypefaces->set(index - 1, std::move(face));
reed54dc4872016-09-13 08:09:45 -070062 }
63 bool setFactory(int index, SkFlattenable::Factory factory) {
64 SkASSERT(index > 0);
65 SkASSERT(factory);
66 index -= 1;
67 if ((unsigned)index < (unsigned)fFactories->count()) {
68 (*fFactories)[index] = factory;
69 return true;
70 }
71 if (fFactories->count() == index) {
72 *fFactories->append() = factory;
73 return true;
74 }
75 SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories->count());
76 return false;
77 }
78
Mike Reedc0cec872017-12-14 10:45:27 -050079 void setDeserialProcs(const SkDeserialProcs& procs) {
80 fProcs = procs;
Mike Reed3ac64b42016-10-18 19:34:08 -040081 }
Ben Wagner63fd7602017-10-09 15:45:33 -040082
reed54dc4872016-09-13 08:09:45 -070083 sk_sp<SkTypeface> makeTypeface(const void* data, size_t size);
Mike Reed3ac64b42016-10-18 19:34:08 -040084 sk_sp<SkImage> makeImage(const sk_sp<SkData>&);
reed54dc4872016-09-13 08:09:45 -070085
86private:
87 SkRefSet<SkImage>* fImages;
88 SkRefSet<SkPicture>* fPictures;
89 SkRefSet<SkTypeface>* fTypefaces;
90 SkTDArray<SkFlattenable::Factory>* fFactories;
Mike Reedc0cec872017-12-14 10:45:27 -050091 SkDeserialProcs fProcs;
reed54dc4872016-09-13 08:09:45 -070092};
93
94///////////////////////////////////////////////////////////////////////////////////////////////////
95
reed54dc4872016-09-13 08:09:45 -070096static SkRRect read_rrect(SkReadBuffer& reader) {
97 SkRRect rrect;
98 rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory);
99 return rrect;
100}
101
102static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) {
103 SkMatrix matrix;
104 matrix.reset();
105
106 if (tm & SkMatrix::kPerspective_Mask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500107 matrix.set9(reader.skipT<SkScalar>(9));
reed54dc4872016-09-13 08:09:45 -0700108 } else if (tm & SkMatrix::kAffine_Mask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500109 const SkScalar* tmp = reader.skipT<SkScalar>(6);
reed54dc4872016-09-13 08:09:45 -0700110 matrix[SkMatrix::kMScaleX] = tmp[0];
111 matrix[SkMatrix::kMSkewX] = tmp[1];
112 matrix[SkMatrix::kMTransX] = tmp[2];
113 matrix[SkMatrix::kMScaleY] = tmp[3];
114 matrix[SkMatrix::kMSkewY] = tmp[4];
115 matrix[SkMatrix::kMTransY] = tmp[5];
116 } else if (tm & SkMatrix::kScale_Mask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500117 const SkScalar* tmp = reader.skipT<SkScalar>(4);
reed54dc4872016-09-13 08:09:45 -0700118 matrix[SkMatrix::kMScaleX] = tmp[0];
119 matrix[SkMatrix::kMTransX] = tmp[1];
120 matrix[SkMatrix::kMScaleY] = tmp[2];
121 matrix[SkMatrix::kMTransY] = tmp[3];
122 } else if (tm & SkMatrix::kTranslate_Mask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500123 const SkScalar* tmp = reader.skipT<SkScalar>(2);
reed54dc4872016-09-13 08:09:45 -0700124 matrix[SkMatrix::kMTransX] = tmp[0];
125 matrix[SkMatrix::kMTransY] = tmp[1];
126 }
127 // else read nothing for Identity
128 return matrix;
129}
130
131///////////////////////////////////////////////////////////////////////////////////////////////////
132
133#define CHECK_SET_SCALAR(Field) \
134 do { if (nondef & k##Field##_NonDef) { \
135 paint.set##Field(reader.readScalar()); \
136 }} while (0)
137
138#define CHECK_SET_FLATTENABLE(Field) \
139 do { if (nondef & k##Field##_NonDef) { \
140 paint.set##Field(reader.read##Field()); \
141 }} while (0)
142
143/*
144 * Header:
145 * paint flags : 32
146 * non_def bits : 16
147 * xfermode enum : 8
148 * pad zeros : 8
149 */
150static SkPaint read_paint(SkReadBuffer& reader) {
reed374772b2016-10-05 17:33:02 -0700151 SkPaint paint;
152
reed54dc4872016-09-13 08:09:45 -0700153 uint32_t packedFlags = reader.read32();
154 uint32_t extra = reader.read32();
155 unsigned nondef = extra >> 16;
reed374772b2016-10-05 17:33:02 -0700156 paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF));
157 SkASSERT((extra & 0xFF) == 0); // zero pad byte
reed54dc4872016-09-13 08:09:45 -0700158
159 packedFlags >>= 2; // currently unused
160 paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFlags >>= 2;
161 paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFlags >>= 2;
162 paint.setHinting((SkPaint::Hinting)(packedFlags & 3)); packedFlags >>= 2;
163 paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFlags >>= 2;
164 paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFlags >>= 2;
165 paint.setStyle((SkPaint::Style)(packedFlags & 3)); packedFlags >>= 2;
166 paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFlags >>= 2;
167 paint.setFlags(packedFlags);
168
169 CHECK_SET_SCALAR(TextSize);
170 CHECK_SET_SCALAR(TextScaleX);
171 CHECK_SET_SCALAR(TextSkewX);
172 CHECK_SET_SCALAR(StrokeWidth);
173 CHECK_SET_SCALAR(StrokeMiter);
174
175 if (nondef & kColor_NonDef) {
176 paint.setColor(reader.read32());
177 }
178
179 CHECK_SET_FLATTENABLE(Typeface);
180 CHECK_SET_FLATTENABLE(PathEffect);
181 CHECK_SET_FLATTENABLE(Shader);
reed54dc4872016-09-13 08:09:45 -0700182 CHECK_SET_FLATTENABLE(MaskFilter);
183 CHECK_SET_FLATTENABLE(ColorFilter);
reed54dc4872016-09-13 08:09:45 -0700184 CHECK_SET_FLATTENABLE(ImageFilter);
185 CHECK_SET_FLATTENABLE(DrawLooper);
186
reed54dc4872016-09-13 08:09:45 -0700187 return paint;
188}
189
190class SkPipeReader : public SkReadBuffer {
191public:
192 SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size)
193 : SkReadBuffer(data, size)
194 , fSink(sink)
195 {}
196
197 SkPipeDeserializer* fSink;
198
199 SkFlattenable::Factory findFactory(const char name[]) {
200 SkFlattenable::Factory factory;
201 // Check if a custom Factory has been specified for this flattenable.
202 if (!(factory = this->getCustomFactory(SkString(name)))) {
203 // If there is no custom Factory, check for a default.
204 factory = SkFlattenable::NameToFactory(name);
205 }
206 return factory;
207 }
Ben Wagner63fd7602017-10-09 15:45:33 -0400208
Mike Reede97e7922018-01-18 15:57:38 -0500209 bool readPaint(SkPaint* paint) override {
reed54dc4872016-09-13 08:09:45 -0700210 *paint = read_paint(*this);
Mike Reede97e7922018-01-18 15:57:38 -0500211 return this->isValid();
reed54dc4872016-09-13 08:09:45 -0700212 }
213};
214
215///////////////////////////////////////////////////////////////////////////////////////////////////
216
217typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*);
218
219static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
220 SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb));
221 canvas->save();
222}
223
224static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
225 SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb));
226 unsigned extra = unpack_verb_extra(packedVerb);
Mike Reed22d77cb2018-01-03 13:22:51 -0500227 const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? reader.skipT<SkRect>() : nullptr;
reed54dc4872016-09-13 08:09:45 -0700228 SkPaint paintStorage, *paint = nullptr;
229 if (extra & kHasPaint_SaveLayerMask) {
230 paintStorage = read_paint(reader);
231 paint = &paintStorage;
232 }
233 sk_sp<SkImageFilter> backdrop;
234 if (extra & kHasBackdrop_SaveLayerMask) {
235 backdrop = reader.readImageFilter();
236 }
Florin Malita53f77bd2017-04-28 13:48:37 -0400237 sk_sp<SkImage> clipMask;
238 if (extra & kHasClipMask_SaveLayerMask) {
239 clipMask = reader.readImage();
240 }
241 SkMatrix clipMatrix;
242 if (extra & kHasClipMatrix_SaveLayerMask) {
243 reader.readMatrix(&clipMatrix);
244 }
reed54dc4872016-09-13 08:09:45 -0700245 SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);
246
247 // unremap this wacky flag
248 if (extra & kDontClipToLayer_SaveLayerMask) {
Cary Clark7eddfb82018-03-13 14:41:10 -0400249 flags |= SkCanvasPriv::kDontClipToLayer_SaveLayerFlag;
reed54dc4872016-09-13 08:09:45 -0700250 }
251
Mike Kleinb34ab042017-05-01 21:34:14 +0000252 canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), clipMask.get(),
Florin Malita53f77bd2017-04-28 13:48:37 -0400253 (extra & kHasClipMatrix_SaveLayerMask) ? &clipMatrix : nullptr, flags));
reed54dc4872016-09-13 08:09:45 -0700254}
255
256static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
257 SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb));
258 canvas->restore();
259}
260
261static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
262 SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb));
263 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)(packedVerb & kTypeMask_ConcatMask);
264 const SkMatrix matrix = read_sparse_matrix(reader, tm);
265 if (packedVerb & kSetMatrix_ConcatMask) {
266 canvas->setMatrix(matrix);
267 } else {
268 canvas->concat(matrix);
269 }
270}
271
272static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
273 SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb));
Mike Reedc1f77742016-12-09 09:00:50 -0500274 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
reed54dc4872016-09-13 08:09:45 -0700275 bool isAA = unpack_verb_extra(packedVerb) & 1;
Mike Reed22d77cb2018-01-03 13:22:51 -0500276 canvas->clipRect(*reader.skipT<SkRect>(), op, isAA);
reed54dc4872016-09-13 08:09:45 -0700277}
278
279static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
280 SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb));
Mike Reedc1f77742016-12-09 09:00:50 -0500281 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
reed54dc4872016-09-13 08:09:45 -0700282 bool isAA = unpack_verb_extra(packedVerb) & 1;
283 canvas->clipRRect(read_rrect(reader), op, isAA);
284}
285
286static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
287 SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb));
Mike Reedc1f77742016-12-09 09:00:50 -0500288 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
reed54dc4872016-09-13 08:09:45 -0700289 bool isAA = unpack_verb_extra(packedVerb) & 1;
290 SkPath path;
291 reader.readPath(&path);
292 canvas->clipPath(path, op, isAA);
293}
294
295static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
296 SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb));
Mike Reedc1f77742016-12-09 09:00:50 -0500297 SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
reed54dc4872016-09-13 08:09:45 -0700298 SkRegion region;
299 reader.readRegion(&region);
300 canvas->clipRegion(region, op);
301}
302
303static void drawArc_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
304 SkASSERT(SkPipeVerb::kDrawArc == unpack_verb(packedVerb));
305 const bool useCenter = (bool)(unpack_verb_extra(packedVerb) & 1);
Mike Reed22d77cb2018-01-03 13:22:51 -0500306 const SkScalar* scalars = reader.skipT<SkScalar>(6); // bounds[0..3], start[4], sweep[5]
reed54dc4872016-09-13 08:09:45 -0700307 const SkRect* bounds = (const SkRect*)scalars;
308 canvas->drawArc(*bounds, scalars[4], scalars[5], useCenter, read_paint(reader));
309}
310
311static void drawAtlas_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
312 SkASSERT(SkPipeVerb::kDrawAtlas == unpack_verb(packedVerb));
Mike Reed7d954ad2016-10-28 15:42:34 -0400313 SkBlendMode mode = (SkBlendMode)(packedVerb & kMode_DrawAtlasMask);
reed54dc4872016-09-13 08:09:45 -0700314 sk_sp<SkImage> image(reader.readImage());
315 int count = reader.read32();
Mike Reed22d77cb2018-01-03 13:22:51 -0500316 const SkRSXform* xform = reader.skipT<SkRSXform>(count);
317 const SkRect* rect = reader.skipT<SkRect>(count);
reed54dc4872016-09-13 08:09:45 -0700318 const SkColor* color = nullptr;
319 if (packedVerb & kHasColors_DrawAtlasMask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500320 color = reader.skipT<SkColor>(count);
reed54dc4872016-09-13 08:09:45 -0700321 }
322 const SkRect* cull = nullptr;
323 if (packedVerb & kHasCull_DrawAtlasMask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500324 cull = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700325 }
326 SkPaint paintStorage, *paint = nullptr;
327 if (packedVerb & kHasPaint_DrawAtlasMask) {
328 paintStorage = read_paint(reader);
329 paint = &paintStorage;
330 }
331 canvas->drawAtlas(image, xform, rect, color, count, mode, cull, paint);
332}
333
334static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
335 SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb));
336 const SkRRect outer = read_rrect(reader);
337 const SkRRect inner = read_rrect(reader);
338 canvas->drawDRRect(outer, inner, read_paint(reader));
339}
340
341static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
342 SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb));
343 uint32_t len = unpack_verb_extra(packedVerb);
344 if (0 == len) {
345 len = reader.read32();
346 }
347 const void* text = reader.skip(SkAlign4(len));
348 SkScalar x = reader.readScalar();
349 SkScalar y = reader.readScalar();
350 canvas->drawText(text, len, x, y, read_paint(reader));
351}
352
353static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
354 SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb));
355 uint32_t len = unpack_verb_extra(packedVerb);
356 if (0 == len) {
357 len = reader.read32();
358 }
359 const void* text = reader.skip(SkAlign4(len));
360 int count = reader.read32();
Mike Reed22d77cb2018-01-03 13:22:51 -0500361 const SkPoint* pos = reader.skipT<SkPoint>(count);
reed54dc4872016-09-13 08:09:45 -0700362 SkPaint paint = read_paint(reader);
363 SkASSERT(paint.countText(text, len) == count);
364 canvas->drawPosText(text, len, pos, paint);
365}
366
367static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
368 SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb));
369 uint32_t len = unpack_verb_extra(packedVerb);
370 if (0 == len) {
371 len = reader.read32();
372 }
373 const void* text = reader.skip(SkAlign4(len));
374 int count = reader.read32();
Mike Reed22d77cb2018-01-03 13:22:51 -0500375 const SkScalar* xpos = reader.skipT<SkScalar>(count);
reed54dc4872016-09-13 08:09:45 -0700376 SkScalar constY = reader.readScalar();
377 SkPaint paint = read_paint(reader);
378 SkASSERT(paint.countText(text, len) == count);
379 canvas->drawPosTextH(text, len, xpos, constY, paint);
380}
381
382static void drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
383 SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb));
384 uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask;
385 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)
386 ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTextOnPathShift);
387
388 if (0 == byteLength) {
389 byteLength = reader.read32();
390 }
391 const void* text = reader.skip(SkAlign4(byteLength));
392 SkPath path;
393 reader.readPath(&path);
394 const SkMatrix* matrix = nullptr;
395 SkMatrix matrixStorage;
396 if (tm != SkMatrix::kIdentity_Mask) {
397 matrixStorage = read_sparse_matrix(reader, tm);
398 matrix = &matrixStorage;
399 }
400 canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader));
401}
402
403static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
Cary Clark53c87692018-07-17 08:59:34 -0400404 sk_sp<SkTextBlob> tb = SkTextBlobPriv::MakeFromBuffer(reader);
reed54dc4872016-09-13 08:09:45 -0700405 SkScalar x = reader.readScalar();
406 SkScalar y = reader.readScalar();
407 canvas->drawTextBlob(tb, x, y, read_paint(reader));
408}
409
410static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
411 SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb));
412 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
413 if (0 == len) {
414 len = reader.read32();
415 }
416 const void* text = reader.skip(SkAlign4(len));
417 int count = reader.read32();
Mike Reed22d77cb2018-01-03 13:22:51 -0500418 const SkRSXform* xform = reader.skipT<SkRSXform>(count);
419 const SkRect* cull = (packedVerb & 1) ? reader.skipT<SkRect>() : nullptr;
reed54dc4872016-09-13 08:09:45 -0700420 SkPaint paint = read_paint(reader);
421 SkASSERT(paint.countText(text, len) == count);
422 canvas->drawTextRSXform(text, len, xform, cull, paint);
423}
424
425static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
426 SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb));
427 const SkColor* colors = nullptr;
428 const SkPoint* tex = nullptr;
Mike Reed22d77cb2018-01-03 13:22:51 -0500429 const SkPoint* cubics = reader.skipT<SkPoint>(12);
reed54dc4872016-09-13 08:09:45 -0700430 if (packedVerb & kHasColors_DrawPatchExtraMask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500431 colors = reader.skipT<SkColor>(4);
reed54dc4872016-09-13 08:09:45 -0700432 }
433 if (packedVerb & kHasTexture_DrawPatchExtraMask) {
Mike Reed22d77cb2018-01-03 13:22:51 -0500434 tex = reader.skipT<SkPoint>(4);
reed54dc4872016-09-13 08:09:45 -0700435 }
Mike Reed7d954ad2016-10-28 15:42:34 -0400436 SkBlendMode mode = (SkBlendMode)(packedVerb & kModeEnum_DrawPatchExtraMask);
437 canvas->drawPatch(cubics, colors, tex, mode, read_paint(reader));
reed54dc4872016-09-13 08:09:45 -0700438}
439
440static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
441 SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb));
442 canvas->drawPaint(read_paint(reader));
443}
444
445static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
446 SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb));
Mike Reed22d77cb2018-01-03 13:22:51 -0500447 const SkRect* rect = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700448 canvas->drawRect(*rect, read_paint(reader));
449}
450
451static void drawRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
452 SkASSERT(SkPipeVerb::kDrawRegion == unpack_verb(packedVerb));
453 size_t size = unpack_verb_extra(packedVerb);
454 if (0 == size) {
455 size = reader.read32();
456 }
457 SkRegion region;
Mike Reed22d77cb2018-01-03 13:22:51 -0500458 region.readFromMemory(reader.skipT<char>(size), size);
reed54dc4872016-09-13 08:09:45 -0700459 canvas->drawRegion(region, read_paint(reader));
460}
461
462static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
463 SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb));
Mike Reed22d77cb2018-01-03 13:22:51 -0500464 const SkRect* rect = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700465 canvas->drawOval(*rect, read_paint(reader));
466}
467
468static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
469 SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb));
470 SkRRect rrect = read_rrect(reader);
471 canvas->drawRRect(rrect, read_paint(reader));
472}
473
474static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
475 SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb));
476 SkPath path;
477 reader.readPath(&path);
478 canvas->drawPath(path, read_paint(reader));
479}
480
Mike Reed7c9c9e42018-01-03 09:23:34 -0500481static void drawShadowRec_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
482 SkASSERT(SkPipeVerb::kDrawShadowRec == unpack_verb(packedVerb));
483 SkPath path;
484 reader.readPath(&path);
485 SkDrawShadowRec rec;
486 reader.readPad32(&rec, sizeof(rec));
487 canvas->private_draw_shadow_rec(path, rec);
488}
489
reed54dc4872016-09-13 08:09:45 -0700490static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
491 SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb));
492 SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb);
493 int count = reader.read32();
Mike Reed22d77cb2018-01-03 13:22:51 -0500494 const SkPoint* points = reader.skipT<SkPoint>(count);
reed54dc4872016-09-13 08:09:45 -0700495 canvas->drawPoints(mode, count, points, read_paint(reader));
496}
497
498static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
499 SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb));
500 sk_sp<SkImage> image(reader.readImage());
501 SkScalar x = reader.readScalar();
502 SkScalar y = reader.readScalar();
503 SkPaint paintStorage, *paint = nullptr;
504 if (packedVerb & kHasPaint_DrawImageMask) {
505 paintStorage = read_paint(reader);
506 paint = &paintStorage;
507 }
508 canvas->drawImage(image, x, y, paint);
509}
510
511static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
512 SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb));
513 sk_sp<SkImage> image(reader.readImage());
514 SkCanvas::SrcRectConstraint constraint =
515 (SkCanvas::SrcRectConstraint)(packedVerb & kConstraint_DrawImageRectMask);
516 const SkRect* src = (packedVerb & kHasSrcRect_DrawImageRectMask) ?
Mike Reed22d77cb2018-01-03 13:22:51 -0500517 reader.skipT<SkRect>() : nullptr;
518 const SkRect* dst = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700519 SkPaint paintStorage, *paint = nullptr;
520 if (packedVerb & kHasPaint_DrawImageRectMask) {
521 paintStorage = read_paint(reader);
522 paint = &paintStorage;
523 }
524 if (src) {
525 canvas->drawImageRect(image, *src, *dst, paint, constraint);
526 } else {
527 canvas->drawImageRect(image, *dst, paint);
528 }
529}
530
531static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
532 SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb));
533 sk_sp<SkImage> image(reader.readImage());
Mike Reed22d77cb2018-01-03 13:22:51 -0500534 const SkIRect* center = reader.skipT<SkIRect>();
535 const SkRect* dst = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700536 SkPaint paintStorage, *paint = nullptr;
537 if (packedVerb & kHasPaint_DrawImageNineMask) {
538 paintStorage = read_paint(reader);
539 paint = &paintStorage;
540 }
541 canvas->drawImageNine(image, *center, *dst, paint);
542}
543
544static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
545 SkASSERT(SkPipeVerb::kDrawImageLattice == unpack_verb(packedVerb));
546 sk_sp<SkImage> image(reader.readImage());
547
548 SkCanvas::Lattice lattice;
Mike Reed7c9c9e42018-01-03 09:23:34 -0500549 if (!SkCanvasPriv::ReadLattice(reader, &lattice)) {
550 return;
reed54dc4872016-09-13 08:09:45 -0700551 }
Mike Reed22d77cb2018-01-03 13:22:51 -0500552 const SkRect* dst = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700553
554 SkPaint paintStorage, *paint = nullptr;
555 if (packedVerb & kHasPaint_DrawImageLatticeMask) {
556 paintStorage = read_paint(reader);
557 paint = &paintStorage;
558 }
559 canvas->drawImageLattice(image.get(), lattice, *dst, paint);
560}
561
562static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
563 SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb));
Mike Reed887cdf12017-04-03 11:11:09 -0400564 SkBlendMode bmode = (SkBlendMode)unpack_verb_extra(packedVerb);
Ruiqi Maof5101492018-06-29 14:32:21 -0400565 sk_sp<SkVertices> vertices = nullptr;
Florin Malitac2ea3272018-05-10 09:41:38 -0400566 if (sk_sp<SkData> data = reader.readByteArrayAsData()) {
Ruiqi Maof5101492018-06-29 14:32:21 -0400567 vertices = SkVertices::Decode(data->data(), data->size());
568 }
569 int boneCount = reader.read32();
570 const SkMatrix* bones = boneCount ? reader.skipT<SkMatrix>(boneCount) : nullptr;
571 if (vertices) {
572 canvas->drawVertices(vertices, bones, boneCount, bmode, read_paint(reader));
Florin Malitac2ea3272018-05-10 09:41:38 -0400573 }
reed54dc4872016-09-13 08:09:45 -0700574}
575
576static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
577 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
578 unsigned extra = unpack_verb_extra(packedVerb);
579 int index = extra & kIndex_ObjectDefinitionMask;
580 SkPicture* pic = reader.getInflator()->getPicture(index);
581 SkMatrix matrixStorage, *matrix = nullptr;
582 SkPaint paintStorage, *paint = nullptr;
583 if (extra & kHasMatrix_DrawPictureExtra) {
584 reader.readMatrix(&matrixStorage);
585 matrix = &matrixStorage;
586 }
587 if (extra & kHasPaint_DrawPictureExtra) {
588 paintStorage = read_paint(reader);
589 paint = &paintStorage;
590 }
591 canvas->drawPicture(pic, matrix, paint);
592}
593
594static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
595 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
Mike Reed22d77cb2018-01-03 13:22:51 -0500596 const SkRect* rect = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700597
598 // len includes the key's trailing 0
599 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
600 if (0 == len) {
601 len = reader.read32();
602 }
Mike Reed22d77cb2018-01-03 13:22:51 -0500603 const char* key = reader.skipT<char>(len);
reed54dc4872016-09-13 08:09:45 -0700604 sk_sp<SkData> data;
605 if (packedVerb & 1) {
606 uint32_t size = reader.read32();
607 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
608 }
609 canvas->drawAnnotation(*rect, key, data);
610}
611
612#if 0
613 stream.write("skiacodc", 8);
614 stream.write32(pmap.width());
615 stream.write32(pmap.height());
616 stream.write16(pmap.colorType());
617 stream.write16(pmap.alphaType());
618 stream.write32(0); // no colorspace for now
619 for (int y = 0; y < pmap.height(); ++y) {
620 stream.write(pmap.addr8(0, y), pmap.width());
621 }
622#endif
623
Mike Reed3ac64b42016-10-18 19:34:08 -0400624sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
Mike Reedc0cec872017-12-14 10:45:27 -0500625 if (fProcs.fImageProc) {
626 return fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
Mike Reed3ac64b42016-10-18 19:34:08 -0400627 }
Mike Reedc0cec872017-12-14 10:45:27 -0500628 return SkImage::MakeFromEncoded(data);
reed54dc4872016-09-13 08:09:45 -0700629}
630
Mike Reed3ac64b42016-10-18 19:34:08 -0400631
reed7e3ba9f2016-09-13 17:25:19 -0700632static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
reed54dc4872016-09-13 08:09:45 -0700633 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
634 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
635 uint32_t extra = unpack_verb_extra(packedVerb);
636 int index = extra & kIndex_ObjectDefinitionMask;
637
638 if (extra & kUndef_ObjectDefinitionMask) {
639 // zero-index means we are "forgetting" that cache entry
640 inflator->setImage(index, nullptr);
641 } else {
642 // we are defining a new image
643 sk_sp<SkData> data = reader.readByteArrayAsData();
Florin Malitac2ea3272018-05-10 09:41:38 -0400644 sk_sp<SkImage> image = data ? inflator->makeImage(data) : nullptr;
reed54dc4872016-09-13 08:09:45 -0700645 if (!image) {
646 SkDebugf("-- failed to decode\n");
647 }
Ben Wagner36fe60d2018-07-10 17:38:12 -0400648 inflator->setImage(index, std::move(image));
reed54dc4872016-09-13 08:09:45 -0700649 }
650}
651
652sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
Mike Reedc0cec872017-12-14 10:45:27 -0500653 if (fProcs.fTypefaceProc) {
654 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
reed54dc4872016-09-13 08:09:45 -0700655 }
656 SkMemoryStream stream(data, size, false);
657 return SkTypeface::MakeDeserialize(&stream);
658}
659
660static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
661 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
662 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
663 uint32_t extra = unpack_verb_extra(packedVerb);
664 int index = extra & kIndex_ObjectDefinitionMask;
665
666 if (extra & kUndef_ObjectDefinitionMask) {
667 // zero-index means we are "forgetting" that cache entry
668 inflator->setTypeface(index, nullptr);
669 } else {
670 // we are defining a new image
671 sk_sp<SkData> data = reader.readByteArrayAsData();
672 // TODO: seems like we could "peek" to see the array, and not need to copy it.
Florin Malitac2ea3272018-05-10 09:41:38 -0400673 sk_sp<SkTypeface> tf = data ? inflator->makeTypeface(data->data(), data->size()) : nullptr;
Ben Wagner36fe60d2018-07-10 17:38:12 -0400674 inflator->setTypeface(index, std::move(tf));
reed54dc4872016-09-13 08:09:45 -0700675 }
676}
677
678static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
679 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
680 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
681 uint32_t extra = unpack_verb_extra(packedVerb);
682 int index = extra >> kNameLength_DefineFactoryExtraBits;
683 size_t len = extra & kNameLength_DefineFactoryExtraMask;
684 // +1 for the trailing null char
685 const char* name = (const char*)reader.skip(SkAlign4(len + 1));
686 SkFlattenable::Factory factory = reader.findFactory(name);
687 if (factory) {
688 inflator->setFactory(index, factory);
689 }
690}
691
692static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
693 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
694 int deleteIndex = unpack_verb_extra(packedVerb);
695
696 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
697
698 if (deleteIndex) {
699 inflator->setPicture(deleteIndex - 1, nullptr);
700 } else {
701 SkPictureRecorder recorder;
702 int pictureIndex = -1; // invalid
Mike Reed22d77cb2018-01-03 13:22:51 -0500703 const SkRect* cull = reader.skipT<SkRect>();
704 if (!cull) {
705 return;
706 }
reed54dc4872016-09-13 08:09:45 -0700707 do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
708 SkASSERT(pictureIndex > 0);
709 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
Ben Wagner36fe60d2018-07-10 17:38:12 -0400710 inflator->setPicture(pictureIndex, std::move(picture));
reed54dc4872016-09-13 08:09:45 -0700711 }
712}
713
714static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
Ben Wagner7ca9a742017-08-17 14:05:04 -0400715 SK_ABORT("not reached"); // never call me
reed54dc4872016-09-13 08:09:45 -0700716}
717
718///////////////////////////////////////////////////////////////////////////////////////////////////
719
720struct HandlerRec {
721 SkPipeHandler fProc;
722 const char* fName;
723};
724
725#define HANDLER(name) { name##_handler, #name }
726const HandlerRec gPipeHandlers[] = {
727 HANDLER(save),
728 HANDLER(saveLayer),
729 HANDLER(restore),
730 HANDLER(concat),
Ben Wagner63fd7602017-10-09 15:45:33 -0400731
reed54dc4872016-09-13 08:09:45 -0700732 HANDLER(clipRect),
733 HANDLER(clipRRect),
734 HANDLER(clipPath),
735 HANDLER(clipRegion),
Ben Wagner63fd7602017-10-09 15:45:33 -0400736
reed54dc4872016-09-13 08:09:45 -0700737 HANDLER(drawArc),
738 HANDLER(drawAtlas),
739 HANDLER(drawDRRect),
740 HANDLER(drawText),
741 HANDLER(drawPosText),
742 HANDLER(drawPosTextH),
743 HANDLER(drawRegion),
744 HANDLER(drawTextOnPath),
745 HANDLER(drawTextBlob),
746 HANDLER(drawTextRSXform),
747 HANDLER(drawPatch),
748 HANDLER(drawPaint),
749 HANDLER(drawPoints),
750 HANDLER(drawRect),
751 HANDLER(drawPath),
Mike Reed7c9c9e42018-01-03 09:23:34 -0500752 HANDLER(drawShadowRec),
reed54dc4872016-09-13 08:09:45 -0700753 HANDLER(drawOval),
754 HANDLER(drawRRect),
Ben Wagner63fd7602017-10-09 15:45:33 -0400755
reed54dc4872016-09-13 08:09:45 -0700756 HANDLER(drawImage),
757 HANDLER(drawImageRect),
758 HANDLER(drawImageNine),
759 HANDLER(drawImageLattice),
Ben Wagner63fd7602017-10-09 15:45:33 -0400760
reed54dc4872016-09-13 08:09:45 -0700761 HANDLER(drawVertices),
Ben Wagner63fd7602017-10-09 15:45:33 -0400762
reed54dc4872016-09-13 08:09:45 -0700763 HANDLER(drawPicture),
764 HANDLER(drawAnnotation),
765
766 HANDLER(defineImage),
767 HANDLER(defineTypeface),
768 HANDLER(defineFactory),
769 HANDLER(definePicture),
770 HANDLER(endPicture), // handled special -- should never be called
771};
772#undef HANDLER
773
774///////////////////////////////////////////////////////////////////////////////////////////////////
775
776class SkPipeDeserializer::Impl {
777public:
778 SkRefSet<SkImage> fImages;
779 SkRefSet<SkPicture> fPictures;
780 SkRefSet<SkTypeface> fTypefaces;
781 SkTDArray<SkFlattenable::Factory> fFactories;
Mike Reedc0cec872017-12-14 10:45:27 -0500782 SkDeserialProcs fProcs;
reed54dc4872016-09-13 08:09:45 -0700783};
784
785SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
786SkPipeDeserializer::~SkPipeDeserializer() {}
787
Mike Reedc0cec872017-12-14 10:45:27 -0500788void SkPipeDeserializer::setDeserialProcs(const SkDeserialProcs& procs) {
789 fImpl->fProcs = procs;
Mike Reed3ac64b42016-10-18 19:34:08 -0400790}
791
reed54dc4872016-09-13 08:09:45 -0700792sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
793 if (size < sizeof(uint32_t)) {
reed7e3ba9f2016-09-13 17:25:19 -0700794 SkDebugf("-------- data length too short for readImage %d\n", size);
reed54dc4872016-09-13 08:09:45 -0700795 return nullptr;
796 }
797
reed7e3ba9f2016-09-13 17:25:19 -0700798 const uint32_t* ptr = (const uint32_t*)data;
799 uint32_t packedVerb = *ptr++;
800 size -= 4;
801
802 if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
803 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
804 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500805 fImpl->fProcs);
reed7e3ba9f2016-09-13 17:25:19 -0700806 SkPipeReader reader(this, ptr, size);
807 reader.setInflator(&inflator);
808 defineImage_handler(reader, packedVerb, nullptr);
809 packedVerb = reader.read32(); // read the next verb
810 }
811 if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
812 SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
reed54dc4872016-09-13 08:09:45 -0700813 return nullptr;
814 }
reed7e3ba9f2016-09-13 17:25:19 -0700815 int index = unpack_verb_extra(packedVerb);
816 if (0 == index) {
817 return nullptr; // writer failed
818 }
819 return sk_ref_sp(fImpl->fImages.get(index - 1));
reed54dc4872016-09-13 08:09:45 -0700820}
821
reed262052c2016-09-15 14:24:53 -0700822sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
823 if (size < sizeof(uint32_t)) {
824 SkDebugf("-------- data length too short for readPicture %d\n", size);
825 return nullptr;
826 }
827
828 const uint32_t* ptr = (const uint32_t*)data;
829 uint32_t packedVerb = *ptr++;
830 size -= 4;
831
832 if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
833 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
834 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500835 fImpl->fProcs);
reed262052c2016-09-15 14:24:53 -0700836 SkPipeReader reader(this, ptr, size);
837 reader.setInflator(&inflator);
838 definePicture_handler(reader, packedVerb, nullptr);
839 packedVerb = reader.read32(); // read the next verb
840 }
841 if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
842 SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
843 return nullptr;
844 }
845 int index = unpack_verb_extra(packedVerb);
846 if (0 == index) {
847 return nullptr; // writer failed
848 }
849 return sk_ref_sp(fImpl->fPictures.get(index - 1));
850}
851
reed54dc4872016-09-13 08:09:45 -0700852static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
853 int indent = 0;
854
855 const bool showEachVerb = false;
856 int counter = 0;
857 while (!reader.eof()) {
858 uint32_t prevOffset = reader.offset();
859 uint32_t packedVerb = reader.read32();
860 SkPipeVerb verb = unpack_verb(packedVerb);
861 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
862 SkDebugf("------- bad verb %d\n", verb);
863 return false;
864 }
865 if (SkPipeVerb::kRestore == verb) {
866 indent -= 1;
867 SkASSERT(indent >= 0);
868 }
869
870 if (SkPipeVerb::kEndPicture == verb) {
871 if (endPictureIndex) {
872 *endPictureIndex = unpack_verb_extra(packedVerb);
873 }
874 return true;
875 }
876 HandlerRec rec = gPipeHandlers[(unsigned)verb];
877 rec.fProc(reader, packedVerb, canvas);
878 if (showEachVerb) {
879 for (int i = 0; i < indent; ++i) {
880 SkDebugf(" ");
881 }
882 SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
883 }
884 if (!reader.isValid()) {
885 SkDebugf("-------- bad reader\n");
886 return false;
887 }
888
889 switch (verb) {
890 case SkPipeVerb::kSave:
891 case SkPipeVerb::kSaveLayer:
892 indent += 1;
893 break;
894 default:
895 break;
896 }
897 }
898 return true;
899}
900
901bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
902 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
903 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500904 fImpl->fProcs);
reed54dc4872016-09-13 08:09:45 -0700905 SkPipeReader reader(this, data, size);
906 reader.setInflator(&inflator);
907 return do_playback(reader, canvas);
908}
909