/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPipeCanvas.h"

#include "SkAutoMalloc.h"
#include "SkCanvasPriv.h"
#include "SkColorFilter.h"
#include "SkDrawLooper.h"
#include "SkDrawShadowInfo.h"
#include "SkDrawable.h"
#include "SkImageFilter.h"
#include "SkMaskFilter.h"
#include "SkPathEffect.h"
#include "SkPipeFormat.h"
#include "SkRSXform.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTextBlobPriv.h"
#include "SkTo.h"
#include "SkTypeface.h"

template <typename T> void write_rrect(T* writer, const SkRRect& rrect) {
    char tmp[SkRRect::kSizeInMemory];
    rrect.writeToMemory(tmp);
    writer->write(tmp, SkRRect::kSizeInMemory);
}

template <typename T> void write_pad(T* writer, const void* buffer, size_t len) {
    writer->write(buffer, len & ~3);
    if (len & 3) {
        const char* src = (const char*)buffer + (len & ~3);
        len &= 3;
        uint32_t tmp = 0;
        memcpy(&tmp, src, len);
        writer->write(&tmp, 4);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) {
    // kRespectsStroke_PaintUsage is only valid if other bits are also set
    SkASSERT(0 != (usage & ~kRespectsStroke_PaintUsage));

    const SkScalar kTextSize_Default    = 12;
    const SkScalar kTextScaleX_Default  = 1;
    const SkScalar kTextSkewX_Default   = 0;
    const SkScalar kStrokeWidth_Default = 0;
    const SkScalar kStrokeMiter_Default = 4;
    const SkColor  kColor_Default       = SK_ColorBLACK;

    unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0;

    if (usage & kText_PaintUsage) {
        bits |= (paint.getTextSize() != kTextSize_Default       ? kTextSize_NonDef : 0);
        bits |= (paint.getTextScaleX() != kTextScaleX_Default   ? kTextScaleX_NonDef : 0);
        bits |= (paint.getTextSkewX() != kTextSkewX_Default     ? kTextSkewX_NonDef : 0);
        bits |= (paint.getTypeface()                            ? kTypeface_NonDef : 0);
    }

    // TODO: kImage_PaintUsage only needs the shader/maskfilter IF its colortype is kAlpha_8

    if (usage & (kVertices_PaintUsage | kDrawPaint_PaintUsage | kImage_PaintUsage |
                 kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) {
        bits |= (paint.getShader()      ? kShader_NonDef : 0);
    }

    if (usage & (kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) {
        bits |= (paint.getPathEffect()  ? kPathEffect_NonDef : 0);

        if (paint.getStyle() != SkPaint::kFill_Style || (usage & kRespectsStroke_PaintUsage)) {
            bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWidth_NonDef : 0);
            bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMiter_NonDef : 0);
        }
    }

    if (usage &
        (kText_PaintUsage | kGeometry_PaintUsage | kImage_PaintUsage | kTextBlob_PaintUsage))
    {
        bits |= (paint.getMaskFilter()  ? kMaskFilter_NonDef : 0);
    }

    bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0);
    bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0);
    bits |= (paint.getDrawLooper()  ? kDrawLooper_NonDef : 0);

    return SkToU16(bits);
}

