Home | History | Annotate | Download | only in pipe
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkBitmapHeap.h"
     11 #include "SkCanvas.h"
     12 #include "SkPaint.h"
     13 #include "SkGPipe.h"
     14 #include "SkGPipePriv.h"
     15 #include "SkReader32.h"
     16 #include "SkStream.h"
     17 
     18 #include "SkColorFilter.h"
     19 #include "SkDrawLooper.h"
     20 #include "SkMaskFilter.h"
     21 #include "SkOrderedReadBuffer.h"
     22 #include "SkPathEffect.h"
     23 #include "SkRasterizer.h"
     24 #include "SkRRect.h"
     25 #include "SkShader.h"
     26 #include "SkTypeface.h"
     27 #include "SkXfermode.h"
     28 
     29 static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
     30     SkASSERT(paintFlat < kCount_PaintFlats);
     31     switch (paintFlat) {
     32         case kColorFilter_PaintFlat:
     33             paint->setColorFilter((SkColorFilter*)obj);
     34             break;
     35         case kDrawLooper_PaintFlat:
     36             paint->setLooper((SkDrawLooper*)obj);
     37             break;
     38         case kMaskFilter_PaintFlat:
     39             paint->setMaskFilter((SkMaskFilter*)obj);
     40             break;
     41         case kPathEffect_PaintFlat:
     42             paint->setPathEffect((SkPathEffect*)obj);
     43             break;
     44         case kRasterizer_PaintFlat:
     45             paint->setRasterizer((SkRasterizer*)obj);
     46             break;
     47         case kShader_PaintFlat:
     48             paint->setShader((SkShader*)obj);
     49             break;
     50         case kImageFilter_PaintFlat:
     51             paint->setImageFilter((SkImageFilter*)obj);
     52             break;
     53         case kXfermode_PaintFlat:
     54             paint->setXfermode((SkXfermode*)obj);
     55             break;
     56         case kAnnotation_PaintFlat:
     57             paint->setAnnotation((SkAnnotation*)obj);
     58             break;
     59         default:
     60             SkDEBUGFAIL("never gets here");
     61     }
     62 }
     63 
     64 template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
     65 public:
     66     ~SkRefCntTDArray() { this->unrefAll(); }
     67 };
     68 
     69 class SkGPipeState : public SkBitmapHeapReader {
     70 public:
     71     SkGPipeState();
     72     ~SkGPipeState();
     73 
     74     void setSilent(bool silent) {
     75         fSilent = silent;
     76     }
     77 
     78     bool shouldDraw() {
     79         return !fSilent;
     80     }
     81 
     82     void setFlags(unsigned flags) {
     83         if (fFlags != flags) {
     84             fFlags = flags;
     85             this->updateReader();
     86         }
     87     }
     88 
     89     unsigned getFlags() const {
     90         return fFlags;
     91     }
     92 
     93     void setReader(SkOrderedReadBuffer* reader) {
     94         fReader = reader;
     95         this->updateReader();
     96     }
     97 
     98     const SkPaint& paint() const { return fPaint; }
     99     SkPaint* editPaint() { return &fPaint; }
    100 
    101     SkFlattenable* getFlat(unsigned index) const {
    102         if (0 == index) {
    103             return NULL;
    104         }
    105         return fFlatArray[index - 1];
    106     }
    107 
    108     void defFlattenable(PaintFlats pf, int index) {
    109         index--;
    110         SkFlattenable* obj = fReader->readFlattenable();
    111         if (fFlatArray.count() == index) {
    112             *fFlatArray.append() = obj;
    113         } else {
    114             SkSafeUnref(fFlatArray[index]);
    115             fFlatArray[index] = obj;
    116         }
    117     }
    118 
    119     void defFactory(const char* name) {
    120         SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
    121         if (factory) {
    122             SkASSERT(fFactoryArray.find(factory) < 0);
    123             *fFactoryArray.append() = factory;
    124         }
    125     }
    126 
    127     /**
    128      * Add a bitmap to the array of bitmaps, or replace an existing one.
    129      * This is only used when in cross process mode without a shared heap.
    130      */
    131     void addBitmap(int index) {
    132         SkASSERT(shouldFlattenBitmaps(fFlags));
    133         SkBitmap* bm;
    134         if(fBitmaps.count() == index) {
    135             bm = SkNEW(SkBitmap);
    136             *fBitmaps.append() = bm;
    137         } else {
    138             bm = fBitmaps[index];
    139         }
    140         fReader->readBitmap(bm);
    141     }
    142 
    143     /**
    144      * Override of SkBitmapHeapReader, so that SkOrderedReadBuffer can use
    145      * these SkBitmaps for bitmap shaders. Used only in cross process mode
    146      * without a shared heap.
    147      */
    148     virtual SkBitmap* getBitmap(int32_t index) const SK_OVERRIDE {
    149         SkASSERT(shouldFlattenBitmaps(fFlags));
    150         return fBitmaps[index];
    151     }
    152 
    153     /**
    154      * Needed to be a non-abstract subclass of SkBitmapHeapReader.
    155      */
    156     virtual void releaseRef(int32_t) SK_OVERRIDE {}
    157 
    158     void setSharedHeap(SkBitmapHeap* heap) {
    159         SkASSERT(!shouldFlattenBitmaps(fFlags) || NULL == heap);
    160         SkRefCnt_SafeAssign(fSharedHeap, heap);
    161         this->updateReader();
    162     }
    163 
    164     /**
    165      * Access the shared heap. Only used in the case when bitmaps are not
    166      * flattened.
    167      */
    168     SkBitmapHeap* getSharedHeap() const {
    169         SkASSERT(!shouldFlattenBitmaps(fFlags));
    170         return fSharedHeap;
    171     }
    172 
    173     void addTypeface() {
    174         size_t size = fReader->read32();
    175         const void* data = fReader->skip(SkAlign4(size));
    176         SkMemoryStream stream(data, size, false);
    177         *fTypefaces.append() = SkTypeface::Deserialize(&stream);
    178     }
    179 
    180     void setTypeface(SkPaint* paint, unsigned id) {
    181         paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
    182     }
    183 
    184 private:
    185     void updateReader() {
    186         if (NULL == fReader) {
    187             return;
    188         }
    189         bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag);
    190         fReader->setFlags(SkSetClearMask(fReader->getFlags(), crossProcess,
    191                                          SkFlattenableReadBuffer::kCrossProcess_Flag));
    192         if (crossProcess) {
    193             fReader->setFactoryArray(&fFactoryArray);
    194         } else {
    195             fReader->setFactoryArray(NULL);
    196         }
    197 
    198         if (shouldFlattenBitmaps(fFlags)) {
    199             fReader->setBitmapStorage(this);
    200         } else {
    201             fReader->setBitmapStorage(fSharedHeap);
    202         }
    203     }
    204     SkOrderedReadBuffer*      fReader;
    205     SkPaint                   fPaint;
    206     SkTDArray<SkFlattenable*> fFlatArray;
    207     SkTDArray<SkTypeface*>    fTypefaces;
    208     SkTDArray<SkFlattenable::Factory> fFactoryArray;
    209     SkTDArray<SkBitmap*>      fBitmaps;
    210     bool                      fSilent;
    211     // Only used when sharing bitmaps with the writer.
    212     SkBitmapHeap*             fSharedHeap;
    213     unsigned                  fFlags;
    214 };
    215 
    216 ///////////////////////////////////////////////////////////////////////////////
    217 
    218 template <typename T> const T* skip(SkReader32* reader, int count = 1) {
    219     SkASSERT(count >= 0);
    220     size_t size = sizeof(T) * count;
    221     SkASSERT(SkAlign4(size) == size);
    222     return reinterpret_cast<const T*>(reader->skip(size));
    223 }
    224 
    225 template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
    226     SkASSERT(count >= 0);
    227     size_t size = SkAlign4(sizeof(T) * count);
    228     return reinterpret_cast<const T*>(reader->skip(size));
    229 }
    230 
    231 ///////////////////////////////////////////////////////////////////////////////
    232 ///////////////////////////////////////////////////////////////////////////////
    233 
    234 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    235                         SkGPipeState* state) {
    236     SkPath path;
    237     reader->readPath(&path);
    238     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    239     canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    240 }
    241 
    242 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    243                           SkGPipeState* state) {
    244     SkRegion rgn;
    245     reader->readRegion(&rgn);
    246     canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
    247 }
    248 
    249 static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    250                         SkGPipeState* state) {
    251     const SkRect* rect = skip<SkRect>(reader);
    252     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    253     canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    254 }
    255 
    256 static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    257                          SkGPipeState* state) {
    258     SkRRect rrect;
    259     reader->readRRect(&rrect);
    260     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    261     canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    262 }
    263 
    264 ///////////////////////////////////////////////////////////////////////////////
    265 
    266 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    267                       SkGPipeState* state) {
    268     SkMatrix matrix;
    269     reader->readMatrix(&matrix);
    270     canvas->setMatrix(matrix);
    271 }
    272 
    273 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    274                       SkGPipeState* state) {
    275     SkMatrix matrix;
    276     reader->readMatrix(&matrix);
    277     canvas->concat(matrix);
    278 }
    279 
    280 static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    281                       SkGPipeState* state) {
    282     const SkScalar* param = skip<SkScalar>(reader, 2);
    283     canvas->scale(param[0], param[1]);
    284 }
    285 
    286 static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    287                       SkGPipeState* state) {
    288     const SkScalar* param = skip<SkScalar>(reader, 2);
    289     canvas->skew(param[0], param[1]);
    290 }
    291 
    292 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    293                       SkGPipeState* state) {
    294     canvas->rotate(reader->readScalar());
    295 }
    296 
    297 static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    298                       SkGPipeState* state) {
    299     const SkScalar* param = skip<SkScalar>(reader, 2);
    300     canvas->translate(param[0], param[1]);
    301 }
    302 
    303 ///////////////////////////////////////////////////////////////////////////////
    304 
    305 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    306                     SkGPipeState* state) {
    307     canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
    308 }
    309 
    310 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    311                          SkGPipeState* state) {
    312     unsigned flags = DrawOp_unpackFlags(op32);
    313     SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
    314 
    315     const SkRect* bounds = NULL;
    316     if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
    317         bounds = skip<SkRect>(reader);
    318     }
    319     const SkPaint* paint = NULL;
    320     if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
    321         paint = &state->paint();
    322     }
    323     canvas->saveLayer(bounds, paint, saveFlags);
    324 }
    325 
    326 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    327                        SkGPipeState* state) {
    328     canvas->restore();
    329 }
    330 
    331 ///////////////////////////////////////////////////////////////////////////////
    332 
    333 static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    334                          SkGPipeState* state) {
    335     SkColor color = 0;
    336     if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
    337         color = reader->readU32();
    338     }
    339     canvas->clear(color);
    340 }
    341 
    342 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    343                          SkGPipeState* state) {
    344     if (state->shouldDraw()) {
    345         canvas->drawPaint(state->paint());
    346     }
    347 }
    348 
    349 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    350                           SkGPipeState* state) {
    351     SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
    352     size_t count = reader->readU32();
    353     const SkPoint* pts = skip<SkPoint>(reader, count);
    354     if (state->shouldDraw()) {
    355         canvas->drawPoints(mode, count, pts, state->paint());
    356     }
    357 }
    358 
    359 static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    360                         SkGPipeState* state) {
    361     const SkRect* rect = skip<SkRect>(reader);
    362     if (state->shouldDraw()) {
    363         canvas->drawOval(*rect, state->paint());
    364     }
    365 }
    366 
    367 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    368                         SkGPipeState* state) {
    369     const SkRect* rect = skip<SkRect>(reader);
    370     if (state->shouldDraw()) {
    371         canvas->drawRect(*rect, state->paint());
    372     }
    373 }
    374 
    375 static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    376                          SkGPipeState* state) {
    377     SkRRect rrect;
    378     reader->readRRect(&rrect);
    379     if (state->shouldDraw()) {
    380         canvas->drawRRect(rrect, state->paint());
    381     }
    382 }
    383 
    384 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    385                         SkGPipeState* state) {
    386     SkPath path;
    387     reader->readPath(&path);
    388     if (state->shouldDraw()) {
    389         canvas->drawPath(path, state->paint());
    390     }
    391 }
    392 
    393 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    394                             SkGPipeState* state) {
    395     unsigned flags = DrawOp_unpackFlags(op32);
    396 
    397     SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
    398     int vertexCount = reader->readU32();
    399     const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
    400 
    401     const SkPoint* texs = NULL;
    402     if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
    403         texs = skip<SkPoint>(reader, vertexCount);
    404     }
    405 
    406     const SkColor* colors = NULL;
    407     if (flags & kDrawVertices_HasColors_DrawOpFlag) {
    408         colors = skip<SkColor>(reader, vertexCount);
    409     }
    410 
    411     // TODO: flatten/unflatten xfermodes
    412     SkXfermode* xfer = NULL;
    413 
    414     int indexCount = 0;
    415     const uint16_t* indices = NULL;
    416     if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
    417         indexCount = reader->readU32();
    418         indices = skipAlign<uint16_t>(reader, indexCount);
    419     }
    420     if (state->shouldDraw()) {
    421         canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
    422                              indices, indexCount, state->paint());
    423     }
    424 }
    425 
    426 ///////////////////////////////////////////////////////////////////////////////
    427 
    428 static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    429                         SkGPipeState* state) {
    430     size_t len = reader->readU32();
    431     const void* text = reader->skip(SkAlign4(len));
    432     const SkScalar* xy = skip<SkScalar>(reader, 2);
    433     if (state->shouldDraw()) {
    434         canvas->drawText(text, len, xy[0], xy[1], state->paint());
    435     }
    436 }
    437 
    438 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    439                         SkGPipeState* state) {
    440     size_t len = reader->readU32();
    441     const void* text = reader->skip(SkAlign4(len));
    442     size_t posCount = reader->readU32();    // compute by our writer
    443     const SkPoint* pos = skip<SkPoint>(reader, posCount);
    444     if (state->shouldDraw()) {
    445         canvas->drawPosText(text, len, pos, state->paint());
    446     }
    447 }
    448 
    449 static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    450                         SkGPipeState* state) {
    451     size_t len = reader->readU32();
    452     const void* text = reader->skip(SkAlign4(len));
    453     size_t posCount = reader->readU32();    // compute by our writer
    454     const SkScalar* xpos = skip<SkScalar>(reader, posCount);
    455     SkScalar constY = reader->readScalar();
    456     if (state->shouldDraw()) {
    457         canvas->drawPosTextH(text, len, xpos, constY, state->paint());
    458     }
    459 }
    460 
    461 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    462                               SkGPipeState* state) {
    463     size_t len = reader->readU32();
    464     const void* text = reader->skip(SkAlign4(len));
    465 
    466     SkPath path;
    467     reader->readPath(&path);
    468 
    469     SkMatrix matrixStorage;
    470     const SkMatrix* matrix = NULL;
    471     if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
    472         reader->readMatrix(&matrixStorage);
    473         matrix = &matrixStorage;
    474     }
    475     if (state->shouldDraw()) {
    476         canvas->drawTextOnPath(text, len, path, matrix, state->paint());
    477     }
    478 }
    479 
    480 ///////////////////////////////////////////////////////////////////////////////
    481 
    482 class BitmapHolder : SkNoncopyable {
    483 public:
    484     BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state);
    485     ~BitmapHolder() {
    486         if (fHeapEntry != NULL) {
    487             fHeapEntry->releaseRef();
    488         }
    489     }
    490     const SkBitmap* getBitmap() {
    491         return fBitmap;
    492     }
    493 private:
    494     SkBitmapHeapEntry* fHeapEntry;
    495     const SkBitmap*    fBitmap;
    496     SkBitmap           fBitmapStorage;
    497 };
    498 
    499 BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32,
    500                            SkGPipeState* state) {
    501     const unsigned flags = state->getFlags();
    502     const unsigned index = DrawOp_unpackData(op32);
    503     if (shouldFlattenBitmaps(flags)) {
    504         fHeapEntry = NULL;
    505         fBitmap = state->getBitmap(index);
    506     } else {
    507         SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index);
    508         if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) {
    509             // Make a shallow copy for thread safety. Each thread will point to the same SkPixelRef,
    510             // which is thread safe.
    511             fBitmapStorage = *entry->getBitmap();
    512             fBitmap = &fBitmapStorage;
    513             // Release the ref on the bitmap now, since we made our own copy.
    514             entry->releaseRef();
    515             fHeapEntry = NULL;
    516         } else {
    517             SkASSERT(!shouldFlattenBitmaps(flags));
    518             SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag));
    519             fHeapEntry = entry;
    520             fBitmap = fHeapEntry->getBitmap();
    521         }
    522     }
    523 }
    524 
    525 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    526                           SkGPipeState* state) {
    527     BitmapHolder holder(reader, op32, state);
    528     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    529     SkScalar left = reader->readScalar();
    530     SkScalar top = reader->readScalar();
    531     const SkBitmap* bitmap = holder.getBitmap();
    532     if (state->shouldDraw()) {
    533         canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : NULL);
    534     }
    535 }
    536 
    537 static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    538                                 SkGPipeState* state) {
    539     BitmapHolder holder(reader, op32, state);
    540     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    541     SkMatrix matrix;
    542     reader->readMatrix(&matrix);
    543     const SkBitmap* bitmap = holder.getBitmap();
    544     if (state->shouldDraw()) {
    545         canvas->drawBitmapMatrix(*bitmap, matrix,
    546                                  hasPaint ? &state->paint() : NULL);
    547     }
    548 }
    549 
    550 static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
    551                               uint32_t op32, SkGPipeState* state) {
    552     BitmapHolder holder(reader, op32, state);
    553     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    554     const SkIRect* center = skip<SkIRect>(reader);
    555     const SkRect* dst = skip<SkRect>(reader);
    556     const SkBitmap* bitmap = holder.getBitmap();
    557     if (state->shouldDraw()) {
    558         canvas->drawBitmapNine(*bitmap, *center, *dst,
    559                                hasPaint ? &state->paint() : NULL);
    560     }
    561 }
    562 
    563 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
    564                               uint32_t op32, SkGPipeState* state) {
    565     BitmapHolder holder(reader, op32, state);
    566     unsigned flags = DrawOp_unpackFlags(op32);
    567     bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
    568     bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag);
    569     const SkRect* src;
    570     if (hasSrc) {
    571         src = skip<SkRect>(reader);
    572     } else {
    573         src = NULL;
    574     }
    575     const SkRect* dst = skip<SkRect>(reader);
    576     const SkBitmap* bitmap = holder.getBitmap();
    577     if (state->shouldDraw()) {
    578         canvas->drawBitmapRectToRect(*bitmap, src, *dst, hasPaint ? &state->paint() : NULL);
    579     }
    580 }
    581 
    582 static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    583                           SkGPipeState* state) {
    584     BitmapHolder holder(reader, op32, state);
    585     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    586     const SkIPoint* point = skip<SkIPoint>(reader);
    587     const SkBitmap* bitmap = holder.getBitmap();
    588     if (state->shouldDraw()) {
    589         canvas->drawSprite(*bitmap, point->fX, point->fY, hasPaint ? &state->paint() : NULL);
    590     }
    591 }
    592 
    593 ///////////////////////////////////////////////////////////////////////////////
    594 
    595 static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    596                         SkGPipeState* state) {
    597     // since we don't have a paint, we can use data for our (small) sizes
    598     size_t size = DrawOp_unpackData(op32);
    599     if (0 == size) {
    600         size = reader->readU32();
    601     }
    602     const void* data = reader->skip(SkAlign4(size));
    603     if (state->shouldDraw()) {
    604         canvas->drawData(data, size);
    605     }
    606 }
    607 
    608 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    609                            SkGPipeState* state) {
    610     UNIMPLEMENTED
    611 }
    612 
    613 ///////////////////////////////////////////////////////////////////////////////
    614 
    615 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
    616                        SkGPipeState* state) {
    617     size_t offset = reader->offset();
    618     size_t stop = offset + PaintOp_unpackData(op32);
    619     SkPaint* p = state->editPaint();
    620 
    621     do {
    622         uint32_t p32 = reader->readU32();
    623         unsigned op = PaintOp_unpackOp(p32);
    624         unsigned data = PaintOp_unpackData(p32);
    625 
    626 //        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
    627 
    628         switch (op) {
    629             case kReset_PaintOp: p->reset(); break;
    630             case kFlags_PaintOp: p->setFlags(data); break;
    631             case kColor_PaintOp: p->setColor(reader->readU32()); break;
    632             case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
    633             case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
    634             case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
    635             case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
    636             case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
    637             case kEncoding_PaintOp:
    638                 p->setTextEncoding((SkPaint::TextEncoding)data);
    639                 break;
    640             case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
    641             case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
    642             case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
    643             case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
    644             case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
    645 
    646             case kFlatIndex_PaintOp: {
    647                 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
    648                 unsigned index = data;
    649                 set_paintflat(p, state->getFlat(index), pf);
    650                 break;
    651             }
    652 
    653             case kTypeface_PaintOp:
    654                 SkASSERT(SkToBool(state->getFlags() &
    655                                   SkGPipeWriter::kCrossProcess_Flag));
    656                 state->setTypeface(p, data); break;
    657             default: SkDEBUGFAIL("bad paintop"); return;
    658         }
    659         SkASSERT(reader->offset() <= stop);
    660     } while (reader->offset() < stop);
    661 }
    662 
    663 static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t,
    664                         SkGPipeState* state) {
    665     SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag));
    666     SkPaint* p = state->editPaint();
    667     p->setTypeface(static_cast<SkTypeface*>(reader->readPtr()));
    668 }
    669 
    670 ///////////////////////////////////////////////////////////////////////////////
    671 
    672 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
    673     state->addTypeface();
    674 }
    675 
    676 static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
    677                              SkGPipeState* state) {
    678     PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
    679     unsigned index = DrawOp_unpackData(op32);
    680     state->defFlattenable(pf, index);
    681 }
    682 
    683 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
    684                           SkGPipeState* state) {
    685     unsigned index = DrawOp_unpackData(op32);
    686     state->addBitmap(index);
    687 }
    688 
    689 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t,
    690                            SkGPipeState* state) {
    691     state->defFactory(reader->readString());
    692 }
    693 
    694 ///////////////////////////////////////////////////////////////////////////////
    695 
    696 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
    697     size_t bytes = DrawOp_unpackData(op32);
    698     (void)reader->skip(bytes);
    699 }
    700 
    701 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
    702                            SkGPipeState* state) {
    703     unsigned flags = DrawOp_unpackFlags(op32);
    704     state->setFlags(flags);
    705 }
    706 
    707 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
    708                            SkGPipeState* state) {
    709     state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
    710 }
    711 
    712 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
    713 
    714 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
    715 
    716 static const ReadProc gReadTable[] = {
    717     skip_rp,
    718     clipPath_rp,
    719     clipRegion_rp,
    720     clipRect_rp,
    721     clipRRect_rp,
    722     concat_rp,
    723     drawBitmap_rp,
    724     drawBitmapMatrix_rp,
    725     drawBitmapNine_rp,
    726     drawBitmapRect_rp,
    727     drawClear_rp,
    728     drawData_rp,
    729     drawOval_rp,
    730     drawPaint_rp,
    731     drawPath_rp,
    732     drawPicture_rp,
    733     drawPoints_rp,
    734     drawPosText_rp,
    735     drawPosTextH_rp,
    736     drawRect_rp,
    737     drawRRect_rp,
    738     drawSprite_rp,
    739     drawText_rp,
    740     drawTextOnPath_rp,
    741     drawVertices_rp,
    742     restore_rp,
    743     rotate_rp,
    744     save_rp,
    745     saveLayer_rp,
    746     scale_rp,
    747     setMatrix_rp,
    748     skew_rp,
    749     translate_rp,
    750 
    751     paintOp_rp,
    752     typeface_rp,
    753     def_Typeface_rp,
    754     def_PaintFlat_rp,
    755     def_Bitmap_rp,
    756     def_Factory_rp,
    757 
    758     reportFlags_rp,
    759     shareBitmapHeap_rp,
    760     done_rp
    761 };
    762 
    763 ///////////////////////////////////////////////////////////////////////////////
    764 
    765 SkGPipeState::SkGPipeState()
    766     : fReader(0)
    767     , fSilent(false)
    768     , fSharedHeap(NULL)
    769     , fFlags(0) {
    770 
    771 }
    772 
    773 SkGPipeState::~SkGPipeState() {
    774     fTypefaces.safeUnrefAll();
    775     fFlatArray.safeUnrefAll();
    776     fBitmaps.deleteAll();
    777     SkSafeUnref(fSharedHeap);
    778 }
    779 
    780 ///////////////////////////////////////////////////////////////////////////////
    781 
    782 #include "SkGPipe.h"
    783 
    784 SkGPipeReader::SkGPipeReader() {
    785     fCanvas = NULL;
    786     fState = NULL;
    787     fProc = NULL;
    788 }
    789 
    790 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
    791     fCanvas = NULL;
    792     this->setCanvas(target);
    793     fState = NULL;
    794     fProc = NULL;
    795 }
    796 
    797 void SkGPipeReader::setCanvas(SkCanvas *target) {
    798     SkRefCnt_SafeAssign(fCanvas, target);
    799 }
    800 
    801 SkGPipeReader::~SkGPipeReader() {
    802     SkSafeUnref(fCanvas);
    803     delete fState;
    804 }
    805 
    806 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
    807                                               uint32_t playbackFlags, size_t* bytesRead) {
    808     if (NULL == fCanvas) {
    809         return kError_Status;
    810     }
    811 
    812     if (NULL == fState) {
    813         fState = new SkGPipeState;
    814     }
    815 
    816     fState->setSilent(playbackFlags & kSilent_PlaybackFlag);
    817 
    818     SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
    819 
    820     const ReadProc* table = gReadTable;
    821     SkOrderedReadBuffer reader(data, length);
    822     reader.setBitmapDecoder(fProc);
    823     SkCanvas* canvas = fCanvas;
    824     Status status = kEOF_Status;
    825 
    826     fState->setReader(&reader);
    827     while (!reader.eof()) {
    828         uint32_t op32 = reader.readUInt();
    829         unsigned op = DrawOp_unpackOp(op32);
    830         // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
    831 
    832         if (op >= SK_ARRAY_COUNT(gReadTable)) {
    833             SkDebugf("---- bad op during GPipeState::playback\n");
    834             status = kError_Status;
    835             break;
    836         }
    837         if (kDone_DrawOp == op) {
    838             status = kDone_Status;
    839             break;
    840         }
    841         table[op](canvas, reader.getReader32(), op32, fState);
    842         if ((playbackFlags & kReadAtom_PlaybackFlag) &&
    843             (table[op] != paintOp_rp &&
    844              table[op] != def_Typeface_rp &&
    845              table[op] != def_PaintFlat_rp &&
    846              table[op] != def_Bitmap_rp
    847              )) {
    848                 status = kReadAtom_Status;
    849                 break;
    850             }
    851     }
    852 
    853     if (bytesRead) {
    854         *bytesRead = reader.offset();
    855     }
    856     return status;
    857 }
    858