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