static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align,
                                 unsigned filter, unsigned style, unsigned caps, unsigned joins,
                                 unsigned encoding) {
    SkASSERT(kFlags_BPF + kHint_BPF + kAlign_BPF + kFilter_BPF <= 32);

    ASSERT_FITS_IN(flags, kFlags_BPF);
    ASSERT_FITS_IN(filter, kFilter_BPF);
    ASSERT_FITS_IN(style, kStyle_BPF);
    ASSERT_FITS_IN(caps, kCaps_BPF);
    ASSERT_FITS_IN(joins, kJoins_BPF);
    ASSERT_FITS_IN(hint, kHint_BPF);
    ASSERT_FITS_IN(align, kAlign_BPF);
    ASSERT_FITS_IN(encoding, kEncoding_BPF);

    // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly
    // add more bits in the future.

    uint32_t packed = 0;
    int shift = 32;

    shift -= kFlags_BPF;    packed |= (flags << shift);
    shift -= kFilter_BPF;   packed |= (filter << shift);
    shift -= kStyle_BPF;    packed |= (style << shift);
    // these are only needed for stroking (geometry or text)
    shift -= kCaps_BPF;     packed |= (caps << shift);
    shift -= kJoins_BPF;    packed |= (joins << shift);
    // these are only needed for text
    shift -= kHint_BPF;     packed |= (hint << shift);
    shift -= kAlign_BPF;    packed |= (align << shift);
    shift -= kEncoding_BPF; packed |= (encoding << shift);

    return packed;
}

#define CHECK_WRITE_SCALAR(writer, nondef, paint, Field)    \
    do { if (nondef & (k##Field##_NonDef)) {                \
        writer.writeScalar(paint.get##Field());             \
    }} while (0)

#define CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Field)   \
    do { if (nondef & (k##Field##_NonDef)) {                    \
        SkFlattenable* f = paint.get##Field();                  \
        SkASSERT(f != nullptr);                                 \
        writer.writeFlattenable(f);                             \
    } } while (0)

/*
 *  Header:
 *      paint flags     : 32
 *      non_def bits    : 16
 *      xfermode enum   : 8
 *      pad zeros       : 8
 */
static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, unsigned usage) {
    uint32_t packedFlags = pack_paint_flags(paint.getFlags(), paint.getHinting(),
                                            paint.getTextAlign(), paint.getFilterQuality(),
                                            paint.getStyle(), paint.getStrokeCap(),
                                            paint.getStrokeJoin(), paint.getTextEncoding());
    writer.write32(packedFlags);

    unsigned nondef = compute_nondef(paint, (PaintUsage)usage);
    const uint8_t pad = 0;
    writer.write32((nondef << 16) | ((unsigned)paint.getBlendMode() << 8) | pad);

    CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize);
    CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX);
    CHECK_WRITE_SCALAR(writer, nondef, paint, TextSkewX);
    CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeWidth);
    CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeMiter);

    if (nondef & kColor_NonDef) {
        writer.write32(paint.getColor());
    }
    if (nondef & kTypeface_NonDef) {
        // TODO: explore idea of writing bits indicating "use the prev (or prev N) face"
        // e.g. 1-N bits is an index into a ring buffer of typefaces
        SkTypeface* tf = paint.getTypeface();
        SkASSERT(tf);
        writer.writeTypeface(tf);
    }

    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, PathEffect);
    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Shader);
    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, MaskFilter);
    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ColorFilter);
    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ImageFilter);
    CHECK_WRITE_FLATTENABLE(writer, nondef, paint, DrawLooper);
}

class SkPipeWriter : public SkBinaryWriteBuffer {
    enum {
        N = 1024/4,
    };
    uint32_t fStorage[N];
    SkWStream* fStream;

public:
    SkPipeWriter(SkWStream* stream, SkDeduper* deduper)
        : SkBinaryWriteBuffer(fStorage, sizeof(fStorage))
        , fStream(stream)
    {
        this->setDeduper(deduper);
    }

    SkPipeWriter(SkPipeCanvas* pc) : SkPipeWriter(pc->fStream, pc->fDeduper) {}

    ~SkPipeWriter() override {
        SkASSERT(SkIsAlign4(fStream->bytesWritten()));
        this->writeToStream(fStream);
    }

    void writePaint(const SkPaint& paint) override {
        write_paint(*this, paint, kUnknown_PaintUsage);
    }
};

///////////////////////////////////////////////////////////////////////////////////////////////////

SkPipeCanvas::SkPipeCanvas(const SkRect& cull, SkPipeDeduper* deduper, SkWStream* stream)
    : INHERITED(cull.roundOut())
    , fDeduper(deduper)
    , fStream(stream)
{}

