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