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