SkPipeCanvas::~SkPipeCanvas() {}

void SkPipeCanvas::willSave() {
    fStream->write32(pack_verb(SkPipeVerb::kSave));
    this->INHERITED::willSave();
}

SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
    SkPipeWriter writer(this);
    uint32_t extra = rec.fSaveLayerFlags;

    // remap this wacky flag
    if (extra & SkCanvasPriv::kDontClipToLayer_SaveLayerFlag) {
        extra &= ~SkCanvasPriv::kDontClipToLayer_SaveLayerFlag;
        extra |= kDontClipToLayer_SaveLayerMask;
    }

    if (rec.fBounds) {
        extra |= kHasBounds_SaveLayerMask;
    }
    if (rec.fPaint) {
        extra |= kHasPaint_SaveLayerMask;
    }
    if (rec.fBackdrop) {
        extra |= kHasBackdrop_SaveLayerMask;
    }
    if (rec.fClipMask) {
        extra |= kHasClipMask_SaveLayerMask;
    }
    if (rec.fClipMatrix) {
        extra |= kHasClipMatrix_SaveLayerMask;
    }

    writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra));
    if (rec.fBounds) {
        writer.writeRect(*rec.fBounds);
    }
    if (rec.fPaint) {
        write_paint(writer, *rec.fPaint, kSaveLayer_PaintUsage);
    }
    if (rec.fBackdrop) {
        writer.writeFlattenable(rec.fBackdrop);
    }
    if (rec.fClipMask) {
        writer.writeImage(rec.fClipMask);
    }
    if (rec.fClipMatrix) {
        writer.writeMatrix(*rec.fClipMatrix);
    }

    return kNoLayer_SaveLayerStrategy;
}

void SkPipeCanvas::willRestore() {
    fStream->write32(pack_verb(SkPipeVerb::kRestore));
    this->INHERITED::willRestore();
}

template <typename T> void write_sparse_matrix(T* writer, const SkMatrix& matrix) {
    SkMatrix::TypeMask tm = matrix.getType();
    SkScalar tmp[9];
    if (tm & SkMatrix::kPerspective_Mask) {
        matrix.get9(tmp);
        writer->write(tmp, 9 * sizeof(SkScalar));
    } else if (tm & SkMatrix::kAffine_Mask) {
        tmp[0] = matrix[SkMatrix::kMScaleX];
        tmp[1] = matrix[SkMatrix::kMSkewX];
        tmp[2] = matrix[SkMatrix::kMTransX];
        tmp[3] = matrix[SkMatrix::kMScaleY];
        tmp[4] = matrix[SkMatrix::kMSkewY];
        tmp[5] = matrix[SkMatrix::kMTransY];
        writer->write(tmp, 6 * sizeof(SkScalar));
    } else if (tm & SkMatrix::kScale_Mask) {
        tmp[0] = matrix[SkMatrix::kMScaleX];
        tmp[1] = matrix[SkMatrix::kMTransX];
        tmp[2] = matrix[SkMatrix::kMScaleY];
        tmp[3] = matrix[SkMatrix::kMTransY];
        writer->write(tmp, 4 * sizeof(SkScalar));
    } else if (tm & SkMatrix::kTranslate_Mask) {
        tmp[0] = matrix[SkMatrix::kMTransX];
        tmp[1] = matrix[SkMatrix::kMTransY];
        writer->write(tmp, 2 * sizeof(SkScalar));
    }
    // else write nothing for Identity
}

static void do_concat(SkWStream* stream, const SkMatrix& matrix, bool isSetMatrix) {
    unsigned mtype = matrix.getType();
    SkASSERT(0 == (mtype & ~kTypeMask_ConcatMask));
    unsigned extra = mtype;
    if (isSetMatrix) {
        extra |= kSetMatrix_ConcatMask;
    }
    if (mtype || isSetMatrix) {
        stream->write32(pack_verb(SkPipeVerb::kConcat, extra));
        write_sparse_matrix(stream, matrix);
    }
}

