blob: d33258c85a56b9b37a8314ce7dbc6cc9f5f732ac [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;
40 case kMaskFilter_PaintFlat:
41 paint->setMaskFilter((SkMaskFilter*)obj);
42 break;
43 case kPathEffect_PaintFlat:
44 paint->setPathEffect((SkPathEffect*)obj);
45 break;
46 case kRasterizer_PaintFlat:
47 paint->setRasterizer((SkRasterizer*)obj);
48 break;
49 case kShader_PaintFlat:
50 paint->setShader((SkShader*)obj);
51 break;
52 case kXfermode_PaintFlat:
53 paint->setXfermode((SkXfermode*)obj);
54 break;
55 default:
56 SkASSERT(!"never gets here");
57 }
58}
59
reed@google.combb6793b2011-05-05 15:18:15 +000060template <typename T> class SkRefCntTDArray : public SkTDArray<T> {
61public:
62 ~SkRefCntTDArray() { this->unrefAll(); }
63};
reed@google.combb6992a2011-04-26 17:41:56 +000064
65class SkGPipeState {
66public:
67 SkGPipeState();
68 ~SkGPipeState();
reed@google.combb6793b2011-05-05 15:18:15 +000069
70 void setReader(SkFlattenableReadBuffer* reader) { fReader = reader; }
71
reed@google.combb6992a2011-04-26 17:41:56 +000072 const SkPaint& getPaint(uint32_t drawOp32) const;
73
74 // Extracts index from DrawOp_unpackData().
75 // Returns the specified paint from our list, or creates a new paint if
76 // index == count. If index > count, return NULL
77 SkPaint* editPaint(uint32_t drawOp32);
reed@google.comf5842f72011-05-04 18:30:04 +000078
reed@google.comb55d1182011-05-11 00:42:04 +000079 SkFlattenable* getFlat(unsigned index) const {
80 if (0 == index) {
81 return NULL;
82 }
83 return fFlatArray[index - 1];
84 }
85
86 void defFlattenable(PaintFlats pf, unsigned index) {
87 SkFlattenable* obj = fReader->readFlattenable();
88 *fFlatArray.append() = obj;
89 SkASSERT(index == fFlatArray.count());
90 }
91
reed@google.combb6793b2011-05-05 15:18:15 +000092 void addTypeface() {
93 size_t size = fReader->readU32();
94 const void* data = fReader->skip(SkAlign4(size));
reed@google.comf5842f72011-05-04 18:30:04 +000095 SkMemoryStream stream(data, size, false);
reed@google.comf5842f72011-05-04 18:30:04 +000096 *fTypefaces.append() = SkTypeface::Deserialize(&stream);
97 }
reed@google.combb6793b2011-05-05 15:18:15 +000098 void addColorFilter() {
99 *fColorFilters.append() = (SkColorFilter*)fReader->readFlattenable();
100 }
101 void addDrawLooper() {
102 *fDrawLoopers.append() = (SkDrawLooper*)fReader->readFlattenable();
103 }
104 void addMaskFilter() {
105 *fMaskFilters.append() = (SkMaskFilter*)fReader->readFlattenable();
106 }
107 void addPathEffect() {
108 *fPathEffects.append() = (SkPathEffect*)fReader->readFlattenable();
109 }
110 void addRasterizer() {
111 *fRasterizers.append() = (SkRasterizer*)fReader->readFlattenable();
112 }
113 void addShader() {
114 *fShaders.append() = (SkShader*)fReader->readFlattenable();
115 }
116 void addXfermode() {
117 *fXfermodes.append() = (SkXfermode*)fReader->readFlattenable();
118 }
119
120 void setColorFilter(SkPaint* paint, unsigned id) {
121 paint->setColorFilter(id ? fColorFilters[id - 1] : NULL);
122 }
123 void setLooper(SkPaint* paint, unsigned id) {
124 paint->setLooper(id ? fDrawLoopers[id - 1] : NULL);
125 }
126 void setMaskFilter(SkPaint* paint, unsigned id) {
127 paint->setMaskFilter(id ? fMaskFilters[id - 1] : NULL);
128 }
129 void setPathEffect(SkPaint* paint, unsigned id) {
130 paint->setPathEffect(id ? fPathEffects[id - 1] : NULL);
131 }
132 void setRasterizer(SkPaint* paint, unsigned id) {
133 paint->setRasterizer(id ? fRasterizers[id - 1] : NULL);
134 }
135 void setShader(SkPaint* paint, unsigned id) {
136 paint->setShader(id ? fShaders[id - 1] : NULL);
137 }
138 void setTypeface(SkPaint* paint, unsigned id) {
139 paint->setTypeface(id ? fTypefaces[id - 1] : NULL);
140 }
141 void setXfermode(SkPaint* paint, unsigned id) {
142 paint->setXfermode(id ? fXfermodes[id - 1] : NULL);
143 }
144
reed@google.combb6793b2011-05-05 15:18:15 +0000145 SkFlattenableReadBuffer* fReader;
reed@google.comb55d1182011-05-11 00:42:04 +0000146 SkTDArray<SkFlattenable*> fFlatArray;
147
148private:
reed@google.combb6793b2011-05-05 15:18:15 +0000149
reed@google.combb6992a2011-04-26 17:41:56 +0000150 SkTDArray<SkPaint*> fPaints;
reed@google.combb6793b2011-05-05 15:18:15 +0000151
152 SkRefCntTDArray<SkColorFilter*> fColorFilters;
153 SkRefCntTDArray<SkDrawLooper*> fDrawLoopers;
154 SkRefCntTDArray<SkMaskFilter*> fMaskFilters;
155 SkRefCntTDArray<SkPathEffect*> fPathEffects;
156 SkRefCntTDArray<SkRasterizer*> fRasterizers;
157 SkRefCntTDArray<SkShader*> fShaders;
158 SkRefCntTDArray<SkTypeface*> fTypefaces;
159 SkRefCntTDArray<SkXfermode*> fXfermodes;
reed@google.combb6992a2011-04-26 17:41:56 +0000160};
161
162///////////////////////////////////////////////////////////////////////////////
163
164template <typename T> const T* skip(SkReader32* reader, int count = 1) {
165 SkASSERT(count >= 0);
166 size_t size = sizeof(T) * count;
167 SkASSERT(SkAlign4(size) == size);
168 return reinterpret_cast<const T*>(reader->skip(size));
169}
170
171template <typename T> const T* skipAlign(SkReader32* reader, int count = 1) {
172 SkASSERT(count >= 0);
173 size_t size = SkAlign4(sizeof(T) * count);
174 return reinterpret_cast<const T*>(reader->skip(size));
175}
176
reed@google.combb6992a2011-04-26 17:41:56 +0000177const SkPaint& SkGPipeState::getPaint(uint32_t op32) const {
178 unsigned index = DrawOp_unpackData(op32);
179 if (index >= fPaints.count()) {
180 SkASSERT(!"paint index out of range");
181 index = 0; // we always have at least 1 paint
182 }
183 return *fPaints[index];
184}
185
186SkPaint* SkGPipeState::editPaint(uint32_t op32) {
187 unsigned index = DrawOp_unpackData(op32);
188
189 if (index > fPaints.count()) {
190 SkASSERT(!"paint index out of range");
191 return NULL;
192 }
193
194 if (index == fPaints.count()) {
195 *fPaints.append() = SkNEW(SkPaint);
196 }
197 return fPaints[index];
198}
199
200///////////////////////////////////////////////////////////////////////////////
201///////////////////////////////////////////////////////////////////////////////
202
203static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
204 SkGPipeState* state) {
205 SkPath path;
206 path.unflatten(*reader);
207 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32));
208}
209
210static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
211 SkGPipeState* state) {
212 SkRegion rgn;
reed@google.comb55d1182011-05-11 00:42:04 +0000213 SkReadRegion(reader, &rgn);
reed@google.combb6992a2011-04-26 17:41:56 +0000214 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32));
215}
216
217static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
218 SkGPipeState* state) {
219 canvas->clipRect(*skip<SkRect>(reader), (SkRegion::Op)DrawOp_unpackData(op32));
220}
221
222///////////////////////////////////////////////////////////////////////////////
223
224static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
225 SkGPipeState* state) {
226 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000227 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000228 canvas->setMatrix(matrix);
229}
230
231static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
232 SkGPipeState* state) {
233 SkMatrix matrix;
reed@google.comb55d1182011-05-11 00:42:04 +0000234 SkReadMatrix(reader, &matrix);
reed@google.combb6992a2011-04-26 17:41:56 +0000235 canvas->concat(matrix);
236}
237
238static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
239 SkGPipeState* state) {
240 const SkScalar* param = skip<SkScalar>(reader, 2);
241 canvas->scale(param[0], param[1]);
242}
243
244static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
245 SkGPipeState* state) {
246 const SkScalar* param = skip<SkScalar>(reader, 2);
247 canvas->skew(param[0], param[1]);
248}
249
250static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
251 SkGPipeState* state) {
252 canvas->rotate(reader->readScalar());
253}
254
255static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
256 SkGPipeState* state) {
257 const SkScalar* param = skip<SkScalar>(reader, 2);
258 canvas->translate(param[0], param[1]);
259}
260
261///////////////////////////////////////////////////////////////////////////////
262
263static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
264 SkGPipeState* state) {
265 canvas->save((SkCanvas::SaveFlags)DrawOp_unpackData(op32));
266}
267
268static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
269 SkGPipeState* state) {
reed@google.comacd471f2011-05-03 21:26:46 +0000270 unsigned flags = DrawOp_unpackFlags(op32);
271 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags)DrawOp_unpackData(op32);
reed@google.combb6992a2011-04-26 17:41:56 +0000272
273 const SkRect* bounds = NULL;
274 if (flags & kSaveLayer_HasBounds_DrawOpFlag) {
275 bounds = skip<SkRect>(reader);
276 }
277 const SkPaint* paint = NULL;
278 if (flags & kSaveLayer_HasPaint_DrawOpFlag) {
279 paint = &state->getPaint(reader->readU32());
280 }
reed@google.comacd471f2011-05-03 21:26:46 +0000281 canvas->saveLayer(bounds, paint, saveFlags);
reed@google.combb6992a2011-04-26 17:41:56 +0000282}
283
284static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
285 SkGPipeState* state) {
286 canvas->restore();
287}
288
289///////////////////////////////////////////////////////////////////////////////
290
291static void drawClear_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
292 SkGPipeState* state) {
293 SkColor color = 0;
294 if (DrawOp_unpackFlags(op32) & kClear_HasColor_DrawOpFlag) {
295 color = reader->readU32();
296 }
297 canvas->clear(color);
298}
299
300static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
301 SkGPipeState* state) {
302 canvas->drawPaint(state->getPaint(op32));
303}
304
305static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
306 SkGPipeState* state) {
307 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32);
308 size_t count = reader->readU32();
309 const SkPoint* pts = skip<SkPoint>(reader, count);
310 canvas->drawPoints(mode, count, pts, state->getPaint(op32));
311}
312
313static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
314 SkGPipeState* state) {
315 canvas->drawRect(*skip<SkRect>(reader), state->getPaint(op32));
316}
317
318static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
319 SkGPipeState* state) {
320 SkPath path;
321 path.unflatten(*reader);
322 canvas->drawPath(path, state->getPaint(op32));
323}
324
325static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
326 SkGPipeState* state) {
327 unsigned flags = DrawOp_unpackFlags(op32);
328
329 SkCanvas::VertexMode mode = (SkCanvas::VertexMode)reader->readU32();
330 int vertexCount = reader->readU32();
331 const SkPoint* verts = skip<SkPoint>(reader, vertexCount);
332
333 const SkPoint* texs = NULL;
334 if (flags & kDrawVertices_HasTexs_DrawOpFlag) {
335 texs = skip<SkPoint>(reader, vertexCount);
336 }
337
338 const SkColor* colors = NULL;
339 if (flags & kDrawVertices_HasColors_DrawOpFlag) {
340 colors = skip<SkColor>(reader, vertexCount);
341 }
342
343 // TODO: flatten/unflatten xfermodes
344 SkXfermode* xfer = NULL;
345
346 int indexCount = 0;
347 const uint16_t* indices = NULL;
348 if (flags & kDrawVertices_HasIndices_DrawOpFlag) {
349 indexCount = reader->readU32();
350 indices = skipAlign<uint16_t>(reader, indexCount);
351 }
352
353 canvas->drawVertices(mode, vertexCount, verts, texs, colors, xfer,
354 indices, indexCount, state->getPaint(op32));
355}
356
357///////////////////////////////////////////////////////////////////////////////
358
359static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
360 SkGPipeState* state) {
361 size_t len = reader->readU32();
362 const void* text = reader->skip(SkAlign4(len));
363 const SkScalar* xy = skip<SkScalar>(reader, 2);
364 canvas->drawText(text, len, xy[0], xy[1], state->getPaint(op32));
365}
366
367static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
368 SkGPipeState* state) {
369 size_t len = reader->readU32();
370 const void* text = reader->skip(SkAlign4(len));
371 size_t posCount = reader->readU32(); // compute by our writer
372 const SkPoint* pos = skip<SkPoint>(reader, posCount);
373 canvas->drawPosText(text, len, pos, state->getPaint(op32));
374}
375
376static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
377 SkGPipeState* state) {
378 size_t len = reader->readU32();
379 const void* text = reader->skip(SkAlign4(len));
380 size_t posCount = reader->readU32(); // compute by our writer
381 const SkScalar* xpos = skip<SkScalar>(reader, posCount);
382 SkScalar constY = reader->readScalar();
383 canvas->drawPosTextH(text, len, xpos, constY, state->getPaint(op32));
384}
385
386static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
387 SkGPipeState* state) {
388 size_t len = reader->readU32();
389 const void* text = reader->skip(SkAlign4(len));
390
391 SkPath path;
392 path.unflatten(*reader);
393
394 SkMatrix matrixStorage;
395 const SkMatrix* matrix = NULL;
396 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) {
reed@google.comb55d1182011-05-11 00:42:04 +0000397 SkReadMatrix(reader, &matrixStorage);
reed@google.combb6992a2011-04-26 17:41:56 +0000398 matrix = &matrixStorage;
399 }
400
401 canvas->drawTextOnPath(text, len, path, matrix, state->getPaint(op32));
402}
403
404///////////////////////////////////////////////////////////////////////////////
405
406static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
407 SkGPipeState* state) {
408 UNIMPLEMENTED
409}
410
411static void drawBitmapMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
412 SkGPipeState* state) {
413 UNIMPLEMENTED
414}
415
416static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
417 SkGPipeState* state) {
418 UNIMPLEMENTED
419}
420
421static void drawSprite_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
422 SkGPipeState* state) {
423 UNIMPLEMENTED
424}
425
426///////////////////////////////////////////////////////////////////////////////
427
428static void drawData_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
429 SkGPipeState* state) {
430 // since we don't have a paint, we can use data for our (small) sizes
431 size_t size = DrawOp_unpackData(op32);
432 if (0 == size) {
433 size = reader->readU32();
434 }
435 const void* data = reader->skip(SkAlign4(size));
436 canvas->drawData(data, size);
437}
438
439static void drawShape_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
440 SkGPipeState* state) {
441 UNIMPLEMENTED
442}
443
444static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
445 SkGPipeState* state) {
446 UNIMPLEMENTED
447}
448
449///////////////////////////////////////////////////////////////////////////////
450
reed@google.combb6992a2011-04-26 17:41:56 +0000451static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
452 SkGPipeState* state) {
reed@google.comb55d1182011-05-11 00:42:04 +0000453 size_t offset = reader->offset();
454 size_t stop = offset + PaintOp_unpackData(op32);
455 SkPaint* p = state->editPaint(0);
reed@google.combb6992a2011-04-26 17:41:56 +0000456 int done;
457
458 do {
459 uint32_t p32 = reader->readU32();
460 unsigned op = PaintOp_unpackOp(p32);
461 unsigned data = PaintOp_unpackData(p32);
462 done = PaintOp_unpackFlags(p32) & kLastOp_PaintOpFlag;
463
reed@google.comb55d1182011-05-11 00:42:04 +0000464// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data);
reed@google.combb6992a2011-04-26 17:41:56 +0000465
466 switch (op) {
467 case kReset_PaintOp: p->reset(); break;
468 case kFlags_PaintOp: p->setFlags(data); break;
469 case kColor_PaintOp: p->setColor(reader->readU32()); break;
470 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break;
471 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break;
472 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break;
473 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break;
474 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break;
475 case kEncoding_PaintOp:
476 p->setTextEncoding((SkPaint::TextEncoding)data);
477 break;
478 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break;
479 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break;
480 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break;
481 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break;
482 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break;
reed@google.combb6793b2011-05-05 15:18:15 +0000483
reed@google.comb55d1182011-05-11 00:42:04 +0000484 case kFlatIndex_PaintOp: {
485 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32);
486 unsigned index = data;
487 set_paintflat(p, state->getFlat(index), pf);
488 break;
489 }
490
reed@google.combb6793b2011-05-05 15:18:15 +0000491 case kTypeface_PaintOp: state->setTypeface(p, data); break;
492 case kPathEffect_PaintOp: state->setPathEffect(p, data); break;
493 case kShader_PaintOp: state->setShader(p, data); break;
494 case kXfermode_PaintOp: state->setXfermode(p, data); break;
495 case kMaskFilter_PaintOp: state->setMaskFilter(p, data); break;
496 case kColorFilter_PaintOp: state->setColorFilter(p, data); break;
497 case kRasterizer_PaintOp: state->setRasterizer(p, data); break;
498 case kDrawLooper_PaintOp: state->setLooper(p, data); break;
reed@google.combb6992a2011-04-26 17:41:56 +0000499 default: SkASSERT(!"bad paintop"); return;
500 }
reed@google.comb55d1182011-05-11 00:42:04 +0000501 SkASSERT(reader->offset() <= stop);
502 done = (reader->offset() >= stop);
reed@google.combb6992a2011-04-26 17:41:56 +0000503 } while (!done);
504}
505
reed@google.combb6793b2011-05-05 15:18:15 +0000506///////////////////////////////////////////////////////////////////////////////
507
reed@google.comb55d1182011-05-11 00:42:04 +0000508static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32,
509 SkGPipeState* state) {
510 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32);
511 unsigned index = DrawOp_unpackData(op32);
512 state->defFlattenable(pf, index);
513}
514
reed@google.combb6793b2011-05-05 15:18:15 +0000515static void def_ColorFilter_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
516 state->addColorFilter();
517}
518
519static void def_DrawLooper_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
520 state->addDrawLooper();
521}
522
523static void def_MaskFilter_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
524 state->addMaskFilter();
525}
526
527static void def_PathEffect_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
528 state->addPathEffect();
529}
530
531static void def_Rasterizer_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
532 state->addRasterizer();
533}
534
535static void def_Shader_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
536 state->addShader();
537}
538
539static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
540 state->addTypeface();
541}
542
543static void def_Xfermode_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) {
544 state->addXfermode();
reed@google.comf5842f72011-05-04 18:30:04 +0000545}
546
reed@google.combb6992a2011-04-26 17:41:56 +0000547///////////////////////////////////////////////////////////////////////////////
548
reed@google.comacd471f2011-05-03 21:26:46 +0000549static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) {
550 size_t bytes = DrawOp_unpackData(op32);
551 (void)reader->skip(bytes);
552}
553
reed@google.combb6992a2011-04-26 17:41:56 +0000554static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {}
555
556typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*);
557
558static const ReadProc gReadTable[] = {
reed@google.comacd471f2011-05-03 21:26:46 +0000559 skip_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000560 clipPath_rp,
561 clipRegion_rp,
562 clipRect_rp,
563 concat_rp,
564 drawBitmap_rp,
565 drawBitmapMatrix_rp,
566 drawBitmapRect_rp,
567 drawClear_rp,
568 drawData_rp,
569 drawPaint_rp,
570 drawPath_rp,
571 drawPicture_rp,
572 drawPoints_rp,
573 drawPosText_rp,
574 drawPosTextH_rp,
575 drawRect_rp,
576 drawShape_rp,
577 drawSprite_rp,
578 drawText_rp,
579 drawTextOnPath_rp,
580 drawVertices_rp,
581 restore_rp,
582 rotate_rp,
583 save_rp,
584 saveLayer_rp,
585 scale_rp,
586 setMatrix_rp,
587 skew_rp,
588 translate_rp,
589 paintOp_rp,
reed@google.comb55d1182011-05-11 00:42:04 +0000590 def_PaintFlat_rp,
reed@google.combb6793b2011-05-05 15:18:15 +0000591 def_ColorFilter_rp,
592 def_DrawLooper_rp,
593 def_MaskFilter_rp,
594 def_PathEffect_rp,
595 def_Rasterizer_rp,
596 def_Shader_rp,
597 def_Typeface_rp,
598 def_Xfermode_rp,
reed@google.combb6992a2011-04-26 17:41:56 +0000599 done_rp
600};
601
602///////////////////////////////////////////////////////////////////////////////
603
604SkGPipeState::SkGPipeState() {
605 // start out with one paint in default state
606 *fPaints.append() = SkNEW(SkPaint);
607}
608
reed@google.comb55d1182011-05-11 00:42:04 +0000609SkGPipeState::~SkGPipeState() {
610 fFlatArray.unrefAll();
reed@google.combb6992a2011-04-26 17:41:56 +0000611 fPaints.deleteAll();
612}
613
614///////////////////////////////////////////////////////////////////////////////
615
616#include "SkGPipe.h"
617
618SkGPipeReader::SkGPipeReader(SkCanvas* target) {
619 SkSafeRef(target);
620 fCanvas = target;
621 fState = NULL;
622}
623
624SkGPipeReader::~SkGPipeReader() {
625 SkSafeUnref(fCanvas);
626 delete fState;
627}
628
629SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length) {
630 if (NULL == fCanvas) {
631 return kError_Status;
632 }
633
634 if (NULL == fState) {
635 fState = new SkGPipeState;
636 }
637
638 const ReadProc* table = gReadTable;
reed@google.combb6793b2011-05-05 15:18:15 +0000639 SkFlattenableReadBuffer reader(data, length);
reed@google.combb6992a2011-04-26 17:41:56 +0000640 SkCanvas* canvas = fCanvas;
reed@google.combb6793b2011-05-05 15:18:15 +0000641
642 fState->setReader(&reader);
reed@google.combb6992a2011-04-26 17:41:56 +0000643 while (!reader.eof()) {
644 uint32_t op32 = reader.readU32();
645 unsigned op = DrawOp_unpackOp(op32);
reed@google.combb6793b2011-05-05 15:18:15 +0000646 SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;)
reed@google.combb6992a2011-04-26 17:41:56 +0000647
648 if (op >= SK_ARRAY_COUNT(gReadTable)) {
649 SkDebugf("---- bad op during GPipeState::playback\n");
650 return kError_Status;
651 }
652 if (kDone_DrawOp == op) {
653 return kDone_Status;
654 }
655 table[op](canvas, &reader, op32, fState);
656 }
657 return kEOF_Status;
658}
659
660