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