void SkPipeCanvas::didConcat(const SkMatrix& matrix) {
    do_concat(fStream, matrix, false);
    this->INHERITED::didConcat(matrix);
}

void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) {
    do_concat(fStream, matrix, true);
    this->INHERITED::didSetMatrix(matrix);
}

void SkPipeCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    fStream->write32(pack_verb(SkPipeVerb::kClipRect, ((unsigned)op << 1) | edgeStyle));
    fStream->write(&rect, 4 * sizeof(SkScalar));

    this->INHERITED::onClipRect(rect, op, edgeStyle);
}

void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    fStream->write32(pack_verb(SkPipeVerb::kClipRRect, ((unsigned)op << 1) | edgeStyle));
    write_rrect(fStream, rrect);

    this->INHERITED::onClipRRect(rrect, op, edgeStyle);
}

void SkPipeCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kClipPath, ((unsigned)op << 1) | edgeStyle));
    writer.writePath(path);

    this->INHERITED::onClipPath(path, op, edgeStyle);
}

void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kClipRegion, (unsigned)op << 1));
    writer.writeRegion(deviceRgn);

    this->INHERITED::onClipRegion(deviceRgn, op);
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void SkPipeCanvas::onDrawArc(const SkRect& bounds, SkScalar startAngle, SkScalar sweepAngle,
                             bool useCenter, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawArc, (int)useCenter));
    writer.writeRect(bounds);
    writer.writeScalar(startAngle);
    writer.writeScalar(sweepAngle);
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect rect[],
                               const SkColor colors[], int count, SkBlendMode mode,
                               const SkRect* cull, const SkPaint* paint) {
    unsigned extra = (unsigned)mode;
    SkASSERT(0 == (extra & ~kMode_DrawAtlasMask));
    if (colors) {
        extra |= kHasColors_DrawAtlasMask;
    }
    if (cull) {
        extra |= kHasCull_DrawAtlasMask;
    }
    if (paint) {
        extra |= kHasPaint_DrawAtlasMask;
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawAtlas, extra));
    writer.writeImage(image);
    writer.write32(count);
    writer.write(xform, count * sizeof(SkRSXform));
    writer.write(rect, count * sizeof(SkRect));
    if (colors) {
        writer.write(colors, count * sizeof(SkColor));
    }
    if (cull) {
        writer.writeRect(*cull);
    }
    if (paint) {
        write_paint(writer, *paint, kImage_PaintUsage);
    }
}

void SkPipeCanvas::onDrawPaint(const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPaint));
    write_paint(writer, paint, kDrawPaint_PaintUsage);
}

void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPoints, mode));
    writer.write32(SkToU32(count));
    writer.write(pts, count * sizeof(SkPoint));
    write_paint(writer, paint, kGeometry_PaintUsage | kRespectsStroke_PaintUsage);
}

void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawRect));
    writer.write(&rect, sizeof(SkRect));
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawOval));
    writer.write(&rect, sizeof(SkRect));
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawRRect));
    write_rrect(&writer, rrect);
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawDRRect));
    write_rrect(&writer, outer);
    write_rrect(&writer, inner);
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPath));
    writer.writePath(path);
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawShadowRec));
    writer.writePath(path);
    writer.write(&rec, sizeof(rec));
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) {
    // If we just "make" an image, it will force a CPU copy (if its mutable), only to have
    // us then either find it in our cache, or compress and send it.
    //
    // Better could be to look it up in our cache first, and only create/compress it if we have to.
    //
    // But for now, just do the dumb thing...
    return SkImage::MakeFromBitmap(bitmap);
}

void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y,
                                const SkPaint* paint) {
    sk_sp<SkImage> image = make_from_bitmap(bitmap);
    if (image) {
        this->onDrawImage(image.get(), x, y, paint);
    }
}

