blob: ada4a21342800a43ae5702a8b0eb0dad75b99dd3 [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"
19#include "SkTextBlob.h"
20#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
54 bool setImage(int index, SkImage* img) {
55 return fImages->set(index - 1, img);
56 }
57 bool setPicture(int index, SkPicture* pic) {
58 return fPictures->set(index - 1, pic);
59 }
60 bool setTypeface(int index, SkTypeface* face) {
61 return fTypefaces->set(index - 1, face);
62 }
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) {
404 sk_sp<SkTextBlob> tb = SkTextBlob::MakeFromBuffer(reader);
405 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);
Florin Malitac2ea3272018-05-10 09:41:38 -0400565 if (sk_sp<SkData> data = reader.readByteArrayAsData()) {
566 canvas->drawVertices(SkVertices::Decode(data->data(), data->size()), bmode,
567 read_paint(reader));
568 }
reed54dc4872016-09-13 08:09:45 -0700569}
570
571static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
572 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
573 unsigned extra = unpack_verb_extra(packedVerb);
574 int index = extra & kIndex_ObjectDefinitionMask;
575 SkPicture* pic = reader.getInflator()->getPicture(index);
576 SkMatrix matrixStorage, *matrix = nullptr;
577 SkPaint paintStorage, *paint = nullptr;
578 if (extra & kHasMatrix_DrawPictureExtra) {
579 reader.readMatrix(&matrixStorage);
580 matrix = &matrixStorage;
581 }
582 if (extra & kHasPaint_DrawPictureExtra) {
583 paintStorage = read_paint(reader);
584 paint = &paintStorage;
585 }
586 canvas->drawPicture(pic, matrix, paint);
587}
588
589static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
590 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
Mike Reed22d77cb2018-01-03 13:22:51 -0500591 const SkRect* rect = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700592
593 // len includes the key's trailing 0
594 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
595 if (0 == len) {
596 len = reader.read32();
597 }
Mike Reed22d77cb2018-01-03 13:22:51 -0500598 const char* key = reader.skipT<char>(len);
reed54dc4872016-09-13 08:09:45 -0700599 sk_sp<SkData> data;
600 if (packedVerb & 1) {
601 uint32_t size = reader.read32();
602 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
603 }
604 canvas->drawAnnotation(*rect, key, data);
605}
606
607#if 0
608 stream.write("skiacodc", 8);
609 stream.write32(pmap.width());
610 stream.write32(pmap.height());
611 stream.write16(pmap.colorType());
612 stream.write16(pmap.alphaType());
613 stream.write32(0); // no colorspace for now
614 for (int y = 0; y < pmap.height(); ++y) {
615 stream.write(pmap.addr8(0, y), pmap.width());
616 }
617#endif
618
Mike Reed3ac64b42016-10-18 19:34:08 -0400619sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
Mike Reedc0cec872017-12-14 10:45:27 -0500620 if (fProcs.fImageProc) {
621 return fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
Mike Reed3ac64b42016-10-18 19:34:08 -0400622 }
Mike Reedc0cec872017-12-14 10:45:27 -0500623 return SkImage::MakeFromEncoded(data);
reed54dc4872016-09-13 08:09:45 -0700624}
625
Mike Reed3ac64b42016-10-18 19:34:08 -0400626
reed7e3ba9f2016-09-13 17:25:19 -0700627static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
reed54dc4872016-09-13 08:09:45 -0700628 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
629 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
630 uint32_t extra = unpack_verb_extra(packedVerb);
631 int index = extra & kIndex_ObjectDefinitionMask;
632
633 if (extra & kUndef_ObjectDefinitionMask) {
634 // zero-index means we are "forgetting" that cache entry
635 inflator->setImage(index, nullptr);
636 } else {
637 // we are defining a new image
638 sk_sp<SkData> data = reader.readByteArrayAsData();
Florin Malitac2ea3272018-05-10 09:41:38 -0400639 sk_sp<SkImage> image = data ? inflator->makeImage(data) : nullptr;
reed54dc4872016-09-13 08:09:45 -0700640 if (!image) {
641 SkDebugf("-- failed to decode\n");
642 }
643 inflator->setImage(index, image.get());
644 }
645}
646
647sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
Mike Reedc0cec872017-12-14 10:45:27 -0500648 if (fProcs.fTypefaceProc) {
649 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
reed54dc4872016-09-13 08:09:45 -0700650 }
651 SkMemoryStream stream(data, size, false);
652 return SkTypeface::MakeDeserialize(&stream);
653}
654
655static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
656 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
657 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
658 uint32_t extra = unpack_verb_extra(packedVerb);
659 int index = extra & kIndex_ObjectDefinitionMask;
660
661 if (extra & kUndef_ObjectDefinitionMask) {
662 // zero-index means we are "forgetting" that cache entry
663 inflator->setTypeface(index, nullptr);
664 } else {
665 // we are defining a new image
666 sk_sp<SkData> data = reader.readByteArrayAsData();
667 // TODO: seems like we could "peek" to see the array, and not need to copy it.
Florin Malitac2ea3272018-05-10 09:41:38 -0400668 sk_sp<SkTypeface> tf = data ? inflator->makeTypeface(data->data(), data->size()) : nullptr;
reed54dc4872016-09-13 08:09:45 -0700669 inflator->setTypeface(index, tf.get());
670 }
671}
672
673static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
674 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
675 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
676 uint32_t extra = unpack_verb_extra(packedVerb);
677 int index = extra >> kNameLength_DefineFactoryExtraBits;
678 size_t len = extra & kNameLength_DefineFactoryExtraMask;
679 // +1 for the trailing null char
680 const char* name = (const char*)reader.skip(SkAlign4(len + 1));
681 SkFlattenable::Factory factory = reader.findFactory(name);
682 if (factory) {
683 inflator->setFactory(index, factory);
684 }
685}
686
687static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
688 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
689 int deleteIndex = unpack_verb_extra(packedVerb);
690
691 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
692
693 if (deleteIndex) {
694 inflator->setPicture(deleteIndex - 1, nullptr);
695 } else {
696 SkPictureRecorder recorder;
697 int pictureIndex = -1; // invalid
Mike Reed22d77cb2018-01-03 13:22:51 -0500698 const SkRect* cull = reader.skipT<SkRect>();
699 if (!cull) {
700 return;
701 }
reed54dc4872016-09-13 08:09:45 -0700702 do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
703 SkASSERT(pictureIndex > 0);
704 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
705 inflator->setPicture(pictureIndex, picture.get());
706 }
707}
708
709static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
Ben Wagner7ca9a742017-08-17 14:05:04 -0400710 SK_ABORT("not reached"); // never call me
reed54dc4872016-09-13 08:09:45 -0700711}
712
713///////////////////////////////////////////////////////////////////////////////////////////////////
714
715struct HandlerRec {
716 SkPipeHandler fProc;
717 const char* fName;
718};
719
720#define HANDLER(name) { name##_handler, #name }
721const HandlerRec gPipeHandlers[] = {
722 HANDLER(save),
723 HANDLER(saveLayer),
724 HANDLER(restore),
725 HANDLER(concat),
Ben Wagner63fd7602017-10-09 15:45:33 -0400726
reed54dc4872016-09-13 08:09:45 -0700727 HANDLER(clipRect),
728 HANDLER(clipRRect),
729 HANDLER(clipPath),
730 HANDLER(clipRegion),
Ben Wagner63fd7602017-10-09 15:45:33 -0400731
reed54dc4872016-09-13 08:09:45 -0700732 HANDLER(drawArc),
733 HANDLER(drawAtlas),
734 HANDLER(drawDRRect),
735 HANDLER(drawText),
736 HANDLER(drawPosText),
737 HANDLER(drawPosTextH),
738 HANDLER(drawRegion),
739 HANDLER(drawTextOnPath),
740 HANDLER(drawTextBlob),
741 HANDLER(drawTextRSXform),
742 HANDLER(drawPatch),
743 HANDLER(drawPaint),
744 HANDLER(drawPoints),
745 HANDLER(drawRect),
746 HANDLER(drawPath),
Mike Reed7c9c9e42018-01-03 09:23:34 -0500747 HANDLER(drawShadowRec),
reed54dc4872016-09-13 08:09:45 -0700748 HANDLER(drawOval),
749 HANDLER(drawRRect),
Ben Wagner63fd7602017-10-09 15:45:33 -0400750
reed54dc4872016-09-13 08:09:45 -0700751 HANDLER(drawImage),
752 HANDLER(drawImageRect),
753 HANDLER(drawImageNine),
754 HANDLER(drawImageLattice),
Ben Wagner63fd7602017-10-09 15:45:33 -0400755
reed54dc4872016-09-13 08:09:45 -0700756 HANDLER(drawVertices),
Ben Wagner63fd7602017-10-09 15:45:33 -0400757
reed54dc4872016-09-13 08:09:45 -0700758 HANDLER(drawPicture),
759 HANDLER(drawAnnotation),
760
761 HANDLER(defineImage),
762 HANDLER(defineTypeface),
763 HANDLER(defineFactory),
764 HANDLER(definePicture),
765 HANDLER(endPicture), // handled special -- should never be called
766};
767#undef HANDLER
768
769///////////////////////////////////////////////////////////////////////////////////////////////////
770
771class SkPipeDeserializer::Impl {
772public:
773 SkRefSet<SkImage> fImages;
774 SkRefSet<SkPicture> fPictures;
775 SkRefSet<SkTypeface> fTypefaces;
776 SkTDArray<SkFlattenable::Factory> fFactories;
Mike Reedc0cec872017-12-14 10:45:27 -0500777 SkDeserialProcs fProcs;
reed54dc4872016-09-13 08:09:45 -0700778};
779
780SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
781SkPipeDeserializer::~SkPipeDeserializer() {}
782
Mike Reedc0cec872017-12-14 10:45:27 -0500783void SkPipeDeserializer::setDeserialProcs(const SkDeserialProcs& procs) {
784 fImpl->fProcs = procs;
Mike Reed3ac64b42016-10-18 19:34:08 -0400785}
786
reed54dc4872016-09-13 08:09:45 -0700787sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
788 if (size < sizeof(uint32_t)) {
reed7e3ba9f2016-09-13 17:25:19 -0700789 SkDebugf("-------- data length too short for readImage %d\n", size);
reed54dc4872016-09-13 08:09:45 -0700790 return nullptr;
791 }
792
reed7e3ba9f2016-09-13 17:25:19 -0700793 const uint32_t* ptr = (const uint32_t*)data;
794 uint32_t packedVerb = *ptr++;
795 size -= 4;
796
797 if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
798 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
799 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500800 fImpl->fProcs);
reed7e3ba9f2016-09-13 17:25:19 -0700801 SkPipeReader reader(this, ptr, size);
802 reader.setInflator(&inflator);
803 defineImage_handler(reader, packedVerb, nullptr);
804 packedVerb = reader.read32(); // read the next verb
805 }
806 if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
807 SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
reed54dc4872016-09-13 08:09:45 -0700808 return nullptr;
809 }
reed7e3ba9f2016-09-13 17:25:19 -0700810 int index = unpack_verb_extra(packedVerb);
811 if (0 == index) {
812 return nullptr; // writer failed
813 }
814 return sk_ref_sp(fImpl->fImages.get(index - 1));
reed54dc4872016-09-13 08:09:45 -0700815}
816
reed262052c2016-09-15 14:24:53 -0700817sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
818 if (size < sizeof(uint32_t)) {
819 SkDebugf("-------- data length too short for readPicture %d\n", size);
820 return nullptr;
821 }
822
823 const uint32_t* ptr = (const uint32_t*)data;
824 uint32_t packedVerb = *ptr++;
825 size -= 4;
826
827 if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
828 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
829 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500830 fImpl->fProcs);
reed262052c2016-09-15 14:24:53 -0700831 SkPipeReader reader(this, ptr, size);
832 reader.setInflator(&inflator);
833 definePicture_handler(reader, packedVerb, nullptr);
834 packedVerb = reader.read32(); // read the next verb
835 }
836 if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
837 SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
838 return nullptr;
839 }
840 int index = unpack_verb_extra(packedVerb);
841 if (0 == index) {
842 return nullptr; // writer failed
843 }
844 return sk_ref_sp(fImpl->fPictures.get(index - 1));
845}
846
reed54dc4872016-09-13 08:09:45 -0700847static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
848 int indent = 0;
849
850 const bool showEachVerb = false;
851 int counter = 0;
852 while (!reader.eof()) {
853 uint32_t prevOffset = reader.offset();
854 uint32_t packedVerb = reader.read32();
855 SkPipeVerb verb = unpack_verb(packedVerb);
856 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
857 SkDebugf("------- bad verb %d\n", verb);
858 return false;
859 }
860 if (SkPipeVerb::kRestore == verb) {
861 indent -= 1;
862 SkASSERT(indent >= 0);
863 }
864
865 if (SkPipeVerb::kEndPicture == verb) {
866 if (endPictureIndex) {
867 *endPictureIndex = unpack_verb_extra(packedVerb);
868 }
869 return true;
870 }
871 HandlerRec rec = gPipeHandlers[(unsigned)verb];
872 rec.fProc(reader, packedVerb, canvas);
873 if (showEachVerb) {
874 for (int i = 0; i < indent; ++i) {
875 SkDebugf(" ");
876 }
877 SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
878 }
879 if (!reader.isValid()) {
880 SkDebugf("-------- bad reader\n");
881 return false;
882 }
883
884 switch (verb) {
885 case SkPipeVerb::kSave:
886 case SkPipeVerb::kSaveLayer:
887 indent += 1;
888 break;
889 default:
890 break;
891 }
892 }
893 return true;
894}
895
896bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
897 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
898 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500899 fImpl->fProcs);
reed54dc4872016-09-13 08:09:45 -0700900 SkPipeReader reader(this, data, size);
901 reader.setInflator(&inflator);
902 return do_playback(reader, canvas);
903}
904