Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: src/pipe/SkPipeCanvas.cpp

Issue 2201323003: add pipecanvas (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: drawVertices and drawTextOnPath Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkPipeCanvas.h"
9 #include "SkPipeFormat.h"
10 #include "SkPathEffect.h"
11 #include "SkShader.h"
12 #include "SkColorFilter.h"
13 #include "SkImageFilter.h"
14 #include "SkMaskFilter.h"
15 #include "SkRasterizer.h"
16 #include "SkRSXform.h"
17 #include "SkStream.h"
18 #include "SkTextBlob.h"
19 #include "SkTypeface.h"
20
21 template <typename T> void write_rrect(T* writer, const SkRRect& rrect) {
22 char tmp[SkRRect::kSizeInMemory];
23 rrect.writeToMemory(tmp);
24 writer->write(tmp, SkRRect::kSizeInMemory);
25 }
26
27 template <typename T> void write_pad(T* writer, const void* buffer, size_t len) {
28 writer->write(buffer, len & ~3);
29 if (len & 3) {
30 const char* src = (const char*)buffer + (len & ~3);
31 len &= 3;
32 uint32_t tmp = 0;
33 memcpy(&tmp, src, len);
34 writer->write(&tmp, 4);
35 }
36 }
37
38 //////////////////////////////////////////////////////////////////////////////// ///////////////////
39
40 static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) {
41 const SkScalar kTextSize_Default = 12;
42 const SkScalar kTextScaleX_Default = 1;
43 const SkScalar kTextSkewX_Default = 0;
44 const SkScalar kStrokeWidth_Default = 0;
45 const SkScalar kStrokeMiter_Default = 4;
46 const SkColor kColor_Default = SK_ColorBLACK;
47
48 unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0;
49
50 if (usage & kText_PaintUsage) {
51 bits |= (paint.getTextSize() != kTextSize_Default ? kTextSize_NonD ef : 0);
52 bits |= (paint.getTextScaleX() != kTextScaleX_Default ? kTextScaleX_No nDef : 0);
53 bits |= (paint.getTextSkewX() != kTextSkewX_Default ? kTextSkewX_Non Def : 0);
54 bits |= (paint.getTypeface() ? kTypeface_NonD ef : 0);
55 }
56
57 if (usage & kVertices_PaintUsage) {
58 bits |= (paint.getShader() ? kShader_NonDef : 0);
59 } else if (usage & (kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_Pain tUsage)) {
60 bits |= (paint.getPathEffect() ? kPathEffect_NonDef : 0);
61 bits |= (paint.getShader() ? kShader_NonDef : 0);
62 bits |= (paint.getRasterizer() ? kRasterizer_NonDef : 0);
63
64 if (paint.getStyle() != SkPaint::kFill_Style) {
65 bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWid th_NonDef : 0);
66 bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMit er_NonDef : 0);
67 }
68 }
69
70 bits |= (paint.getXfermode() ? kXfermode_NonDef : 0);
71 bits |= (paint.getMaskFilter() ? kMaskFilter_NonDef : 0);
72 bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0);
73 bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0);
74
75 return SkToU16(bits);
76 }
77
78 static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align,
79 unsigned filter, unsigned style, unsigned caps, unsigned joins,
80 unsigned encoding) {
81 SkASSERT(kFlags_BPF + kHint_BPF + kAlign_BPF + kFilter_BPF <= 32);
82
83 ASSERT_FITS_IN(flags, kFlags_BPF);
84 ASSERT_FITS_IN(filter, kFilter_BPF);
85 ASSERT_FITS_IN(style, kStyle_BPF);
86 ASSERT_FITS_IN(caps, kCaps_BPF);
87 ASSERT_FITS_IN(joins, kJoins_BPF);
88 ASSERT_FITS_IN(hint, kHint_BPF);
89 ASSERT_FITS_IN(align, kAlign_BPF);
90 ASSERT_FITS_IN(encoding, kEncoding_BPF);
91
92 // left-align the fields of "known" size, and right-align the last (flatFlag s) so it can easly
93 // add more bits in the future.
94
95 uint32_t packed = 0;
96 int shift = 32;
97
98 shift -= kFlags_BPF; packed |= (flags << shift);
99 shift -= kFilter_BPF; packed |= (filter << shift);
100 shift -= kStyle_BPF; packed |= (style << shift);
101 // these are only needed for stroking (geometry or text)
102 shift -= kCaps_BPF; packed |= (caps << shift);
103 shift -= kJoins_BPF; packed |= (joins << shift);
104 // these are only needed for text
105 shift -= kHint_BPF; packed |= (hint << shift);
106 shift -= kAlign_BPF; packed |= (align << shift);
107 shift -= kEncoding_BPF; packed |= (encoding << shift);
108
109 return packed;
110 }
111
112 #define CHECK_WRITE_SCALAR(writer, nondef, paint, Field) \
113 do { if (nondef & (k##Field##_NonDef)) { \
114 writer.writeScalar(paint.get##Field()); \
115 }} while (0)
116
117 #define CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Field) \
118 do { if (nondef & (k##Field##_NonDef)) { \
119 SkFlattenable* f = paint.get##Field(); \
120 SkASSERT(f != nullptr); \
121 writer.writeFlattenable(f); \
122 } } while (0)
123
124 /*
125 * Header:
126 * paint flags : 32
127 * non_def bits : 16
128 * xfermode enum : 8
129 * pad zeros : 8
130 */
131 static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, PaintUsage usage) {
132 uint32_t packedFlags = pack_paint_flags(paint.getFlags(), paint.getHinting() ,
133 paint.getTextAlign(), paint.getFilte rQuality(),
134 paint.getStyle(), paint.getStrokeCap (),
135 paint.getStrokeJoin(), paint.getText Encoding());
136 writer.write32(packedFlags);
137
138 unsigned nondef = compute_nondef(paint, usage);
139 SkXfermode::Mode mode;
140 if (SkXfermode::AsMode(paint.getXfermode(), &mode)) {
141 nondef &= ~kXfermode_NonDef; // don't need to store a pointer since w e have an enum
142 } else {
143 SkASSERT(nondef & kXfermode_NonDef);
144 mode = (SkXfermode::Mode)0;
145 }
146 const uint8_t pad = 0;
147 writer.write32((nondef << 16) | ((unsigned)mode << 8) | pad);
148
149 CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize);
150 CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX);
151 CHECK_WRITE_SCALAR(writer, nondef, paint, TextSkewX);
152 CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeWidth);
153 CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeMiter);
154
155 if (nondef & kColor_NonDef) {
156 writer.write32(paint.getColor());
157 }
158 if (nondef & kTypeface_NonDef) {
159 }
160
161 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, PathEffect);
162 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Shader);
163 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Xfermode);
164 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, MaskFilter);
165 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ColorFilter);
166 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Rasterizer);
167 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ImageFilter);
168 }
169
170 class SkPipeWriter : public SkBinaryWriteBuffer {
171 enum {
172 N = 1024/4,
173 };
174 uint32_t fStorage[N];
175 SkWStream* fStream;
176
177 public:
178 SkPipeWriter(SkPipeCanvas* pc)
179 : SkBinaryWriteBuffer(fStorage, sizeof(fStorage))
180 , fStream(pc->fStream)
181 {
182 this->setDeduper(pc->fDeduper);
183 }
184
185 ~SkPipeWriter() override {
186 SkASSERT(SkIsAlign4(fStream->bytesWritten()));
187 this->writeToStream(fStream);
188 }
189
190 void writePaint(const SkPaint& paint) override {
191 write_paint(*this, paint, kUnknown_PaintUsage);
192 }
193 };
194
195 //////////////////////////////////////////////////////////////////////////////// ///////////////////
196
197 SkPipeCanvas::SkPipeCanvas(const SkRect& cull, SkPipeDeduper* deduper, SkWStream * stream)
198 : INHERITED(SkScalarCeilToInt(cull.width()), SkScalarCeilToInt(cull.height() ))
199 , fDeduper(deduper)
200 , fStream(stream)
201 {}
202
203 SkPipeCanvas::~SkPipeCanvas() {}
204
205 void SkPipeCanvas::willSave() {
206 fStream->write32(pack_verb(SkPipeVerb::kSave));
207 this->INHERITED::willSave();
208 }
209
210 SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRe c& rec) {
211 SkPipeWriter writer(this);
212 uint32_t extra = rec.fSaveLayerFlags;
213 if (rec.fBounds) {
214 extra |= kHasBounds_SaveLayerMask;
215 }
216 if (rec.fPaint) {
217 extra |= kHasPaint_SaveLayerMask;
218 }
219 if (rec.fBackdrop) {
220 extra |= kHasBackdrop_SaveLayerMask;
221 }
222
223 writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra));
224 if (rec.fBounds) {
225 writer.writeRect(*rec.fBounds);
226 }
227 if (rec.fPaint) {
228 write_paint(writer, *rec.fPaint, kSaveLayer_PaintUsage);
229 }
230 if (rec.fBackdrop) {
231 writer.writeFlattenable(rec.fBackdrop);
232 }
233 return kNoLayer_SaveLayerStrategy;
234 }
235
236 void SkPipeCanvas::willRestore() {
237 fStream->write32(pack_verb(SkPipeVerb::kRestore));
238 this->INHERITED::willRestore();
239 }
240
241 template <typename T> void write_sparse_matrix(T* writer, const SkMatrix& matrix ) {
242 SkMatrix::TypeMask tm = matrix.getType();
243 SkScalar tmp[9];
244 if (tm & SkMatrix::kPerspective_Mask) {
245 matrix.get9(tmp);
246 writer->write(tmp, 9 * sizeof(SkScalar));
247 } else if (tm & SkMatrix::kAffine_Mask) {
248 tmp[0] = matrix[SkMatrix::kMScaleX];
249 tmp[1] = matrix[SkMatrix::kMSkewX];
250 tmp[2] = matrix[SkMatrix::kMTransX];
251 tmp[3] = matrix[SkMatrix::kMScaleY];
252 tmp[4] = matrix[SkMatrix::kMSkewY];
253 tmp[5] = matrix[SkMatrix::kMTransY];
254 writer->write(tmp, 6 * sizeof(SkScalar));
255 } else if (tm & SkMatrix::kScale_Mask) {
256 tmp[0] = matrix[SkMatrix::kMScaleX];
257 tmp[1] = matrix[SkMatrix::kMTransX];
258 tmp[2] = matrix[SkMatrix::kMScaleY];
259 tmp[3] = matrix[SkMatrix::kMTransY];
260 writer->write(tmp, 4 * sizeof(SkScalar));
261 } else if (tm & SkMatrix::kTranslate_Mask) {
262 tmp[0] = matrix[SkMatrix::kMTransX];
263 tmp[1] = matrix[SkMatrix::kMTransY];
264 writer->write(tmp, 2 * sizeof(SkScalar));
265 }
266 // else write nothing for Identity
267 }
268
269 void SkPipeCanvas::didConcat(const SkMatrix& matrix) {
270 SkMatrix::TypeMask tm = matrix.getType();
271 SkASSERT(tm != SkMatrix::kIdentity_Mask);
272 fStream->write32(pack_verb(SkPipeVerb::kConcat, tm));
273 write_sparse_matrix(fStream, matrix);
274
275 this->INHERITED::didConcat(matrix);
276 }
277
278 void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) {
279 // Can we eliminate this?
mtklein 2016/08/26 18:43:23 Ah ha, was wondering how you handled this. If we
280 this->INHERITED::didSetMatrix(matrix);
281 }
282
283 void SkPipeCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
284 fStream->write32(pack_verb(SkPipeVerb::kClipRect, ((unsigned)op << 1) | edge Style));
285 fStream->write(&rect, 4 * sizeof(SkScalar));
286
287 this->INHERITED::onClipRect(rect, op, edgeStyle);
288 }
289
290 void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeSt yle edgeStyle) {
291 fStream->write32(pack_verb(SkPipeVerb::kClipRRect, ((unsigned)op << 1) | edg eStyle));
292 write_rrect(fStream, rrect);
293
294 this->INHERITED::onClipRRect(rrect, op, edgeStyle);
295 }
296
297 void SkPipeCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
298 SkPipeWriter writer(this);
299 writer.write32(pack_verb(SkPipeVerb::kClipPath, ((unsigned)op << 1) | edgeSt yle));
300 writer.writePath(path);
301
302 this->INHERITED::onClipPath(path, op, edgeStyle);
303 }
304
305 void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) {
306 SkPipeWriter writer(this);
307 writer.write32(pack_verb(SkPipeVerb::kClipRegion, (unsigned)op << 1));
308 writer.writeRegion(deviceRgn);
309
310 this->INHERITED::onClipRegion(deviceRgn, op);
311 }
312
313 //////////////////////////////////////////////////////////////////////////////// ///////////////////
314
315 void SkPipeCanvas::onDrawPaint(const SkPaint& paint) {
316 SkPipeWriter writer(this);
317 writer.write32(pack_verb(SkPipeVerb::kDrawPaint));
318 write_paint(writer, paint, kDrawPaint_PaintUsage);
319 }
320
321 void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[ ],
322 const SkPaint& paint) {
323 SkPipeWriter writer(this);
324 writer.write32(pack_verb(SkPipeVerb::kDrawPoints, mode));
325 writer.write32(SkToU32(count));
326 writer.write(pts, count * sizeof(SkPoint));
327 write_paint(writer, paint, kGeometry_PaintUsage);
328 }
329
330 void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
331 SkPipeWriter writer(this);
332 writer.write32(pack_verb(SkPipeVerb::kDrawRect));
333 writer.write(&rect, sizeof(SkRect));
334 write_paint(writer, paint, kGeometry_PaintUsage);
335 }
336
337 void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
338 SkPipeWriter writer(this);
339 writer.write32(pack_verb(SkPipeVerb::kDrawOval));
340 writer.write(&rect, sizeof(SkRect));
341 write_paint(writer, paint, kGeometry_PaintUsage);
342 }
343
344 void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
345 SkPipeWriter writer(this);
346 writer.write32(pack_verb(SkPipeVerb::kDrawRRect));
347 write_rrect(&writer, rrect);
348 write_paint(writer, paint, kGeometry_PaintUsage);
349 }
350
351 void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, cons t SkPaint& paint) {
352 SkPipeWriter writer(this);
353 writer.write32(pack_verb(SkPipeVerb::kDrawDRRect));
354 write_rrect(&writer, outer);
355 write_rrect(&writer, inner);
356 write_paint(writer, paint, kGeometry_PaintUsage);
357 }
358
359 void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
360 SkPipeWriter writer(this);
361 writer.write32(pack_verb(SkPipeVerb::kDrawPath));
362 writer.writePath(path);
363 write_paint(writer, paint, kGeometry_PaintUsage);
364 }
365
366 //////////////////////////////////////////////////////////////////////////////// ///////////////////
367
368 static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) {
369 // If we just "make" an image, it will force a CPU copy (if its mutable), on ly to have
370 // us then either find it in our cache, or compress and send it.
371 //
372 // Better could be to look it up in our cache first, and only create/compres s it if we have to.
373 //
374 // But for now, just do the dumb thing...
375 return SkImage::MakeFromBitmap(bitmap);
376 }
377
378 void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
379 const SkPaint* paint) {
380 sk_sp<SkImage> image = make_from_bitmap(bitmap);
381 if (image) {
382 this->onDrawImage(image.get(), x, y, paint);
383 }
384 }
385
386 void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, c onst SkRect& dst,
387 const SkPaint* paint, SrcRectConstraint cons traint) {
388 sk_sp<SkImage> image = make_from_bitmap(bitmap);
389 if (image) {
390 this->onDrawImageRect(image.get(), src, dst, paint, constraint);
391 }
392 }
393
394 void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& cente r,
395 const SkRect& dst, const SkPaint* paint) {
396 sk_sp<SkImage> image = make_from_bitmap(bitmap);
397 if (image) {
398 this->onDrawImageNine(image.get(), center, dst, paint);
399 }
400 }
401
402 void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top ,
403 const SkPaint* paint) {
404 SkPipeWriter writer(this);
405 writer.write32(pack_verb(SkPipeVerb::kDrawImage, paint != nullptr));
406 writer.writeImage(image);
407 writer.writeScalar(left);
408 writer.writeScalar(top);
409 if (paint) {
410 write_paint(writer, *paint, kImage_PaintUsage);
411 }
412 }
413
414 void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, cons t SkRect& dst,
415 const SkPaint* paint, SrcRectConstraint const raint) {
416 SkPipeWriter writer(this);
417 writer.write32(pack_verb(SkPipeVerb::kDrawImageRect, ((src != nullptr) << 1) | (paint != nullptr)));
418 writer.writeImage(image);
419 if (src) {
420 writer.write(src, sizeof(*src));
421 }
422 writer.write(&dst, sizeof(dst));
423 if (paint) {
424 write_paint(writer, *paint, kImage_PaintUsage);
425 }
426 }
427
428 void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
429 const SkPaint* paint) {
430 SkPipeWriter writer(this);
431 writer.write32(pack_verb(SkPipeVerb::kDrawImageNine, paint != nullptr));
432 writer.writeImage(image);
433 writer.write(&center, sizeof(center));
434 writer.write(&dst, sizeof(dst));
435 if (paint) {
436 write_paint(writer, *paint, kImage_PaintUsage);
437 }
438 }
439
440 //////////////////////////////////////////////////////////////////////////////// ///////////////////
441
442 void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, S kScalar y,
443 const SkPaint& paint) {
444 SkASSERT(byteLength);
445
446 bool compact = fits_in(byteLength, 24);
447
448 SkPipeWriter writer(this);
449 writer.write32(pack_verb(SkPipeVerb::kDrawText, compact ? (unsigned)byteLeng th : 0));
450 if (!compact) {
451 writer.write32(SkToU32(byteLength));
452 }
453 write_pad(&writer, text, byteLength);
454 writer.writeScalar(x);
455 writer.writeScalar(y);
456 write_paint(writer, paint, kText_PaintUsage);
457 }
458
459 void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPo int pos[],
460 const SkPaint& paint) {
461 SkASSERT(byteLength);
462
463 bool compact = fits_in(byteLength, 24);
464
465 SkPipeWriter writer(this);
466 writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteL ength : 0));
467 if (!compact) {
468 writer.write32(SkToU32(byteLength));
469 }
470 write_pad(&writer, text, byteLength);
471 writer.writePointArray(pos, paint.countText(text, byteLength));
472 write_paint(writer, paint, kText_PaintUsage);
473 }
474
475 void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkS calar xpos[],
476 SkScalar constY, const SkPaint& paint) {
477 SkASSERT(byteLength);
478
479 bool compact = fits_in(byteLength, 24);
480
481 SkPipeWriter writer(this);
482 writer.write32(pack_verb(SkPipeVerb::kDrawPosTextH, compact ? (unsigned)byte Length : 0));
483 if (!compact) {
484 writer.write32(SkToU32(byteLength));
485 }
486 write_pad(&writer, text, byteLength);
487 writer.writeScalarArray(xpos, paint.countText(text, byteLength));
488 writer.writeScalar(constY);
489 write_paint(writer, paint, kText_PaintUsage);
490 }
491
492 void SkPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const S kPath& path,
493 const SkMatrix* matrix, const SkPaint& paint ) {
494 SkASSERT(byteLength > 0);
495
496 unsigned extra = 0;
497 if (byteLength <= kTextLength_DrawTextOnPathMask) {
498 extra |= byteLength;
499 } // else we will write the length after the packedverb
500 SkMatrix::TypeMask tm = matrix ? matrix->getType() : SkMatrix::kIdentity_Mas k;
501 extra |= (unsigned)tm << kMatrixType_DrawTextOnPathShift;
502
503 SkPipeWriter writer(this);
504 writer.write32(pack_verb(SkPipeVerb::kDrawTextOnPath, extra));
505 if (byteLength > kTextLength_DrawTextOnPathMask) {
506 writer.write32(byteLength);
507 }
508 write_pad(&writer, text, byteLength);
509 writer.writePath(path);
510 if (matrix) {
511 write_sparse_matrix(&writer, *matrix);
512 }
513 write_paint(writer, paint, kText_PaintUsage);
514 }
515
516 void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
517 const SkRect* cull, const SkPaint& paint) {
518 SkASSERT(byteLength);
519
520 bool compact = fits_in(byteLength, 23);
521 unsigned extra = compact ? (byteLength << 1) : 0;
522 if (cull) {
523 extra |= 1;
524 }
525
526 SkPipeWriter writer(this);
527 writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra));
528 if (!compact) {
529 writer.write32(SkToU32(byteLength));
530 }
531 write_pad(&writer, text, byteLength);
532
533 int count = paint.countText(text, byteLength);
534 writer.write32(count); // maybe we can/should store this in extra as well?
535 writer.write(xform, count * sizeof(SkRSXform));
536 if (cull) {
537 writer.writeRect(*cull);
538 }
539 write_paint(writer, paint, kText_PaintUsage);
540 }
541
542 void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y ,
543 const SkPaint &paint) {
544 SkPipeWriter writer(this);
545 writer.write32(pack_verb(SkPipeVerb::kDrawTextBlob, 0));
546 blob->flatten(writer);
547 writer.writeScalar(x);
548 writer.writeScalar(y);
549 write_paint(writer, paint, kTextBlob_PaintUsage);
550 }
551
552 void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matri x,
553 const SkPaint* paint) {
554 unsigned extra = fDeduper->findOrDefinePicture(const_cast<SkPicture*>(pictur e));
555 if (matrix) {
556 extra |= kHasMatrix_DrawPictureExtra;
557 }
558 if (paint) {
559 extra |= kHasPaint_DrawPictureExtra;
560 }
561 SkPipeWriter writer(this);
562 writer.write32(pack_verb(SkPipeVerb::kDrawPicture, extra));
563 if (matrix) {
564 writer.writeMatrix(*matrix);
565 }
566 if (paint) {
567 write_paint(writer, *paint, kSaveLayer_PaintUsage);
568 }
569 }
570
571 void SkPipeCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
572 const SkPoint vertices[], const SkPoint texs[] ,
573 const SkColor colors[], SkXfermode* xmode,
574 const uint16_t indices[], int indexCount,
575 const SkPaint& paint) {
576 SkASSERT(vertexCount > 0);
577
578 unsigned extra = 0;
579 if (vertexCount <= kVCount_DrawVerticesMask) {
580 extra |= vertexCount;
581 }
582 extra |= (unsigned)vmode << kVMode_DrawVerticesShift;
583
584 SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
585 if (xmode && !SkXfermode::AsMode(xmode, &mode)) {
586 mode = (SkXfermode::Mode)0xFF; // sentinel for read the xfer later
587 }
588 extra |= (unsigned)mode << kXMode_DrawVerticesShift;
589
590 if (texs) {
591 extra |= kHasTex_DrawVerticesMask;
592 }
593 if (colors) {
594 extra |= kHasColors_DrawVerticesMask;
595 }
596 if (indexCount > 0) {
597 extra |= kHasIndices_DrawVerticesMask;
598 }
599
600 SkPipeWriter writer(this);
601 writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra));
602 if (vertexCount > kVCount_DrawVerticesMask) {
603 writer.write32(vertexCount);
604 }
605 if (mode == (SkXfermode::Mode)0xFF) {
606 writer.writeFlattenable(xmode);
607 }
608 writer.write(vertices, vertexCount * sizeof(SkPoint));
609 if (texs) {
610 writer.write(texs, vertexCount * sizeof(SkPoint));
611 }
612 if (colors) {
613 writer.write(colors, vertexCount * sizeof(SkColor));
614 }
615 if (indexCount > 0) {
616 writer.write32(indexCount);
617 SkASSERT(SkIsAlign2(indexCount));
618 writer.write(indices, indexCount * sizeof(uint16_t));
619 }
620 write_paint(writer, paint, kVertices_PaintUsage);
621 }
622
623 void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4] ,
624 const SkPoint texCoords[4], SkXfermode* xfer,
625 const SkPaint& paint) {
626 SkPipeWriter writer(this);
627 unsigned extra = 0;
628 SkXfermode::Mode mode = SkXfermode::kModulate_Mode;
629 if (xfer && !xfer->asMode(&mode)) {
630 mode = (SkXfermode::Mode)kExplicitXfer_DrawPatchExtraValue;
631 } else {
632 xfer = nullptr; // signal that we're using the mode enum
633 }
634 SkASSERT(0 == (mode & ~kModeEnum_DrawPatchExtraMask));
635 extra = (unsigned)mode;
636 if (colors) {
637 extra |= kHasColors_DrawPatchExtraMask;
638 }
639 if (texCoords) {
640 extra |= kHasTexture_DrawPatchExtraMask;
641 }
642 writer.write32(pack_verb(SkPipeVerb::kDrawPatch, extra));
643 writer.write(cubics, sizeof(SkPoint) * 12);
644 if (colors) {
645 writer.write(colors, sizeof(SkColor) * 4);
646 }
647 if (texCoords) {
648 writer.write(texCoords, sizeof(SkPoint) * 4);
649 }
650 if (xfer) {
651 xfer->flatten(writer);
652 }
653 write_paint(writer, paint, kGeometry_PaintUsage);
654 }
655
656 void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData * data) {
657 const size_t len = strlen(key) + 1; // must write the trailing 0
658 bool compact = fits_in(len, 23);
659 uint32_t extra = compact ? (unsigned)len : 0;
660 extra <<= 1; // make room for has_data_sentinel
661 if (data) {
662 extra |= 1;
663 }
664
665 fStream->write32(pack_verb(SkPipeVerb::kDrawAnnotation, extra));
666 fStream->write(&rect, sizeof(SkRect));
667 if (!compact) {
668 fStream->write32(SkToU32(len));
669 }
670 write_pad(fStream, key, len);
671 if (data) {
672 fStream->write32(SkToU32(data->size()));
673 write_pad(fStream, data->data(), data->size());
674 }
675 }
676
677 //////////////////////////////////////////////////////////////////////////////// ///////////////////
678
679 static bool show_deduper_traffic = false;
680
681 int SkPipeDeduper::findOrDefineImage(SkImage* image) {
682 int index = fImages.find(image->uniqueID());
683 SkASSERT(index >= 0);
684 if (index) {
685 if (show_deduper_traffic) {
686 SkDebugf(" reuseImage(%d)\n", index - 1);
687 }
688 return index;
689 }
690
691 sk_sp<SkData> data(image->encode());
692 if (data) {
693 index = fImages.add(image->uniqueID());
694 SkASSERT(index > 0);
695 SkASSERT(fits_in(index, 24));
696 fStream->write32(pack_verb(SkPipeVerb::kDefineImage, index));
697
698 uint32_t len = SkToU32(data->size());
699 fStream->write32(SkAlign4(len));
700 write_pad(fStream, data->data(), len);
701
702 if (show_deduper_traffic) {
703 int size = image->width() * image->height() << 2;
704 SkDebugf(" defineImage(%d) %d -> %d\n", index - 1, size, len);
705 }
706 return index;
707 }
708 SkDebugf("+++ failed to encode image [%d %d]\n", image->width(), image->heig ht());
709 return 0; // failed to encode
710 }
711
712 int SkPipeDeduper::findOrDefinePicture(SkPicture* picture) {
713 int index = fPictures.find(picture->uniqueID());
714 SkASSERT(index >= 0);
715 if (index) {
716 if (show_deduper_traffic) {
717 SkDebugf(" reusePicture(%d)\n", index - 1);
718 }
719 return index;
720 }
721
722 index = fPictures.add(picture->uniqueID());
723 ASSERT_FITS_IN(index, kDefineObjectBits);
724 size_t prevWritten = fStream->bytesWritten();
725 fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, index));
726 picture->playback(fPipeCanvas);
727 fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, kEnd_DefinePictureMas k));
728 SkDebugf(" definePicture(%d) %d\n",
729 index - 1, SkToU32(fStream->bytesWritten() - prevWritten));
730 return index;
731 }
732
733 int SkPipeDeduper::findOrDefineTypeface(SkTypeface* typeface) {
734 return 0;
735 }
736
737 int SkPipeDeduper::findOrDefineFactory(SkFlattenable* flattenable) {
738 if (!flattenable) {
739 return 0;
740 }
741
742 int index = fFactories.find(flattenable->getFactory());
743 SkASSERT(index >= 0);
744 if (index) {
745 if (show_deduper_traffic) {
746 SkDebugf(" reuseFactory(%d)\n", index - 1);
747 }
748 return index;
749 }
750
751 index = fFactories.add(flattenable->getFactory());
752 ASSERT_FITS_IN(index, kIndex_DefineFactoryExtraBits);
753 const char* name = flattenable->getTypeName();
754 size_t len = strlen(name);
755 ASSERT_FITS_IN(len, kNameLength_DefineFactoryExtraBits);
756 unsigned extra = (index << kNameLength_DefineFactoryExtraBits) | len;
757 size_t prevWritten = fStream->bytesWritten();
758 fStream->write32(pack_verb(SkPipeVerb::kDefineFactory, extra));
759 write_pad(fStream, name, len + 1);
760 SkDebugf(" defineFactory(%d) %d %s\n",
761 index - 1, SkToU32(fStream->bytesWritten() - prevWritten), name);
762 return index;
763 }
764
765 //////////////////////////////////////////////////////////////////////////////// ///////////////////
766 #include "SkPipe.h"
767
768 class SkPipeSerializer::Impl {
769 public:
770 SkPipeDeduper fDeduper;
771 std::unique_ptr<SkPipeCanvas> fCanvas;
772 };
773
774 SkPipeSerializer::SkPipeSerializer() : fImpl(new Impl) {}
775
776 SkPipeSerializer::~SkPipeSerializer() { delete fImpl; }
777
778 void SkPipeSerializer::reset() {
779 fImpl->fDeduper.resetCaches();
780 }
781
782 void SkPipeSerializer::write(SkPicture* picture, SkWStream* stream) {
783 stream->write32(kDefinePicture_ExtPipeVerb);
784 SkRect cull = picture->cullRect();
785 stream->write(&cull.fLeft, sizeof(SkRect));
786 picture->playback(this->beginWrite(cull, stream));
787 this->endWrite();
788 }
789
790 void SkPipeSerializer::write(SkImage*, SkWStream* stream) {
791 stream->write32(kDefineImage_ExtPipeVerb);
792 }
793
794 SkCanvas* SkPipeSerializer::beginWrite(const SkRect& cull, SkWStream* stream) {
795 SkASSERT(nullptr == fImpl->fCanvas);
796 fImpl->fCanvas.reset(new SkPipeCanvas(cull, &fImpl->fDeduper, stream));
797 fImpl->fDeduper.setStream(stream);
798 fImpl->fDeduper.setCanvas(fImpl->fCanvas.get());
799 return fImpl->fCanvas.get();
800 }
801
802 void SkPipeSerializer::endWrite() {
803 fImpl->fCanvas.reset(nullptr);
804 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698