void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
                                    const SkPaint* paint, SrcRectConstraint constraint) {
    sk_sp<SkImage> image = make_from_bitmap(bitmap);
    if (image) {
        this->onDrawImageRect(image.get(), src, dst, paint, constraint);
    }
}

void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                    const SkRect& dst, const SkPaint* paint) {
    sk_sp<SkImage> image = make_from_bitmap(bitmap);
    if (image) {
        this->onDrawImageNine(image.get(), center, dst, paint);
    }
}

void SkPipeCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice,
                                       const SkRect& dst, const SkPaint* paint) {
    sk_sp<SkImage> image = make_from_bitmap(bitmap);
    if (image) {
        this->onDrawImageLattice(image.get(), lattice, dst, paint);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top,
                               const SkPaint* paint) {
    unsigned extra = 0;
    if (paint) {
        extra |= kHasPaint_DrawImageMask;
    }
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawImage, extra));
    writer.writeImage(image);
    writer.writeScalar(left);
    writer.writeScalar(top);
    if (paint) {
        write_paint(writer, *paint, kImage_PaintUsage);
    }
}

void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
                                   const SkPaint* paint, SrcRectConstraint constraint) {
    SkASSERT(0 == ((unsigned)constraint & ~1));
    unsigned extra = (unsigned)constraint;
    if (paint) {
        extra |= kHasPaint_DrawImageRectMask;
    }
    if (src) {
        extra |= kHasSrcRect_DrawImageRectMask;
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawImageRect, extra));
    writer.writeImage(image);
    if (src) {
        writer.write(src, sizeof(*src));
    }
    writer.write(&dst, sizeof(dst));
    if (paint) {
        write_paint(writer, *paint, kImage_PaintUsage);
    }
}

void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
                                   const SkPaint* paint) {
    unsigned extra = 0;
    if (paint) {
        extra |= kHasPaint_DrawImageNineMask;
    }
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawImageNine, extra));
    writer.writeImage(image);
    writer.write(&center, sizeof(center));
    writer.write(&dst, sizeof(dst));
    if (paint) {
        write_paint(writer, *paint, kImage_PaintUsage);
    }
}

void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
                                      const SkRect& dst, const SkPaint* paint) {
    unsigned extra = 0;
    if (paint) {
        extra |= kHasPaint_DrawImageLatticeMask;
    }
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawImageLattice, extra));
    writer.writeImage(image);
    SkCanvasPriv::WriteLattice(writer, lattice);
    writer.write(&dst, sizeof(dst));
    if (paint) {
        write_paint(writer, *paint, kImage_PaintUsage);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                              const SkPaint& paint) {
    SkASSERT(byteLength);

    bool compact = fits_in(byteLength, 24);

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawText, compact ? (unsigned)byteLength : 0));
    if (!compact) {
        writer.write32(SkToU32(byteLength));
    }
    write_pad(&writer, text, byteLength);
    writer.writeScalar(x);
    writer.writeScalar(y);
    write_paint(writer, paint, kText_PaintUsage);
}

void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
                                 const SkPaint& paint) {
    SkASSERT(byteLength);

    bool compact = fits_in(byteLength, 24);

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteLength : 0));
    if (!compact) {
        writer.write32(SkToU32(byteLength));
    }
    write_pad(&writer, text, byteLength);
    writer.writePointArray(pos, paint.countText(text, byteLength));
    write_paint(writer, paint, kText_PaintUsage);
}

void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
                                  SkScalar constY, const SkPaint& paint) {
    SkASSERT(byteLength);

    bool compact = fits_in(byteLength, 24);

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPosTextH, compact ? (unsigned)byteLength : 0));
    if (!compact) {
        writer.write32(SkToU32(byteLength));
    }
    write_pad(&writer, text, byteLength);
    writer.writeScalarArray(xpos, paint.countText(text, byteLength));
    writer.writeScalar(constY);
    write_paint(writer, paint, kText_PaintUsage);
}

