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 "SkAutoMalloc.h" 9 #include "SkColorFilter.h" 10 #include "SkDrawLooper.h" 11 #include "SkImageFilter.h" 12 #include "SkMaskFilter.h" 13 #include "SkPathEffect.h" 14 #include "SkPipeCanvas.h" 15 #include "SkPipeFormat.h" 16 #include "SkRSXform.h" 17 #include "SkRasterizer.h" 18 #include "SkShader.h" 19 #include "SkStream.h" 20 #include "SkTextBlob.h" 21 #include "SkTypeface.h" 22 23 template <typename T> void write_rrect(T* writer, const SkRRect& rrect) { 24 char tmp[SkRRect::kSizeInMemory]; 25 rrect.writeToMemory(tmp); 26 writer->write(tmp, SkRRect::kSizeInMemory); 27 } 28 29 template <typename T> void write_pad(T* writer, const void* buffer, size_t len) { 30 writer->write(buffer, len & ~3); 31 if (len & 3) { 32 const char* src = (const char*)buffer + (len & ~3); 33 len &= 3; 34 uint32_t tmp = 0; 35 memcpy(&tmp, src, len); 36 writer->write(&tmp, 4); 37 } 38 } 39 40 /////////////////////////////////////////////////////////////////////////////////////////////////// 41 42 static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) { 43 // kRespectsStroke_PaintUsage is only valid if other bits are also set 44 SkASSERT(0 != (usage & ~kRespectsStroke_PaintUsage)); 45 46 const SkScalar kTextSize_Default = 12; 47 const SkScalar kTextScaleX_Default = 1; 48 const SkScalar kTextSkewX_Default = 0; 49 const SkScalar kStrokeWidth_Default = 0; 50 const SkScalar kStrokeMiter_Default = 4; 51 const SkColor kColor_Default = SK_ColorBLACK; 52 53 unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0; 54 55 if (usage & kText_PaintUsage) { 56 bits |= (paint.getTextSize() != kTextSize_Default ? kTextSize_NonDef : 0); 57 bits |= (paint.getTextScaleX() != kTextScaleX_Default ? kTextScaleX_NonDef : 0); 58 bits |= (paint.getTextSkewX() != kTextSkewX_Default ? kTextSkewX_NonDef : 0); 59 bits |= (paint.getTypeface() ? kTypeface_NonDef : 0); 60 } 61 62 // TODO: kImage_PaintUsage only needs the shader/maskfilter IF its colortype is kAlpha_8 63 64 if (usage & (kVertices_PaintUsage | kDrawPaint_PaintUsage | kImage_PaintUsage | 65 kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) { 66 bits |= (paint.getShader() ? kShader_NonDef : 0); 67 } 68 69 if (usage & (kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) { 70 bits |= (paint.getPathEffect() ? kPathEffect_NonDef : 0); 71 bits |= (paint.getRasterizer() ? kRasterizer_NonDef : 0); 72 73 if (paint.getStyle() != SkPaint::kFill_Style || (usage & kRespectsStroke_PaintUsage)) { 74 bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWidth_NonDef : 0); 75 bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMiter_NonDef : 0); 76 } 77 } 78 79 if (usage & 80 (kText_PaintUsage | kGeometry_PaintUsage | kImage_PaintUsage | kTextBlob_PaintUsage)) 81 { 82 bits |= (paint.getMaskFilter() ? kMaskFilter_NonDef : 0); 83 } 84 85 bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0); 86 bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0); 87 bits |= (paint.getDrawLooper() ? kDrawLooper_NonDef : 0); 88 89 return SkToU16(bits); 90 } 91 92 static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, 93 unsigned filter, unsigned style, unsigned caps, unsigned joins, 94 unsigned encoding) { 95 SkASSERT(kFlags_BPF + kHint_BPF + kAlign_BPF + kFilter_BPF <= 32); 96 97 ASSERT_FITS_IN(flags, kFlags_BPF); 98 ASSERT_FITS_IN(filter, kFilter_BPF); 99 ASSERT_FITS_IN(style, kStyle_BPF); 100 ASSERT_FITS_IN(caps, kCaps_BPF); 101 ASSERT_FITS_IN(joins, kJoins_BPF); 102 ASSERT_FITS_IN(hint, kHint_BPF); 103 ASSERT_FITS_IN(align, kAlign_BPF); 104 ASSERT_FITS_IN(encoding, kEncoding_BPF); 105 106 // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly 107 // add more bits in the future. 108 109 uint32_t packed = 0; 110 int shift = 32; 111 112 shift -= kFlags_BPF; packed |= (flags << shift); 113 shift -= kFilter_BPF; packed |= (filter << shift); 114 shift -= kStyle_BPF; packed |= (style << shift); 115 // these are only needed for stroking (geometry or text) 116 shift -= kCaps_BPF; packed |= (caps << shift); 117 shift -= kJoins_BPF; packed |= (joins << shift); 118 // these are only needed for text 119 shift -= kHint_BPF; packed |= (hint << shift); 120 shift -= kAlign_BPF; packed |= (align << shift); 121 shift -= kEncoding_BPF; packed |= (encoding << shift); 122 123 return packed; 124 } 125 126 #define CHECK_WRITE_SCALAR(writer, nondef, paint, Field) \ 127 do { if (nondef & (k##Field##_NonDef)) { \ 128 writer.writeScalar(paint.get##Field()); \ 129 }} while (0) 130 131 #define CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Field) \ 132 do { if (nondef & (k##Field##_NonDef)) { \ 133 SkFlattenable* f = paint.get##Field(); \ 134 SkASSERT(f != nullptr); \ 135 writer.writeFlattenable(f); \ 136 } } while (0) 137 138 /* 139 * Header: 140 * paint flags : 32 141 * non_def bits : 16 142 * xfermode enum : 8 143 * pad zeros : 8 144 */ 145 static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, unsigned usage) { 146 uint32_t packedFlags = pack_paint_flags(paint.getFlags(), paint.getHinting(), 147 paint.getTextAlign(), paint.getFilterQuality(), 148 paint.getStyle(), paint.getStrokeCap(), 149 paint.getStrokeJoin(), paint.getTextEncoding()); 150 writer.write32(packedFlags); 151 152 unsigned nondef = compute_nondef(paint, (PaintUsage)usage); 153 const uint8_t pad = 0; 154 writer.write32((nondef << 16) | ((unsigned)paint.getBlendMode() << 8) | pad); 155 156 CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize); 157 CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX); 158 CHECK_WRITE_SCALAR(writer, nondef, paint, TextSkewX); 159 CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeWidth); 160 CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeMiter); 161 162 if (nondef & kColor_NonDef) { 163 writer.write32(paint.getColor()); 164 } 165 if (nondef & kTypeface_NonDef) { 166 // TODO: explore idea of writing bits indicating "use the prev (or prev N) face" 167 // e.g. 1-N bits is an index into a ring buffer of typefaces 168 SkTypeface* tf = paint.getTypeface(); 169 SkASSERT(tf); 170 writer.writeTypeface(tf); 171 } 172 173 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, PathEffect); 174 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Shader); 175 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, MaskFilter); 176 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ColorFilter); 177 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Rasterizer); 178 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ImageFilter); 179 CHECK_WRITE_FLATTENABLE(writer, nondef, paint, DrawLooper); 180 } 181 182 class SkPipeWriter : public SkBinaryWriteBuffer { 183 enum { 184 N = 1024/4, 185 }; 186 uint32_t fStorage[N]; 187 SkWStream* fStream; 188 189 public: 190 SkPipeWriter(SkWStream* stream, SkDeduper* deduper) 191 : SkBinaryWriteBuffer(fStorage, sizeof(fStorage)) 192 , fStream(stream) 193 { 194 this->setDeduper(deduper); 195 } 196 197 SkPipeWriter(SkPipeCanvas* pc) : SkPipeWriter(pc->fStream, pc->fDeduper) {} 198 199 ~SkPipeWriter() override { 200 SkASSERT(SkIsAlign4(fStream->bytesWritten())); 201 this->writeToStream(fStream); 202 } 203 204 void writePaint(const SkPaint& paint) override { 205 write_paint(*this, paint, kUnknown_PaintUsage); 206 } 207 }; 208 209 /////////////////////////////////////////////////////////////////////////////////////////////////// 210 211 SkPipeCanvas::SkPipeCanvas(const SkRect& cull, SkPipeDeduper* deduper, SkWStream* stream) 212 : INHERITED(cull.roundOut()) 213 , fDeduper(deduper) 214 , fStream(stream) 215 {} 216 217 SkPipeCanvas::~SkPipeCanvas() {} 218 219 void SkPipeCanvas::willSave() { 220 fStream->write32(pack_verb(SkPipeVerb::kSave)); 221 this->INHERITED::willSave(); 222 } 223 224 SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { 225 SkPipeWriter writer(this); 226 uint32_t extra = rec.fSaveLayerFlags; 227 228 // remap this wacky flag 229 if (extra & (1 << 31)/*SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag*/) { 230 extra &= ~(1 << 31); 231 extra |= kDontClipToLayer_SaveLayerMask; 232 } 233 234 if (rec.fBounds) { 235 extra |= kHasBounds_SaveLayerMask; 236 } 237 if (rec.fPaint) { 238 extra |= kHasPaint_SaveLayerMask; 239 } 240 if (rec.fBackdrop) { 241 extra |= kHasBackdrop_SaveLayerMask; 242 } 243 244 writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra)); 245 if (rec.fBounds) { 246 writer.writeRect(*rec.fBounds); 247 } 248 if (rec.fPaint) { 249 write_paint(writer, *rec.fPaint, kSaveLayer_PaintUsage); 250 } 251 if (rec.fBackdrop) { 252 writer.writeFlattenable(rec.fBackdrop); 253 } 254 return kNoLayer_SaveLayerStrategy; 255 } 256 257 void SkPipeCanvas::willRestore() { 258 fStream->write32(pack_verb(SkPipeVerb::kRestore)); 259 this->INHERITED::willRestore(); 260 } 261 262 template <typename T> void write_sparse_matrix(T* writer, const SkMatrix& matrix) { 263 SkMatrix::TypeMask tm = matrix.getType(); 264 SkScalar tmp[9]; 265 if (tm & SkMatrix::kPerspective_Mask) { 266 matrix.get9(tmp); 267 writer->write(tmp, 9 * sizeof(SkScalar)); 268 } else if (tm & SkMatrix::kAffine_Mask) { 269 tmp[0] = matrix[SkMatrix::kMScaleX]; 270 tmp[1] = matrix[SkMatrix::kMSkewX]; 271 tmp[2] = matrix[SkMatrix::kMTransX]; 272 tmp[3] = matrix[SkMatrix::kMScaleY]; 273 tmp[4] = matrix[SkMatrix::kMSkewY]; 274 tmp[5] = matrix[SkMatrix::kMTransY]; 275 writer->write(tmp, 6 * sizeof(SkScalar)); 276 } else if (tm & SkMatrix::kScale_Mask) { 277 tmp[0] = matrix[SkMatrix::kMScaleX]; 278 tmp[1] = matrix[SkMatrix::kMTransX]; 279 tmp[2] = matrix[SkMatrix::kMScaleY]; 280 tmp[3] = matrix[SkMatrix::kMTransY]; 281 writer->write(tmp, 4 * sizeof(SkScalar)); 282 } else if (tm & SkMatrix::kTranslate_Mask) { 283 tmp[0] = matrix[SkMatrix::kMTransX]; 284 tmp[1] = matrix[SkMatrix::kMTransY]; 285 writer->write(tmp, 2 * sizeof(SkScalar)); 286 } 287 // else write nothing for Identity 288 } 289 290 static void do_concat(SkWStream* stream, const SkMatrix& matrix, bool isSetMatrix) { 291 unsigned mtype = matrix.getType(); 292 SkASSERT(0 == (mtype & ~kTypeMask_ConcatMask)); 293 unsigned extra = mtype; 294 if (isSetMatrix) { 295 extra |= kSetMatrix_ConcatMask; 296 } 297 if (mtype || isSetMatrix) { 298 stream->write32(pack_verb(SkPipeVerb::kConcat, extra)); 299 write_sparse_matrix(stream, matrix); 300 } 301 } 302 303 void SkPipeCanvas::didConcat(const SkMatrix& matrix) { 304 do_concat(fStream, matrix, false); 305 this->INHERITED::didConcat(matrix); 306 } 307 308 void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) { 309 do_concat(fStream, matrix, true); 310 this->INHERITED::didSetMatrix(matrix); 311 } 312 313 void SkPipeCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 314 fStream->write32(pack_verb(SkPipeVerb::kClipRect, ((unsigned)op << 1) | edgeStyle)); 315 fStream->write(&rect, 4 * sizeof(SkScalar)); 316 317 this->INHERITED::onClipRect(rect, op, edgeStyle); 318 } 319 320 void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 321 fStream->write32(pack_verb(SkPipeVerb::kClipRRect, ((unsigned)op << 1) | edgeStyle)); 322 write_rrect(fStream, rrect); 323 324 this->INHERITED::onClipRRect(rrect, op, edgeStyle); 325 } 326 327 void SkPipeCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 328 SkPipeWriter writer(this); 329 writer.write32(pack_verb(SkPipeVerb::kClipPath, ((unsigned)op << 1) | edgeStyle)); 330 writer.writePath(path); 331 332 this->INHERITED::onClipPath(path, op, edgeStyle); 333 } 334 335 void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) { 336 SkPipeWriter writer(this); 337 writer.write32(pack_verb(SkPipeVerb::kClipRegion, (unsigned)op << 1)); 338 writer.writeRegion(deviceRgn); 339 340 this->INHERITED::onClipRegion(deviceRgn, op); 341 } 342 343 /////////////////////////////////////////////////////////////////////////////////////////////////// 344 345 void SkPipeCanvas::onDrawArc(const SkRect& bounds, SkScalar startAngle, SkScalar sweepAngle, 346 bool useCenter, const SkPaint& paint) { 347 SkPipeWriter writer(this); 348 writer.write32(pack_verb(SkPipeVerb::kDrawArc, (int)useCenter)); 349 writer.writeRect(bounds); 350 writer.writeScalar(startAngle); 351 writer.writeScalar(sweepAngle); 352 write_paint(writer, paint, kGeometry_PaintUsage); 353 } 354 355 void SkPipeCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect rect[], 356 const SkColor colors[], int count, SkBlendMode mode, 357 const SkRect* cull, const SkPaint* paint) { 358 unsigned extra = (unsigned)mode; 359 SkASSERT(0 == (extra & ~kMode_DrawAtlasMask)); 360 if (colors) { 361 extra |= kHasColors_DrawAtlasMask; 362 } 363 if (cull) { 364 extra |= kHasCull_DrawAtlasMask; 365 } 366 if (paint) { 367 extra |= kHasPaint_DrawAtlasMask; 368 } 369 370 SkPipeWriter writer(this); 371 writer.write32(pack_verb(SkPipeVerb::kDrawAtlas, extra)); 372 writer.writeImage(image); 373 writer.write32(count); 374 writer.write(xform, count * sizeof(SkRSXform)); 375 writer.write(rect, count * sizeof(SkRect)); 376 if (colors) { 377 writer.write(colors, count * sizeof(SkColor)); 378 } 379 if (cull) { 380 writer.writeRect(*cull); 381 } 382 if (paint) { 383 write_paint(writer, *paint, kImage_PaintUsage); 384 } 385 } 386 387 void SkPipeCanvas::onDrawPaint(const SkPaint& paint) { 388 SkPipeWriter writer(this); 389 writer.write32(pack_verb(SkPipeVerb::kDrawPaint)); 390 write_paint(writer, paint, kDrawPaint_PaintUsage); 391 } 392 393 void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 394 const SkPaint& paint) { 395 SkPipeWriter writer(this); 396 writer.write32(pack_verb(SkPipeVerb::kDrawPoints, mode)); 397 writer.write32(SkToU32(count)); 398 writer.write(pts, count * sizeof(SkPoint)); 399 write_paint(writer, paint, kGeometry_PaintUsage | kRespectsStroke_PaintUsage); 400 } 401 402 void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { 403 SkPipeWriter writer(this); 404 writer.write32(pack_verb(SkPipeVerb::kDrawRect)); 405 writer.write(&rect, sizeof(SkRect)); 406 write_paint(writer, paint, kGeometry_PaintUsage); 407 } 408 409 void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { 410 SkPipeWriter writer(this); 411 writer.write32(pack_verb(SkPipeVerb::kDrawOval)); 412 writer.write(&rect, sizeof(SkRect)); 413 write_paint(writer, paint, kGeometry_PaintUsage); 414 } 415 416 void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 417 SkPipeWriter writer(this); 418 writer.write32(pack_verb(SkPipeVerb::kDrawRRect)); 419 write_rrect(&writer, rrect); 420 write_paint(writer, paint, kGeometry_PaintUsage); 421 } 422 423 void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { 424 SkPipeWriter writer(this); 425 writer.write32(pack_verb(SkPipeVerb::kDrawDRRect)); 426 write_rrect(&writer, outer); 427 write_rrect(&writer, inner); 428 write_paint(writer, paint, kGeometry_PaintUsage); 429 } 430 431 void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { 432 SkPipeWriter writer(this); 433 writer.write32(pack_verb(SkPipeVerb::kDrawPath)); 434 writer.writePath(path); 435 write_paint(writer, paint, kGeometry_PaintUsage); 436 } 437 438 /////////////////////////////////////////////////////////////////////////////////////////////////// 439 440 static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) { 441 // If we just "make" an image, it will force a CPU copy (if its mutable), only to have 442 // us then either find it in our cache, or compress and send it. 443 // 444 // Better could be to look it up in our cache first, and only create/compress it if we have to. 445 // 446 // But for now, just do the dumb thing... 447 return SkImage::MakeFromBitmap(bitmap); 448 } 449 450 void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, 451 const SkPaint* paint) { 452 sk_sp<SkImage> image = make_from_bitmap(bitmap); 453 if (image) { 454 this->onDrawImage(image.get(), x, y, paint); 455 } 456 } 457 458 void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 459 const SkPaint* paint, SrcRectConstraint constraint) { 460 sk_sp<SkImage> image = make_from_bitmap(bitmap); 461 if (image) { 462 this->onDrawImageRect(image.get(), src, dst, paint, constraint); 463 } 464 } 465 466 void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 467 const SkRect& dst, const SkPaint* paint) { 468 sk_sp<SkImage> image = make_from_bitmap(bitmap); 469 if (image) { 470 this->onDrawImageNine(image.get(), center, dst, paint); 471 } 472 } 473 474 void SkPipeCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, 475 const SkRect& dst, const SkPaint* paint) { 476 sk_sp<SkImage> image = make_from_bitmap(bitmap); 477 if (image) { 478 this->onDrawImageLattice(image.get(), lattice, dst, paint); 479 } 480 } 481 482 /////////////////////////////////////////////////////////////////////////////////////////////////// 483 484 void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, 485 const SkPaint* paint) { 486 unsigned extra = 0; 487 if (paint) { 488 extra |= kHasPaint_DrawImageMask; 489 } 490 SkPipeWriter writer(this); 491 writer.write32(pack_verb(SkPipeVerb::kDrawImage, extra)); 492 writer.writeImage(image); 493 writer.writeScalar(left); 494 writer.writeScalar(top); 495 if (paint) { 496 write_paint(writer, *paint, kImage_PaintUsage); 497 } 498 } 499 500 void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 501 const SkPaint* paint, SrcRectConstraint constraint) { 502 SkASSERT(0 == ((unsigned)constraint & ~1)); 503 unsigned extra = (unsigned)constraint; 504 if (paint) { 505 extra |= kHasPaint_DrawImageRectMask; 506 } 507 if (src) { 508 extra |= kHasSrcRect_DrawImageRectMask; 509 } 510 511 SkPipeWriter writer(this); 512 writer.write32(pack_verb(SkPipeVerb::kDrawImageRect, extra)); 513 writer.writeImage(image); 514 if (src) { 515 writer.write(src, sizeof(*src)); 516 } 517 writer.write(&dst, sizeof(dst)); 518 if (paint) { 519 write_paint(writer, *paint, kImage_PaintUsage); 520 } 521 } 522 523 void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, 524 const SkPaint* paint) { 525 unsigned extra = 0; 526 if (paint) { 527 extra |= kHasPaint_DrawImageNineMask; 528 } 529 SkPipeWriter writer(this); 530 writer.write32(pack_verb(SkPipeVerb::kDrawImageNine, extra)); 531 writer.writeImage(image); 532 writer.write(¢er, sizeof(center)); 533 writer.write(&dst, sizeof(dst)); 534 if (paint) { 535 write_paint(writer, *paint, kImage_PaintUsage); 536 } 537 } 538 539 void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, 540 const SkRect& dst, const SkPaint* paint) { 541 unsigned extra = 0; 542 if (paint) { 543 extra |= kHasPaint_DrawImageLatticeMask; 544 } 545 if (lattice.fFlags) { 546 extra |= kHasFlags_DrawImageLatticeMask; 547 } 548 if (lattice.fXCount >= kCount_DrawImageLatticeMask) { 549 extra |= kCount_DrawImageLatticeMask << kXCount_DrawImageLatticeShift; 550 } else { 551 extra |= lattice.fXCount << kXCount_DrawImageLatticeShift; 552 } 553 if (lattice.fYCount >= kCount_DrawImageLatticeMask) { 554 extra |= kCount_DrawImageLatticeMask << kYCount_DrawImageLatticeShift; 555 } else { 556 extra |= lattice.fYCount << kYCount_DrawImageLatticeShift; 557 } 558 559 SkPipeWriter writer(this); 560 writer.write32(pack_verb(SkPipeVerb::kDrawImageLattice, extra)); 561 writer.writeImage(image); 562 if (lattice.fXCount >= kCount_DrawImageLatticeMask) { 563 writer.write32(lattice.fXCount); 564 } 565 if (lattice.fYCount >= kCount_DrawImageLatticeMask) { 566 writer.write32(lattice.fYCount); 567 } 568 // Often these divs will be small (8 or 16 bits). Consider sniffing that and writing a flag 569 // so we can store them smaller. 570 writer.write(lattice.fXDivs, lattice.fXCount * sizeof(int32_t)); 571 writer.write(lattice.fYDivs, lattice.fYCount * sizeof(int32_t)); 572 if (lattice.fFlags) { 573 int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1); 574 SkASSERT(count > 0); 575 write_pad(&writer, lattice.fFlags, count); 576 } 577 SkASSERT(lattice.fBounds); 578 writer.write(&lattice.fBounds, sizeof(*lattice.fBounds)); 579 writer.write(&dst, sizeof(dst)); 580 if (paint) { 581 write_paint(writer, *paint, kImage_PaintUsage); 582 } 583 } 584 585 /////////////////////////////////////////////////////////////////////////////////////////////////// 586 587 void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 588 const SkPaint& paint) { 589 SkASSERT(byteLength); 590 591 bool compact = fits_in(byteLength, 24); 592 593 SkPipeWriter writer(this); 594 writer.write32(pack_verb(SkPipeVerb::kDrawText, compact ? (unsigned)byteLength : 0)); 595 if (!compact) { 596 writer.write32(SkToU32(byteLength)); 597 } 598 write_pad(&writer, text, byteLength); 599 writer.writeScalar(x); 600 writer.writeScalar(y); 601 write_paint(writer, paint, kText_PaintUsage); 602 } 603 604 void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 605 const SkPaint& paint) { 606 SkASSERT(byteLength); 607 608 bool compact = fits_in(byteLength, 24); 609 610 SkPipeWriter writer(this); 611 writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteLength : 0)); 612 if (!compact) { 613 writer.write32(SkToU32(byteLength)); 614 } 615 write_pad(&writer, text, byteLength); 616 writer.writePointArray(pos, paint.countText(text, byteLength)); 617 write_paint(writer, paint, kText_PaintUsage); 618 } 619 620 void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 621 SkScalar constY, const SkPaint& paint) { 622 SkASSERT(byteLength); 623 624 bool compact = fits_in(byteLength, 24); 625 626 SkPipeWriter writer(this); 627 writer.write32(pack_verb(SkPipeVerb::kDrawPosTextH, compact ? (unsigned)byteLength : 0)); 628 if (!compact) { 629 writer.write32(SkToU32(byteLength)); 630 } 631 write_pad(&writer, text, byteLength); 632 writer.writeScalarArray(xpos, paint.countText(text, byteLength)); 633 writer.writeScalar(constY); 634 write_paint(writer, paint, kText_PaintUsage); 635 } 636 637 void SkPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 638 const SkMatrix* matrix, const SkPaint& paint) { 639 SkASSERT(byteLength > 0); 640 641 unsigned extra = 0; 642 if (byteLength <= kTextLength_DrawTextOnPathMask) { 643 extra |= byteLength; 644 } // else we will write the length after the packedverb 645 SkMatrix::TypeMask tm = matrix ? matrix->getType() : SkMatrix::kIdentity_Mask; 646 extra |= (unsigned)tm << kMatrixType_DrawTextOnPathShift; 647 648 SkPipeWriter writer(this); 649 writer.write32(pack_verb(SkPipeVerb::kDrawTextOnPath, extra)); 650 if (byteLength > kTextLength_DrawTextOnPathMask) { 651 writer.write32(byteLength); 652 } 653 write_pad(&writer, text, byteLength); 654 writer.writePath(path); 655 if (matrix) { 656 write_sparse_matrix(&writer, *matrix); 657 } 658 write_paint(writer, paint, kText_PaintUsage); 659 } 660 661 void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], 662 const SkRect* cull, const SkPaint& paint) { 663 SkASSERT(byteLength); 664 665 bool compact = fits_in(byteLength, 23); 666 unsigned extra = compact ? (byteLength << 1) : 0; 667 if (cull) { 668 extra |= 1; 669 } 670 671 SkPipeWriter writer(this); 672 writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra)); 673 if (!compact) { 674 writer.write32(SkToU32(byteLength)); 675 } 676 write_pad(&writer, text, byteLength); 677 678 int count = paint.countText(text, byteLength); 679 writer.write32(count); // maybe we can/should store this in extra as well? 680 writer.write(xform, count * sizeof(SkRSXform)); 681 if (cull) { 682 writer.writeRect(*cull); 683 } 684 write_paint(writer, paint, kText_PaintUsage); 685 } 686 687 void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 688 const SkPaint &paint) { 689 SkPipeWriter writer(this); 690 writer.write32(pack_verb(SkPipeVerb::kDrawTextBlob, 0)); 691 blob->flatten(writer); 692 writer.writeScalar(x); 693 writer.writeScalar(y); 694 write_paint(writer, paint, kTextBlob_PaintUsage); 695 } 696 697 void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 698 const SkPaint* paint) { 699 unsigned extra = fDeduper->findOrDefinePicture(const_cast<SkPicture*>(picture)); 700 if (matrix) { 701 extra |= kHasMatrix_DrawPictureExtra; 702 } 703 if (paint) { 704 extra |= kHasPaint_DrawPictureExtra; 705 } 706 SkPipeWriter writer(this); 707 writer.write32(pack_verb(SkPipeVerb::kDrawPicture, extra)); 708 if (matrix) { 709 writer.writeMatrix(*matrix); 710 } 711 if (paint) { 712 write_paint(writer, *paint, kSaveLayer_PaintUsage); 713 } 714 } 715 716 void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 717 size_t size = region.writeToMemory(nullptr); 718 unsigned extra = 0; 719 if (fits_in(size, 24)) { 720 extra = SkToUInt(size); 721 } 722 723 SkPipeWriter writer(this); 724 writer.write32(pack_verb(SkPipeVerb::kDrawRegion, extra)); 725 if (0 == extra) { 726 writer.write32(size); 727 } 728 SkAutoSMalloc<2048> storage(size); 729 region.writeToMemory(storage.get()); 730 write_pad(&writer, storage.get(), size); 731 write_paint(writer, paint, kGeometry_PaintUsage); 732 } 733 734 void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode, 735 const SkPaint& paint) { 736 unsigned extra = static_cast<unsigned>(bmode); 737 738 SkPipeWriter writer(this); 739 writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra)); 740 // TODO: dedup vertices? 741 writer.writeDataAsByteArray(vertices->encode().get()); 742 write_paint(writer, paint, kVertices_PaintUsage); 743 } 744 745 void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 746 const SkPoint texCoords[4], SkBlendMode bmode, 747 const SkPaint& paint) { 748 SkPipeWriter writer(this); 749 unsigned extra = 0; 750 SkASSERT(0 == ((int)bmode & ~kModeEnum_DrawPatchExtraMask)); 751 extra = (unsigned)bmode; 752 if (colors) { 753 extra |= kHasColors_DrawPatchExtraMask; 754 } 755 if (texCoords) { 756 extra |= kHasTexture_DrawPatchExtraMask; 757 } 758 writer.write32(pack_verb(SkPipeVerb::kDrawPatch, extra)); 759 writer.write(cubics, sizeof(SkPoint) * 12); 760 if (colors) { 761 writer.write(colors, sizeof(SkColor) * 4); 762 } 763 if (texCoords) { 764 writer.write(texCoords, sizeof(SkPoint) * 4); 765 } 766 write_paint(writer, paint, kGeometry_PaintUsage); 767 } 768 769 void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) { 770 const size_t len = strlen(key) + 1; // must write the trailing 0 771 bool compact = fits_in(len, 23); 772 uint32_t extra = compact ? (unsigned)len : 0; 773 extra <<= 1; // make room for has_data_sentinel 774 if (data) { 775 extra |= 1; 776 } 777 778 fStream->write32(pack_verb(SkPipeVerb::kDrawAnnotation, extra)); 779 fStream->write(&rect, sizeof(SkRect)); 780 if (!compact) { 781 fStream->write32(SkToU32(len)); 782 } 783 write_pad(fStream, key, len); 784 if (data) { 785 fStream->write32(SkToU32(data->size())); 786 write_pad(fStream, data->data(), data->size()); 787 } 788 } 789 790 /////////////////////////////////////////////////////////////////////////////////////////////////// 791 792 class A8Serializer : public SkPixelSerializer { 793 protected: 794 bool onUseEncodedData(const void* data, size_t len) { 795 return true; 796 } 797 798 SkData* onEncode(const SkPixmap& pmap) { 799 if (kAlpha_8_SkColorType == pmap.colorType()) { 800 SkDynamicMemoryWStream stream; 801 stream.write("skiaimgf", 8); 802 stream.write32(pmap.width()); 803 stream.write32(pmap.height()); 804 stream.write16(pmap.colorType()); 805 stream.write16(pmap.alphaType()); 806 stream.write32(0); // no colorspace for now 807 for (int y = 0; y < pmap.height(); ++y) { 808 stream.write(pmap.addr8(0, y), pmap.width()); 809 } 810 return stream.detachAsData().release(); 811 } 812 return nullptr; 813 } 814 }; 815 816 static sk_sp<SkData> default_image_serializer(SkImage* image) { 817 A8Serializer serial; 818 sk_sp<SkData> data(image->encode(&serial)); 819 if (!data) { 820 data.reset(image->encode()); 821 } 822 return data; 823 } 824 825 static bool show_deduper_traffic = false; 826 827 int SkPipeDeduper::findOrDefineImage(SkImage* image) { 828 int index = fImages.find(image->uniqueID()); 829 SkASSERT(index >= 0); 830 if (index) { 831 if (show_deduper_traffic) { 832 SkDebugf(" reuseImage(%d)\n", index - 1); 833 } 834 return index; 835 } 836 837 sk_sp<SkData> data = fIMSerializer ? fIMSerializer->serialize(image) 838 : default_image_serializer(image); 839 if (data) { 840 index = fImages.add(image->uniqueID()); 841 SkASSERT(index > 0); 842 SkASSERT(fits_in(index, 24)); 843 fStream->write32(pack_verb(SkPipeVerb::kDefineImage, index)); 844 845 uint32_t len = SkToU32(data->size()); 846 fStream->write32(SkAlign4(len)); 847 write_pad(fStream, data->data(), len); 848 849 if (show_deduper_traffic) { 850 int size = image->width() * image->height() << 2; 851 SkDebugf(" defineImage(%d) %d -> %d\n", index - 1, size, len); 852 } 853 return index; 854 } 855 SkDebugf("+++ failed to encode image [%d %d]\n", image->width(), image->height()); 856 return 0; // failed to encode 857 } 858 859 int SkPipeDeduper::findOrDefinePicture(SkPicture* picture) { 860 int index = fPictures.find(picture->uniqueID()); 861 SkASSERT(index >= 0); 862 if (index) { 863 if (show_deduper_traffic) { 864 SkDebugf(" reusePicture(%d)\n", index - 1); 865 } 866 return index; 867 } 868 869 size_t prevWritten = fStream->bytesWritten(); 870 unsigned extra = 0; // 0 means we're defining a new picture, non-zero means undef_index + 1 871 fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, extra)); 872 const SkRect cull = picture->cullRect(); 873 fStream->write(&cull, sizeof(cull)); 874 picture->playback(fPipeCanvas); 875 // call fPictures.add *after* we're written the picture, so that any nested pictures will have 876 // already been defined, and we get the "last" index value. 877 index = fPictures.add(picture->uniqueID()); 878 ASSERT_FITS_IN(index, kObjectDefinitionBits); 879 fStream->write32(pack_verb(SkPipeVerb::kEndPicture, index)); 880 881 if (show_deduper_traffic) { 882 SkDebugf(" definePicture(%d) %d\n", 883 index - 1, SkToU32(fStream->bytesWritten() - prevWritten)); 884 } 885 return index; 886 } 887 888 static sk_sp<SkData> encode(SkTypeface* tf) { 889 SkDynamicMemoryWStream stream; 890 tf->serialize(&stream); 891 return sk_sp<SkData>(stream.detachAsData()); 892 } 893 894 int SkPipeDeduper::findOrDefineTypeface(SkTypeface* typeface) { 895 if (!typeface) { 896 return 0; // default 897 } 898 899 int index = fTypefaces.find(typeface->uniqueID()); 900 SkASSERT(index >= 0); 901 if (index) { 902 if (show_deduper_traffic) { 903 SkDebugf(" reuseTypeface(%d)\n", index - 1); 904 } 905 return index; 906 } 907 908 sk_sp<SkData> data = fTFSerializer ? fTFSerializer->serialize(typeface) : encode(typeface); 909 if (data) { 910 index = fTypefaces.add(typeface->uniqueID()); 911 SkASSERT(index > 0); 912 SkASSERT(fits_in(index, 24)); 913 fStream->write32(pack_verb(SkPipeVerb::kDefineTypeface, index)); 914 915 uint32_t len = SkToU32(data->size()); 916 fStream->write32(SkAlign4(len)); 917 write_pad(fStream, data->data(), len); 918 919 if (show_deduper_traffic) { 920 SkDebugf(" defineTypeface(%d) %d\n", index - 1, len); 921 } 922 return index; 923 } 924 SkDebugf("+++ failed to encode typeface %d\n", typeface->uniqueID()); 925 return 0; // failed to encode 926 } 927 928 int SkPipeDeduper::findOrDefineFactory(SkFlattenable* flattenable) { 929 if (!flattenable) { 930 return 0; 931 } 932 933 int index = fFactories.find(flattenable->getFactory()); 934 SkASSERT(index >= 0); 935 if (index) { 936 if (show_deduper_traffic) { 937 SkDebugf(" reuseFactory(%d)\n", index - 1); 938 } 939 return index; 940 } 941 942 index = fFactories.add(flattenable->getFactory()); 943 ASSERT_FITS_IN(index, kIndex_DefineFactoryExtraBits); 944 const char* name = flattenable->getTypeName(); 945 size_t len = strlen(name); 946 ASSERT_FITS_IN(len, kNameLength_DefineFactoryExtraBits); 947 unsigned extra = (index << kNameLength_DefineFactoryExtraBits) | len; 948 size_t prevWritten = fStream->bytesWritten(); 949 fStream->write32(pack_verb(SkPipeVerb::kDefineFactory, extra)); 950 write_pad(fStream, name, len + 1); 951 if (false) { 952 SkDebugf(" defineFactory(%d) %d %s\n", 953 index - 1, SkToU32(fStream->bytesWritten() - prevWritten), name); 954 } 955 return index; 956 } 957 958 /////////////////////////////////////////////////////////////////////////////////////////////////// 959 #include "SkPipe.h" 960 961 class SkPipeSerializer::Impl { 962 public: 963 SkPipeDeduper fDeduper; 964 std::unique_ptr<SkPipeCanvas> fCanvas; 965 }; 966 967 SkPipeSerializer::SkPipeSerializer() : fImpl(new Impl) {} 968 969 SkPipeSerializer::~SkPipeSerializer() { 970 if (fImpl->fCanvas) { 971 this->endWrite(); 972 } 973 } 974 975 void SkPipeSerializer::setTypefaceSerializer(SkTypefaceSerializer* tfs) { 976 fImpl->fDeduper.setTypefaceSerializer(tfs); 977 } 978 979 void SkPipeSerializer::setImageSerializer(SkImageSerializer* ims) { 980 fImpl->fDeduper.setImageSerializer(ims); 981 } 982 983 void SkPipeSerializer::resetCache() { 984 fImpl->fDeduper.resetCaches(); 985 } 986 987 sk_sp<SkData> SkPipeSerializer::writeImage(SkImage* image) { 988 SkDynamicMemoryWStream stream; 989 this->writeImage(image, &stream); 990 return stream.detachAsData(); 991 } 992 993 sk_sp<SkData> SkPipeSerializer::writePicture(SkPicture* picture) { 994 SkDynamicMemoryWStream stream; 995 this->writePicture(picture, &stream); 996 return stream.detachAsData(); 997 } 998 999 void SkPipeSerializer::writePicture(SkPicture* picture, SkWStream* stream) { 1000 int index = fImpl->fDeduper.findPicture(picture); 1001 if (0 == index) { 1002 // Try to define the picture 1003 this->beginWrite(picture->cullRect(), stream); 1004 index = fImpl->fDeduper.findOrDefinePicture(picture); 1005 this->endWrite(); 1006 } 1007 stream->write32(pack_verb(SkPipeVerb::kWritePicture, index)); 1008 } 1009 1010 void SkPipeSerializer::writeImage(SkImage* image, SkWStream* stream) { 1011 int index = fImpl->fDeduper.findImage(image); 1012 if (0 == index) { 1013 // Try to define the image 1014 fImpl->fDeduper.setStream(stream); 1015 index = fImpl->fDeduper.findOrDefineImage(image); 1016 } 1017 stream->write32(pack_verb(SkPipeVerb::kWriteImage, index)); 1018 } 1019 1020 SkCanvas* SkPipeSerializer::beginWrite(const SkRect& cull, SkWStream* stream) { 1021 SkASSERT(nullptr == fImpl->fCanvas); 1022 fImpl->fCanvas.reset(new SkPipeCanvas(cull, &fImpl->fDeduper, stream)); 1023 fImpl->fDeduper.setStream(stream); 1024 fImpl->fDeduper.setCanvas(fImpl->fCanvas.get()); 1025 return fImpl->fCanvas.get(); 1026 } 1027 1028 void SkPipeSerializer::endWrite() { 1029 fImpl->fCanvas->restoreToCount(1); 1030 fImpl->fCanvas.reset(nullptr); 1031 fImpl->fDeduper.setCanvas(nullptr); 1032 } 1033