SkGPipeRead.cpp revision 94e75ee46a569cbcdf61fb7f04ee3a69d3ca0896
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
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 {
66public:
67    SkGPipeState();
68    ~SkGPipeState();
69
70    void setReader(SkFlattenableReadBuffer* reader) {
71        fReader = reader;
72        fReader->setFactoryArray(&fFactoryArray);
73    }
74
75    const SkPaint& paint() const { return fPaint; }
76    SkPaint* editPaint() { return &fPaint; }
77
78    SkFlattenable* getFlat(unsigned index) const {
79        if (0 == index) {
80            return NULL;
81        }
82        return fFlatArray[index - 1];
83    }
84
85    void defFlattenable(PaintFlats pf, int index) {
86        SkASSERT(index == fFlatArray.count() + 1);
87        SkFlattenable* obj = fReader->readFlattenable();
88        *fFlatArray.append() = obj;
89    }
90
91    void addBitmap(int index) {
92        SkASSERT(fBitmaps.count() == index);
93        SkBitmap* bm = new SkBitmap();
94        size_t size = fReader->readU32();
95        SkOrderedReadBuffer readBuffer(fReader->skip(size), size);
96        bm->unflatten(readBuffer);
97        *fBitmaps.append() = bm;
98    }
99
100    SkBitmap* getBitmap(unsigned index) {
101        return fBitmaps[index];
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
116private:
117    SkPaint                   fPaint;
118    SkTDArray<SkFlattenable*> fFlatArray;
119    SkTDArray<SkTypeface*>    fTypefaces;
120    SkTDArray<SkFlattenable::Factory> fFactoryArray;
121    SkTDArray<SkBitmap*>      fBitmaps;
122};
123
124///////////////////////////////////////////////////////////////////////////////
125
126template <typename T> const T* skip(SkReader32* reader, int count = 1) {
127    SkASSERT(count >= 0);
128    size_t size = sizeof(T) * count;
129    SkASSERT(SkAlign4(size) == size);
130    return reinterpret_cast<const T*>(reader->skip(size));
131}
132
133template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
134    SkASSERT(count >= 0);
135    size_t size = SkAlign4(sizeof(T) * count);
136    return reinterpret_cast<const T*>(reader->skip(size));
137}
138
139///////////////////////////////////////////////////////////////////////////////
140///////////////////////////////////////////////////////////////////////////////
141
142static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
143                        SkGPipeState* state) {
144    SkPath path;
145    reader->readPath(&path);
146    canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32),
147                     reader->readBool());
148}
149
150static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
151                          SkGPipeState* state) {
152    SkRegion rgn;
153    reader->readRegion(&rgn);
154    canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
155}
156
157static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
158                        SkGPipeState* state) {
159    const SkRect* rect = skip<SkRect>(reader);
160    bool doAA = reader->readBool();
161    canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
162}
163
164///////////////////////////////////////////////////////////////////////////////
165
166static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
167                      SkGPipeState* state) {
168    SkMatrix matrix;
169    reader->readMatrix(&matrix);
170    canvas->setMatrix(matrix);
171}
172
173static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
174                      SkGPipeState* state) {
175    SkMatrix matrix;
176    reader->readMatrix(&matrix);
177    canvas->concat(matrix);
178}
179
180static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
181                      SkGPipeState* state) {
182    const SkScalar* param = skip<SkScalar>(reader, 2);
183    canvas->scale(param[0], param[1]);
184}
185
186static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
187                      SkGPipeState* state) {
188    const SkScalar* param = skip<SkScalar>(reader, 2);
189    canvas->skew(param[0], param[1]);
190}
191
192static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
193                      SkGPipeState* state) {
194    canvas->rotate(reader->readScalar());
195}
196
197static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
198                      SkGPipeState* state) {
199    const SkScalar* param = skip<SkScalar>(reader, 2);
200    canvas->translate(param[0], param[1]);
201}
202
203///////////////////////////////////////////////////////////////////////////////
204
205static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
206                    SkGPipeState* state) {
207    canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
208}
209
210static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
211                         SkGPipeState* state) {
212    unsigned flags = DrawOp_unpackFlags(op32);
213    SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
214
215    const SkRect* bounds = NULL;
216    if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
217        bounds = skip<SkRect>(reader);
218    }
219    const SkPaint* paint = NULL;
220    if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
221        paint = &state->paint();
222    }
223    canvas->saveLayer(bounds, paint, saveFlags);
224}
225
226static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
227                       SkGPipeState* state) {
228    canvas->restore();
229}
230
231///////////////////////////////////////////////////////////////////////////////
232
233static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
234                         SkGPipeState* state) {
235    SkColor color = 0;
236    if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
237        color = reader->readU32();
238    }
239    canvas->clear(color);
240}
241
242static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
243                         SkGPipeState* state) {
244    canvas->drawPaint(state->paint());
245}
246
247static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
248                          SkGPipeState* state) {
249    SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
250    size_t count = reader->readU32();
251    const SkPoint* pts = skip<SkPoint>(reader, count);
252    canvas->drawPoints(mode, count, pts, state->paint());
253}
254
255static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
256                        SkGPipeState* state) {
257    canvas->drawRect(*skip<SkRect>(reader), state->paint());
258}
259
260static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
261                        SkGPipeState* state) {
262    SkPath path;
263    reader->readPath(&path);
264    canvas->drawPath(path, state->paint());
265}
266
267static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
268                            SkGPipeState* state) {
269    unsigned flags = DrawOp_unpackFlags(op32);
270
271    SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
272    int vertexCount = reader->readU32();
273    const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
274
275    const SkPoint* texs = NULL;
276    if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
277        texs = skip<SkPoint>(reader, vertexCount);
278    }
279
280    const SkColor* colors = NULL;
281    if (flags & kDrawVertices_HasColors_DrawOpFlag) {
282        colors = skip<SkColor>(reader, vertexCount);
283    }
284
285    // TODO: flatten/unflatten xfermodes
286    SkXfermode* xfer = NULL;
287
288    int indexCount = 0;
289    const uint16_t* indices = NULL;
290    if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
291        indexCount = reader->readU32();
292        indices = skipAlign<uint16_t>(reader, indexCount);
293    }
294
295    canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
296                         indices, indexCount, state->paint());
297}
298
299///////////////////////////////////////////////////////////////////////////////
300
301static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
302                        SkGPipeState* state) {
303    size_t len = reader->readU32();
304    const void* text = reader->skip(SkAlign4(len));
305    const SkScalar* xy = skip<SkScalar>(reader, 2);
306    canvas->drawText(text, len, xy[0], xy[1], state->paint());
307}
308
309static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
310                        SkGPipeState* state) {
311    size_t len = reader->readU32();
312    const void* text = reader->skip(SkAlign4(len));
313    size_t posCount = reader->readU32();    // compute by our writer
314    const SkPoint* pos = skip<SkPoint>(reader, posCount);
315    canvas->drawPosText(text, len, pos, state->paint());
316}
317
318static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
319                        SkGPipeState* state) {
320    size_t len = reader->readU32();
321    const void* text = reader->skip(SkAlign4(len));
322    size_t posCount = reader->readU32();    // compute by our writer
323    const SkScalar* xpos = skip<SkScalar>(reader, posCount);
324    SkScalar constY = reader->readScalar();
325    canvas->drawPosTextH(text, len, xpos, constY, state->paint());
326}
327
328static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
329                              SkGPipeState* state) {
330    size_t len = reader->readU32();
331    const void* text = reader->skip(SkAlign4(len));
332
333    SkPath path;
334    reader->readPath(&path);
335
336    SkMatrix matrixStorage;
337    const SkMatrix* matrix = NULL;
338    if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
339        reader->readMatrix(&matrixStorage);
340        matrix = &matrixStorage;
341    }
342
343    canvas->drawTextOnPath(text, len, path, matrix, state->paint());
344}
345
346///////////////////////////////////////////////////////////////////////////////
347
348static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
349                          SkGPipeState* state) {
350    unsigned index = DrawOp_unpackData(op32);
351    SkBitmap* bm = state->getBitmap(index);
352    bool hasPaint = reader->readBool();
353    SkScalar left = reader->readScalar();
354    SkScalar top = reader->readScalar();
355    canvas->drawBitmap(*bm, left, top, hasPaint ? &state->paint() : NULL);
356}
357
358static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
359                                SkGPipeState* state) {
360    UNIMPLEMENTED
361}
362
363static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader,
364                              uint32_t op32, SkGPipeState* state) {
365    unsigned index = DrawOp_unpackData(op32);
366    SkBitmap* bm = state->getBitmap(index);
367    bool hasPaint = reader->readBool();
368    const SkIRect* center = skip<SkIRect>(reader);
369    const SkRect* dst = skip<SkRect>(reader);
370    canvas->drawBitmapNine(*bm, *center, *dst,
371                           hasPaint ? &state->paint() : NULL);
372}
373
374static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader,
375                              uint32_t op32, SkGPipeState* state) {
376    unsigned index = DrawOp_unpackData(op32);
377    SkBitmap* bm = state->getBitmap(index);
378    bool hasPaint = reader->readBool();
379    bool hasSrc = reader->readBool();
380    const SkIRect* src;
381    if (hasSrc) {
382        src = skip<SkIRect>(reader);
383    } else {
384        src = NULL;
385    }
386    const SkRect* dst = skip<SkRect>(reader);
387    canvas->drawBitmapRect(*bm, src, *dst, hasPaint ? &state->paint() : NULL);
388}
389
390static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
391                          SkGPipeState* state) {
392    unsigned index = DrawOp_unpackData(op32);
393    SkBitmap* bm = state->getBitmap(index);
394    bool hasPaint = reader->readBool();
395    const SkIPoint* point = skip<SkIPoint>(reader);
396    canvas->drawSprite(*bm, point->fX, point->fY, hasPaint ? &state->paint() : NULL);
397}
398
399///////////////////////////////////////////////////////////////////////////////
400
401static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
402                        SkGPipeState* state) {
403    // since we don't have a paint, we can use data for our (small) sizes
404    size_t size = DrawOp_unpackData(op32);
405    if (0 == size) {
406        size = reader->readU32();
407    }
408    const void* data = reader->skip(SkAlign4(size));
409    canvas->drawData(data, size);
410}
411
412static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
413                           SkGPipeState* state) {
414    UNIMPLEMENTED
415}
416
417///////////////////////////////////////////////////////////////////////////////
418
419static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
420                       SkGPipeState* state) {
421    size_t offset = reader->offset();
422    size_t stop = offset + PaintOp_unpackData(op32);
423    SkPaint* p = state->editPaint();
424
425    do {
426        uint32_t p32 = reader->readU32();
427        unsigned op = PaintOp_unpackOp(p32);
428        unsigned data = PaintOp_unpackData(p32);
429
430//        SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
431
432        switch (op) {
433            case kReset_PaintOp: p->reset(); break;
434            case kFlags_PaintOp: p->setFlags(data); break;
435            case kColor_PaintOp: p->setColor(reader->readU32()); break;
436            case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
437            case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
438            case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
439            case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
440            case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
441            case kEncoding_PaintOp:
442                p->setTextEncoding((SkPaint::TextEncoding)data);
443                break;
444            case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
445            case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
446            case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
447            case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
448            case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
449
450            case kFlatIndex_PaintOp: {
451                PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
452                unsigned index = data;
453                set_paintflat(p, state->getFlat(index), pf);
454                break;
455            }
456
457            case kTypeface_PaintOp: state->setTypeface(p, data); break;
458            default: SkDEBUGFAIL("bad paintop"); return;
459        }
460        SkASSERT(reader->offset() <= stop);
461    } while (reader->offset() < stop);
462}
463
464///////////////////////////////////////////////////////////////////////////////
465
466static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
467    state->addTypeface();
468}
469
470static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
471                             SkGPipeState* state) {
472    PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
473    unsigned index = DrawOp_unpackData(op32);
474    state->defFlattenable(pf, index);
475}
476
477static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
478                          SkGPipeState* state) {
479    unsigned index = DrawOp_unpackData(op32);
480    state->addBitmap(index);
481}
482
483///////////////////////////////////////////////////////////////////////////////
484
485static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
486    size_t bytes = DrawOp_unpackData(op32);
487    (void)reader->skip(bytes);
488}
489
490static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
491
492typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
493
494static const ReadProc gReadTable[] = {
495    skip_rp,
496    clipPath_rp,
497    clipRegion_rp,
498    clipRect_rp,
499    concat_rp,
500    drawBitmap_rp,
501    drawBitmapMatrix_rp,
502    drawBitmapNine_rp,
503    drawBitmapRect_rp,
504    drawClear_rp,
505    drawData_rp,
506    drawPaint_rp,
507    drawPath_rp,
508    drawPicture_rp,
509    drawPoints_rp,
510    drawPosText_rp,
511    drawPosTextH_rp,
512    drawRect_rp,
513    drawSprite_rp,
514    drawText_rp,
515    drawTextOnPath_rp,
516    drawVertices_rp,
517    restore_rp,
518    rotate_rp,
519    save_rp,
520    saveLayer_rp,
521    scale_rp,
522    setMatrix_rp,
523    skew_rp,
524    translate_rp,
525
526    paintOp_rp,
527    def_Typeface_rp,
528    def_PaintFlat_rp,
529    def_Bitmap_rp,
530
531    done_rp
532};
533
534///////////////////////////////////////////////////////////////////////////////
535
536SkGPipeState::SkGPipeState() {}
537
538SkGPipeState::~SkGPipeState() {
539    fTypefaces.safeUnrefAll();
540    fFlatArray.safeUnrefAll();
541    fBitmaps.deleteAll();
542}
543
544///////////////////////////////////////////////////////////////////////////////
545
546#include "SkGPipe.h"
547
548SkGPipeReader::SkGPipeReader() {
549    fCanvas = NULL;
550    fState = NULL;
551}
552
553SkGPipeReader::SkGPipeReader(SkCanvas* target) {
554    fCanvas = NULL;
555    this->setCanvas(target);
556    fState = NULL;
557}
558
559void SkGPipeReader::setCanvas(SkCanvas *target) {
560    SkRefCnt_SafeAssign(fCanvas, target);
561}
562
563SkGPipeReader::~SkGPipeReader() {
564    SkSafeUnref(fCanvas);
565    delete fState;
566}
567
568SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length,
569                                              size_t* bytesRead, bool readAtom) {
570    if (NULL == fCanvas) {
571        return kError_Status;
572    }
573
574    if (NULL == fState) {
575        fState = new SkGPipeState;
576    }
577
578    SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
579
580    const ReadProc* table = gReadTable;
581    SkOrderedReadBuffer reader(data, length);
582    SkCanvas* canvas = fCanvas;
583    Status status = kEOF_Status;
584
585    fState->setReader(&reader);
586    while (!reader.eof()) {
587        uint32_t op32 = reader.readU32();
588        unsigned op = DrawOp_unpackOp(op32);
589        // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
590
591        if (op >= SK_ARRAY_COUNT(gReadTable)) {
592            SkDebugf("---- bad op during GPipeState::playback\n");
593            status = kError_Status;
594            break;
595        }
596        if (kDone_DrawOp == op) {
597            status = kDone_Status;
598            break;
599        }
600        table[op](canvas, reader.getReader32(), op32, fState);
601        if (readAtom &&
602            (table[op] != paintOp_rp &&
603             table[op] != def_Typeface_rp &&
604             table[op] != def_PaintFlat_rp &&
605             table[op] != def_Bitmap_rp
606             )) {
607                status = kReadAtom_Status;
608                break;
609            }
610    }
611
612    if (bytesRead) {
613        *bytesRead = reader.offset();
614    }
615    return status;
616}
617
618
619