void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
                                     const SkRect* cull, const SkPaint& paint) {
    SkASSERT(byteLength);

    bool compact = fits_in(byteLength, 23);
    unsigned extra = compact ? (byteLength << 1) : 0;
    if (cull) {
        extra |= 1;
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra));
    if (!compact) {
        writer.write32(SkToU32(byteLength));
    }
    write_pad(&writer, text, byteLength);

    int count = paint.countText(text, byteLength);
    writer.write32(count);  // maybe we can/should store this in extra as well?
    writer.write(xform, count * sizeof(SkRSXform));
    if (cull) {
        writer.writeRect(*cull);
    }
    write_paint(writer, paint, kText_PaintUsage);
}

void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                  const SkPaint &paint) {
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawTextBlob, 0));
    SkTextBlobPriv::Flatten(*blob, writer);
    writer.writeScalar(x);
    writer.writeScalar(y);
    write_paint(writer, paint, kTextBlob_PaintUsage);
}

void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                 const SkPaint* paint) {
    unsigned extra = fDeduper->findOrDefinePicture(const_cast<SkPicture*>(picture));
    if (matrix) {
        extra |= kHasMatrix_DrawPictureExtra;
    }
    if (paint) {
        extra |= kHasPaint_DrawPictureExtra;
    }
    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawPicture, extra));
    if (matrix) {
        writer.writeMatrix(*matrix);
    }
    if (paint) {
        write_paint(writer, *paint, kSaveLayer_PaintUsage);
    }
}

void SkPipeCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
    // TODO: Is there a better solution than just exploding the drawable?
    drawable->draw(this, matrix);
}

void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
    size_t size = region.writeToMemory(nullptr);
    unsigned extra = 0;
    if (fits_in(size, 24)) {
        extra = SkToUInt(size);
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawRegion, extra));
    if (0 == extra) {
        writer.write32(size);
    }
    SkAutoSMalloc<2048> storage(size);
    region.writeToMemory(storage.get());
    write_pad(&writer, storage.get(), size);
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
                                        int boneCount, SkBlendMode bmode, const SkPaint& paint) {
    unsigned extra = static_cast<unsigned>(bmode);

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra));
    // TODO: dedup vertices?
    writer.writeDataAsByteArray(vertices->encode().get());
    writer.write32(boneCount);
    writer.write(bones, sizeof(SkVertices::Bone) * boneCount);
    write_paint(writer, paint, kVertices_PaintUsage);
}

void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                               const SkPoint texCoords[4], SkBlendMode bmode,
                               const SkPaint& paint) {
    SkPipeWriter writer(this);
    unsigned extra = 0;
    SkASSERT(0 == ((int)bmode & ~kModeEnum_DrawPatchExtraMask));
    extra = (unsigned)bmode;
    if (colors) {
        extra |= kHasColors_DrawPatchExtraMask;
    }
    if (texCoords) {
        extra |= kHasTexture_DrawPatchExtraMask;
    }
    writer.write32(pack_verb(SkPipeVerb::kDrawPatch, extra));
    writer.write(cubics, sizeof(SkPoint) * 12);
    if (colors) {
        writer.write(colors, sizeof(SkColor) * 4);
    }
    if (texCoords) {
        writer.write(texCoords, sizeof(SkPoint) * 4);
    }
    write_paint(writer, paint, kGeometry_PaintUsage);
}

