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 "SkOrderedReadBuffer.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(SkOrderedReadBuffer* 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 SkOrderedReadBuffer 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                                          SkFlattenableReadBuffer::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     SkOrderedReadBuffer*      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, int count = 1) {
    234     SkASSERT(count >= 0);
    235     size_t size = sizeof(T) * count;
    236     SkASSERT(SkAlign4(size) == size);
    237     return reinterpret_cast<const T*>(reader->skip(size));
    238 }
    239 
    240 template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
    241     SkASSERT(count >= 0);
    242     size_t size = SkAlign4(sizeof(T) * count);
    243     return reinterpret_cast<const T*>(reader->skip(size));
    244 }
    245 
    246 ///////////////////////////////////////////////////////////////////////////////
    247 ///////////////////////////////////////////////////////////////////////////////
    248 
    249 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    250                         SkGPipeState* state) {
    251     SkPath path;
    252     reader->readPath(&path);
    253     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    254     canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    255 }
    256 
    257 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    258                           SkGPipeState* state) {
    259     SkRegion rgn;
    260     reader->readRegion(&rgn);
    261     canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
    262 }
    263 
    264 static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    265                         SkGPipeState* state) {
    266     const SkRect* rect = skip<SkRect>(reader);
    267     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    268     canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    269 }
    270 
    271 static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    272                          SkGPipeState* state) {
    273     SkRRect rrect;
    274     reader->readRRect(&rrect);
    275     bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
    276     canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
    277 }
    278 
    279 ///////////////////////////////////////////////////////////////////////////////
    280 
    281 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    282                       SkGPipeState* state) {
    283     SkMatrix matrix;
    284     reader->readMatrix(&matrix);
    285     canvas->setMatrix(matrix);
    286 }
    287 
    288 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    289                       SkGPipeState* state) {
    290     SkMatrix matrix;
    291     reader->readMatrix(&matrix);
    292     canvas->concat(matrix);
    293 }
    294 
    295 static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    296                       SkGPipeState* state) {
    297     const SkScalar* param = skip<SkScalar>(reader, 2);
    298     canvas->scale(param[0], param[1]);
    299 }
    300 
    301 static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    302                       SkGPipeState* state) {
    303     const SkScalar* param = skip<SkScalar>(reader, 2);
    304     canvas->skew(param[0], param[1]);
    305 }
    306 
    307 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    308                       SkGPipeState* state) {
    309     canvas->rotate(reader->readScalar());
    310 }
    311 
    312 static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    313                       SkGPipeState* state) {
    314     const SkScalar* param = skip<SkScalar>(reader, 2);
    315     canvas->translate(param[0], param[1]);
    316 }
    317 
    318 ///////////////////////////////////////////////////////////////////////////////
    319 
    320 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    321                     SkGPipeState* state) {
    322     canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
    323 }
    324 
    325 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    326                          SkGPipeState* state) {
    327     unsigned flags = DrawOp_unpackFlags(op32);
    328     SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
    329 
    330     const SkRect* bounds = NULL;
    331     if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
    332         bounds = skip<SkRect>(reader);
    333     }
    334     const SkPaint* paint = NULL;
    335     if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
    336         paint = &state->paint();
    337     }
    338     canvas->saveLayer(bounds, paint, saveFlags);
    339 }
    340 
    341 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    342                        SkGPipeState* state) {
    343     canvas->restore();
    344 }
    345 
    346 ///////////////////////////////////////////////////////////////////////////////
    347 
    348 static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    349                          SkGPipeState* state) {
    350     SkColor color = 0;
    351     if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
    352         color = reader->readU32();
    353     }
    354     canvas->clear(color);
    355 }
    356 
    357 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    358                          SkGPipeState* state) {
    359     if (state->shouldDraw()) {
    360         canvas->drawPaint(state->paint());
    361     }
    362 }
    363 
    364 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    365                           SkGPipeState* state) {
    366     SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
    367     size_t count = reader->readU32();
    368     const SkPoint* pts = skip<SkPoint>(reader, count);
    369     if (state->shouldDraw()) {
    370         canvas->drawPoints(mode, count, pts, state->paint());
    371     }
    372 }
    373 
    374 static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    375                         SkGPipeState* state) {
    376     const SkRect* rect = skip<SkRect>(reader);
    377     if (state->shouldDraw()) {
    378         canvas->drawOval(*rect, state->paint());
    379     }
    380 }
    381 
    382 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    383                         SkGPipeState* state) {
    384     const SkRect* rect = skip<SkRect>(reader);
    385     if (state->shouldDraw()) {
    386         canvas->drawRect(*rect, state->paint());
    387     }
    388 }
    389 
    390 static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    391                          SkGPipeState* state) {
    392     SkRRect rrect;
    393     reader->readRRect(&rrect);
    394     if (state->shouldDraw()) {
    395         canvas->drawRRect(rrect, state->paint());
    396     }
    397 }
    398 
    399 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    400                         SkGPipeState* state) {
    401     SkPath path;
    402     reader->readPath(&path);
    403     if (state->shouldDraw()) {
    404         canvas->drawPath(path, state->paint());
    405     }
    406 }
    407 
    408 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    409                             SkGPipeState* state) {
    410     unsigned flags = DrawOp_unpackFlags(op32);
    411 
    412     SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
    413     int vertexCount = reader->readU32();
    414     const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
    415 
    416     const SkPoint* texs = NULL;
    417     if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
    418         texs = skip<SkPoint>(reader, vertexCount);
    419     }
    420 
    421     const SkColor* colors = NULL;
    422     if (flags & kDrawVertices_HasColors_DrawOpFlag) {
    423         colors = skip<SkColor>(reader, vertexCount);
    424     }
    425 
    426     // TODO: flatten/unflatten xfermodes
    427     SkXfermode* xfer = NULL;
    428 
    429     int indexCount = 0;
    430     const uint16_t* indices = NULL;
    431     if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
    432         indexCount = reader->readU32();
    433         indices = skipAlign<uint16_t>(reader, indexCount);
    434     }
    435     if (state->shouldDraw()) {
    436         canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
    437                              indices, indexCount, state->paint());
    438     }
    439 }
    440 
    441 ///////////////////////////////////////////////////////////////////////////////
    442 
    443 static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    444                         SkGPipeState* state) {
    445     size_t len = reader->readU32();
    446     const void* text = reader->skip(SkAlign4(len));
    447     const SkScalar* xy = skip<SkScalar>(reader, 2);
    448     if (state->shouldDraw()) {
    449         canvas->drawText(text, len, xy[0], xy[1], state->paint());
    450     }
    451 }
    452 
    453 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    454                         SkGPipeState* state) {
    455     size_t len = reader->readU32();
    456     const void* text = reader->skip(SkAlign4(len));
    457     size_t posCount = reader->readU32();    // compute by our writer
    458     const SkPoint* pos = skip<SkPoint>(reader, posCount);
    459     if (state->shouldDraw()) {
    460         canvas->drawPosText(text, len, pos, state->paint());
    461     }
    462 }
    463 
    464 static void drawPosTextH_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 SkScalar* xpos = skip<SkScalar>(reader, posCount);
    470     SkScalar constY = reader->readScalar();
    471     if (state->shouldDraw()) {
    472         canvas->drawPosTextH(text, len, xpos, constY, state->paint());
    473     }
    474 }
    475 
    476 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    477                               SkGPipeState* state) {
    478     size_t len = reader->readU32();
    479     const void* text = reader->skip(SkAlign4(len));
    480 
    481     SkPath path;
    482     reader->readPath(&path);
    483 
    484     SkMatrix matrixStorage;
    485     const SkMatrix* matrix = NULL;
    486     if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
    487         reader->readMatrix(&matrixStorage);
    488         matrix = &matrixStorage;
    489     }
    490     if (state->shouldDraw()) {
    491         canvas->drawTextOnPath(text, len, path, matrix, state->paint());
    492     }
    493 }
    494 
    495 ///////////////////////////////////////////////////////////////////////////////
    496 
    497 class BitmapHolder : SkNoncopyable {
    498 public:
    499     BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state);
    500     ~BitmapHolder() {
    501         if (fHeapEntry != NULL) {
    502             fHeapEntry->releaseRef();
    503         }
    504     }
    505     const SkBitmap* getBitmap() {
    506         return fBitmap;
    507     }
    508 private:
    509     SkBitmapHeapEntry* fHeapEntry;
    510     const SkBitmap*    fBitmap;
    511     SkBitmap           fBitmapStorage;
    512 };
    513 
    514 BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32,
    515                            SkGPipeState* state) {
    516     const unsigned flags = state->getFlags();
    517     const unsigned index = DrawOp_unpackData(op32);
    518     if (shouldFlattenBitmaps(flags)) {
    519         fHeapEntry = NULL;
    520         fBitmap = state->getBitmap(index);
    521     } else {
    522         SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index);
    523         if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) {
    524             // Make a shallow copy for thread safety. Each thread will point to the same SkPixelRef,
    525             // which is thread safe.
    526             fBitmapStorage = *entry->getBitmap();
    527             fBitmap = &fBitmapStorage;
    528             // Release the ref on the bitmap now, since we made our own copy.
    529             entry->releaseRef();
    530             fHeapEntry = NULL;
    531         } else {
    532             SkASSERT(!shouldFlattenBitmaps(flags));
    533             SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag));
    534             fHeapEntry = entry;
    535             fBitmap = fHeapEntry->getBitmap();
    536         }
    537     }
    538 }
    539 
    540 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    541                           SkGPipeState* state) {
    542     BitmapHolder holder(reader, op32, state);
    543     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    544     SkScalar left = reader->readScalar();
    545     SkScalar top = reader->readScalar();
    546     const SkBitmap* bitmap = holder.getBitmap();
    547     if (state->shouldDraw()) {
    548         canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : NULL);
    549     }
    550 }
    551 
    552 static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    553                                 SkGPipeState* state) {
    554     BitmapHolder holder(reader, op32, state);
    555     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    556     SkMatrix matrix;
    557     reader->readMatrix(&matrix);
    558     const SkBitmap* bitmap = holder.getBitmap();
    559     if (state->shouldDraw()) {
    560         canvas->drawBitmapMatrix(*bitmap, matrix,
    561                                  hasPaint ? &state->paint() : NULL);
    562     }
    563 }
    564 
    565 static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
    566                               uint32_t op32, SkGPipeState* state) {
    567     BitmapHolder holder(reader, op32, state);
    568     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    569     const SkIRect* center = skip<SkIRect>(reader);
    570     const SkRect* dst = skip<SkRect>(reader);
    571     const SkBitmap* bitmap = holder.getBitmap();
    572     if (state->shouldDraw()) {
    573         canvas->drawBitmapNine(*bitmap, *center, *dst,
    574                                hasPaint ? &state->paint() : NULL);
    575     }
    576 }
    577 
    578 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
    579                               uint32_t op32, SkGPipeState* state) {
    580     BitmapHolder holder(reader, op32, state);
    581     unsigned flags = DrawOp_unpackFlags(op32);
    582     bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag);
    583     bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag);
    584     const SkRect* src;
    585     if (hasSrc) {
    586         src = skip<SkRect>(reader);
    587     } else {
    588         src = NULL;
    589     }
    590     SkCanvas::DrawBitmapRectFlags dbmrFlags = SkCanvas::kNone_DrawBitmapRectFlag;
    591     if (flags & kDrawBitmap_Bleed_DrawOpFlag) {
    592         dbmrFlags = (SkCanvas::DrawBitmapRectFlags)(dbmrFlags|SkCanvas::kBleed_DrawBitmapRectFlag);
    593     }
    594     const SkRect* dst = skip<SkRect>(reader);
    595     const SkBitmap* bitmap = holder.getBitmap();
    596     if (state->shouldDraw()) {
    597         canvas->drawBitmapRectToRect(*bitmap, src, *dst,
    598                                      hasPaint ? &state->paint() : NULL, dbmrFlags);
    599     }
    600 }
    601 
    602 static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    603                           SkGPipeState* state) {
    604     BitmapHolder holder(reader, op32, state);
    605     bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag);
    606     const SkIPoint* point = skip<SkIPoint>(reader);
    607     const SkBitmap* bitmap = holder.getBitmap();
    608     if (state->shouldDraw()) {
    609         canvas->drawSprite(*bitmap, point->fX, point->fY, hasPaint ? &state->paint() : NULL);
    610     }
    611 }
    612 
    613 ///////////////////////////////////////////////////////////////////////////////
    614 
    615 static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    616                         SkGPipeState* state) {
    617     // since we don't have a paint, we can use data for our (small) sizes
    618     size_t size = DrawOp_unpackData(op32);
    619     if (0 == size) {
    620         size = reader->readU32();
    621     }
    622     const void* data = reader->skip(SkAlign4(size));
    623     if (state->shouldDraw()) {
    624         canvas->drawData(data, size);
    625     }
    626 }
    627 
    628 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    629                            SkGPipeState* state) {
    630     UNIMPLEMENTED
    631 }
    632 
    633 ///////////////////////////////////////////////////////////////////////////////
    634 
    635 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
    636                        SkGPipeState* state) {
    637     size_t offset = reader->offset();
    638     size_t stop = offset + PaintOp_unpackData(op32);
    639     SkPaint* p = state->editPaint();
    640 
    641     do {
    642         uint32_t p32 = reader->readU32();
    643         unsigned op = PaintOp_unpackOp(p32);
    644         unsigned data = PaintOp_unpackData(p32);
    645 
    646 //        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
    647 
    648         switch (op) {
    649             case kReset_PaintOp: p->reset(); break;
    650             case kFlags_PaintOp: p->setFlags(data); break;
    651             case kColor_PaintOp: p->setColor(reader->readU32()); break;
    652             case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
    653             case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
    654             case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
    655             case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
    656             case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
    657             case kEncoding_PaintOp:
    658                 p->setTextEncoding((SkPaint::TextEncoding)data);
    659                 break;
    660             case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
    661             case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
    662             case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
    663             case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
    664             case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
    665 
    666             case kFlatIndex_PaintOp: {
    667                 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
    668                 unsigned index = data;
    669                 set_paintflat(p, state->getFlat(index), pf);
    670                 break;
    671             }
    672 
    673             case kTypeface_PaintOp:
    674                 SkASSERT(SkToBool(state->getFlags() &
    675                                   SkGPipeWriter::kCrossProcess_Flag));
    676                 state->setTypeface(p, data); break;
    677             default: SkDEBUGFAIL("bad paintop"); return;
    678         }
    679         SkASSERT(reader->offset() <= stop);
    680     } while (reader->offset() < stop);
    681 }
    682 
    683 static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t,
    684                         SkGPipeState* state) {
    685     SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag));
    686     SkPaint* p = state->editPaint();
    687     p->setTypeface(static_cast<SkTypeface*>(reader->readPtr()));
    688 }
    689 
    690 static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
    691                           SkGPipeState* state) {
    692     SkPaint* p = state->editPaint();
    693 
    694     const size_t size = DrawOp_unpackData(op32);
    695     if (size > 0) {
    696         SkOrderedReadBuffer buffer(reader->skip(size), size);
    697         p->setAnnotation(SkNEW_ARGS(SkAnnotation, (buffer)))->unref();
    698         SkASSERT(buffer.offset() == size);
    699     } else {
    700         p->setAnnotation(NULL);
    701     }
    702 }
    703 
    704 ///////////////////////////////////////////////////////////////////////////////
    705 
    706 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
    707     state->addTypeface();
    708 }
    709 
    710 static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
    711                              SkGPipeState* state) {
    712     PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
    713     unsigned index = DrawOp_unpackData(op32);
    714     state->defFlattenable(pf, index);
    715 }
    716 
    717 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
    718                           SkGPipeState* state) {
    719     unsigned index = DrawOp_unpackData(op32);
    720     state->addBitmap(index);
    721 }
    722 
    723 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t,
    724                            SkGPipeState* state) {
    725     state->defFactory(reader->readString());
    726 }
    727 
    728 ///////////////////////////////////////////////////////////////////////////////
    729 
    730 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
    731     size_t bytes = DrawOp_unpackData(op32);
    732     (void)reader->skip(bytes);
    733 }
    734 
    735 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
    736                            SkGPipeState* state) {
    737     unsigned flags = DrawOp_unpackFlags(op32);
    738     state->setFlags(flags);
    739 }
    740 
    741 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
    742                            SkGPipeState* state) {
    743     state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
    744 }
    745 
    746 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
    747 
    748 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
    749 
    750 static const ReadProc gReadTable[] = {
    751     skip_rp,
    752     clipPath_rp,
    753     clipRegion_rp,
    754     clipRect_rp,
    755     clipRRect_rp,
    756     concat_rp,
    757     drawBitmap_rp,
    758     drawBitmapMatrix_rp,
    759     drawBitmapNine_rp,
    760     drawBitmapRect_rp,
    761     drawClear_rp,
    762     drawData_rp,
    763     drawOval_rp,
    764     drawPaint_rp,
    765     drawPath_rp,
    766     drawPicture_rp,
    767     drawPoints_rp,
    768     drawPosText_rp,
    769     drawPosTextH_rp,
    770     drawRect_rp,
    771     drawRRect_rp,
    772     drawSprite_rp,
    773     drawText_rp,
    774     drawTextOnPath_rp,
    775     drawVertices_rp,
    776     restore_rp,
    777     rotate_rp,
    778     save_rp,
    779     saveLayer_rp,
    780     scale_rp,
    781     setMatrix_rp,
    782     skew_rp,
    783     translate_rp,
    784 
    785     paintOp_rp,
    786     typeface_rp,
    787     annotation_rp,
    788 
    789     def_Typeface_rp,
    790     def_PaintFlat_rp,
    791     def_Bitmap_rp,
    792     def_Factory_rp,
    793 
    794     reportFlags_rp,
    795     shareBitmapHeap_rp,
    796     done_rp
    797 };
    798 
    799 ///////////////////////////////////////////////////////////////////////////////
    800 
    801 SkGPipeState::SkGPipeState()
    802     : fReader(0)
    803     , fSilent(false)
    804     , fSharedHeap(NULL)
    805     , fFlags(0) {
    806 
    807 }
    808 
    809 SkGPipeState::~SkGPipeState() {
    810     fTypefaces.safeUnrefAll();
    811     fFlatArray.safeUnrefAll();
    812     fBitmaps.deleteAll();
    813     SkSafeUnref(fSharedHeap);
    814 }
    815 
    816 ///////////////////////////////////////////////////////////////////////////////
    817 
    818 #include "SkGPipe.h"
    819 
    820 SkGPipeReader::SkGPipeReader() {
    821     fCanvas = NULL;
    822     fState = NULL;
    823     fProc = NULL;
    824 }
    825 
    826 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
    827     fCanvas = NULL;
    828     this->setCanvas(target);
    829     fState = NULL;
    830     fProc = NULL;
    831 }
    832 
    833 void SkGPipeReader::setCanvas(SkCanvas *target) {
    834     SkRefCnt_SafeAssign(fCanvas, target);
    835 }
    836 
    837 SkGPipeReader::~SkGPipeReader() {
    838     SkSafeUnref(fCanvas);
    839     delete fState;
    840 }
    841 
    842 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
    843                                               uint32_t playbackFlags, size_t* bytesRead) {
    844     if (NULL == fCanvas) {
    845         return kError_Status;
    846     }
    847 
    848     if (NULL == fState) {
    849         fState = new SkGPipeState;
    850     }
    851 
    852     fState->setSilent(playbackFlags & kSilent_PlaybackFlag);
    853 
    854     SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
    855 
    856     const ReadProc* table = gReadTable;
    857     SkOrderedReadBuffer reader(data, length);
    858     reader.setBitmapDecoder(fProc);
    859     SkCanvas* canvas = fCanvas;
    860     Status status = kEOF_Status;
    861 
    862     fState->setReader(&reader);
    863     while (!reader.eof()) {
    864         uint32_t op32 = reader.readUInt();
    865         unsigned op = DrawOp_unpackOp(op32);
    866         // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
    867 
    868         if (op >= SK_ARRAY_COUNT(gReadTable)) {
    869             SkDebugf("---- bad op during GPipeState::playback\n");
    870             status = kError_Status;
    871             break;
    872         }
    873         if (kDone_DrawOp == op) {
    874             status = kDone_Status;
    875             break;
    876         }
    877         table[op](canvas, reader.getReader32(), op32, fState);
    878         if ((playbackFlags & kReadAtom_PlaybackFlag) &&
    879             (table[op] != paintOp_rp &&
    880              table[op] != def_Typeface_rp &&
    881              table[op] != def_PaintFlat_rp &&
    882              table[op] != def_Bitmap_rp
    883              )) {
    884                 status = kReadAtom_Status;
    885                 break;
    886             }
    887     }
    888 
    889     if (bytesRead) {
    890         *bytesRead = reader.offset();
    891     }
    892     return status;
    893 }
    894