• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
paintflat_to_flattype(PaintFlats pf)33 static 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 
set_paintflat(SkPaint * paint,SkFlattenable * obj,unsigned paintFlat)49 static 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 
81 template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
82 public:
~SkRefCntTDArray()83     ~SkRefCntTDArray() { this->unrefAll(); }
84 };
85 
86 class SkGPipeState : public SkBitmapHeapReader {
87 public:
88     SkGPipeState();
89     ~SkGPipeState();
90 
setSilent(bool silent)91     void setSilent(bool silent) {
92         fSilent = silent;
93     }
94 
shouldDraw()95     bool shouldDraw() {
96         return !fSilent;
97     }
98 
setFlags(unsigned flags)99     void setFlags(unsigned flags) {
100         if (fFlags != flags) {
101             fFlags = flags;
102             this->updateReader();
103         }
104     }
105 
getFlags() const106     unsigned getFlags() const {
107         return fFlags;
108     }
109 
setReader(SkReadBuffer * reader)110     void setReader(SkReadBuffer* reader) {
111         fReader = reader;
112         this->updateReader();
113     }
114 
paint() const115     const SkPaint& paint() const { return fPaint; }
editPaint()116     SkPaint* editPaint() { return &fPaint; }
117 
getFlat(unsigned index) const118     SkFlattenable* getFlat(unsigned index) const {
119         if (0 == index) {
120             return NULL;
121         }
122         return fFlatArray[index - 1];
123     }
124 
defFlattenable(PaintFlats pf,int index)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 
defFactory(const char * name)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      */
addBitmap(int index)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      */
getBitmap(int32_t index) const165     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      */
releaseRef(int32_t)173     void releaseRef(int32_t) override {}
174 
setSharedHeap(SkBitmapHeap * heap)175     void setSharedHeap(SkBitmapHeap* heap) {
176         SkASSERT(!shouldFlattenBitmaps(fFlags) || NULL == heap);
177         SkRefCnt_SafeAssign(fSharedHeap, heap);
178         this->updateReader();
179     }
180 
setImageHeap(SkImageHeap * heap)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      */
getSharedHeap() const189     SkBitmapHeap* getSharedHeap() const {
190         SkASSERT(!shouldFlattenBitmaps(fFlags));
191         return fSharedHeap;
192     }
193 
addTypeface()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 
getTypeface(unsigned id) const201     SkTypeface* getTypeface(unsigned id) const {
202         return id ? fTypefaces[id - 1] : NULL;
203     }
204 
getImage(int32_t slot) const205     const SkImage* getImage(int32_t slot) const {
206         return fImageHeap->get(slot);
207     }
208 
209 private:
updateReader()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 
skip(SkReader32 * reader,size_t count=1)244 template <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 
skipAlign(SkReader32 * reader,size_t count=1)250 template <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 
clipPath_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)258 static 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 
clipRegion_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)266 static 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 
clipRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)273 static 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 
clipRRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)280 static 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 
setMatrix_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)290 static 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 
concat_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)297 static 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 
scale_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)304 static 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 
skew_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)310 static 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 
rotate_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)316 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
317                       SkGPipeState* state) {
318     canvas->rotate(reader->readScalar());
319 }
320 
translate_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)321 static 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 
save_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)329 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
330                     SkGPipeState* state) {
331     canvas->save();
332 }
333 
saveLayer_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)334 static 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 
restore_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)350 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
351                        SkGPipeState* state) {
352     canvas->restore();
353 }
354 
355 ///////////////////////////////////////////////////////////////////////////////
356 
drawPaint_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)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 
drawPoints_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)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 
drawOval_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)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 
drawRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)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 
drawRRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)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 
drawDRRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)399 static 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 
drawPatch_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)409 static 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 
drawPath_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)437 static 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 
drawVertices_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)446 static 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 
drawText_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)484 static 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 
drawPosText_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)494 static 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 
drawPosTextH_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)505 static 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 
drawTextOnPath_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)517 static 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 
538 class BitmapHolder : SkNoncopyable {
539 public:
540     BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state);
~BitmapHolder()541     ~BitmapHolder() {
542         if (fHeapEntry != NULL) {
543             fHeapEntry->releaseRef();
544         }
545     }
getBitmap()546     const SkBitmap* getBitmap() {
547         return fBitmap;
548     }
549 private:
550     SkBitmapHeapEntry* fHeapEntry;
551     const SkBitmap*    fBitmap;
552     SkBitmap           fBitmapStorage;
553 };
554 
BitmapHolder(SkReader32 * reader,uint32_t op32,SkGPipeState * state)555 BitmapHolder::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 
drawBitmap_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)581 static 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 
drawBitmapNine_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)593 static 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 
drawBitmapRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)606 static 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 
drawSprite_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)630 static 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 
drawImage_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)641 static 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 
drawImageRect_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)653 static 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 
drawPicture_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)672 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
673                            SkGPipeState* state) {
674     UNIMPLEMENTED
675 }
676 
drawTextBlob_rp(SkCanvas * canvas,SkReader32 * reader,uint32_t op32,SkGPipeState * state)677 static 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 
paintOp_rp(SkCanvas *,SkReader32 * reader,uint32_t op32,SkGPipeState * state)706 static 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 
typeface_rp(SkCanvas *,SkReader32 * reader,uint32_t,SkGPipeState * state)756 static 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 
annotation_rp(SkCanvas *,SkReader32 * reader,uint32_t op32,SkGPipeState * state)763 static 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 
def_Typeface_rp(SkCanvas *,SkReader32 *,uint32_t,SkGPipeState * state)779 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
780     state->addTypeface();
781 }
782 
def_PaintFlat_rp(SkCanvas *,SkReader32 *,uint32_t op32,SkGPipeState * state)783 static 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 
def_Bitmap_rp(SkCanvas *,SkReader32 *,uint32_t op32,SkGPipeState * state)790 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
791                           SkGPipeState* state) {
792     unsigned index = DrawOp_unpackData(op32);
793     state->addBitmap(index);
794 }
795 
def_Factory_rp(SkCanvas *,SkReader32 * reader,uint32_t,SkGPipeState * state)796 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t,
797                            SkGPipeState* state) {
798     state->defFactory(reader->readString());
799 }
800 
801 ///////////////////////////////////////////////////////////////////////////////
802 
skip_rp(SkCanvas *,SkReader32 * reader,uint32_t op32,SkGPipeState *)803 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
804     size_t bytes = DrawOp_unpackData(op32);
805     (void)reader->skip(bytes);
806 }
807 
reportFlags_rp(SkCanvas *,SkReader32 *,uint32_t op32,SkGPipeState * state)808 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
809                            SkGPipeState* state) {
810     unsigned flags = DrawOp_unpackFlags(op32);
811     state->setFlags(flags);
812 }
813 
shareBitmapHeap_rp(SkCanvas *,SkReader32 * reader,uint32_t,SkGPipeState * state)814 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
815                                SkGPipeState* state) {
816     state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
817 }
818 
shareImageHeap_rp(SkCanvas *,SkReader32 * reader,uint32_t,SkGPipeState * state)819 static void shareImageHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, SkGPipeState* state) {
820     state->setImageHeap(static_cast<SkImageHeap*>(reader->readPtr()));
821 }
822 
done_rp(SkCanvas *,SkReader32 *,uint32_t,SkGPipeState *)823 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
824 
825 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
826 
827 static 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 
SkGPipeState()881 SkGPipeState::SkGPipeState()
882     : fReader(0)
883     , fSilent(false)
884     , fSharedHeap(NULL)
885     , fFlags(0) {
886 
887 }
888 
~SkGPipeState()889 SkGPipeState::~SkGPipeState() {
890     fTypefaces.safeUnrefAll();
891     fFlatArray.safeUnrefAll();
892     fBitmaps.deleteAll();
893     SkSafeUnref(fSharedHeap);
894 }
895 
896 ///////////////////////////////////////////////////////////////////////////////
897 
898 #include "SkGPipe.h"
899 
SkGPipeReader()900 SkGPipeReader::SkGPipeReader() {
901     fCanvas = NULL;
902     fState = NULL;
903     fProc = NULL;
904 }
905 
SkGPipeReader(SkCanvas * target)906 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
907     fCanvas = NULL;
908     this->setCanvas(target);
909     fState = NULL;
910     fProc = NULL;
911 }
912 
setCanvas(SkCanvas * target)913 void SkGPipeReader::setCanvas(SkCanvas *target) {
914     SkRefCnt_SafeAssign(fCanvas, target);
915 }
916 
~SkGPipeReader()917 SkGPipeReader::~SkGPipeReader() {
918     SkSafeUnref(fCanvas);
919     delete fState;
920 }
921 
playback(const void * data,size_t length,uint32_t playbackFlags,size_t * bytesRead)922 SkGPipeReader::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