Home | History | Annotate | Download | only in pipe
      1 /*
      2     Copyright 2011 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8     http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 
     18 #include "SkCanvas.h"
     19 #include "SkPaint.h"
     20 #include "SkGPipe.h"
     21 #include "SkGPipePriv.h"
     22 #include "SkReader32.h"
     23 #include "SkStream.h"
     24 
     25 #include "SkColorFilter.h"
     26 #include "SkDrawLooper.h"
     27 #include "SkMaskFilter.h"
     28 #include "SkPathEffect.h"
     29 #include "SkRasterizer.h"
     30 #include "SkShader.h"
     31 #include "SkTypeface.h"
     32 #include "SkXfermode.h"
     33 
     34 static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
     35     SkASSERT(paintFlat < kCount_PaintFlats);
     36     switch (paintFlat) {
     37         case kColorFilter_PaintFlat:
     38             paint->setColorFilter((SkColorFilter*)obj);
     39             break;
     40         case kDrawLooper_PaintFlat:
     41             paint->setLooper((SkDrawLooper*)obj);
     42             break;
     43         case kMaskFilter_PaintFlat:
     44             paint->setMaskFilter((SkMaskFilter*)obj);
     45             break;
     46         case kPathEffect_PaintFlat:
     47             paint->setPathEffect((SkPathEffect*)obj);
     48             break;
     49         case kRasterizer_PaintFlat:
     50             paint->setRasterizer((SkRasterizer*)obj);
     51             break;
     52         case kShader_PaintFlat:
     53             paint->setShader((SkShader*)obj);
     54             break;
     55         case kXfermode_PaintFlat:
     56             paint->setXfermode((SkXfermode*)obj);
     57             break;
     58         default:
     59             SkASSERT(!"never gets here");
     60     }
     61 }
     62 
     63 template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
     64 public:
     65     ~SkRefCntTDArray() { this->unrefAll(); }
     66 };
     67 
     68 class SkGPipeState {
     69 public:
     70     SkGPipeState();
     71     ~SkGPipeState();
     72 
     73     void setReader(SkFlattenableReadBuffer* reader) {
     74         fReader = reader;
     75         fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
     76     }
     77 
     78     const SkPaint& paint() const { return fPaint; }
     79     SkPaint* editPaint() { return &fPaint; }
     80 
     81     SkFlattenable* getFlat(unsigned index) const {
     82         if (0 == index) {
     83             return NULL;
     84         }
     85         return fFlatArray[index - 1];
     86     }
     87 
     88     void defFlattenable(PaintFlats pf, unsigned index) {
     89         SkASSERT(index == fFlatArray.count() + 1);
     90         SkFlattenable* obj = fReader->readFlattenable();
     91         *fFlatArray.append() = obj;
     92     }
     93 
     94     void nameFlattenable(PaintFlats pf, unsigned index) {
     95         SkASSERT(index == fFactoryArray.count() + 1);
     96         const char* name = fReader->readString();
     97         SkFlattenable::Factory fact = SkFlattenable::NameToFactory(name);
     98         *fFactoryArray.append() = fact;
     99 
    100         // update this each time we grow the array
    101         fReader->setFactoryPlayback(fFactoryArray.begin(), fFactoryArray.count());
    102     }
    103 
    104     void addTypeface() {
    105         size_t size = fReader->readU32();
    106         const void* data = fReader->skip(SkAlign4(size));
    107         SkMemoryStream stream(data, size, false);
    108         *fTypefaces.append() = SkTypeface::Deserialize(&stream);
    109     }
    110     void setTypeface(SkPaint* paint, unsigned id) {
    111         paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
    112     }
    113 
    114     SkFlattenableReadBuffer* fReader;
    115 
    116 private:
    117     SkPaint                   fPaint;
    118     SkTDArray<SkFlattenable*> fFlatArray;
    119     SkTDArray<SkTypeface*>    fTypefaces;
    120     SkTDArray<SkFlattenable::Factory> fFactoryArray;
    121 };
    122 
    123 ///////////////////////////////////////////////////////////////////////////////
    124 
    125 template <typename T> const T* skip(SkReader32* reader, int count = 1) {
    126     SkASSERT(count >= 0);
    127     size_t size = sizeof(T) * count;
    128     SkASSERT(SkAlign4(size) == size);
    129     return reinterpret_cast<const T*>(reader->skip(size));
    130 }
    131 
    132 template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
    133     SkASSERT(count >= 0);
    134     size_t size = SkAlign4(sizeof(T) * count);
    135     return reinterpret_cast<const T*>(reader->skip(size));
    136 }
    137 
    138 ///////////////////////////////////////////////////////////////////////////////
    139 ///////////////////////////////////////////////////////////////////////////////
    140 
    141 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    142                         SkGPipeState* state) {
    143     SkPath path;
    144     path.unflatten(*reader);
    145     canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
    146 }
    147 
    148 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    149                           SkGPipeState* state) {
    150     SkRegion rgn;
    151     SkReadRegion(reader, &rgn);
    152     canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
    153 }
    154 
    155 static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    156                         SkGPipeState* state) {
    157     canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
    158 }
    159 
    160 ///////////////////////////////////////////////////////////////////////////////
    161 
    162 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    163                       SkGPipeState* state) {
    164     SkMatrix matrix;
    165     SkReadMatrix(reader, &matrix);
    166     canvas->setMatrix(matrix);
    167 }
    168 
    169 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    170                       SkGPipeState* state) {
    171     SkMatrix matrix;
    172     SkReadMatrix(reader, &matrix);
    173     canvas->concat(matrix);
    174 }
    175 
    176 static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    177                       SkGPipeState* state) {
    178     const SkScalar* param = skip<SkScalar>(reader, 2);
    179     canvas->scale(param[0], param[1]);
    180 }
    181 
    182 static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    183                       SkGPipeState* state) {
    184     const SkScalar* param = skip<SkScalar>(reader, 2);
    185     canvas->skew(param[0], param[1]);
    186 }
    187 
    188 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    189                       SkGPipeState* state) {
    190     canvas->rotate(reader->readScalar());
    191 }
    192 
    193 static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    194                       SkGPipeState* state) {
    195     const SkScalar* param = skip<SkScalar>(reader, 2);
    196     canvas->translate(param[0], param[1]);
    197 }
    198 
    199 ///////////////////////////////////////////////////////////////////////////////
    200 
    201 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    202                     SkGPipeState* state) {
    203     canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
    204 }
    205 
    206 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    207                          SkGPipeState* state) {
    208     unsigned flags = DrawOp_unpackFlags(op32);
    209     SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
    210 
    211     const SkRect* bounds = NULL;
    212     if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
    213         bounds = skip<SkRect>(reader);
    214     }
    215     const SkPaint* paint = NULL;
    216     if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
    217         paint = &state->paint();
    218     }
    219     canvas->saveLayer(bounds, paint, saveFlags);
    220 }
    221 
    222 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    223                        SkGPipeState* state) {
    224     canvas->restore();
    225 }
    226 
    227 ///////////////////////////////////////////////////////////////////////////////
    228 
    229 static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    230                          SkGPipeState* state) {
    231     SkColor color = 0;
    232     if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
    233         color = reader->readU32();
    234     }
    235     canvas->clear(color);
    236 }
    237 
    238 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    239                          SkGPipeState* state) {
    240     canvas->drawPaint(state->paint());
    241 }
    242 
    243 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    244                           SkGPipeState* state) {
    245     SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
    246     size_t count = reader->readU32();
    247     const SkPoint* pts = skip<SkPoint>(reader, count);
    248     canvas->drawPoints(mode, count, pts, state->paint());
    249 }
    250 
    251 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    252                         SkGPipeState* state) {
    253     canvas->drawRect(*skip<SkRect>(reader), state->paint());
    254 }
    255 
    256 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    257                         SkGPipeState* state) {
    258     SkPath path;
    259     path.unflatten(*reader);
    260     canvas->drawPath(path, state->paint());
    261 }
    262 
    263 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    264                             SkGPipeState* state) {
    265     unsigned flags = DrawOp_unpackFlags(op32);
    266 
    267     SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
    268     int vertexCount = reader->readU32();
    269     const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
    270 
    271     const SkPoint* texs = NULL;
    272     if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
    273         texs = skip<SkPoint>(reader, vertexCount);
    274     }
    275 
    276     const SkColor* colors = NULL;
    277     if (flags & kDrawVertices_HasColors_DrawOpFlag) {
    278         colors = skip<SkColor>(reader, vertexCount);
    279     }
    280 
    281     // TODO: flatten/unflatten xfermodes
    282     SkXfermode* xfer = NULL;
    283 
    284     int indexCount = 0;
    285     const uint16_t* indices = NULL;
    286     if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
    287         indexCount = reader->readU32();
    288         indices = skipAlign<uint16_t>(reader, indexCount);
    289     }
    290 
    291     canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
    292                          indices, indexCount, state->paint());
    293 }
    294 
    295 ///////////////////////////////////////////////////////////////////////////////
    296 
    297 static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    298                         SkGPipeState* state) {
    299     size_t len = reader->readU32();
    300     const void* text = reader->skip(SkAlign4(len));
    301     const SkScalar* xy = skip<SkScalar>(reader, 2);
    302     canvas->drawText(text, len, xy[0], xy[1], state->paint());
    303 }
    304 
    305 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    306                         SkGPipeState* state) {
    307     size_t len = reader->readU32();
    308     const void* text = reader->skip(SkAlign4(len));
    309     size_t posCount = reader->readU32();    // compute by our writer
    310     const SkPoint* pos = skip<SkPoint>(reader, posCount);
    311     canvas->drawPosText(text, len, pos, state->paint());
    312 }
    313 
    314 static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    315                         SkGPipeState* state) {
    316     size_t len = reader->readU32();
    317     const void* text = reader->skip(SkAlign4(len));
    318     size_t posCount = reader->readU32();    // compute by our writer
    319     const SkScalar* xpos = skip<SkScalar>(reader, posCount);
    320     SkScalar constY = reader->readScalar();
    321     canvas->drawPosTextH(text, len, xpos, constY, state->paint());
    322 }
    323 
    324 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    325                               SkGPipeState* state) {
    326     size_t len = reader->readU32();
    327     const void* text = reader->skip(SkAlign4(len));
    328 
    329     SkPath path;
    330     path.unflatten(*reader);
    331 
    332     SkMatrix matrixStorage;
    333     const SkMatrix* matrix = NULL;
    334     if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
    335         SkReadMatrix(reader, &matrixStorage);
    336         matrix = &matrixStorage;
    337     }
    338 
    339     canvas->drawTextOnPath(text, len, path, matrix, state->paint());
    340 }
    341 
    342 ///////////////////////////////////////////////////////////////////////////////
    343 
    344 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    345                           SkGPipeState* state) {
    346     UNIMPLEMENTED
    347 }
    348 
    349 static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    350                                 SkGPipeState* state) {
    351     UNIMPLEMENTED
    352 }
    353 
    354 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    355                               SkGPipeState* state) {
    356     UNIMPLEMENTED
    357 }
    358 
    359 static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    360                           SkGPipeState* state) {
    361     UNIMPLEMENTED
    362 }
    363 
    364 ///////////////////////////////////////////////////////////////////////////////
    365 
    366 static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    367                         SkGPipeState* state) {
    368     // since we don't have a paint, we can use data for our (small) sizes
    369     size_t size = DrawOp_unpackData(op32);
    370     if (0 == size) {
    371         size = reader->readU32();
    372     }
    373     const void* data = reader->skip(SkAlign4(size));
    374     canvas->drawData(data, size);
    375 }
    376 
    377 static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    378                          SkGPipeState* state) {
    379     UNIMPLEMENTED
    380 }
    381 
    382 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
    383                            SkGPipeState* state) {
    384     UNIMPLEMENTED
    385 }
    386 
    387 ///////////////////////////////////////////////////////////////////////////////
    388 
    389 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
    390                        SkGPipeState* state) {
    391     size_t offset = reader->offset();
    392     size_t stop = offset + PaintOp_unpackData(op32);
    393     SkPaint* p = state->editPaint();
    394 
    395     do {
    396         uint32_t p32 = reader->readU32();
    397         unsigned op = PaintOp_unpackOp(p32);
    398         unsigned data = PaintOp_unpackData(p32);
    399 
    400 //        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
    401 
    402         switch (op) {
    403             case kReset_PaintOp: p->reset(); break;
    404             case kFlags_PaintOp: p->setFlags(data); break;
    405             case kColor_PaintOp: p->setColor(reader->readU32()); break;
    406             case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
    407             case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
    408             case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
    409             case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
    410             case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
    411             case kEncoding_PaintOp:
    412                 p->setTextEncoding((SkPaint::TextEncoding)data);
    413                 break;
    414             case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
    415             case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
    416             case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
    417             case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
    418             case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
    419 
    420             case kFlatIndex_PaintOp: {
    421                 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
    422                 unsigned index = data;
    423                 set_paintflat(p, state->getFlat(index), pf);
    424                 break;
    425             }
    426 
    427             case kTypeface_PaintOp: state->setTypeface(p, data); break;
    428             default: SkASSERT(!"bad paintop"); return;
    429         }
    430         SkASSERT(reader->offset() <= stop);
    431     } while (reader->offset() < stop);
    432 }
    433 
    434 ///////////////////////////////////////////////////////////////////////////////
    435 
    436 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
    437     state->addTypeface();
    438 }
    439 
    440 static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
    441                              SkGPipeState* state) {
    442     PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
    443     unsigned index = DrawOp_unpackData(op32);
    444     state->defFlattenable(pf, index);
    445 }
    446 
    447 static void name_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
    448                               SkGPipeState* state) {
    449     PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
    450     unsigned index = DrawOp_unpackData(op32);
    451     state->nameFlattenable(pf, index);
    452 }
    453 
    454 ///////////////////////////////////////////////////////////////////////////////
    455 
    456 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
    457     size_t bytes = DrawOp_unpackData(op32);
    458     (void)reader->skip(bytes);
    459 }
    460 
    461 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
    462 
    463 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
    464 
    465 static const ReadProc gReadTable[] = {
    466     skip_rp,
    467     clipPath_rp,
    468     clipRegion_rp,
    469     clipRect_rp,
    470     concat_rp,
    471     drawBitmap_rp,
    472     drawBitmapMatrix_rp,
    473     drawBitmapRect_rp,
    474     drawClear_rp,
    475     drawData_rp,
    476     drawPaint_rp,
    477     drawPath_rp,
    478     drawPicture_rp,
    479     drawPoints_rp,
    480     drawPosText_rp,
    481     drawPosTextH_rp,
    482     drawRect_rp,
    483     drawShape_rp,
    484     drawSprite_rp,
    485     drawText_rp,
    486     drawTextOnPath_rp,
    487     drawVertices_rp,
    488     restore_rp,
    489     rotate_rp,
    490     save_rp,
    491     saveLayer_rp,
    492     scale_rp,
    493     setMatrix_rp,
    494     skew_rp,
    495     translate_rp,
    496 
    497     paintOp_rp,
    498     def_Typeface_rp,
    499     def_PaintFlat_rp,
    500     name_PaintFlat_rp,
    501 
    502     done_rp
    503 };
    504 
    505 ///////////////////////////////////////////////////////////////////////////////
    506 
    507 SkGPipeState::SkGPipeState() {}
    508 
    509 SkGPipeState::~SkGPipeState() {
    510     fTypefaces.unrefAll();
    511     fFlatArray.unrefAll();
    512 }
    513 
    514 ///////////////////////////////////////////////////////////////////////////////
    515 
    516 #include "SkGPipe.h"
    517 
    518 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
    519     SkSafeRef(target);
    520     fCanvas = target;
    521     fState = NULL;
    522 }
    523 
    524 SkGPipeReader::~SkGPipeReader() {
    525     SkSafeUnref(fCanvas);
    526     delete fState;
    527 }
    528 
    529 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
    530                                               size_t* bytesRead) {
    531     if (NULL == fCanvas) {
    532         return kError_Status;
    533     }
    534 
    535     if (NULL == fState) {
    536         fState = new SkGPipeState;
    537     }
    538 
    539     SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
    540 
    541     const ReadProc* table = gReadTable;
    542     SkFlattenableReadBuffer reader(data, length);
    543     SkCanvas* canvas = fCanvas;
    544     Status status = kEOF_Status;
    545 
    546     fState->setReader(&reader);
    547     while (!reader.eof()) {
    548         uint32_t op32 = reader.readU32();
    549         unsigned op = DrawOp_unpackOp(op32);
    550         SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
    551 
    552         if (op >= SK_ARRAY_COUNT(gReadTable)) {
    553             SkDebugf("---- bad op during GPipeState::playback\n");
    554             status = kError_Status;
    555             break;
    556         }
    557         if (kDone_DrawOp == op) {
    558             status = kDone_Status;
    559             break;
    560         }
    561         table[op](canvas, &reader, op32, fState);
    562     }
    563 
    564     if (bytesRead) {
    565         *bytesRead = reader.offset();
    566     }
    567     return status;
    568 }
    569 
    570 
    571