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