/*
 * 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 "SkPathEffect.h"
#include "SkColorFilter.h"
#include "SkDrawLooper.h"
#include "SkImageFilter.h"
#include "SkMaskFilter.h"
#include "SkPipeCanvas.h"
#include "SkPipeFormat.h"
#include "SkRasterizer.h"
#include "SkRSXform.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkTextBlob.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);
        bits |= (paint.getRasterizer()  ? kRasterizer_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, Rasterizer);
    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(), SkCanvas::kConservativeRasterClip_InitFlag)
    , 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 & (1 << 31)/*SkCanvas::kDontClipToLayer_PrivateSaveLayerFlag*/) {
        extra &= ~(1 << 31);
        extra |= kDontClipToLayer_SaveLayerMask;
    }

    if (rec.fBounds) {
        extra |= kHasBounds_SaveLayerMask;
    }
    if (rec.fPaint) {
        extra |= kHasPaint_SaveLayerMask;
    }
    if (rec.fBackdrop) {
        extra |= kHasBackdrop_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);
    }
    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, ClipOp 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, ClipOp 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, ClipOp 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, ClipOp 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);
}

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

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;
    }
    if (lattice.fFlags) {
        extra |= kHasFlags_DrawImageLatticeMask;
    }
    if (lattice.fXCount >= kCount_DrawImageLatticeMask) {
        extra |= kCount_DrawImageLatticeMask << kXCount_DrawImageLatticeShift;
    } else {
        extra |= lattice.fXCount << kXCount_DrawImageLatticeShift;
    }
    if (lattice.fYCount >= kCount_DrawImageLatticeMask) {
        extra |= kCount_DrawImageLatticeMask << kYCount_DrawImageLatticeShift;
    } else {
        extra |= lattice.fYCount << kYCount_DrawImageLatticeShift;
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawImageLattice, extra));
    writer.writeImage(image);
    if (lattice.fXCount >= kCount_DrawImageLatticeMask) {
        writer.write32(lattice.fXCount);
    }
    if (lattice.fYCount >= kCount_DrawImageLatticeMask) {
        writer.write32(lattice.fYCount);
    }
    // Often these divs will be small (8 or 16 bits). Consider sniffing that and writing a flag
    // so we can store them smaller.
    writer.write(lattice.fXDivs, lattice.fXCount * sizeof(int32_t));
    writer.write(lattice.fYDivs, lattice.fYCount * sizeof(int32_t));
    if (lattice.fFlags) {
        int32_t count = (lattice.fXCount + 1) * (lattice.fYCount + 1);
        SkASSERT(count > 0);
        write_pad(&writer, lattice.fFlags, count);
    }
    SkASSERT(lattice.fBounds);
    writer.write(&lattice.fBounds, sizeof(*lattice.fBounds));
    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::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                    const SkMatrix* matrix, const SkPaint& paint) {
    SkASSERT(byteLength > 0);

    unsigned extra = 0;
    if (byteLength <= kTextLength_DrawTextOnPathMask) {
        extra |= byteLength;
    } // else we will write the length after the packedverb
    SkMatrix::TypeMask tm = matrix ? matrix->getType() : SkMatrix::kIdentity_Mask;
    extra |= (unsigned)tm << kMatrixType_DrawTextOnPathShift;

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawTextOnPath, extra));
    if (byteLength > kTextLength_DrawTextOnPathMask) {
        writer.write32(byteLength);
    }
    write_pad(&writer, text, byteLength);
    writer.writePath(path);
    if (matrix) {
        write_sparse_matrix(&writer, *matrix);
    }
    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));
    blob->flatten(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::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::onDrawVertices(VertexMode vmode, int vertexCount,
                                  const SkPoint vertices[], const SkPoint texs[],
                                  const SkColor colors[], SkBlendMode bmode,
                                  const uint16_t indices[], int indexCount,
                                  const SkPaint& paint) {
    SkASSERT(vertexCount > 0);

    unsigned extra = 0;
    if (vertexCount <= kVCount_DrawVerticesMask) {
        extra |= vertexCount;
    }
    extra |= (unsigned)vmode << kVMode_DrawVerticesShift;
    extra |= (unsigned)bmode << kXMode_DrawVerticesShift;

    if (texs) {
        extra |= kHasTex_DrawVerticesMask;
    }
    if (colors) {
        extra |= kHasColors_DrawVerticesMask;
    }
    if (indexCount > 0) {
        extra |= kHasIndices_DrawVerticesMask;
    }

    SkPipeWriter writer(this);
    writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra));
    if (vertexCount > kVCount_DrawVerticesMask) {
        writer.write32(vertexCount);
    }
    writer.write(vertices, vertexCount * sizeof(SkPoint));
    if (texs) {
        writer.write(texs, vertexCount * sizeof(SkPoint));
    }
    if (colors) {
        writer.write(colors, vertexCount * sizeof(SkColor));
    }
    if (indexCount > 0) {
        writer.write32(indexCount);
        SkASSERT(SkIsAlign2(indexCount));
        writer.write(indices, indexCount * sizeof(uint16_t));
    }
    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());
    }
}

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

class A8Serializer : public SkPixelSerializer {
protected:
    bool onUseEncodedData(const void* data, size_t len) {
        return true;
    }

    SkData* onEncode(const SkPixmap& pmap) {
        if (kAlpha_8_SkColorType == pmap.colorType()) {
            SkDynamicMemoryWStream stream;
            stream.write("skiaimgf", 8);
            stream.write32(pmap.width());
            stream.write32(pmap.height());
            stream.write16(pmap.colorType());
            stream.write16(pmap.alphaType());
            stream.write32(0);  // no colorspace for now
            for (int y = 0; y < pmap.height(); ++y) {
                stream.write(pmap.addr8(0, y), pmap.width());
            }
            return stream.detachAsData().release();
        }
        return nullptr;
    }
};

static sk_sp<SkData> default_image_serializer(SkImage* image) {
    A8Serializer serial;
    sk_sp<SkData> data(image->encode(&serial));
    if (!data) {
        data.reset(image->encode());
    }
    return data;
}

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 = fIMSerializer ? fIMSerializer->serialize(image)
                                       : default_image_serializer(image);
    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));

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

static sk_sp<SkData> encode(SkTypeface* tf) {
    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 = fTFSerializer ? fTFSerializer->serialize(typeface) : encode(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::setTypefaceSerializer(SkTypefaceSerializer* tfs) {
    fImpl->fDeduper.setTypefaceSerializer(tfs);
}

void SkPipeSerializer::setImageSerializer(SkImageSerializer* ims) {
    fImpl->fDeduper.setImageSerializer(ims);
}

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);
}
