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