LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/pipe - SkPipeReader.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 584 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 78 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       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"
       9             : #include "SkDeduper.h"
      10             : #include "SkImageDeserializer.h"
      11             : #include "SkPicture.h"
      12             : #include "SkPictureRecorder.h"
      13             : #include "SkPipe.h"
      14             : #include "SkPipeFormat.h"
      15             : #include "SkReadBuffer.h"
      16             : #include "SkRefSet.h"
      17             : #include "SkRSXform.h"
      18             : #include "SkTextBlob.h"
      19             : #include "SkTypeface.h"
      20             : #include "SkVertices.h"
      21             : 
      22             : class SkPipeReader;
      23             : 
      24             : static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex = nullptr);
      25             : 
      26             : ///////////////////////////////////////////////////////////////////////////////////////////////////
      27             : 
      28           0 : class SkPipeInflator : public SkInflator {
      29             : public:
      30           0 :     SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures,
      31             :                    SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Factory>* factories,
      32             :                    SkTypefaceDeserializer* tfd, SkImageDeserializer* imd)
      33           0 :         : fImages(images)
      34             :         , fPictures(pictures)
      35             :         , fTypefaces(typefaces)
      36             :         , fFactories(factories)
      37             :         , fTFDeserializer(tfd)
      38           0 :         , fIMDeserializer(imd)
      39           0 :     {}
      40             :     
      41           0 :     SkImage* getImage(int index) override {
      42           0 :         return index ? fImages->get(index - 1) : nullptr;
      43             :     }
      44           0 :     SkPicture* getPicture(int index) override {
      45           0 :         return index ? fPictures->get(index - 1) : nullptr;
      46             :     }
      47           0 :     SkTypeface* getTypeface(int index) override {
      48           0 :         return fTypefaces->get(index - 1);
      49             :     }
      50           0 :     SkFlattenable::Factory getFactory(int index) override {
      51           0 :         return index ? fFactories->getAt(index - 1) : nullptr;
      52             :     }
      53             : 
      54           0 :     bool setImage(int index, SkImage* img) {
      55           0 :         return fImages->set(index - 1, img);
      56             :     }
      57           0 :     bool setPicture(int index, SkPicture* pic) {
      58           0 :         return fPictures->set(index - 1, pic);
      59             :     }
      60           0 :     bool setTypeface(int index, SkTypeface* face) {
      61           0 :         return fTypefaces->set(index - 1, face);
      62             :     }
      63           0 :     bool setFactory(int index, SkFlattenable::Factory factory) {
      64           0 :         SkASSERT(index > 0);
      65           0 :         SkASSERT(factory);
      66           0 :         index -= 1;
      67           0 :         if ((unsigned)index < (unsigned)fFactories->count()) {
      68           0 :             (*fFactories)[index] = factory;
      69           0 :             return true;
      70             :         }
      71           0 :         if (fFactories->count() == index) {
      72           0 :             *fFactories->append() = factory;
      73           0 :             return true;
      74             :         }
      75           0 :         SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories->count());
      76           0 :         return false;
      77             :     }
      78             : 
      79             :     void setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
      80             :         fTFDeserializer = tfd;
      81             :     }
      82             :     
      83             :     void setImageDeserializer(SkImageDeserializer* imd) {
      84             :         fIMDeserializer = imd;
      85             :     }
      86             :     
      87             :     sk_sp<SkTypeface> makeTypeface(const void* data, size_t size);
      88             :     sk_sp<SkImage> makeImage(const sk_sp<SkData>&);
      89             : 
      90             : private:
      91             :     SkRefSet<SkImage>*                  fImages;
      92             :     SkRefSet<SkPicture>*                fPictures;
      93             :     SkRefSet<SkTypeface>*               fTypefaces;
      94             :     SkTDArray<SkFlattenable::Factory>*  fFactories;
      95             : 
      96             :     SkTypefaceDeserializer*             fTFDeserializer;
      97             :     SkImageDeserializer*                fIMDeserializer;
      98             : };
      99             : 
     100             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     101             : 
     102           0 : template <typename T> const T* skip(SkReadBuffer& reader, int count = 1) {
     103           0 :     return (const T*)reader.skip(count * sizeof(T));
     104             : }
     105             : 
     106           0 : static SkRRect read_rrect(SkReadBuffer& reader) {
     107           0 :     SkRRect rrect;
     108           0 :     rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory);
     109           0 :     return rrect;
     110             : }
     111             : 
     112           0 : static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) {
     113             :     SkMatrix matrix;
     114           0 :     matrix.reset();
     115             : 
     116           0 :     if (tm & SkMatrix::kPerspective_Mask) {
     117           0 :         matrix.set9(skip<SkScalar>(reader, 9));
     118           0 :     } else if (tm & SkMatrix::kAffine_Mask) {
     119           0 :         const SkScalar* tmp = skip<SkScalar>(reader, 6);
     120           0 :         matrix[SkMatrix::kMScaleX] = tmp[0];
     121           0 :         matrix[SkMatrix::kMSkewX]  = tmp[1];
     122           0 :         matrix[SkMatrix::kMTransX] = tmp[2];
     123           0 :         matrix[SkMatrix::kMScaleY] = tmp[3];
     124           0 :         matrix[SkMatrix::kMSkewY]  = tmp[4];
     125           0 :         matrix[SkMatrix::kMTransY] = tmp[5];
     126           0 :     } else if (tm & SkMatrix::kScale_Mask) {
     127           0 :         const SkScalar* tmp = skip<SkScalar>(reader, 4);
     128           0 :         matrix[SkMatrix::kMScaleX] = tmp[0];
     129           0 :         matrix[SkMatrix::kMTransX] = tmp[1];
     130           0 :         matrix[SkMatrix::kMScaleY] = tmp[2];
     131           0 :         matrix[SkMatrix::kMTransY] = tmp[3];
     132           0 :     } else if (tm & SkMatrix::kTranslate_Mask) {
     133           0 :         const SkScalar* tmp = skip<SkScalar>(reader, 2);
     134           0 :         matrix[SkMatrix::kMTransX] = tmp[0];
     135           0 :         matrix[SkMatrix::kMTransY] = tmp[1];
     136             :     }
     137             :     // else read nothing for Identity
     138           0 :     return matrix;
     139             : }
     140             : 
     141             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     142             : 
     143             : #define CHECK_SET_SCALAR(Field)                 \
     144             :     do { if (nondef & k##Field##_NonDef) {      \
     145             :         paint.set##Field(reader.readScalar());  \
     146             :     }} while (0)
     147             : 
     148             : #define CHECK_SET_FLATTENABLE(Field)            \
     149             :     do { if (nondef & k##Field##_NonDef) {      \
     150             :         paint.set##Field(reader.read##Field()); \
     151             :     }} while (0)
     152             : 
     153             : /*
     154             :  *  Header:
     155             :  *      paint flags     : 32
     156             :  *      non_def bits    : 16
     157             :  *      xfermode enum   : 8
     158             :  *      pad zeros       : 8
     159             :  */
     160           0 : static SkPaint read_paint(SkReadBuffer& reader) {
     161           0 :     SkPaint paint;
     162             : 
     163           0 :     uint32_t packedFlags = reader.read32();
     164           0 :     uint32_t extra = reader.read32();
     165           0 :     unsigned nondef = extra >> 16;
     166           0 :     paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF));
     167           0 :     SkASSERT((extra & 0xFF) == 0);  // zero pad byte
     168             : 
     169           0 :     packedFlags >>= 2;  // currently unused
     170           0 :     paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3));    packedFlags >>= 2;
     171           0 :     paint.setTextAlign((SkPaint::Align)(packedFlags & 3));              packedFlags >>= 2;
     172           0 :     paint.setHinting((SkPaint::Hinting)(packedFlags & 3));              packedFlags >>= 2;
     173           0 :     paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3));              packedFlags >>= 2;
     174           0 :     paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3));                packedFlags >>= 2;
     175           0 :     paint.setStyle((SkPaint::Style)(packedFlags & 3));                  packedFlags >>= 2;
     176           0 :     paint.setFilterQuality((SkFilterQuality)(packedFlags & 3));         packedFlags >>= 2;
     177           0 :     paint.setFlags(packedFlags);
     178             : 
     179           0 :     CHECK_SET_SCALAR(TextSize);
     180           0 :     CHECK_SET_SCALAR(TextScaleX);
     181           0 :     CHECK_SET_SCALAR(TextSkewX);
     182           0 :     CHECK_SET_SCALAR(StrokeWidth);
     183           0 :     CHECK_SET_SCALAR(StrokeMiter);
     184             : 
     185           0 :     if (nondef & kColor_NonDef) {
     186           0 :         paint.setColor(reader.read32());
     187             :     }
     188             : 
     189           0 :     CHECK_SET_FLATTENABLE(Typeface);
     190           0 :     CHECK_SET_FLATTENABLE(PathEffect);
     191           0 :     CHECK_SET_FLATTENABLE(Shader);
     192           0 :     CHECK_SET_FLATTENABLE(MaskFilter);
     193           0 :     CHECK_SET_FLATTENABLE(ColorFilter);
     194           0 :     CHECK_SET_FLATTENABLE(Rasterizer);
     195           0 :     CHECK_SET_FLATTENABLE(ImageFilter);
     196           0 :     CHECK_SET_FLATTENABLE(DrawLooper);
     197             : 
     198           0 :     return paint;
     199             : }
     200             : 
     201           0 : class SkPipeReader : public SkReadBuffer {
     202             : public:
     203           0 :     SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size)
     204           0 :     : SkReadBuffer(data, size)
     205           0 :     , fSink(sink)
     206           0 :     {}
     207             : 
     208             :     SkPipeDeserializer* fSink;
     209             : 
     210           0 :     SkFlattenable::Factory findFactory(const char name[]) {
     211             :         SkFlattenable::Factory factory;
     212             :         // Check if a custom Factory has been specified for this flattenable.
     213           0 :         if (!(factory = this->getCustomFactory(SkString(name)))) {
     214             :             // If there is no custom Factory, check for a default.
     215           0 :             factory = SkFlattenable::NameToFactory(name);
     216             :         }
     217           0 :         return factory;
     218             :     }
     219             :     
     220           0 :     void readPaint(SkPaint* paint) override {
     221           0 :         *paint = read_paint(*this);
     222           0 :     }
     223             : };
     224             : 
     225             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     226             : 
     227             : typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*);
     228             : 
     229           0 : static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     230           0 :     SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb));
     231           0 :     canvas->save();
     232           0 : }
     233             : 
     234           0 : static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     235           0 :     SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb));
     236           0 :     unsigned extra = unpack_verb_extra(packedVerb);
     237           0 :     const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? skip<SkRect>(reader) : nullptr;
     238           0 :     SkPaint paintStorage, *paint = nullptr;
     239           0 :     if (extra & kHasPaint_SaveLayerMask) {
     240           0 :         paintStorage = read_paint(reader);
     241           0 :         paint = &paintStorage;
     242             :     }
     243           0 :     sk_sp<SkImageFilter> backdrop;
     244           0 :     if (extra & kHasBackdrop_SaveLayerMask) {
     245           0 :         backdrop = reader.readImageFilter();
     246             :     }
     247           0 :     SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask);
     248             : 
     249             :     // unremap this wacky flag
     250           0 :     if (extra & kDontClipToLayer_SaveLayerMask) {
     251           0 :         flags |= (1 << 31);//SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag;
     252             :     }
     253             : 
     254           0 :     canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), flags));
     255           0 : }
     256             : 
     257           0 : static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     258           0 :     SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb));
     259           0 :     canvas->restore();
     260           0 : }
     261             : 
     262           0 : static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     263           0 :     SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb));
     264           0 :     SkMatrix::TypeMask tm = (SkMatrix::TypeMask)(packedVerb & kTypeMask_ConcatMask);
     265           0 :     const SkMatrix matrix = read_sparse_matrix(reader, tm);
     266           0 :     if (packedVerb & kSetMatrix_ConcatMask) {
     267           0 :         canvas->setMatrix(matrix);
     268             :     } else {
     269           0 :         canvas->concat(matrix);
     270             :     }
     271           0 : }
     272             : 
     273           0 : static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     274           0 :     SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb));
     275           0 :     SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
     276           0 :     bool isAA = unpack_verb_extra(packedVerb) & 1;
     277           0 :     canvas->clipRect(*skip<SkRect>(reader), op, isAA);
     278           0 : }
     279             : 
     280           0 : static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     281           0 :     SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb));
     282           0 :     SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
     283           0 :     bool isAA = unpack_verb_extra(packedVerb) & 1;
     284           0 :     canvas->clipRRect(read_rrect(reader), op, isAA);
     285           0 : }
     286             : 
     287           0 : static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     288           0 :     SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb));
     289           0 :     SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
     290           0 :     bool isAA = unpack_verb_extra(packedVerb) & 1;
     291           0 :     SkPath path;
     292           0 :     reader.readPath(&path);
     293           0 :     canvas->clipPath(path, op, isAA);
     294           0 : }
     295             : 
     296           0 : static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     297           0 :     SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb));
     298           0 :     SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1);
     299           0 :     SkRegion region;
     300           0 :     reader.readRegion(&region);
     301           0 :     canvas->clipRegion(region, op);
     302           0 : }
     303             : 
     304           0 : static void drawArc_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     305           0 :     SkASSERT(SkPipeVerb::kDrawArc == unpack_verb(packedVerb));
     306           0 :     const bool useCenter = (bool)(unpack_verb_extra(packedVerb) & 1);
     307           0 :     const SkScalar* scalars = skip<SkScalar>(reader, 6);    // bounds[0..3], start[4], sweep[5]
     308           0 :     const SkRect* bounds = (const SkRect*)scalars;
     309           0 :     canvas->drawArc(*bounds, scalars[4], scalars[5], useCenter, read_paint(reader));
     310           0 : }
     311             : 
     312           0 : static void drawAtlas_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     313           0 :     SkASSERT(SkPipeVerb::kDrawAtlas == unpack_verb(packedVerb));
     314           0 :     SkBlendMode mode = (SkBlendMode)(packedVerb & kMode_DrawAtlasMask);
     315           0 :     sk_sp<SkImage> image(reader.readImage());
     316           0 :     int count = reader.read32();
     317           0 :     const SkRSXform* xform = skip<SkRSXform>(reader, count);
     318           0 :     const SkRect* rect = skip<SkRect>(reader, count);
     319           0 :     const SkColor* color = nullptr;
     320           0 :     if (packedVerb & kHasColors_DrawAtlasMask) {
     321           0 :         color = skip<SkColor>(reader, count);
     322             :     }
     323           0 :     const SkRect* cull = nullptr;
     324           0 :     if (packedVerb & kHasCull_DrawAtlasMask) {
     325           0 :         cull = skip<SkRect>(reader);
     326             :     }
     327           0 :     SkPaint paintStorage, *paint = nullptr;
     328           0 :     if (packedVerb & kHasPaint_DrawAtlasMask) {
     329           0 :         paintStorage = read_paint(reader);
     330           0 :         paint = &paintStorage;
     331             :     }
     332           0 :     canvas->drawAtlas(image, xform, rect, color, count, mode, cull, paint);
     333           0 : }
     334             : 
     335           0 : static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     336           0 :     SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb));
     337           0 :     const SkRRect outer = read_rrect(reader);
     338           0 :     const SkRRect inner = read_rrect(reader);
     339           0 :     canvas->drawDRRect(outer, inner, read_paint(reader));
     340           0 : }
     341             : 
     342           0 : static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     343           0 :     SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb));
     344           0 :     uint32_t len = unpack_verb_extra(packedVerb);
     345           0 :     if (0 == len) {
     346           0 :         len = reader.read32();
     347             :     }
     348           0 :     const void* text = reader.skip(SkAlign4(len));
     349           0 :     SkScalar x = reader.readScalar();
     350           0 :     SkScalar y = reader.readScalar();
     351           0 :     canvas->drawText(text, len, x, y, read_paint(reader));
     352           0 : }
     353             : 
     354           0 : static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     355           0 :     SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb));
     356           0 :     uint32_t len = unpack_verb_extra(packedVerb);
     357           0 :     if (0 == len) {
     358           0 :         len = reader.read32();
     359             :     }
     360           0 :     const void* text = reader.skip(SkAlign4(len));
     361           0 :     int count = reader.read32();
     362           0 :     const SkPoint* pos = skip<SkPoint>(reader, count);
     363           0 :     SkPaint paint = read_paint(reader);
     364           0 :     SkASSERT(paint.countText(text, len) == count);
     365           0 :     canvas->drawPosText(text, len, pos, paint);
     366           0 : }
     367             : 
     368           0 : static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     369           0 :     SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb));
     370           0 :     uint32_t len = unpack_verb_extra(packedVerb);
     371           0 :     if (0 == len) {
     372           0 :         len = reader.read32();
     373             :     }
     374           0 :     const void* text = reader.skip(SkAlign4(len));
     375           0 :     int count = reader.read32();
     376           0 :     const SkScalar* xpos = skip<SkScalar>(reader, count);
     377           0 :     SkScalar constY = reader.readScalar();
     378           0 :     SkPaint paint = read_paint(reader);
     379           0 :     SkASSERT(paint.countText(text, len) == count);
     380           0 :     canvas->drawPosTextH(text, len, xpos, constY, paint);
     381           0 : }
     382             : 
     383           0 : static void drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     384           0 :     SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb));
     385           0 :     uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask;
     386             :     SkMatrix::TypeMask tm = (SkMatrix::TypeMask)
     387           0 :             ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTextOnPathShift);
     388             : 
     389           0 :     if (0 == byteLength) {
     390           0 :         byteLength = reader.read32();
     391             :     }
     392           0 :     const void* text = reader.skip(SkAlign4(byteLength));
     393           0 :     SkPath path;
     394           0 :     reader.readPath(&path);
     395           0 :     const SkMatrix* matrix = nullptr;
     396             :     SkMatrix matrixStorage;
     397           0 :     if (tm != SkMatrix::kIdentity_Mask) {
     398           0 :         matrixStorage = read_sparse_matrix(reader, tm);
     399           0 :         matrix = &matrixStorage;
     400             :     }
     401           0 :     canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader));
     402           0 : }
     403             : 
     404           0 : static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     405           0 :     sk_sp<SkTextBlob> tb = SkTextBlob::MakeFromBuffer(reader);
     406           0 :     SkScalar x = reader.readScalar();
     407           0 :     SkScalar y = reader.readScalar();
     408           0 :     canvas->drawTextBlob(tb, x, y, read_paint(reader));
     409           0 : }
     410             : 
     411           0 : static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     412           0 :     SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb));
     413           0 :     uint32_t len = unpack_verb_extra(packedVerb) >> 1;
     414           0 :     if (0 == len) {
     415           0 :         len = reader.read32();
     416             :     }
     417           0 :     const void* text = reader.skip(SkAlign4(len));
     418           0 :     int count = reader.read32();
     419           0 :     const SkRSXform* xform = skip<SkRSXform>(reader, count);
     420           0 :     const SkRect* cull = (packedVerb & 1) ? skip<SkRect>(reader) : nullptr;
     421           0 :     SkPaint paint = read_paint(reader);
     422           0 :     SkASSERT(paint.countText(text, len) == count);
     423           0 :     canvas->drawTextRSXform(text, len, xform, cull, paint);
     424           0 : }
     425             : 
     426           0 : static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     427           0 :     SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb));
     428           0 :     const SkColor* colors = nullptr;
     429           0 :     const SkPoint* tex = nullptr;
     430           0 :     const SkPoint* cubics = skip<SkPoint>(reader, 12);
     431           0 :     if (packedVerb & kHasColors_DrawPatchExtraMask) {
     432           0 :         colors = skip<SkColor>(reader, 4);
     433             :     }
     434           0 :     if (packedVerb & kHasTexture_DrawPatchExtraMask) {
     435           0 :         tex = skip<SkPoint>(reader, 4);
     436             :     }
     437           0 :     SkBlendMode mode = (SkBlendMode)(packedVerb & kModeEnum_DrawPatchExtraMask);
     438           0 :     canvas->drawPatch(cubics, colors, tex, mode, read_paint(reader));
     439           0 : }
     440             : 
     441           0 : static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     442           0 :     SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb));
     443           0 :     canvas->drawPaint(read_paint(reader));
     444           0 : }
     445             : 
     446           0 : static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     447           0 :     SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb));
     448           0 :     const SkRect* rect = skip<SkRect>(reader);
     449           0 :     canvas->drawRect(*rect, read_paint(reader));
     450           0 : }
     451             : 
     452           0 : static void drawRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     453           0 :     SkASSERT(SkPipeVerb::kDrawRegion == unpack_verb(packedVerb));
     454           0 :     size_t size = unpack_verb_extra(packedVerb);
     455           0 :     if (0 == size) {
     456           0 :         size = reader.read32();
     457             :     }
     458           0 :     SkRegion region;
     459           0 :     region.readFromMemory(skip<char>(reader, SkAlign4(size)), size);
     460           0 :     canvas->drawRegion(region, read_paint(reader));
     461           0 : }
     462             : 
     463           0 : static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     464           0 :     SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb));
     465           0 :     const SkRect* rect = skip<SkRect>(reader);
     466           0 :     canvas->drawOval(*rect, read_paint(reader));
     467           0 : }
     468             : 
     469           0 : static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     470           0 :     SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb));
     471           0 :     SkRRect rrect = read_rrect(reader);
     472           0 :     canvas->drawRRect(rrect, read_paint(reader));
     473           0 : }
     474             : 
     475           0 : static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     476           0 :     SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb));
     477           0 :     SkPath path;
     478           0 :     reader.readPath(&path);
     479           0 :     canvas->drawPath(path, read_paint(reader));
     480           0 : }
     481             : 
     482           0 : static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     483           0 :     SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb));
     484           0 :     SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb);
     485           0 :     int count = reader.read32();
     486           0 :     const SkPoint* points = skip<SkPoint>(reader, count);
     487           0 :     canvas->drawPoints(mode, count, points, read_paint(reader));
     488           0 : }
     489             : 
     490           0 : static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     491           0 :     SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb));
     492           0 :     sk_sp<SkImage> image(reader.readImage());
     493           0 :     SkScalar x = reader.readScalar();
     494           0 :     SkScalar y = reader.readScalar();
     495           0 :     SkPaint paintStorage, *paint = nullptr;
     496           0 :     if (packedVerb & kHasPaint_DrawImageMask) {
     497           0 :         paintStorage = read_paint(reader);
     498           0 :         paint = &paintStorage;
     499             :     }
     500           0 :     canvas->drawImage(image, x, y, paint);
     501           0 : }
     502             : 
     503           0 : static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     504           0 :     SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb));
     505           0 :     sk_sp<SkImage> image(reader.readImage());
     506             :     SkCanvas::SrcRectConstraint constraint =
     507           0 :             (SkCanvas::SrcRectConstraint)(packedVerb & kConstraint_DrawImageRectMask);
     508           0 :     const SkRect* src = (packedVerb & kHasSrcRect_DrawImageRectMask) ?
     509           0 :                         skip<SkRect>(reader) : nullptr;
     510           0 :     const SkRect* dst = skip<SkRect>(reader);
     511           0 :     SkPaint paintStorage, *paint = nullptr;
     512           0 :     if (packedVerb & kHasPaint_DrawImageRectMask) {
     513           0 :         paintStorage = read_paint(reader);
     514           0 :         paint = &paintStorage;
     515             :     }
     516           0 :     if (src) {
     517           0 :         canvas->drawImageRect(image, *src, *dst, paint, constraint);
     518             :     } else {
     519           0 :         canvas->drawImageRect(image, *dst, paint);
     520             :     }
     521           0 : }
     522             : 
     523           0 : static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     524           0 :     SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb));
     525           0 :     sk_sp<SkImage> image(reader.readImage());
     526           0 :     const SkIRect* center = skip<SkIRect>(reader);
     527           0 :     const SkRect* dst = skip<SkRect>(reader);
     528           0 :     SkPaint paintStorage, *paint = nullptr;
     529           0 :     if (packedVerb & kHasPaint_DrawImageNineMask) {
     530           0 :         paintStorage = read_paint(reader);
     531           0 :         paint = &paintStorage;
     532             :     }
     533           0 :     canvas->drawImageNine(image, *center, *dst, paint);
     534           0 : }
     535             : 
     536           0 : static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     537           0 :     SkASSERT(SkPipeVerb::kDrawImageLattice == unpack_verb(packedVerb));
     538           0 :     sk_sp<SkImage> image(reader.readImage());
     539             : 
     540             :     SkCanvas::Lattice lattice;
     541           0 :     lattice.fXCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
     542           0 :     if (lattice.fXCount == kCount_DrawImageLatticeMask) {
     543           0 :         lattice.fXCount = reader.read32();
     544             :     }
     545           0 :     lattice.fYCount = (packedVerb >> kXCount_DrawImageLatticeShift) & kCount_DrawImageLatticeMask;
     546           0 :     if (lattice.fYCount == kCount_DrawImageLatticeMask) {
     547           0 :         lattice.fYCount = reader.read32();
     548             :     }
     549           0 :     lattice.fXDivs = skip<int32_t>(reader, lattice.fXCount);
     550           0 :     lattice.fYDivs = skip<int32_t>(reader, lattice.fYCount);
     551           0 :     if (packedVerb & kHasFlags_DrawImageLatticeMask) {
     552           0 :         int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
     553           0 :         SkASSERT(count > 0);
     554           0 :         lattice.fFlags = skip<SkCanvas::Lattice::Flags>(reader, SkAlign4(count));
     555             :     } else {
     556           0 :         lattice.fFlags = nullptr;
     557             :     }
     558           0 :     lattice.fBounds = skip<SkIRect>(reader);
     559           0 :     const SkRect* dst = skip<SkRect>(reader);
     560             : 
     561           0 :     SkPaint paintStorage, *paint = nullptr;
     562           0 :     if (packedVerb & kHasPaint_DrawImageLatticeMask) {
     563           0 :         paintStorage = read_paint(reader);
     564           0 :         paint = &paintStorage;
     565             :     }
     566           0 :     canvas->drawImageLattice(image.get(), lattice, *dst, paint);
     567           0 : }
     568             : 
     569           0 : static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     570           0 :     SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb));
     571           0 :     SkBlendMode bmode = (SkBlendMode)unpack_verb_extra(packedVerb);
     572           0 :     sk_sp<SkData> data = reader.readByteArrayAsData();
     573           0 :     canvas->drawVertices(SkVertices::Decode(data->data(), data->size()), bmode, read_paint(reader));
     574           0 : }
     575             : 
     576           0 : static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     577           0 :     SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb));
     578           0 :     unsigned extra = unpack_verb_extra(packedVerb);
     579           0 :     int index = extra & kIndex_ObjectDefinitionMask;
     580           0 :     SkPicture* pic = reader.getInflator()->getPicture(index);
     581           0 :     SkMatrix matrixStorage, *matrix = nullptr;
     582           0 :     SkPaint paintStorage, *paint = nullptr;
     583           0 :     if (extra & kHasMatrix_DrawPictureExtra) {
     584           0 :         reader.readMatrix(&matrixStorage);
     585           0 :         matrix = &matrixStorage;
     586             :     }
     587           0 :     if (extra & kHasPaint_DrawPictureExtra) {
     588           0 :         paintStorage = read_paint(reader);
     589           0 :         paint = &paintStorage;
     590             :     }
     591           0 :     canvas->drawPicture(pic, matrix, paint);
     592           0 : }
     593             : 
     594           0 : static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     595           0 :     SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb));
     596           0 :     const SkRect* rect = skip<SkRect>(reader);
     597             : 
     598             :     // len includes the key's trailing 0
     599           0 :     uint32_t len = unpack_verb_extra(packedVerb) >> 1;
     600           0 :     if (0 == len) {
     601           0 :         len = reader.read32();
     602             :     }
     603           0 :     const char* key = skip<char>(reader, len);
     604           0 :     sk_sp<SkData> data;
     605           0 :     if (packedVerb & 1) {
     606           0 :         uint32_t size = reader.read32();
     607           0 :         data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size);
     608             :     }
     609           0 :     canvas->drawAnnotation(*rect, key, data);
     610           0 : }
     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             : 
     624           0 : static sk_sp<SkImage> make_from_skiaimageformat(const void* encoded, size_t encodedSize) {
     625           0 :     if (encodedSize < 24) {
     626           0 :         return nullptr;
     627             :     }
     628             : 
     629           0 :     SkMemoryStream stream(encoded, encodedSize);
     630             :     char signature[8];
     631           0 :     stream.read(signature, 8);
     632           0 :     if (memcmp(signature, "skiaimgf", 8)) {
     633           0 :         return nullptr;
     634             :     }
     635             : 
     636           0 :     int width = stream.readU32();
     637           0 :     int height = stream.readU32();
     638           0 :     SkColorType ct = (SkColorType)stream.readU16();
     639           0 :     SkAlphaType at = (SkAlphaType)stream.readU16();
     640           0 :     SkASSERT(kAlpha_8_SkColorType == ct);
     641             : 
     642           0 :     SkDEBUGCODE(size_t colorSpaceSize =) stream.readU32();
     643           0 :     SkASSERT(0 == colorSpaceSize);
     644             : 
     645           0 :     SkImageInfo info = SkImageInfo::Make(width, height, ct, at);
     646           0 :     size_t size = width * height;
     647           0 :     sk_sp<SkData> pixels = SkData::MakeUninitialized(size);
     648           0 :     stream.read(pixels->writable_data(), size);
     649           0 :     SkASSERT(encodedSize == SkAlign4(stream.getPosition()));
     650           0 :     return SkImage::MakeRasterData(info, pixels, width);
     651             : }
     652             : 
     653           0 : sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) {
     654           0 :     if (fIMDeserializer) {
     655           0 :         return fIMDeserializer->makeFromData(data.get(), nullptr);
     656             :     }
     657           0 :     sk_sp<SkImage> image = make_from_skiaimageformat(data->data(), data->size());
     658           0 :     if (!image) {
     659           0 :         image = SkImage::MakeFromEncoded(data);
     660             :     }
     661           0 :     return image;
     662             : }
     663             : 
     664             : 
     665           0 : static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) {
     666           0 :     SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb));
     667           0 :     SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
     668           0 :     uint32_t extra = unpack_verb_extra(packedVerb);
     669           0 :     int index = extra & kIndex_ObjectDefinitionMask;
     670             : 
     671           0 :     if (extra & kUndef_ObjectDefinitionMask) {
     672             :         // zero-index means we are "forgetting" that cache entry
     673           0 :         inflator->setImage(index, nullptr);
     674             :     } else {
     675             :         // we are defining a new image
     676           0 :         sk_sp<SkData> data = reader.readByteArrayAsData();
     677           0 :         sk_sp<SkImage> image = inflator->makeImage(data);
     678           0 :         if (!image) {
     679           0 :             SkDebugf("-- failed to decode\n");
     680             :         }
     681           0 :         inflator->setImage(index, image.get());
     682             :     }
     683           0 : }
     684             : 
     685           0 : sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) {
     686           0 :     if (fTFDeserializer) {
     687           0 :         return fTFDeserializer->deserialize(data, size);
     688             :     }
     689           0 :     SkMemoryStream stream(data, size, false);
     690           0 :     return SkTypeface::MakeDeserialize(&stream);
     691             : }
     692             : 
     693           0 : static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     694           0 :     SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb));
     695           0 :     SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
     696           0 :     uint32_t extra = unpack_verb_extra(packedVerb);
     697           0 :     int index = extra & kIndex_ObjectDefinitionMask;
     698             : 
     699           0 :     if (extra & kUndef_ObjectDefinitionMask) {
     700             :         // zero-index means we are "forgetting" that cache entry
     701           0 :         inflator->setTypeface(index, nullptr);
     702             :     } else {
     703             :         // we are defining a new image
     704           0 :         sk_sp<SkData> data = reader.readByteArrayAsData();
     705             :         // TODO: seems like we could "peek" to see the array, and not need to copy it.
     706           0 :         sk_sp<SkTypeface> tf = inflator->makeTypeface(data->data(), data->size());
     707           0 :         inflator->setTypeface(index, tf.get());
     708             :     }
     709           0 : }
     710             : 
     711           0 : static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     712           0 :     SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb));
     713           0 :     SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
     714           0 :     uint32_t extra = unpack_verb_extra(packedVerb);
     715           0 :     int index = extra >> kNameLength_DefineFactoryExtraBits;
     716           0 :     size_t len = extra & kNameLength_DefineFactoryExtraMask;
     717             :     // +1 for the trailing null char
     718           0 :     const char* name = (const char*)reader.skip(SkAlign4(len + 1));
     719           0 :     SkFlattenable::Factory factory = reader.findFactory(name);
     720           0 :     if (factory) {
     721           0 :         inflator->setFactory(index, factory);
     722             :     }
     723           0 : }
     724             : 
     725           0 : static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     726           0 :     SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb));
     727           0 :     int deleteIndex = unpack_verb_extra(packedVerb);
     728             : 
     729           0 :     SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator();
     730             : 
     731           0 :     if (deleteIndex) {
     732           0 :         inflator->setPicture(deleteIndex - 1, nullptr);
     733             :     } else {
     734           0 :         SkPictureRecorder recorder;
     735           0 :         int pictureIndex = -1;  // invalid
     736           0 :         const SkRect* cull = skip<SkRect>(reader);
     737           0 :         do_playback(reader, recorder.beginRecording(*cull), &pictureIndex);
     738           0 :         SkASSERT(pictureIndex > 0);
     739           0 :         sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
     740           0 :         inflator->setPicture(pictureIndex, picture.get());
     741             :     }
     742           0 : }
     743             : 
     744           0 : static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) {
     745           0 :     sk_throw();     // never call me
     746           0 : }
     747             : 
     748             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     749             : 
     750             : struct HandlerRec {
     751             :     SkPipeHandler   fProc;
     752             :     const char*     fName;
     753             : };
     754             : 
     755             : #define HANDLER(name)   { name##_handler, #name }
     756             : const HandlerRec gPipeHandlers[] = {
     757             :     HANDLER(save),
     758             :     HANDLER(saveLayer),
     759             :     HANDLER(restore),
     760             :     HANDLER(concat),
     761             :     
     762             :     HANDLER(clipRect),
     763             :     HANDLER(clipRRect),
     764             :     HANDLER(clipPath),
     765             :     HANDLER(clipRegion),
     766             :     
     767             :     HANDLER(drawArc),
     768             :     HANDLER(drawAtlas),
     769             :     HANDLER(drawDRRect),
     770             :     HANDLER(drawText),
     771             :     HANDLER(drawPosText),
     772             :     HANDLER(drawPosTextH),
     773             :     HANDLER(drawRegion),
     774             :     HANDLER(drawTextOnPath),
     775             :     HANDLER(drawTextBlob),
     776             :     HANDLER(drawTextRSXform),
     777             :     HANDLER(drawPatch),
     778             :     HANDLER(drawPaint),
     779             :     HANDLER(drawPoints),
     780             :     HANDLER(drawRect),
     781             :     HANDLER(drawPath),
     782             :     HANDLER(drawOval),
     783             :     HANDLER(drawRRect),
     784             :     
     785             :     HANDLER(drawImage),
     786             :     HANDLER(drawImageRect),
     787             :     HANDLER(drawImageNine),
     788             :     HANDLER(drawImageLattice),
     789             :     
     790             :     HANDLER(drawVertices),
     791             :     
     792             :     HANDLER(drawPicture),
     793             :     HANDLER(drawAnnotation),
     794             : 
     795             :     HANDLER(defineImage),
     796             :     HANDLER(defineTypeface),
     797             :     HANDLER(defineFactory),
     798             :     HANDLER(definePicture),
     799             :     HANDLER(endPicture),        // handled special -- should never be called
     800             : };
     801             : #undef HANDLER
     802             : 
     803             : ///////////////////////////////////////////////////////////////////////////////////////////////////
     804             : 
     805           0 : class SkPipeDeserializer::Impl {
     806             : public:
     807             :     SkRefSet<SkImage>                   fImages;
     808             :     SkRefSet<SkPicture>                 fPictures;
     809             :     SkRefSet<SkTypeface>                fTypefaces;
     810             :     SkTDArray<SkFlattenable::Factory>   fFactories;
     811             : 
     812             :     SkTypefaceDeserializer*             fTFDeserializer = nullptr;
     813             :     SkImageDeserializer*                fIMDeserializer = nullptr;
     814             : };
     815             : 
     816           0 : SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {}
     817           0 : SkPipeDeserializer::~SkPipeDeserializer() {}
     818             : 
     819           0 : void SkPipeDeserializer::setTypefaceDeserializer(SkTypefaceDeserializer* tfd) {
     820           0 :     fImpl->fTFDeserializer = tfd;
     821           0 : }
     822             : 
     823           0 : void SkPipeDeserializer::setImageDeserializer(SkImageDeserializer* imd) {
     824           0 :     fImpl->fIMDeserializer = imd;
     825           0 : }
     826             : 
     827           0 : sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) {
     828           0 :     if (size < sizeof(uint32_t)) {
     829           0 :         SkDebugf("-------- data length too short for readImage %d\n", size);
     830           0 :         return nullptr;
     831             :     }
     832             : 
     833           0 :     const uint32_t* ptr = (const uint32_t*)data;
     834           0 :     uint32_t packedVerb = *ptr++;
     835           0 :     size -= 4;
     836             : 
     837           0 :     if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) {
     838           0 :         SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
     839           0 :                                 &fImpl->fTypefaces, &fImpl->fFactories,
     840           0 :                                 fImpl->fTFDeserializer, fImpl->fIMDeserializer);
     841           0 :         SkPipeReader reader(this, ptr, size);
     842           0 :         reader.setInflator(&inflator);
     843           0 :         defineImage_handler(reader, packedVerb, nullptr);
     844           0 :         packedVerb = reader.read32();  // read the next verb
     845             :     }
     846           0 :     if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) {
     847           0 :         SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb));
     848           0 :         return nullptr;
     849             :     }
     850           0 :     int index = unpack_verb_extra(packedVerb);
     851           0 :     if (0 == index) {
     852           0 :         return nullptr; // writer failed
     853             :     }
     854           0 :     return sk_ref_sp(fImpl->fImages.get(index - 1));
     855             : }
     856             : 
     857           0 : sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) {
     858           0 :     if (size < sizeof(uint32_t)) {
     859           0 :         SkDebugf("-------- data length too short for readPicture %d\n", size);
     860           0 :         return nullptr;
     861             :     }
     862             : 
     863           0 :     const uint32_t* ptr = (const uint32_t*)data;
     864           0 :     uint32_t packedVerb = *ptr++;
     865           0 :     size -= 4;
     866             : 
     867           0 :     if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) {
     868           0 :         SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
     869           0 :                                 &fImpl->fTypefaces, &fImpl->fFactories,
     870           0 :                                 fImpl->fTFDeserializer, fImpl->fIMDeserializer);
     871           0 :         SkPipeReader reader(this, ptr, size);
     872           0 :         reader.setInflator(&inflator);
     873           0 :         definePicture_handler(reader, packedVerb, nullptr);
     874           0 :         packedVerb = reader.read32();  // read the next verb
     875             :     }
     876           0 :     if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) {
     877           0 :         SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb));
     878           0 :         return nullptr;
     879             :     }
     880           0 :     int index = unpack_verb_extra(packedVerb);
     881           0 :     if (0 == index) {
     882           0 :         return nullptr; // writer failed
     883             :     }
     884           0 :     return sk_ref_sp(fImpl->fPictures.get(index - 1));
     885             : }
     886             : 
     887           0 : static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) {
     888           0 :     int indent = 0;
     889             : 
     890           0 :     const bool showEachVerb = false;
     891           0 :     int counter = 0;
     892           0 :     while (!reader.eof()) {
     893           0 :         uint32_t prevOffset = reader.offset();
     894           0 :         uint32_t packedVerb = reader.read32();
     895           0 :         SkPipeVerb verb = unpack_verb(packedVerb);
     896           0 :         if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) {
     897           0 :             SkDebugf("------- bad verb %d\n", verb);
     898           0 :             return false;
     899             :         }
     900           0 :         if (SkPipeVerb::kRestore == verb) {
     901           0 :             indent -= 1;
     902           0 :             SkASSERT(indent >= 0);
     903             :         }
     904             : 
     905           0 :         if (SkPipeVerb::kEndPicture == verb) {
     906           0 :             if (endPictureIndex) {
     907           0 :                 *endPictureIndex = unpack_verb_extra(packedVerb);
     908             :             }
     909           0 :             return true;
     910             :         }
     911           0 :         HandlerRec rec = gPipeHandlers[(unsigned)verb];
     912           0 :         rec.fProc(reader, packedVerb, canvas);
     913             :         if (showEachVerb) {
     914             :             for (int i = 0; i < indent; ++i) {
     915             :                 SkDebugf("    ");
     916             :             }
     917             :             SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset);
     918             :         }
     919           0 :         if (!reader.isValid()) {
     920           0 :             SkDebugf("-------- bad reader\n");
     921           0 :             return false;
     922             :         }
     923             : 
     924           0 :         switch (verb) {
     925             :             case SkPipeVerb::kSave:
     926             :             case SkPipeVerb::kSaveLayer:
     927           0 :                 indent += 1;
     928           0 :                 break;
     929             :             default:
     930           0 :                 break;
     931             :         }
     932             :     }
     933           0 :     return true;
     934             : }
     935             : 
     936           0 : bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) {
     937           0 :     SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures,
     938           0 :                             &fImpl->fTypefaces, &fImpl->fFactories,
     939           0 :                             fImpl->fTFDeserializer, fImpl->fIMDeserializer);
     940           0 :     SkPipeReader reader(this, data, size);
     941           0 :     reader.setInflator(&inflator);
     942           0 :     return do_playback(reader, canvas);
     943             : }
     944             : 

Generated by: LCOV version 1.13