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