3 * Copyright 2011 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #include "SkBitmapHeap.h"
14 #include "SkGPipePriv.h"
15 #include "SkReader32.h"
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"
29 #include "SkTypeface.h"
30 #include "SkXfermode.h"
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,
44 SkASSERT((size_t)pf < SK_ARRAY_COUNT(gEffectTypesInPaintFlatsOrder));
45 return (SkFlattenable::Type)gEffectTypesInPaintFlatsOrder[pf];
48 static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
49 SkASSERT(paintFlat < kCount_PaintFlats);
51 case kColorFilter_PaintFlat:
52 paint->setColorFilter((SkColorFilter*)obj);
54 case kDrawLooper_PaintFlat:
55 paint->setLooper((SkDrawLooper*)obj);
57 case kMaskFilter_PaintFlat:
58 paint->setMaskFilter((SkMaskFilter*)obj);
60 case kPathEffect_PaintFlat:
61 paint->setPathEffect((SkPathEffect*)obj);
63 case kRasterizer_PaintFlat:
64 paint->setRasterizer((SkRasterizer*)obj);
66 case kShader_PaintFlat:
67 paint->setShader((SkShader*)obj);
69 case kImageFilter_PaintFlat:
70 paint->setImageFilter((SkImageFilter*)obj);
72 case kXfermode_PaintFlat:
73 paint->setXfermode((SkXfermode*)obj);
76 SkDEBUGFAIL("never gets here");
80 template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
82 ~SkRefCntTDArray() { this->unrefAll(); }
85 class SkGPipeState : public SkBitmapHeapReader {
90 void setSilent(bool silent) {
98 void setFlags(unsigned flags) {
99 if (fFlags != flags) {
101 this->updateReader();
105 unsigned getFlags() const {
109 void setReader(SkReadBuffer* reader) {
111 this->updateReader();
114 const SkPaint& paint() const { return fPaint; }
115 SkPaint* editPaint() { return &fPaint; }
117 SkFlattenable* getFlat(unsigned index) const {
121 return fFlatArray[index - 1];
124 void defFlattenable(PaintFlats pf, int index) {
126 SkFlattenable* obj = fReader->readFlattenable(paintflat_to_flattype(pf));
127 if (fFlatArray.count() == index) {
128 *fFlatArray.append() = obj;
130 SkSafeUnref(fFlatArray[index]);
131 fFlatArray[index] = obj;
135 void defFactory(const char* name) {
136 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name);
138 SkASSERT(fFactoryArray.find(factory) < 0);
139 *fFactoryArray.append() = factory;
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.
147 void addBitmap(int index) {
148 SkASSERT(shouldFlattenBitmaps(fFlags));
150 if(fBitmaps.count() == index) {
151 bm = SkNEW(SkBitmap);
152 *fBitmaps.append() = bm;
154 bm = fBitmaps[index];
156 fReader->readBitmap(bm);
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.
164 virtual SkBitmap* getBitmap(int32_t index) const SK_OVERRIDE {
165 SkASSERT(shouldFlattenBitmaps(fFlags));
166 return fBitmaps[index];
170 * Needed to be a non-abstract subclass of SkBitmapHeapReader.
172 virtual void releaseRef(int32_t) SK_OVERRIDE {}
174 void setSharedHeap(SkBitmapHeap* heap) {
175 SkASSERT(!shouldFlattenBitmaps(fFlags) || NULL == heap);
176 SkRefCnt_SafeAssign(fSharedHeap, heap);
177 this->updateReader();
181 * Access the shared heap. Only used in the case when bitmaps are not
184 SkBitmapHeap* getSharedHeap() const {
185 SkASSERT(!shouldFlattenBitmaps(fFlags));
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);
196 void setTypeface(SkPaint* paint, unsigned id) {
197 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
201 void updateReader() {
202 if (NULL == fReader) {
205 bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag);
206 fReader->setFlags(SkSetClearMask(fReader->getFlags(), crossProcess,
207 SkReadBuffer::kCrossProcess_Flag));
209 fReader->setFactoryArray(&fFactoryArray);
211 fReader->setFactoryArray(NULL);
214 if (shouldFlattenBitmaps(fFlags)) {
215 fReader->setBitmapStorage(this);
217 fReader->setBitmapStorage(fSharedHeap);
220 SkReadBuffer* fReader;
222 SkTDArray<SkFlattenable*> fFlatArray;
223 SkTDArray<SkTypeface*> fTypefaces;
224 SkTDArray<SkFlattenable::Factory> fFactoryArray;
225 SkTDArray<SkBitmap*> fBitmaps;
227 // Only used when sharing bitmaps with the writer.
228 SkBitmapHeap* fSharedHeap;
232 ///////////////////////////////////////////////////////////////////////////////
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));
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));
245 ///////////////////////////////////////////////////////////////////////////////
246 ///////////////////////////////////////////////////////////////////////////////
248 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
249 SkGPipeState* state) {
251 reader->readPath(&path);
252 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
253 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
256 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
257 SkGPipeState* state) {
259 reader->readRegion(&rgn);
260 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
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);
270 static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
271 SkGPipeState* state) {
273 reader->readRRect(&rrect);
274 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag);
275 canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA);
278 ///////////////////////////////////////////////////////////////////////////////
280 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
281 SkGPipeState* state) {
283 reader->readMatrix(&matrix);
284 canvas->setMatrix(matrix);
287 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
288 SkGPipeState* state) {
290 reader->readMatrix(&matrix);
291 canvas->concat(matrix);
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]);
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]);
306 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
307 SkGPipeState* state) {
308 canvas->rotate(reader->readScalar());
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]);
317 ///////////////////////////////////////////////////////////////////////////////
319 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
320 SkGPipeState* state) {
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);
329 const SkRect* bounds = NULL;
330 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
331 bounds = skip<SkRect>(reader);
333 const SkPaint* paint = NULL;
334 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
335 paint = &state->paint();
337 canvas->saveLayer(bounds, paint, saveFlags);
340 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
341 SkGPipeState* state) {
345 ///////////////////////////////////////////////////////////////////////////////
347 static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
348 SkGPipeState* state) {
350 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
351 color = reader->readU32();
353 canvas->clear(color);
356 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
357 SkGPipeState* state) {
358 if (state->shouldDraw()) {
359 canvas->drawPaint(state->paint());
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());
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());
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());
389 static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
390 SkGPipeState* state) {
392 reader->readRRect(&rrect);
393 if (state->shouldDraw()) {
394 canvas->drawRRect(rrect, state->paint());
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());
408 static void drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
409 SkGPipeState* state) {
411 unsigned flags = DrawOp_unpackFlags(op32);
413 const SkPoint* cubics = skip<SkPoint>(reader, SkPatchUtils::kNumCtrlPts);
415 const SkColor* colors = NULL;
416 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
417 colors = skip<SkColor>(reader, SkPatchUtils::kNumCorners);
419 const SkPoint* texCoords = NULL;
420 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
421 texCoords = skip<SkPoint>(reader, SkPatchUtils::kNumCorners);
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;
429 xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
431 if (state->shouldDraw()) {
432 canvas->drawPatch(cubics, colors, texCoords, xfer, state->paint());
436 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
437 SkGPipeState* state) {
439 reader->readPath(&path);
440 if (state->shouldDraw()) {
441 canvas->drawPath(path, state->paint());
445 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
446 SkGPipeState* state) {
447 unsigned flags = DrawOp_unpackFlags(op32);
449 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readU32();
450 int vertexCount = reader->readU32();
451 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
453 const SkPoint* texs = NULL;
454 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
455 texs = skip<SkPoint>(reader, vertexCount);
458 const SkColor* colors = NULL;
459 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
460 colors = skip<SkColor>(reader, vertexCount);
463 SkAutoTUnref<SkXfermode> xfer;
464 if (flags & kDrawVertices_HasXfermode_DrawOpFlag) {
465 SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32();
466 xfer.reset(SkXfermode::Create(mode));
470 const uint16_t* indices = NULL;
471 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
472 indexCount = reader->readU32();
473 indices = skipAlign<uint16_t>(reader, indexCount);
475 if (state->shouldDraw()) {
476 canvas->drawVertices(vmode, vertexCount, verts, texs, colors, xfer,
477 indices, indexCount, state->paint());
481 ///////////////////////////////////////////////////////////////////////////////
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());
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());
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());
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));
522 reader->readPath(&path);
524 SkMatrix matrixStorage;
525 const SkMatrix* matrix = NULL;
526 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
527 reader->readMatrix(&matrixStorage);
528 matrix = &matrixStorage;
530 if (state->shouldDraw()) {
531 canvas->drawTextOnPath(text, len, path, matrix, state->paint());
535 ///////////////////////////////////////////////////////////////////////////////
537 class BitmapHolder : SkNoncopyable {
539 BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state);
541 if (fHeapEntry != NULL) {
542 fHeapEntry->releaseRef();
545 const SkBitmap* getBitmap() {
549 SkBitmapHeapEntry* fHeapEntry;
550 const SkBitmap* fBitmap;
551 SkBitmap fBitmapStorage;
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)) {
560 fBitmap = state->getBitmap(index);
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.
572 SkASSERT(!shouldFlattenBitmaps(flags));
573 SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag));
575 fBitmap = fHeapEntry->getBitmap();
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);
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);
597 reader->readMatrix(&matrix);
598 const SkBitmap* bitmap = holder.getBitmap();
599 if (state->shouldDraw()) {
600 canvas->drawBitmapMatrix(*bitmap, matrix,
601 hasPaint ? &state->paint() : NULL);
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);
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);
626 src = skip<SkRect>(reader);
630 SkCanvas::DrawBitmapRectFlags dbmrFlags = SkCanvas::kNone_DrawBitmapRectFlag;
631 if (flags & kDrawBitmap_Bleed_DrawOpFlag) {
632 dbmrFlags = (SkCanvas::DrawBitmapRectFlags)(dbmrFlags|SkCanvas::kBleed_DrawBitmapRectFlag);
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);
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);
653 ///////////////////////////////////////////////////////////////////////////////
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);
660 size = reader->readU32();
662 const void* data = reader->skip(SkAlign4(size));
663 if (state->shouldDraw()) {
664 canvas->drawData(data, size);
668 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
669 SkGPipeState* state) {
673 ///////////////////////////////////////////////////////////////////////////////
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();
682 uint32_t p32 = reader->readU32();
683 unsigned op = PaintOp_unpackOp(p32);
684 unsigned data = PaintOp_unpackData(p32);
686 // SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
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);
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;
707 case kFlatIndex_PaintOp: {
708 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
709 unsigned index = data;
710 set_paintflat(p, state->getFlat(index), pf);
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;
720 SkASSERT(reader->offset() <= stop);
721 } while (reader->offset() < stop);
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()));
731 static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
732 SkGPipeState* state) {
733 SkPaint* p = state->editPaint();
735 const size_t size = DrawOp_unpackData(op32);
737 SkReadBuffer buffer(reader->skip(size), size);
738 p->setAnnotation(SkAnnotation::Create(buffer))->unref();
739 SkASSERT(buffer.offset() == size);
741 p->setAnnotation(NULL);
745 ///////////////////////////////////////////////////////////////////////////////
747 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
748 state->addTypeface();
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);
758 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32,
759 SkGPipeState* state) {
760 unsigned index = DrawOp_unpackData(op32);
761 state->addBitmap(index);
764 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t,
765 SkGPipeState* state) {
766 state->defFactory(reader->readString());
769 ///////////////////////////////////////////////////////////////////////////////
771 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
772 size_t bytes = DrawOp_unpackData(op32);
773 (void)reader->skip(bytes);
776 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32,
777 SkGPipeState* state) {
778 unsigned flags = DrawOp_unpackFlags(op32);
779 state->setFlags(flags);
782 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t,
783 SkGPipeState* state) {
784 state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr()));
787 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
789 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
791 static const ReadProc gReadTable[] = {
842 ///////////////////////////////////////////////////////////////////////////////
844 SkGPipeState::SkGPipeState()
852 SkGPipeState::~SkGPipeState() {
853 fTypefaces.safeUnrefAll();
854 fFlatArray.safeUnrefAll();
855 fBitmaps.deleteAll();
856 SkSafeUnref(fSharedHeap);
859 ///////////////////////////////////////////////////////////////////////////////
863 SkGPipeReader::SkGPipeReader() {
869 SkGPipeReader::SkGPipeReader(SkCanvas* target) {
871 this->setCanvas(target);
876 void SkGPipeReader::setCanvas(SkCanvas *target) {
877 SkRefCnt_SafeAssign(fCanvas, target);
880 SkGPipeReader::~SkGPipeReader() {
881 SkSafeUnref(fCanvas);
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;
891 if (NULL == fState) {
892 fState = new SkGPipeState;
895 fState->setSilent(playbackFlags & kSilent_PlaybackFlag);
897 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
899 const ReadProc* table = gReadTable;
900 SkReadBuffer reader(data, length);
901 reader.setBitmapDecoder(fProc);
902 SkCanvas* canvas = fCanvas;
903 Status status = kEOF_Status;
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;)
911 if (op >= SK_ARRAY_COUNT(gReadTable)) {
912 SkDebugf("---- bad op during GPipeState::playback\n");
913 status = kError_Status;
916 if (kDone_DrawOp == op) {
917 status = kDone_Status;
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
927 status = kReadAtom_Status;
933 *bytesRead = reader.offset();