void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
    const size_t len = strlen(key) + 1; // must write the trailing 0
    bool compact = fits_in(len, 23);
    uint32_t extra = compact ? (unsigned)len : 0;
    extra <<= 1;   // make room for has_data_sentinel
    if (data) {
        extra |= 1;
    }

    fStream->write32(pack_verb(SkPipeVerb::kDrawAnnotation, extra));
    fStream->write(&rect, sizeof(SkRect));
    if (!compact) {
        fStream->write32(SkToU32(len));
    }
    write_pad(fStream, key, len);
    if (data) {
        fStream->write32(SkToU32(data->size()));
        write_pad(fStream, data->data(), data->size());
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static sk_sp<SkData> encode(SkImage* img, SkSerialImageProc proc, void* ctx) {
    if (proc) {
        if (auto data = proc(img, ctx)) {
            return data;
        }
    }
    return img->encodeToData();
}

static bool show_deduper_traffic = false;

int SkPipeDeduper::findOrDefineImage(SkImage* image) {
    int index = fImages.find(image->uniqueID());
    SkASSERT(index >= 0);
    if (index) {
        if (show_deduper_traffic) {
            SkDebugf("  reuseImage(%d)\n", index - 1);
        }
        return index;
    }

    sk_sp<SkData> data = encode(image, fProcs.fImageProc, fProcs.fImageCtx);
    if (data) {
        index = fImages.add(image->uniqueID());
        SkASSERT(index > 0);
        SkASSERT(fits_in(index, 24));
        fStream->write32(pack_verb(SkPipeVerb::kDefineImage, index));

        uint32_t len = SkToU32(data->size());
        fStream->write32(SkAlign4(len));
        write_pad(fStream, data->data(), len);

        if (show_deduper_traffic) {
            int size = image->width() * image->height() << 2;
            SkDebugf("  defineImage(%d) %d -> %d\n", index - 1, size, len);
        }
        return index;
    }
    SkDebugf("+++ failed to encode image [%d %d]\n", image->width(), image->height());
    return 0;   // failed to encode
}

int SkPipeDeduper::findOrDefinePicture(SkPicture* picture) {
    int index = fPictures.find(picture->uniqueID());
    SkASSERT(index >= 0);
    if (index) {
        if (show_deduper_traffic) {
            SkDebugf("  reusePicture(%d)\n", index - 1);
        }
        return index;
    }

    size_t prevWritten = fStream->bytesWritten();
    unsigned extra = 0; // 0 means we're defining a new picture, non-zero means undef_index + 1
    fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, extra));
    const SkRect cull = picture->cullRect();
    fStream->write(&cull, sizeof(cull));
    picture->playback(fPipeCanvas);
    // call fPictures.add *after* we're written the picture, so that any nested pictures will have
    // already been defined, and we get the "last" index value.
    index = fPictures.add(picture->uniqueID());
    ASSERT_FITS_IN(index, kObjectDefinitionBits);
    fStream->write32(pack_verb(SkPipeVerb::kEndPicture, index));

    if (show_deduper_traffic) {
        SkDebugf("  definePicture(%d) %d\n",
                 index - 1, SkToU32(fStream->bytesWritten() - prevWritten));
    }
    return index;
}

static sk_sp<SkData> encode(const SkSerialProcs& procs, SkTypeface* tf) {
    if (procs.fTypefaceProc) {
        auto data = procs.fTypefaceProc(tf, procs.fTypefaceCtx);
        if (data) {
            return data;
        }
    }
    SkDynamicMemoryWStream stream;
    tf->serialize(&stream);
    return sk_sp<SkData>(stream.detachAsData());
}

int SkPipeDeduper::findOrDefineTypeface(SkTypeface* typeface) {
    if (!typeface) {
        return 0;   // default
    }

    int index = fTypefaces.find(typeface->uniqueID());
    SkASSERT(index >= 0);
    if (index) {
        if (show_deduper_traffic) {
            SkDebugf("  reuseTypeface(%d)\n", index - 1);
        }
        return index;
    }

    sk_sp<SkData> data = encode(fProcs, typeface);
    if (data) {
        index = fTypefaces.add(typeface->uniqueID());
        SkASSERT(index > 0);
        SkASSERT(fits_in(index, 24));
        fStream->write32(pack_verb(SkPipeVerb::kDefineTypeface, index));

        uint32_t len = SkToU32(data->size());
        fStream->write32(SkAlign4(len));
        write_pad(fStream, data->data(), len);

        if (show_deduper_traffic) {
            SkDebugf("  defineTypeface(%d) %d\n", index - 1, len);
        }
        return index;
    }
    SkDebugf("+++ failed to encode typeface %d\n", typeface->uniqueID());
    return 0;   // failed to encode
}

