Home | History | Annotate | Download | only in pipe
      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     if (rec.fClipMask) {
    244         extra |= kHasClipMask_SaveLayerMask;
    245     }
    246     if (rec.fClipMatrix) {
    247         extra |= kHasClipMatrix_SaveLayerMask;
    248     }
    249 
    250     writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra));
    251     if (rec.fBounds) {
    252         writer.writeRect(*rec.fBounds);
    253     }
    254     if (rec.fPaint) {
    255         write_paint(writer, *rec.fPaint, kSaveLayer_PaintUsage);
    256     }
    257     if (rec.fBackdrop) {
    258         writer.writeFlattenable(rec.fBackdrop);
    259     }
    260     if (rec.fClipMask) {
    261         writer.writeImage(rec.fClipMask);
    262     }
    263     if (rec.fClipMatrix) {
    264         writer.writeMatrix(*rec.fClipMatrix);
    265     }
    266 
    267     return kNoLayer_SaveLayerStrategy;
    268 }
    269 
    270 void SkPipeCanvas::willRestore() {
    271     fStream->write32(pack_verb(SkPipeVerb::kRestore));
    272     this->INHERITED::willRestore();
    273 }
    274 
    275 template <typename T> void write_sparse_matrix(T* writer, const SkMatrix& matrix) {
    276     SkMatrix::TypeMask tm = matrix.getType();
    277     SkScalar tmp[9];
    278     if (tm & SkMatrix::kPerspective_Mask) {
    279         matrix.get9(tmp);
    280         writer->write(tmp, 9 * sizeof(SkScalar));
    281     } else if (tm & SkMatrix::kAffine_Mask) {
    282         tmp[0] = matrix[SkMatrix::kMScaleX];
    283         tmp[1] = matrix[SkMatrix::kMSkewX];
    284         tmp[2] = matrix[SkMatrix::kMTransX];
    285         tmp[3] = matrix[SkMatrix::kMScaleY];
    286         tmp[4] = matrix[SkMatrix::kMSkewY];
    287         tmp[5] = matrix[SkMatrix::kMTransY];
    288         writer->write(tmp, 6 * sizeof(SkScalar));
    289     } else if (tm & SkMatrix::kScale_Mask) {
    290         tmp[0] = matrix[SkMatrix::kMScaleX];
    291         tmp[1] = matrix[SkMatrix::kMTransX];
    292         tmp[2] = matrix[SkMatrix::kMScaleY];
    293         tmp[3] = matrix[SkMatrix::kMTransY];
    294         writer->write(tmp, 4 * sizeof(SkScalar));
    295     } else if (tm & SkMatrix::kTranslate_Mask) {
    296         tmp[0] = matrix[SkMatrix::kMTransX];
    297         tmp[1] = matrix[SkMatrix::kMTransY];
    298         writer->write(tmp, 2 * sizeof(SkScalar));
    299     }
    300     // else write nothing for Identity
    301 }
    302 
    303 static void do_concat(SkWStream* stream, const SkMatrix& matrix, bool isSetMatrix) {
    304     unsigned mtype = matrix.getType();
    305     SkASSERT(0 == (mtype & ~kTypeMask_ConcatMask));
    306     unsigned extra = mtype;
    307     if (isSetMatrix) {
    308         extra |= kSetMatrix_ConcatMask;
    309     }
    310     if (mtype || isSetMatrix) {
    311         stream->write32(pack_verb(SkPipeVerb::kConcat, extra));
    312         write_sparse_matrix(stream, matrix);
    313     }
    314 }
    315 
    316 void SkPipeCanvas::didConcat(const SkMatrix& matrix) {
    317     do_concat(fStream, matrix, false);
    318     this->INHERITED::didConcat(matrix);
    319 }
    320 
    321 void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) {
    322     do_concat(fStream, matrix, true);
    323     this->INHERITED::didSetMatrix(matrix);
    324 }
    325 
    326 void SkPipeCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    327     fStream->write32(pack_verb(SkPipeVerb::kClipRect, ((unsigned)op << 1) | edgeStyle));
    328     fStream->write(&rect, 4 * sizeof(SkScalar));
    329 
    330     this->INHERITED::onClipRect(rect, op, edgeStyle);
    331 }
    332 
    333 void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    334     fStream->write32(pack_verb(SkPipeVerb::kClipRRect, ((unsigned)op << 1) | edgeStyle));
    335     write_rrect(fStream, rrect);
    336 
    337     this->INHERITED::onClipRRect(rrect, op, edgeStyle);
    338 }
    339 
    340 void SkPipeCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
    341     SkPipeWriter writer(this);
    342     writer.write32(pack_verb(SkPipeVerb::kClipPath, ((unsigned)op << 1) | edgeStyle));
    343     writer.writePath(path);
    344 
    345     this->INHERITED::onClipPath(path, op, edgeStyle);
    346 }
    347 
    348 void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    349     SkPipeWriter writer(this);
    350     writer.write32(pack_verb(SkPipeVerb::kClipRegion, (unsigned)op << 1));
    351     writer.writeRegion(deviceRgn);
    352 
    353     this->INHERITED::onClipRegion(deviceRgn, op);
    354 }
    355 
    356 ///////////////////////////////////////////////////////////////////////////////////////////////////
    357 
    358 void SkPipeCanvas::onDrawArc(const SkRect& bounds, SkScalar startAngle, SkScalar sweepAngle,
    359                              bool useCenter, const SkPaint& paint) {
    360     SkPipeWriter writer(this);
    361     writer.write32(pack_verb(SkPipeVerb::kDrawArc, (int)useCenter));
    362     writer.writeRect(bounds);
    363     writer.writeScalar(startAngle);
    364     writer.writeScalar(sweepAngle);
    365     write_paint(writer, paint, kGeometry_PaintUsage);
    366 }
    367 
    368 void SkPipeCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect rect[],
    369                                const SkColor colors[], int count, SkBlendMode mode,
    370                                const SkRect* cull, const SkPaint* paint) {
    371     unsigned extra = (unsigned)mode;
    372     SkASSERT(0 == (extra & ~kMode_DrawAtlasMask));
    373     if (colors) {
    374         extra |= kHasColors_DrawAtlasMask;
    375     }
    376     if (cull) {
    377         extra |= kHasCull_DrawAtlasMask;
    378     }
    379     if (paint) {
    380         extra |= kHasPaint_DrawAtlasMask;
    381     }
    382 
    383     SkPipeWriter writer(this);
    384     writer.write32(pack_verb(SkPipeVerb::kDrawAtlas, extra));
    385     writer.writeImage(image);
    386     writer.write32(count);
    387     writer.write(xform, count * sizeof(SkRSXform));
    388     writer.write(rect, count * sizeof(SkRect));
    389     if (colors) {
    390         writer.write(colors, count * sizeof(SkColor));
    391     }
    392     if (cull) {
    393         writer.writeRect(*cull);
    394     }
    395     if (paint) {
    396         write_paint(writer, *paint, kImage_PaintUsage);
    397     }
    398 }
    399 
    400 void SkPipeCanvas::onDrawPaint(const SkPaint& paint) {
    401     SkPipeWriter writer(this);
    402     writer.write32(pack_verb(SkPipeVerb::kDrawPaint));
    403     write_paint(writer, paint, kDrawPaint_PaintUsage);
    404 }
    405 
    406 void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
    407                                 const SkPaint& paint) {
    408     SkPipeWriter writer(this);
    409     writer.write32(pack_verb(SkPipeVerb::kDrawPoints, mode));
    410     writer.write32(SkToU32(count));
    411     writer.write(pts, count * sizeof(SkPoint));
    412     write_paint(writer, paint, kGeometry_PaintUsage | kRespectsStroke_PaintUsage);
    413 }
    414 
    415 void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    416     SkPipeWriter writer(this);
    417     writer.write32(pack_verb(SkPipeVerb::kDrawRect));
    418     writer.write(&rect, sizeof(SkRect));
    419     write_paint(writer, paint, kGeometry_PaintUsage);
    420 }
    421 
    422 void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
    423     SkPipeWriter writer(this);
    424     writer.write32(pack_verb(SkPipeVerb::kDrawOval));
    425     writer.write(&rect, sizeof(SkRect));
    426     write_paint(writer, paint, kGeometry_PaintUsage);
    427 }
    428 
    429 void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    430     SkPipeWriter writer(this);
    431     writer.write32(pack_verb(SkPipeVerb::kDrawRRect));
    432     write_rrect(&writer, rrect);
    433     write_paint(writer, paint, kGeometry_PaintUsage);
    434 }
    435 
    436 void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
    437     SkPipeWriter writer(this);
    438     writer.write32(pack_verb(SkPipeVerb::kDrawDRRect));
    439     write_rrect(&writer, outer);
    440     write_rrect(&writer, inner);
    441     write_paint(writer, paint, kGeometry_PaintUsage);
    442 }
    443 
    444 void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    445     SkPipeWriter writer(this);
    446     writer.write32(pack_verb(SkPipeVerb::kDrawPath));
    447     writer.writePath(path);
    448     write_paint(writer, paint, kGeometry_PaintUsage);
    449 }
    450 
    451 ///////////////////////////////////////////////////////////////////////////////////////////////////
    452 
    453 static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) {
    454     // If we just "make" an image, it will force a CPU copy (if its mutable), only to have
    455     // us then either find it in our cache, or compress and send it.
    456     //
    457     // Better could be to look it up in our cache first, and only create/compress it if we have to.
    458     //
    459     // But for now, just do the dumb thing...
    460     return SkImage::MakeFromBitmap(bitmap);
    461 }
    462 
    463 void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
    464                                 const SkPaint* paint) {
    465     sk_sp<SkImage> image = make_from_bitmap(bitmap);
    466     if (image) {
    467         this->onDrawImage(image.get(), x, y, paint);
    468     }
    469 }
    470 
    471 void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
    472                                     const SkPaint* paint, SrcRectConstraint constraint) {
    473     sk_sp<SkImage> image = make_from_bitmap(bitmap);
    474     if (image) {
    475         this->onDrawImageRect(image.get(), src, dst, paint, constraint);
    476     }
    477 }
    478 
    479 void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
    480                                     const SkRect& dst, const SkPaint* paint) {
    481     sk_sp<SkImage> image = make_from_bitmap(bitmap);
    482     if (image) {
    483         this->onDrawImageNine(image.get(), center, dst, paint);
    484     }
    485 }
    486 
    487 void SkPipeCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
    488                                        const SkRect& dst, const SkPaint* paint) {
    489     sk_sp<SkImage> image = make_from_bitmap(bitmap);
    490     if (image) {
    491         this->onDrawImageLattice(image.get(), lattice, dst, paint);
    492     }
    493 }
    494 
    495 ///////////////////////////////////////////////////////////////////////////////////////////////////
    496 
    497 void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
    498                                const SkPaint* paint) {
    499     unsigned extra = 0;
    500     if (paint) {
    501         extra |= kHasPaint_DrawImageMask;
    502     }
    503     SkPipeWriter writer(this);
    504     writer.write32(pack_verb(SkPipeVerb::kDrawImage, extra));
    505     writer.writeImage(image);
    506     writer.writeScalar(left);
    507     writer.writeScalar(top);
    508     if (paint) {
    509         write_paint(writer, *paint, kImage_PaintUsage);
    510     }
    511 }
    512 
    513 void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
    514                                    const SkPaint* paint, SrcRectConstraint constraint) {
    515     SkASSERT(0 == ((unsigned)constraint & ~1));
    516     unsigned extra = (unsigned)constraint;
    517     if (paint) {
    518         extra |= kHasPaint_DrawImageRectMask;
    519     }
    520     if (src) {
    521         extra |= kHasSrcRect_DrawImageRectMask;
    522     }
    523 
    524     SkPipeWriter writer(this);
    525     writer.write32(pack_verb(SkPipeVerb::kDrawImageRect, extra));
    526     writer.writeImage(image);
    527     if (src) {
    528         writer.write(src, sizeof(*src));
    529     }
    530     writer.write(&dst, sizeof(dst));
    531     if (paint) {
    532         write_paint(writer, *paint, kImage_PaintUsage);
    533     }
    534 }
    535 
    536 void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
    537                                    const SkPaint* paint) {
    538     unsigned extra = 0;
    539     if (paint) {
    540         extra |= kHasPaint_DrawImageNineMask;
    541     }
    542     SkPipeWriter writer(this);
    543     writer.write32(pack_verb(SkPipeVerb::kDrawImageNine, extra));
    544     writer.writeImage(image);
    545     writer.write(&center, sizeof(center));
    546     writer.write(&dst, sizeof(dst));
    547     if (paint) {
    548         write_paint(writer, *paint, kImage_PaintUsage);
    549     }
    550 }
    551 
    552 void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
    553                                       const SkRect& dst, const SkPaint* paint) {
    554     unsigned extra = 0;
    555     if (paint) {
    556         extra |= kHasPaint_DrawImageLatticeMask;
    557     }
    558     if (lattice.fFlags) {
    559         extra |= kHasFlags_DrawImageLatticeMask;
    560     }
    561     if (lattice.fXCount >= kCount_DrawImageLatticeMask) {
    562         extra |= kCount_DrawImageLatticeMask << kXCount_DrawImageLatticeShift;
    563     } else {
    564         extra |= lattice.fXCount << kXCount_DrawImageLatticeShift;
    565     }
    566     if (lattice.fYCount >= kCount_DrawImageLatticeMask) {
    567         extra |= kCount_DrawImageLatticeMask << kYCount_DrawImageLatticeShift;
    568     } else {
    569         extra |= lattice.fYCount << kYCount_DrawImageLatticeShift;
    570     }
    571 
    572     SkPipeWriter writer(this);
    573     writer.write32(pack_verb(SkPipeVerb::kDrawImageLattice, extra));
    574     writer.writeImage(image);
    575     if (lattice.fXCount >= kCount_DrawImageLatticeMask) {
    576         writer.write32(lattice.fXCount);
    577     }
    578     if (lattice.fYCount >= kCount_DrawImageLatticeMask) {
    579         writer.write32(lattice.fYCount);
    580     }
    581     // Often these divs will be small (8 or 16 bits). Consider sniffing that and writing a flag
    582     // so we can store them smaller.
    583     writer.write(lattice.fXDivs, lattice.fXCount * sizeof(int32_t));
    584     writer.write(lattice.fYDivs, lattice.fYCount * sizeof(int32_t));
    585     if (lattice.fFlags) {
    586         int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
    587         SkASSERT(count > 0);
    588         write_pad(&writer, lattice.fFlags, count);
    589     }
    590     SkASSERT(lattice.fBounds);
    591     writer.write(&lattice.fBounds, sizeof(*lattice.fBounds));
    592     writer.write(&dst, sizeof(dst));
    593     if (paint) {
    594         write_paint(writer, *paint, kImage_PaintUsage);
    595     }
    596 }
    597 
    598 ///////////////////////////////////////////////////////////////////////////////////////////////////
    599 
    600 void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
    601                               const SkPaint& paint) {
    602     SkASSERT(byteLength);
    603 
    604     bool compact = fits_in(byteLength, 24);
    605 
    606     SkPipeWriter writer(this);
    607     writer.write32(pack_verb(SkPipeVerb::kDrawText, compact ? (unsigned)byteLength : 0));
    608     if (!compact) {
    609         writer.write32(SkToU32(byteLength));
    610     }
    611     write_pad(&writer, text, byteLength);
    612     writer.writeScalar(x);
    613     writer.writeScalar(y);
    614     write_paint(writer, paint, kText_PaintUsage);
    615 }
    616 
    617 void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
    618                                  const SkPaint& paint) {
    619     SkASSERT(byteLength);
    620 
    621     bool compact = fits_in(byteLength, 24);
    622 
    623     SkPipeWriter writer(this);
    624     writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteLength : 0));
    625     if (!compact) {
    626         writer.write32(SkToU32(byteLength));
    627     }
    628     write_pad(&writer, text, byteLength);
    629     writer.writePointArray(pos, paint.countText(text, byteLength));
    630     write_paint(writer, paint, kText_PaintUsage);
    631 }
    632 
    633 void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
    634                                   SkScalar constY, const SkPaint& paint) {
    635     SkASSERT(byteLength);
    636 
    637     bool compact = fits_in(byteLength, 24);
    638 
    639     SkPipeWriter writer(this);
    640     writer.write32(pack_verb(SkPipeVerb::kDrawPosTextH, compact ? (unsigned)byteLength : 0));
    641     if (!compact) {
    642         writer.write32(SkToU32(byteLength));
    643     }
    644     write_pad(&writer, text, byteLength);
    645     writer.writeScalarArray(xpos, paint.countText(text, byteLength));
    646     writer.writeScalar(constY);
    647     write_paint(writer, paint, kText_PaintUsage);
    648 }
    649 
    650 void SkPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
    651                                     const SkMatrix* matrix, const SkPaint& paint) {
    652     SkASSERT(byteLength > 0);
    653 
    654     unsigned extra = 0;
    655     if (byteLength <= kTextLength_DrawTextOnPathMask) {
    656         extra |= byteLength;
    657     } // else we will write the length after the packedverb
    658     SkMatrix::TypeMask tm = matrix ? matrix->getType() : SkMatrix::kIdentity_Mask;
    659     extra |= (unsigned)tm << kMatrixType_DrawTextOnPathShift;
    660 
    661     SkPipeWriter writer(this);
    662     writer.write32(pack_verb(SkPipeVerb::kDrawTextOnPath, extra));
    663     if (byteLength > kTextLength_DrawTextOnPathMask) {
    664         writer.write32(byteLength);
    665     }
    666     write_pad(&writer, text, byteLength);
    667     writer.writePath(path);
    668     if (matrix) {
    669         write_sparse_matrix(&writer, *matrix);
    670     }
    671     write_paint(writer, paint, kText_PaintUsage);
    672 }
    673 
    674 void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
    675                                      const SkRect* cull, const SkPaint& paint) {
    676     SkASSERT(byteLength);
    677 
    678     bool compact = fits_in(byteLength, 23);
    679     unsigned extra = compact ? (byteLength << 1) : 0;
    680     if (cull) {
    681         extra |= 1;
    682     }
    683 
    684     SkPipeWriter writer(this);
    685     writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra));
    686     if (!compact) {
    687         writer.write32(SkToU32(byteLength));
    688     }
    689     write_pad(&writer, text, byteLength);
    690 
    691     int count = paint.countText(text, byteLength);
    692     writer.write32(count);  // maybe we can/should store this in extra as well?
    693     writer.write(xform, count * sizeof(SkRSXform));
    694     if (cull) {
    695         writer.writeRect(*cull);
    696     }
    697     write_paint(writer, paint, kText_PaintUsage);
    698 }
    699 
    700 void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
    701                                   const SkPaint &paint) {
    702     SkPipeWriter writer(this);
    703     writer.write32(pack_verb(SkPipeVerb::kDrawTextBlob, 0));
    704     blob->flatten(writer);
    705     writer.writeScalar(x);
    706     writer.writeScalar(y);
    707     write_paint(writer, paint, kTextBlob_PaintUsage);
    708 }
    709 
    710 void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
    711                                  const SkPaint* paint) {
    712     unsigned extra = fDeduper->findOrDefinePicture(const_cast<SkPicture*>(picture));
    713     if (matrix) {
    714         extra |= kHasMatrix_DrawPictureExtra;
    715     }
    716     if (paint) {
    717         extra |= kHasPaint_DrawPictureExtra;
    718     }
    719     SkPipeWriter writer(this);
    720     writer.write32(pack_verb(SkPipeVerb::kDrawPicture, extra));
    721     if (matrix) {
    722         writer.writeMatrix(*matrix);
    723     }
    724     if (paint) {
    725         write_paint(writer, *paint, kSaveLayer_PaintUsage);
    726     }
    727 }
    728 
    729 void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
    730     size_t size = region.writeToMemory(nullptr);
    731     unsigned extra = 0;
    732     if (fits_in(size, 24)) {
    733         extra = SkToUInt(size);
    734     }
    735 
    736     SkPipeWriter writer(this);
    737     writer.write32(pack_verb(SkPipeVerb::kDrawRegion, extra));
    738     if (0 == extra) {
    739         writer.write32(size);
    740     }
    741     SkAutoSMalloc<2048> storage(size);
    742     region.writeToMemory(storage.get());
    743     write_pad(&writer, storage.get(), size);
    744     write_paint(writer, paint, kGeometry_PaintUsage);
    745 }
    746 
    747 void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, SkBlendMode bmode,
    748                                         const SkPaint& paint) {
    749     unsigned extra = static_cast<unsigned>(bmode);
    750 
    751     SkPipeWriter writer(this);
    752     writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra));
    753     // TODO: dedup vertices?
    754     writer.writeDataAsByteArray(vertices->encode().get());
    755     write_paint(writer, paint, kVertices_PaintUsage);
    756 }
    757 
    758 void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
    759                                const SkPoint texCoords[4], SkBlendMode bmode,
    760                                const SkPaint& paint) {
    761     SkPipeWriter writer(this);
    762     unsigned extra = 0;
    763     SkASSERT(0 == ((int)bmode & ~kModeEnum_DrawPatchExtraMask));
    764     extra = (unsigned)bmode;
    765     if (colors) {
    766         extra |= kHasColors_DrawPatchExtraMask;
    767     }
    768     if (texCoords) {
    769         extra |= kHasTexture_DrawPatchExtraMask;
    770     }
    771     writer.write32(pack_verb(SkPipeVerb::kDrawPatch, extra));
    772     writer.write(cubics, sizeof(SkPoint) * 12);
    773     if (colors) {
    774         writer.write(colors, sizeof(SkColor) * 4);
    775     }
    776     if (texCoords) {
    777         writer.write(texCoords, sizeof(SkPoint) * 4);
    778     }
    779     write_paint(writer, paint, kGeometry_PaintUsage);
    780 }
    781 
    782 void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
    783     const size_t len = strlen(key) + 1; // must write the trailing 0
    784     bool compact = fits_in(len, 23);
    785     uint32_t extra = compact ? (unsigned)len : 0;
    786     extra <<= 1;   // make room for has_data_sentinel
    787     if (data) {
    788         extra |= 1;
    789     }
    790 
    791     fStream->write32(pack_verb(SkPipeVerb::kDrawAnnotation, extra));
    792     fStream->write(&rect, sizeof(SkRect));
    793     if (!compact) {
    794         fStream->write32(SkToU32(len));
    795     }
    796     write_pad(fStream, key, len);
    797     if (data) {
    798         fStream->write32(SkToU32(data->size()));
    799         write_pad(fStream, data->data(), data->size());
    800     }
    801 }
    802 
    803 ///////////////////////////////////////////////////////////////////////////////////////////////////
    804 
    805 class A8Serializer : public SkPixelSerializer {
    806 protected:
    807     bool onUseEncodedData(const void* data, size_t len) {
    808         return true;
    809     }
    810 
    811     SkData* onEncode(const SkPixmap& pmap) {
    812         if (kAlpha_8_SkColorType == pmap.colorType()) {
    813             SkDynamicMemoryWStream stream;
    814             stream.write("skiaimgf", 8);
    815             stream.write32(pmap.width());
    816             stream.write32(pmap.height());
    817             stream.write16(pmap.colorType());
    818             stream.write16(pmap.alphaType());
    819             stream.write32(0);  // no colorspace for now
    820             for (int y = 0; y < pmap.height(); ++y) {
    821                 stream.write(pmap.addr8(0, y), pmap.width());
    822             }
    823             return stream.detachAsData().release();
    824         }
    825         return nullptr;
    826     }
    827 };
    828 
    829 static sk_sp<SkData> default_image_serializer(SkImage* image) {
    830     A8Serializer serial;
    831     sk_sp<SkData> data = image->encodeToData(&serial);
    832     if (!data) {
    833         data = image->encodeToData();
    834     }
    835     return data;
    836 }
    837 
    838 static bool show_deduper_traffic = false;
    839 
    840 int SkPipeDeduper::findOrDefineImage(SkImage* image) {
    841     int index = fImages.find(image->uniqueID());
    842     SkASSERT(index >= 0);
    843     if (index) {
    844         if (show_deduper_traffic) {
    845             SkDebugf("  reuseImage(%d)\n", index - 1);
    846         }
    847         return index;
    848     }
    849 
    850     sk_sp<SkData> data = fIMSerializer ? fIMSerializer->serialize(image)
    851                                        : default_image_serializer(image);
    852     if (data) {
    853         index = fImages.add(image->uniqueID());
    854         SkASSERT(index > 0);
    855         SkASSERT(fits_in(index, 24));
    856         fStream->write32(pack_verb(SkPipeVerb::kDefineImage, index));
    857 
    858         uint32_t len = SkToU32(data->size());
    859         fStream->write32(SkAlign4(len));
    860         write_pad(fStream, data->data(), len);
    861 
    862         if (show_deduper_traffic) {
    863             int size = image->width() * image->height() << 2;
    864             SkDebugf("  defineImage(%d) %d -> %d\n", index - 1, size, len);
    865         }
    866         return index;
    867     }
    868     SkDebugf("+++ failed to encode image [%d %d]\n", image->width(), image->height());
    869     return 0;   // failed to encode
    870 }
    871 
    872 int SkPipeDeduper::findOrDefinePicture(SkPicture* picture) {
    873     int index = fPictures.find(picture->uniqueID());
    874     SkASSERT(index >= 0);
    875     if (index) {
    876         if (show_deduper_traffic) {
    877             SkDebugf("  reusePicture(%d)\n", index - 1);
    878         }
    879         return index;
    880     }
    881 
    882     size_t prevWritten = fStream->bytesWritten();
    883     unsigned extra = 0; // 0 means we're defining a new picture, non-zero means undef_index + 1
    884     fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, extra));
    885     const SkRect cull = picture->cullRect();
    886     fStream->write(&cull, sizeof(cull));
    887     picture->playback(fPipeCanvas);
    888     // call fPictures.add *after* we're written the picture, so that any nested pictures will have
    889     // already been defined, and we get the "last" index value.
    890     index = fPictures.add(picture->uniqueID());
    891     ASSERT_FITS_IN(index, kObjectDefinitionBits);
    892     fStream->write32(pack_verb(SkPipeVerb::kEndPicture, index));
    893 
    894     if (show_deduper_traffic) {
    895         SkDebugf("  definePicture(%d) %d\n",
    896                  index - 1, SkToU32(fStream->bytesWritten() - prevWritten));
    897     }
    898     return index;
    899 }
    900 
    901 static sk_sp<SkData> encode(SkTypeface* tf) {
    902     SkDynamicMemoryWStream stream;
    903     tf->serialize(&stream);
    904     return sk_sp<SkData>(stream.detachAsData());
    905 }
    906 
    907 int SkPipeDeduper::findOrDefineTypeface(SkTypeface* typeface) {
    908     if (!typeface) {
    909         return 0;   // default
    910     }
    911 
    912     int index = fTypefaces.find(typeface->uniqueID());
    913     SkASSERT(index >= 0);
    914     if (index) {
    915         if (show_deduper_traffic) {
    916             SkDebugf("  reuseTypeface(%d)\n", index - 1);
    917         }
    918         return index;
    919     }
    920 
    921     sk_sp<SkData> data = fTFSerializer ? fTFSerializer->serialize(typeface) : encode(typeface);
    922     if (data) {
    923         index = fTypefaces.add(typeface->uniqueID());
    924         SkASSERT(index > 0);
    925         SkASSERT(fits_in(index, 24));
    926         fStream->write32(pack_verb(SkPipeVerb::kDefineTypeface, index));
    927 
    928         uint32_t len = SkToU32(data->size());
    929         fStream->write32(SkAlign4(len));
    930         write_pad(fStream, data->data(), len);
    931 
    932         if (show_deduper_traffic) {
    933             SkDebugf("  defineTypeface(%d) %d\n", index - 1, len);
    934         }
    935         return index;
    936     }
    937     SkDebugf("+++ failed to encode typeface %d\n", typeface->uniqueID());
    938     return 0;   // failed to encode
    939 }
    940 
    941 int SkPipeDeduper::findOrDefineFactory(SkFlattenable* flattenable) {
    942     if (!flattenable) {
    943         return 0;
    944     }
    945 
    946     int index = fFactories.find(flattenable->getFactory());
    947     SkASSERT(index >= 0);
    948     if (index) {
    949         if (show_deduper_traffic) {
    950             SkDebugf("  reuseFactory(%d)\n", index - 1);
    951         }
    952         return index;
    953     }
    954 
    955     index = fFactories.add(flattenable->getFactory());
    956     ASSERT_FITS_IN(index, kIndex_DefineFactoryExtraBits);
    957     const char* name = flattenable->getTypeName();
    958     size_t len = strlen(name);
    959     ASSERT_FITS_IN(len, kNameLength_DefineFactoryExtraBits);
    960     unsigned extra = (index << kNameLength_DefineFactoryExtraBits) | len;
    961     size_t prevWritten = fStream->bytesWritten();
    962     fStream->write32(pack_verb(SkPipeVerb::kDefineFactory, extra));
    963     write_pad(fStream, name, len + 1);
    964     if (false) {
    965         SkDebugf("  defineFactory(%d) %d %s\n",
    966              index - 1, SkToU32(fStream->bytesWritten() - prevWritten), name);
    967     }
    968     return index;
    969 }
    970 
    971 ///////////////////////////////////////////////////////////////////////////////////////////////////
    972 #include "SkPipe.h"
    973 
    974 class SkPipeSerializer::Impl {
    975 public:
    976     SkPipeDeduper   fDeduper;
    977     std::unique_ptr<SkPipeCanvas> fCanvas;
    978 };
    979 
    980 SkPipeSerializer::SkPipeSerializer() : fImpl(new Impl) {}
    981 
    982 SkPipeSerializer::~SkPipeSerializer() {
    983     if (fImpl->fCanvas) {
    984         this->endWrite();
    985     }
    986 }
    987 
    988 void SkPipeSerializer::setTypefaceSerializer(SkTypefaceSerializer* tfs) {
    989     fImpl->fDeduper.setTypefaceSerializer(tfs);
    990 }
    991 
    992 void SkPipeSerializer::setImageSerializer(SkImageSerializer* ims) {
    993     fImpl->fDeduper.setImageSerializer(ims);
    994 }
    995 
    996 void SkPipeSerializer::resetCache() {
    997     fImpl->fDeduper.resetCaches();
    998 }
    999 
   1000 sk_sp<SkData> SkPipeSerializer::writeImage(SkImage* image) {
   1001     SkDynamicMemoryWStream stream;
   1002     this->writeImage(image, &stream);
   1003     return stream.detachAsData();
   1004 }
   1005 
   1006 sk_sp<SkData> SkPipeSerializer::writePicture(SkPicture* picture) {
   1007     SkDynamicMemoryWStream stream;
   1008     this->writePicture(picture, &stream);
   1009     return stream.detachAsData();
   1010 }
   1011 
   1012 void SkPipeSerializer::writePicture(SkPicture* picture, SkWStream* stream) {
   1013     int index = fImpl->fDeduper.findPicture(picture);
   1014     if (0 == index) {
   1015         // Try to define the picture
   1016         this->beginWrite(picture->cullRect(), stream);
   1017         index = fImpl->fDeduper.findOrDefinePicture(picture);
   1018         this->endWrite();
   1019     }
   1020     stream->write32(pack_verb(SkPipeVerb::kWritePicture, index));
   1021 }
   1022 
   1023 void SkPipeSerializer::writeImage(SkImage* image, SkWStream* stream) {
   1024     int index = fImpl->fDeduper.findImage(image);
   1025     if (0 == index) {
   1026         // Try to define the image
   1027         fImpl->fDeduper.setStream(stream);
   1028         index = fImpl->fDeduper.findOrDefineImage(image);
   1029     }
   1030     stream->write32(pack_verb(SkPipeVerb::kWriteImage, index));
   1031 }
   1032 
   1033 SkCanvas* SkPipeSerializer::beginWrite(const SkRect& cull, SkWStream* stream) {
   1034     SkASSERT(nullptr == fImpl->fCanvas);
   1035     fImpl->fCanvas.reset(new SkPipeCanvas(cull, &fImpl->fDeduper, stream));
   1036     fImpl->fDeduper.setStream(stream);
   1037     fImpl->fDeduper.setCanvas(fImpl->fCanvas.get());
   1038     return fImpl->fCanvas.get();
   1039 }
   1040 
   1041 void SkPipeSerializer::endWrite() {
   1042     fImpl->fCanvas->restoreToCount(1);
   1043     fImpl->fCanvas.reset(nullptr);
   1044     fImpl->fDeduper.setCanvas(nullptr);
   1045 }
   1046