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