int SkPipeDeduper::findOrDefineFactory(SkFlattenable* flattenable) {
    if (!flattenable) {
        return 0;
    }

    int index = fFactories.find(flattenable->getFactory());
    SkASSERT(index >= 0);
    if (index) {
        if (show_deduper_traffic) {
            SkDebugf("  reuseFactory(%d)\n", index - 1);
        }
        return index;
    }

    index = fFactories.add(flattenable->getFactory());
    ASSERT_FITS_IN(index, kIndex_DefineFactoryExtraBits);
    const char* name = flattenable->getTypeName();
    size_t len = strlen(name);
    ASSERT_FITS_IN(len, kNameLength_DefineFactoryExtraBits);
    unsigned extra = (index << kNameLength_DefineFactoryExtraBits) | len;
    size_t prevWritten = fStream->bytesWritten();
    fStream->write32(pack_verb(SkPipeVerb::kDefineFactory, extra));
    write_pad(fStream, name, len + 1);
    if (false) {
        SkDebugf("  defineFactory(%d) %d %s\n",
             index - 1, SkToU32(fStream->bytesWritten() - prevWritten), name);
    }
    return index;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkPipe.h"

class SkPipeSerializer::Impl {
public:
    SkPipeDeduper   fDeduper;
    std::unique_ptr<SkPipeCanvas> fCanvas;
};

SkPipeSerializer::SkPipeSerializer() : fImpl(new Impl) {}

SkPipeSerializer::~SkPipeSerializer() {
    if (fImpl->fCanvas) {
        this->endWrite();
    }
}

void SkPipeSerializer::resetCache() {
    fImpl->fDeduper.resetCaches();
}

sk_sp<SkData> SkPipeSerializer::writeImage(SkImage* image) {
    SkDynamicMemoryWStream stream;
    this->writeImage(image, &stream);
    return stream.detachAsData();
}

sk_sp<SkData> SkPipeSerializer::writePicture(SkPicture* picture) {
    SkDynamicMemoryWStream stream;
    this->writePicture(picture, &stream);
    return stream.detachAsData();
}

void SkPipeSerializer::writePicture(SkPicture* picture, SkWStream* stream) {
    int index = fImpl->fDeduper.findPicture(picture);
    if (0 == index) {
        // Try to define the picture
        this->beginWrite(picture->cullRect(), stream);
        index = fImpl->fDeduper.findOrDefinePicture(picture);
        this->endWrite();
    }
    stream->write32(pack_verb(SkPipeVerb::kWritePicture, index));
}

void SkPipeSerializer::writeImage(SkImage* image, SkWStream* stream) {
    int index = fImpl->fDeduper.findImage(image);
    if (0 == index) {
        // Try to define the image
        fImpl->fDeduper.setStream(stream);
        index = fImpl->fDeduper.findOrDefineImage(image);
    }
    stream->write32(pack_verb(SkPipeVerb::kWriteImage, index));
}

SkCanvas* SkPipeSerializer::beginWrite(const SkRect& cull, SkWStream* stream) {
    SkASSERT(nullptr == fImpl->fCanvas);
    fImpl->fCanvas.reset(new SkPipeCanvas(cull, &fImpl->fDeduper, stream));
    fImpl->fDeduper.setStream(stream);
    fImpl->fDeduper.setCanvas(fImpl->fCanvas.get());
    return fImpl->fCanvas.get();
}

void SkPipeSerializer::endWrite() {
    fImpl->fCanvas->restoreToCount(1);
    fImpl->fCanvas.reset(nullptr);
    fImpl->fDeduper.setCanvas(nullptr);
}
