blob: 2614c4ecd519ad1c295d4a347e8a8e9eb0779c7b [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);
565 sk_sp<SkData> data = reader.readByteArrayAsData();
566 canvas->drawVertices(SkVertices::Decode(data->data(), data->size()), bmode, read_paint(reader));
reed54dc4872016-09-13 08:09:45 -0700567}
568
569static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
570 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
571 unsigned extra = unpack_verb_extra(packedVerb);
572 int index = extra & kIndex_ObjectDefinitionMask;
573 SkPicture* pic = reader.getInflator()->getPicture(index);
574 SkMatrix matrixStorage, *matrix = nullptr;
575 SkPaint paintStorage, *paint = nullptr;
576 if (extra & kHasMatrix_DrawPictureExtra) {
577 reader.readMatrix(&matrixStorage);
578 matrix = &matrixStorage;
579 }
580 if (extra & kHasPaint_DrawPictureExtra) {
581 paintStorage = read_paint(reader);
582 paint = &paintStorage;
583 }
584 canvas->drawPicture(pic, matrix, paint);
585}
586
587static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
588 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
Mike Reed22d77cb2018-01-03 13:22:51 -0500589 const SkRect* rect = reader.skipT<SkRect>();
reed54dc4872016-09-13 08:09:45 -0700590
591 // len includes the key's trailing 0
592 uint32_t len = unpack_verb_extra(packedVerb) >> 1;
593 if (0 == len) {
594 len = reader.read32();
595 }
Mike Reed22d77cb2018-01-03 13:22:51 -0500596 const char* key = reader.skipT<char>(len);
reed54dc4872016-09-13 08:09:45 -0700597 sk_sp<SkData> data;
598 if (packedVerb & 1) {
599 uint32_t size = reader.read32();
600 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
601 }
602 canvas->drawAnnotation(*rect, key, data);
603}
604
605#if 0
606 stream.write("skiacodc", 8);
607 stream.write32(pmap.width());
608 stream.write32(pmap.height());
609 stream.write16(pmap.colorType());
610 stream.write16(pmap.alphaType());
611 stream.write32(0); // no colorspace for now
612 for (int y = 0; y < pmap.height(); ++y) {
613 stream.write(pmap.addr8(0, y), pmap.width());
614 }
615#endif
616
Mike Reed3ac64b42016-10-18 19:34:08 -0400617sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
Mike Reedc0cec872017-12-14 10:45:27 -0500618 if (fProcs.fImageProc) {
619 return fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
Mike Reed3ac64b42016-10-18 19:34:08 -0400620 }
Mike Reedc0cec872017-12-14 10:45:27 -0500621 return SkImage::MakeFromEncoded(data);
reed54dc4872016-09-13 08:09:45 -0700622}
623
Mike Reed3ac64b42016-10-18 19:34:08 -0400624
reed7e3ba9f2016-09-13 17:25:19 -0700625static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
reed54dc4872016-09-13 08:09:45 -0700626 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
627 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
628 uint32_t extra = unpack_verb_extra(packedVerb);
629 int index = extra & kIndex_ObjectDefinitionMask;
630
631 if (extra & kUndef_ObjectDefinitionMask) {
632 // zero-index means we are "forgetting" that cache entry
633 inflator->setImage(index, nullptr);
634 } else {
635 // we are defining a new image
636 sk_sp<SkData> data = reader.readByteArrayAsData();
Mike Reed3ac64b42016-10-18 19:34:08 -0400637 sk_sp<SkImage> image = inflator->makeImage(data);
reed54dc4872016-09-13 08:09:45 -0700638 if (!image) {
639 SkDebugf("-- failed to decode\n");
640 }
641 inflator->setImage(index, image.get());
642 }
643}
644
645sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
Mike Reedc0cec872017-12-14 10:45:27 -0500646 if (fProcs.fTypefaceProc) {
647 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
reed54dc4872016-09-13 08:09:45 -0700648 }
649 SkMemoryStream stream(data, size, false);
650 return SkTypeface::MakeDeserialize(&stream);
651}
652
653static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
654 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
655 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
656 uint32_t extra = unpack_verb_extra(packedVerb);
657 int index = extra & kIndex_ObjectDefinitionMask;
658
659 if (extra & kUndef_ObjectDefinitionMask) {
660 // zero-index means we are "forgetting" that cache entry
661 inflator->setTypeface(index, nullptr);
662 } else {
663 // we are defining a new image
664 sk_sp<SkData> data = reader.readByteArrayAsData();
665 // TODO: seems like we could "peek" to see the array, and not need to copy it.
666 sk_sp<SkTypeface> tf = inflator->makeTypeface(data->data(), data->size());
667 inflator->setTypeface(index, tf.get());
668 }
669}
670
671static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
672 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
673 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
674 uint32_t extra = unpack_verb_extra(packedVerb);
675 int index = extra >> kNameLength_DefineFactoryExtraBits;
676 size_t len = extra & kNameLength_DefineFactoryExtraMask;
677 // +1 for the trailing null char
678 const char* name = (const char*)reader.skip(SkAlign4(len + 1));
679 SkFlattenable::Factory factory = reader.findFactory(name);
680 if (factory) {
681 inflator->setFactory(index, factory);
682 }
683}
684
685static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
686 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
687 int deleteIndex = unpack_verb_extra(packedVerb);
688
689 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
690
691 if (deleteIndex) {
692 inflator->setPicture(deleteIndex - 1, nullptr);
693 } else {
694 SkPictureRecorder recorder;
695 int pictureIndex = -1; // invalid
Mike Reed22d77cb2018-01-03 13:22:51 -0500696 const SkRect* cull = reader.skipT<SkRect>();
697 if (!cull) {
698 return;
699 }
reed54dc4872016-09-13 08:09:45 -0700700 do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
701 SkASSERT(pictureIndex > 0);
702 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
703 inflator->setPicture(pictureIndex, picture.get());
704 }
705}
706
707static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
Ben Wagner7ca9a742017-08-17 14:05:04 -0400708 SK_ABORT("not reached"); // never call me
reed54dc4872016-09-13 08:09:45 -0700709}
710
711///////////////////////////////////////////////////////////////////////////////////////////////////
712
713struct HandlerRec {
714 SkPipeHandler fProc;
715 const char* fName;
716};
717
718#define HANDLER(name) { name##_handler, #name }
719const HandlerRec gPipeHandlers[] = {
720 HANDLER(save),
721 HANDLER(saveLayer),
722 HANDLER(restore),
723 HANDLER(concat),
Ben Wagner63fd7602017-10-09 15:45:33 -0400724
reed54dc4872016-09-13 08:09:45 -0700725 HANDLER(clipRect),
726 HANDLER(clipRRect),
727 HANDLER(clipPath),
728 HANDLER(clipRegion),
Ben Wagner63fd7602017-10-09 15:45:33 -0400729
reed54dc4872016-09-13 08:09:45 -0700730 HANDLER(drawArc),
731 HANDLER(drawAtlas),
732 HANDLER(drawDRRect),
733 HANDLER(drawText),
734 HANDLER(drawPosText),
735 HANDLER(drawPosTextH),
736 HANDLER(drawRegion),
737 HANDLER(drawTextOnPath),
738 HANDLER(drawTextBlob),
739 HANDLER(drawTextRSXform),
740 HANDLER(drawPatch),
741 HANDLER(drawPaint),
742 HANDLER(drawPoints),
743 HANDLER(drawRect),
744 HANDLER(drawPath),
Mike Reed7c9c9e42018-01-03 09:23:34 -0500745 HANDLER(drawShadowRec),
reed54dc4872016-09-13 08:09:45 -0700746 HANDLER(drawOval),
747 HANDLER(drawRRect),
Ben Wagner63fd7602017-10-09 15:45:33 -0400748
reed54dc4872016-09-13 08:09:45 -0700749 HANDLER(drawImage),
750 HANDLER(drawImageRect),
751 HANDLER(drawImageNine),
752 HANDLER(drawImageLattice),
Ben Wagner63fd7602017-10-09 15:45:33 -0400753
reed54dc4872016-09-13 08:09:45 -0700754 HANDLER(drawVertices),
Ben Wagner63fd7602017-10-09 15:45:33 -0400755
reed54dc4872016-09-13 08:09:45 -0700756 HANDLER(drawPicture),
757 HANDLER(drawAnnotation),
758
759 HANDLER(defineImage),
760 HANDLER(defineTypeface),
761 HANDLER(defineFactory),
762 HANDLER(definePicture),
763 HANDLER(endPicture), // handled special -- should never be called
764};
765#undef HANDLER
766
767///////////////////////////////////////////////////////////////////////////////////////////////////
768
769class SkPipeDeserializer::Impl {
770public:
771 SkRefSet<SkImage> fImages;
772 SkRefSet<SkPicture> fPictures;
773 SkRefSet<SkTypeface> fTypefaces;
774 SkTDArray<SkFlattenable::Factory> fFactories;
Mike Reedc0cec872017-12-14 10:45:27 -0500775 SkDeserialProcs fProcs;
reed54dc4872016-09-13 08:09:45 -0700776};
777
778SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
779SkPipeDeserializer::~SkPipeDeserializer() {}
780
Mike Reedc0cec872017-12-14 10:45:27 -0500781void SkPipeDeserializer::setDeserialProcs(const SkDeserialProcs& procs) {
782 fImpl->fProcs = procs;
Mike Reed3ac64b42016-10-18 19:34:08 -0400783}
784
reed54dc4872016-09-13 08:09:45 -0700785sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
786 if (size < sizeof(uint32_t)) {
reed7e3ba9f2016-09-13 17:25:19 -0700787 SkDebugf("-------- data length too short for readImage %d\n", size);
reed54dc4872016-09-13 08:09:45 -0700788 return nullptr;
789 }
790
reed7e3ba9f2016-09-13 17:25:19 -0700791 const uint32_t* ptr = (const uint32_t*)data;
792 uint32_t packedVerb = *ptr++;
793 size -= 4;
794
795 if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
796 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
797 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500798 fImpl->fProcs);
reed7e3ba9f2016-09-13 17:25:19 -0700799 SkPipeReader reader(this, ptr, size);
800 reader.setInflator(&inflator);
801 defineImage_handler(reader, packedVerb, nullptr);
802 packedVerb = reader.read32(); // read the next verb
803 }
804 if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
805 SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
reed54dc4872016-09-13 08:09:45 -0700806 return nullptr;
807 }
reed7e3ba9f2016-09-13 17:25:19 -0700808 int index = unpack_verb_extra(packedVerb);
809 if (0 == index) {
810 return nullptr; // writer failed
811 }
812 return sk_ref_sp(fImpl->fImages.get(index - 1));
reed54dc4872016-09-13 08:09:45 -0700813}
814
reed262052c2016-09-15 14:24:53 -0700815sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
816 if (size < sizeof(uint32_t)) {
817 SkDebugf("-------- data length too short for readPicture %d\n", size);
818 return nullptr;
819 }
820
821 const uint32_t* ptr = (const uint32_t*)data;
822 uint32_t packedVerb = *ptr++;
823 size -= 4;
824
825 if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
826 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
827 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500828 fImpl->fProcs);
reed262052c2016-09-15 14:24:53 -0700829 SkPipeReader reader(this, ptr, size);
830 reader.setInflator(&inflator);
831 definePicture_handler(reader, packedVerb, nullptr);
832 packedVerb = reader.read32(); // read the next verb
833 }
834 if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
835 SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
836 return nullptr;
837 }
838 int index = unpack_verb_extra(packedVerb);
839 if (0 == index) {
840 return nullptr; // writer failed
841 }
842 return sk_ref_sp(fImpl->fPictures.get(index - 1));
843}
844
reed54dc4872016-09-13 08:09:45 -0700845static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
846 int indent = 0;
847
848 const bool showEachVerb = false;
849 int counter = 0;
850 while (!reader.eof()) {
851 uint32_t prevOffset = reader.offset();
852 uint32_t packedVerb = reader.read32();
853 SkPipeVerb verb = unpack_verb(packedVerb);
854 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
855 SkDebugf("------- bad verb %d\n", verb);
856 return false;
857 }
858 if (SkPipeVerb::kRestore == verb) {
859 indent -= 1;
860 SkASSERT(indent >= 0);
861 }
862
863 if (SkPipeVerb::kEndPicture == verb) {
864 if (endPictureIndex) {
865 *endPictureIndex = unpack_verb_extra(packedVerb);
866 }
867 return true;
868 }
869 HandlerRec rec = gPipeHandlers[(unsigned)verb];
870 rec.fProc(reader, packedVerb, canvas);
871 if (showEachVerb) {
872 for (int i = 0; i < indent; ++i) {
873 SkDebugf(" ");
874 }
875 SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
876 }
877 if (!reader.isValid()) {
878 SkDebugf("-------- bad reader\n");
879 return false;
880 }
881
882 switch (verb) {
883 case SkPipeVerb::kSave:
884 case SkPipeVerb::kSaveLayer:
885 indent += 1;
886 break;
887 default:
888 break;
889 }
890 }
891 return true;
892}
893
894bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
895 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
896 &fImpl->fTypefaces, &fImpl->fFactories,
Mike Reedc0cec872017-12-14 10:45:27 -0500897 fImpl->fProcs);
reed54dc4872016-09-13 08:09:45 -0700898 SkPipeReader reader(this, data, size);
899 reader.setInflator(&inflator);
900 return do_playback(reader, canvas);
901}
902