blob: ee20d8089001c95e42208e011b8a2d8381d31796 [file] [log] [blame]
reed@google.combb6992a2011-04-26 17:41:56 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "SkCanvas.h"
19#include "SkPaint.h"
reed@google.comacd471f2011-05-03 21:26:46 +000020#include "SkGPipe.h"
reed@google.combb6992a2011-04-26 17:41:56 +000021#include "SkGPipePriv.h"
22#include "SkReader32.h"
reed@google.comf5842f72011-05-04 18:30:04 +000023#include "SkStream.h"
reed@google.combb6793b2011-05-05 15:18:15 +000024
25#include "SkColorFilter.h"
26#include "SkDrawLooper.h"
27#include "SkMaskFilter.h"
28#include "SkPathEffect.h"
29#include "SkRasterizer.h"
30#include "SkShader.h"
reed@google.comf5842f72011-05-04 18:30:04 +000031#include "SkTypeface.h"
reed@google.combb6793b2011-05-05 15:18:15 +000032#include "SkXfermode.h"
33
reed@google.comb55d1182011-05-11 00:42:04 +000034static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) {
35 SkASSERT(paintFlat < kCount_PaintFlats);
36 switch (paintFlat) {
37 case kColorFilter_PaintFlat:
38 paint->setColorFilter((SkColorFilter*)obj);
39 break;
reed@google.com0faac1e2011-05-11 05:58:58 +000040 case kDrawLooper_PaintFlat:
41 paint->setLooper((SkDrawLooper*)obj);
42 break;
reed@google.comb55d1182011-05-11 00:42:04 +000043 case kMaskFilter_PaintFlat:
44 paint->setMaskFilter((SkMaskFilter*)obj);
45 break;
46 case kPathEffect_PaintFlat:
47 paint->setPathEffect((SkPathEffect*)obj);
48 break;
49 case kRasterizer_PaintFlat:
50 paint->setRasterizer((SkRasterizer*)obj);
51 break;
52 case kShader_PaintFlat:
53 paint->setShader((SkShader*)obj);
54 break;
55 case kXfermode_PaintFlat:
56 paint->setXfermode((SkXfermode*)obj);
57 break;
58 default:
59 SkASSERT(!"never gets here");
60 }
61}
62
reed@google.combb6793b2011-05-05 15:18:15 +000063template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
64public:
65 ~SkRefCntTDArray() { this->unrefAll(); }
66};
reed@google.combb6992a2011-04-26 17:41:56 +000067
68class SkGPipeState {
69public:
70 SkGPipeState();
71 ~SkGPipeState();
reed@google.combb6793b2011-05-05 15:18:15 +000072
73 void setReader(SkFlattenableReadBuffer* reader) { fReader = reader; }
74
reed@google.combb6992a2011-04-26 17:41:56 +000075 const SkPaint& getPaint(uint32_t drawOp32) const;
76
77 // Extracts index from DrawOp_unpackData().
78 // Returns the specified paint from our list, or creates a new paint if
79 // index == count. If index > count, return NULL
80 SkPaint* editPaint(uint32_t drawOp32);
reed@google.comf5842f72011-05-04 18:30:04 +000081
reed@google.comb55d1182011-05-11 00:42:04 +000082 SkFlattenable* getFlat(unsigned index) const {
83 if (0 == index) {
84 return NULL;
85 }
86 return fFlatArray[index - 1];
87 }
88
89 void defFlattenable(PaintFlats pf, unsigned index) {
90 SkFlattenable* obj = fReader->readFlattenable();
91 *fFlatArray.append() = obj;
92 SkASSERT(index == fFlatArray.count());
93 }
94
reed@google.combb6793b2011-05-05 15:18:15 +000095 void addTypeface() {
96 size_t size = fReader->readU32();
97 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +000098 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +000099 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
reed@google.com0faac1e2011-05-11 05:58:58 +0000100 }
reed@google.combb6793b2011-05-05 15:18:15 +0000101 void setTypeface(SkPaint* paint, unsigned id) {
102 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
103 }
reed@google.combb6793b2011-05-05 15:18:15 +0000104
reed@google.combb6793b2011-05-05 15:18:15 +0000105 SkFlattenableReadBuffer* fReader;
reed@google.comb55d1182011-05-11 00:42:04 +0000106 SkTDArray<SkFlattenable*> fFlatArray;
107
108private:
reed@google.combb6793b2011-05-05 15:18:15 +0000109
reed@google.combb6992a2011-04-26 17:41:56 +0000110 SkTDArray<SkPaint*> fPaints;
reed@google.combb6793b2011-05-05 15:18:15 +0000111
112 SkRefCntTDArray<SkColorFilter*> fColorFilters;
113 SkRefCntTDArray<SkDrawLooper*> fDrawLoopers;
114 SkRefCntTDArray<SkMaskFilter*> fMaskFilters;
115 SkRefCntTDArray<SkPathEffect*> fPathEffects;
116 SkRefCntTDArray<SkRasterizer*> fRasterizers;
117 SkRefCntTDArray<SkShader*> fShaders;
118 SkRefCntTDArray<SkTypeface*> fTypefaces;
119 SkRefCntTDArray<SkXfermode*> fXfermodes;
reed@google.combb6992a2011-04-26 17:41:56 +0000120};
121
122///////////////////////////////////////////////////////////////////////////////
123
124template <typename T> const T* skip(SkReader32* reader, int count = 1) {
125 SkASSERT(count >= 0);
126 size_t size = sizeof(T) * count;
127 SkASSERT(SkAlign4(size) == size);
128 return reinterpret_cast<const T*>(reader->skip(size));
129}
130
131template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
132 SkASSERT(count >= 0);
133 size_t size = SkAlign4(sizeof(T) * count);
134 return reinterpret_cast<const T*>(reader->skip(size));
135}
136
reed@google.combb6992a2011-04-26 17:41:56 +0000137const SkPaint& SkGPipeState::getPaint(uint32_t op32) const {
138 unsigned index = DrawOp_unpackData(op32);
139 if (index >= fPaints.count()) {
140 SkASSERT(!"paint index out of range");
141 index = 0; // we always have at least 1 paint
142 }
143 return *fPaints[index];
144}
145
146SkPaint* SkGPipeState::editPaint(uint32_t op32) {
147 unsigned index = DrawOp_unpackData(op32);
148
149 if (index > fPaints.count()) {
150 SkASSERT(!"paint index out of range");
151 return NULL;
152 }
153
154 if (index == fPaints.count()) {
155 *fPaints.append() = SkNEW(SkPaint);
156 }
157 return fPaints[index];
158}
159
160///////////////////////////////////////////////////////////////////////////////
161///////////////////////////////////////////////////////////////////////////////
162
163static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
164 SkGPipeState* state) {
165 SkPath path;
166 path.unflatten(*reader);
167 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
168}
169
170static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
171 SkGPipeState* state) {
172 SkRegion rgn;
reed@google.comb55d1182011-05-11 00:42:04 +0000173 SkReadRegion(reader, &rgn);
reed@google.combb6992a2011-04-26 17:41:56 +0000174 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
175}
176
177static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
178 SkGPipeState* state) {
179 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
180}
181
182///////////////////////////////////////////////////////////////////////////////
183
184static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
185 SkGPipeState* state) {
186 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000187 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000188 canvas->setMatrix(matrix);
189}
190
191static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
192 SkGPipeState* state) {
193 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000194 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000195 canvas->concat(matrix);
196}
197
198static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
199 SkGPipeState* state) {
200 const SkScalar* param = skip<SkScalar>(reader, 2);
201 canvas->scale(param[0], param[1]);
202}
203
204static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
205 SkGPipeState* state) {
206 const SkScalar* param = skip<SkScalar>(reader, 2);
207 canvas->skew(param[0], param[1]);
208}
209
210static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
211 SkGPipeState* state) {
212 canvas->rotate(reader->readScalar());
213}
214
215static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
216 SkGPipeState* state) {
217 const SkScalar* param = skip<SkScalar>(reader, 2);
218 canvas->translate(param[0], param[1]);
219}
220
221///////////////////////////////////////////////////////////////////////////////
222
223static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
224 SkGPipeState* state) {
225 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
226}
227
228static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
229 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000230 unsigned flags = DrawOp_unpackFlags(op32);
231 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000232
233 const SkRect* bounds = NULL;
234 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
235 bounds = skip<SkRect>(reader);
236 }
237 const SkPaint* paint = NULL;
238 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
239 paint = &state->getPaint(reader->readU32());
240 }
reed@google.comacd471f2011-05-03 21:26:46 +0000241 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000242}
243
244static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
245 SkGPipeState* state) {
246 canvas->restore();
247}
248
249///////////////////////////////////////////////////////////////////////////////
250
251static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
252 SkGPipeState* state) {
253 SkColor color = 0;
254 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
255 color = reader->readU32();
256 }
257 canvas->clear(color);
258}
259
260static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
261 SkGPipeState* state) {
262 canvas->drawPaint(state->getPaint(op32));
263}
264
265static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
266 SkGPipeState* state) {
267 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
268 size_t count = reader->readU32();
269 const SkPoint* pts = skip<SkPoint>(reader, count);
270 canvas->drawPoints(mode, count, pts, state->getPaint(op32));
271}
272
273static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
274 SkGPipeState* state) {
275 canvas->drawRect(*skip<SkRect>(reader), state->getPaint(op32));
276}
277
278static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
279 SkGPipeState* state) {
280 SkPath path;
281 path.unflatten(*reader);
282 canvas->drawPath(path, state->getPaint(op32));
283}
284
285static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
286 SkGPipeState* state) {
287 unsigned flags = DrawOp_unpackFlags(op32);
288
289 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
290 int vertexCount = reader->readU32();
291 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
292
293 const SkPoint* texs = NULL;
294 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
295 texs = skip<SkPoint>(reader, vertexCount);
296 }
297
298 const SkColor* colors = NULL;
299 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
300 colors = skip<SkColor>(reader, vertexCount);
301 }
302
303 // TODO: flatten/unflatten xfermodes
304 SkXfermode* xfer = NULL;
305
306 int indexCount = 0;
307 const uint16_t* indices = NULL;
308 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
309 indexCount = reader->readU32();
310 indices = skipAlign<uint16_t>(reader, indexCount);
311 }
312
313 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
314 indices, indexCount, state->getPaint(op32));
315}
316
317///////////////////////////////////////////////////////////////////////////////
318
319static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
320 SkGPipeState* state) {
321 size_t len = reader->readU32();
322 const void* text = reader->skip(SkAlign4(len));
323 const SkScalar* xy = skip<SkScalar>(reader, 2);
324 canvas->drawText(text, len, xy[0], xy[1], state->getPaint(op32));
325}
326
327static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
328 SkGPipeState* state) {
329 size_t len = reader->readU32();
330 const void* text = reader->skip(SkAlign4(len));
331 size_t posCount = reader->readU32(); // compute by our writer
332 const SkPoint* pos = skip<SkPoint>(reader, posCount);
333 canvas->drawPosText(text, len, pos, state->getPaint(op32));
334}
335
336static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
337 SkGPipeState* state) {
338 size_t len = reader->readU32();
339 const void* text = reader->skip(SkAlign4(len));
340 size_t posCount = reader->readU32(); // compute by our writer
341 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
342 SkScalar constY = reader->readScalar();
343 canvas->drawPosTextH(text, len, xpos, constY, state->getPaint(op32));
344}
345
346static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
347 SkGPipeState* state) {
348 size_t len = reader->readU32();
349 const void* text = reader->skip(SkAlign4(len));
350
351 SkPath path;
352 path.unflatten(*reader);
353
354 SkMatrix matrixStorage;
355 const SkMatrix* matrix = NULL;
356 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
reed@google.comb55d1182011-05-11 00:42:04 +0000357 SkReadMatrix(reader, &matrixStorage);
reed@google.combb6992a2011-04-26 17:41:56 +0000358 matrix = &matrixStorage;
359 }
360
361 canvas->drawTextOnPath(text, len, path, matrix, state->getPaint(op32));
362}
363
364///////////////////////////////////////////////////////////////////////////////
365
366static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
367 SkGPipeState* state) {
368 UNIMPLEMENTED
369}
370
371static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
372 SkGPipeState* state) {
373 UNIMPLEMENTED
374}
375
376static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
377 SkGPipeState* state) {
378 UNIMPLEMENTED
379}
380
381static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
382 SkGPipeState* state) {
383 UNIMPLEMENTED
384}
385
386///////////////////////////////////////////////////////////////////////////////
387
388static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
389 SkGPipeState* state) {
390 // since we don't have a paint, we can use data for our (small) sizes
391 size_t size = DrawOp_unpackData(op32);
392 if (0 == size) {
393 size = reader->readU32();
394 }
395 const void* data = reader->skip(SkAlign4(size));
396 canvas->drawData(data, size);
397}
398
399static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
400 SkGPipeState* state) {
401 UNIMPLEMENTED
402}
403
404static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
405 SkGPipeState* state) {
406 UNIMPLEMENTED
407}
408
409///////////////////////////////////////////////////////////////////////////////
410
reed@google.combb6992a2011-04-26 17:41:56 +0000411static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
412 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000413 size_t offset = reader->offset();
414 size_t stop = offset + PaintOp_unpackData(op32);
415 SkPaint* p = state->editPaint(0);
reed@google.combb6992a2011-04-26 17:41:56 +0000416 int done;
417
418 do {
419 uint32_t p32 = reader->readU32();
420 unsigned op = PaintOp_unpackOp(p32);
421 unsigned data = PaintOp_unpackData(p32);
422 done = PaintOp_unpackFlags(p32) & kLastOp_PaintOpFlag;
423
reed@google.comb55d1182011-05-11 00:42:04 +0000424// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000425
426 switch (op) {
427 case kReset_PaintOp: p->reset(); break;
428 case kFlags_PaintOp: p->setFlags(data); break;
429 case kColor_PaintOp: p->setColor(reader->readU32()); break;
430 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
431 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
432 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
433 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
434 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
435 case kEncoding_PaintOp:
436 p->setTextEncoding((SkPaint::TextEncoding)data);
437 break;
438 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
439 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
440 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
441 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
442 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000443
reed@google.comb55d1182011-05-11 00:42:04 +0000444 case kFlatIndex_PaintOp: {
445 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
446 unsigned index = data;
447 set_paintflat(p, state->getFlat(index), pf);
448 break;
449 }
450
reed@google.combb6793b2011-05-05 15:18:15 +0000451 case kTypeface_PaintOp: state->setTypeface(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000452 default: SkASSERT(!"bad paintop"); return;
453 }
reed@google.comb55d1182011-05-11 00:42:04 +0000454 SkASSERT(reader->offset() <= stop);
455 done = (reader->offset() >= stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000456 } while (!done);
457}
458
reed@google.combb6793b2011-05-05 15:18:15 +0000459///////////////////////////////////////////////////////////////////////////////
460
reed@google.com0faac1e2011-05-11 05:58:58 +0000461static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
462 state->addTypeface();
463}
464
reed@google.comb55d1182011-05-11 00:42:04 +0000465static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
466 SkGPipeState* state) {
467 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
468 unsigned index = DrawOp_unpackData(op32);
469 state->defFlattenable(pf, index);
470}
471
reed@google.combb6992a2011-04-26 17:41:56 +0000472///////////////////////////////////////////////////////////////////////////////
473
reed@google.comacd471f2011-05-03 21:26:46 +0000474static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
475 size_t bytes = DrawOp_unpackData(op32);
476 (void)reader->skip(bytes);
477}
478
reed@google.combb6992a2011-04-26 17:41:56 +0000479static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
480
481typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
482
483static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000484 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000485 clipPath_rp,
486 clipRegion_rp,
487 clipRect_rp,
488 concat_rp,
489 drawBitmap_rp,
490 drawBitmapMatrix_rp,
491 drawBitmapRect_rp,
492 drawClear_rp,
493 drawData_rp,
494 drawPaint_rp,
495 drawPath_rp,
496 drawPicture_rp,
497 drawPoints_rp,
498 drawPosText_rp,
499 drawPosTextH_rp,
500 drawRect_rp,
501 drawShape_rp,
502 drawSprite_rp,
503 drawText_rp,
504 drawTextOnPath_rp,
505 drawVertices_rp,
506 restore_rp,
507 rotate_rp,
508 save_rp,
509 saveLayer_rp,
510 scale_rp,
511 setMatrix_rp,
512 skew_rp,
513 translate_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000514
reed@google.combb6992a2011-04-26 17:41:56 +0000515 paintOp_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000516 def_Typeface_rp,
reed@google.com0faac1e2011-05-11 05:58:58 +0000517 def_PaintFlat_rp,
518
reed@google.combb6992a2011-04-26 17:41:56 +0000519 done_rp
520};
521
522///////////////////////////////////////////////////////////////////////////////
523
524SkGPipeState::SkGPipeState() {
525 // start out with one paint in default state
526 *fPaints.append() = SkNEW(SkPaint);
527}
528
reed@google.comb55d1182011-05-11 00:42:04 +0000529SkGPipeState::~SkGPipeState() {
530 fFlatArray.unrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000531 fPaints.deleteAll();
532}
533
534///////////////////////////////////////////////////////////////////////////////
535
536#include "SkGPipe.h"
537
538SkGPipeReader::SkGPipeReader(SkCanvas* target) {
539 SkSafeRef(target);
540 fCanvas = target;
541 fState = NULL;
542}
543
544SkGPipeReader::~SkGPipeReader() {
545 SkSafeUnref(fCanvas);
546 delete fState;
547}
548
549SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length) {
550 if (NULL == fCanvas) {
551 return kError_Status;
552 }
553
554 if (NULL == fState) {
555 fState = new SkGPipeState;
556 }
557
reed@google.com0faac1e2011-05-11 05:58:58 +0000558 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1));
559
reed@google.combb6992a2011-04-26 17:41:56 +0000560 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000561 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000562 SkCanvas* canvas = fCanvas;
reed@google.combb6793b2011-05-05 15:18:15 +0000563
564 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000565 while (!reader.eof()) {
566 uint32_t op32 = reader.readU32();
567 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000568 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000569
570 if (op >= SK_ARRAY_COUNT(gReadTable)) {
571 SkDebugf("---- bad op during GPipeState::playback\n");
572 return kError_Status;
573 }
574 if (kDone_DrawOp == op) {
575 return kDone_Status;
576 }
577 table[op](canvas, &reader, op32, fState);
578 }
579 return kEOF_Status;
580}
581
582