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

#include "src/core/SkPictureRecord.h"

#include "include/core/SkRRect.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkTextBlob.h"
#include "include/private/SkTo.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkSamplingPriv.h"
#include "src/core/SkTSearch.h"
#include "src/image/SkImage_Base.h"
#include "src/utils/SkPatchUtils.h"

#if SK_SUPPORT_GPU
#include "include/private/chromium/Slug.h"
#endif

#define HEAP_BLOCK_SIZE 4096

enum {
    // just need a value that save or getSaveCount would never return
    kNoInitialSave = -1,
};

// A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc.
static int const kUInt32Size = 4;

SkPictureRecord::SkPictureRecord(const SkIRect& dimensions, uint32_t flags)
    : INHERITED(dimensions)
    , fRecordFlags(flags)
    , fInitialSaveCount(kNoInitialSave) {
}

SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
    : SkPictureRecord(SkIRect::MakeSize(dimensions), flags) {}

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

void SkPictureRecord::onFlush() {
    size_t size = sizeof(kUInt32Size);
    size_t initialOffset = this->addDraw(FLUSH, &size);
    this->validate(initialOffset, size);
}

void SkPictureRecord::willSave() {
    // record the offset to us, making it non-positive to distinguish a save
    // from a clip entry.
    fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten());
    this->recordSave();

    this->INHERITED::willSave();
}

void SkPictureRecord::recordSave() {
    // op only
    size_t size = sizeof(kUInt32Size);
    size_t initialOffset = this->addDraw(SAVE, &size);

    this->validate(initialOffset, size);
}

SkCanvas::SaveLayerStrategy SkPictureRecord::getSaveLayerStrategy(const SaveLayerRec& rec) {
    // record the offset to us, making it non-positive to distinguish a save
    // from a clip entry.
    fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten());
    this->recordSaveLayer(rec);

    (void)this->INHERITED::getSaveLayerStrategy(rec);
    /*  No need for a (potentially very big) layer which we don't actually need
        at this time (and may not be able to afford since during record our
        clip starts out the size of the picture, which is often much larger
        than the size of the actual device we'll use during playback).
     */
    return kNoLayer_SaveLayerStrategy;
}

bool SkPictureRecord::onDoSaveBehind(const SkRect* subset) {
    fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten());

    size_t size = sizeof(kUInt32Size) + sizeof(uint32_t); // op + flags
    uint32_t flags = 0;
    if (subset) {
        flags |= SAVEBEHIND_HAS_SUBSET;
        size += sizeof(*subset);
    }

    size_t initialOffset = this->addDraw(SAVE_BEHIND, &size);
    this->addInt(flags);
    if (subset) {
        this->addRect(*subset);
    }

    this->validate(initialOffset, size);
    return false;
}

void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) {
    // op + flatflags
    size_t size = 2 * kUInt32Size;
    uint32_t flatFlags = 0;

    if (rec.fBounds) {
        flatFlags |= SAVELAYERREC_HAS_BOUNDS;
        size += sizeof(*rec.fBounds);
    }
    if (rec.fPaint) {
        flatFlags |= SAVELAYERREC_HAS_PAINT;
        size += sizeof(uint32_t); // index
    }
    if (rec.fBackdrop) {
        flatFlags |= SAVELAYERREC_HAS_BACKDROP;
        size += sizeof(uint32_t); // (paint) index
    }
    if (rec.fSaveLayerFlags) {
        flatFlags |= SAVELAYERREC_HAS_FLAGS;
        size += sizeof(uint32_t);
    }
    if (SkCanvasPriv::GetBackdropScaleFactor(rec) != 1.f) {
        flatFlags |= SAVELAYERREC_HAS_BACKDROP_SCALE;
        size += sizeof(SkScalar);
    }

    const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size);
    this->addInt(flatFlags);
    if (flatFlags & SAVELAYERREC_HAS_BOUNDS) {
        this->addRect(*rec.fBounds);
    }
    if (flatFlags & SAVELAYERREC_HAS_PAINT) {
        this->addPaintPtr(rec.fPaint);
    }
    if (flatFlags & SAVELAYERREC_HAS_BACKDROP) {
        // overkill, but we didn't already track single flattenables, so using a paint for that
        SkPaint paint;
        paint.setImageFilter(sk_ref_sp(const_cast<SkImageFilter*>(rec.fBackdrop)));
        this->addPaint(paint);
    }
    if (flatFlags & SAVELAYERREC_HAS_FLAGS) {
        this->addInt(rec.fSaveLayerFlags);
    }
    if (flatFlags & SAVELAYERREC_HAS_BACKDROP_SCALE) {
        this->addScalar(SkCanvasPriv::GetBackdropScaleFactor(rec));
    }
    this->validate(initialOffset, size);
}

#ifdef SK_DEBUG
/*
 * Read the op code from 'offset' in 'writer' and extract the size too.
 */
static DrawType peek_op_and_size(SkWriter32* writer, size_t offset, uint32_t* size) {
    uint32_t peek = writer->readTAt<uint32_t>(offset);

    uint32_t op;
    UNPACK_8_24(peek, op, *size);
    if (MASK_24 == *size) {
        // size required its own slot right after the op code
        *size = writer->readTAt<uint32_t>(offset + kUInt32Size);
    }
    return (DrawType) op;
}
#endif//SK_DEBUG

void SkPictureRecord::willRestore() {
#if 0
    SkASSERT(fRestoreOffsetStack.count() > 1);
#endif

    // check for underflow
    if (fRestoreOffsetStack.count() == 0) {
        return;
    }

    this->recordRestore();

    fRestoreOffsetStack.pop();

    this->INHERITED::willRestore();
}

void SkPictureRecord::recordRestore(bool fillInSkips) {
    if (fillInSkips) {
        this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten());
    }
    size_t size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code
    size_t initialOffset = this->addDraw(RESTORE, &size);
    this->validate(initialOffset, size);
}

void SkPictureRecord::recordTranslate(const SkMatrix& m) {
    SkASSERT(SkMatrix::kTranslate_Mask == m.getType());

    // op + dx + dy
    size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
    size_t initialOffset = this->addDraw(TRANSLATE, &size);
    this->addScalar(m.getTranslateX());
    this->addScalar(m.getTranslateY());
    this->validate(initialOffset, size);
}

void SkPictureRecord::recordScale(const SkMatrix& m) {
    SkASSERT(SkMatrix::kScale_Mask == m.getType());

    // op + sx + sy
    size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar);
    size_t initialOffset = this->addDraw(SCALE, &size);
    this->addScalar(m.getScaleX());
    this->addScalar(m.getScaleY());
    this->validate(initialOffset, size);
}

void SkPictureRecord::didConcat44(const SkM44& m) {
    this->validate(fWriter.bytesWritten(), 0);
    // op + matrix
    size_t size = kUInt32Size + 16 * sizeof(SkScalar);
    size_t initialOffset = this->addDraw(CONCAT44, &size);
    fWriter.write(SkMatrixPriv::M44ColMajor(m), 16 * sizeof(SkScalar));
    this->validate(initialOffset, size);

    this->INHERITED::didConcat44(m);
}

void SkPictureRecord::didSetM44(const SkM44& m) {
    this->validate(fWriter.bytesWritten(), 0);
    // op + matrix
    size_t size = kUInt32Size + 16 * sizeof(SkScalar);
    size_t initialOffset = this->addDraw(SET_M44, &size);
    fWriter.write(SkMatrixPriv::M44ColMajor(m), 16 * sizeof(SkScalar));
    this->validate(initialOffset, size);
    this->INHERITED::didSetM44(m);
}

void SkPictureRecord::didScale(SkScalar x, SkScalar y) {
    this->didConcat44(SkM44::Scale(x, y));
}

void SkPictureRecord::didTranslate(SkScalar x, SkScalar y) {
    this->didConcat44(SkM44::Translate(x, y));
}

void SkPictureRecord::recordConcat(const SkMatrix& matrix) {
    this->validate(fWriter.bytesWritten(), 0);
    // op + matrix
    size_t size = kUInt32Size + SkMatrixPriv::WriteToMemory(matrix, nullptr);
    size_t initialOffset = this->addDraw(CONCAT, &size);
    this->addMatrix(matrix);
    this->validate(initialOffset, size);
}

void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) {
    int32_t offset = fRestoreOffsetStack.top();
    while (offset > 0) {
        uint32_t peek = fWriter.readTAt<uint32_t>(offset);
        fWriter.overwriteTAt(offset, restoreOffset);
        offset = peek;
    }

#ifdef SK_DEBUG
    // offset of 0 has been disabled, so we skip it
    if (offset > 0) {
        // assert that the final offset value points to a save verb
        uint32_t opSize;
        DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize);
        SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERREC == drawOp);
    }
#endif
}

void SkPictureRecord::beginRecording() {
    // we have to call this *after* our constructor, to ensure that it gets
    // recorded. This is balanced by restoreToCount() call from endRecording,
    // which in-turn calls our overridden restore(), so those get recorded too.
    fInitialSaveCount = this->save();
}

void SkPictureRecord::endRecording() {
    SkASSERT(kNoInitialSave != fInitialSaveCount);
    this->restoreToCount(fInitialSaveCount);
}

size_t SkPictureRecord::recordRestoreOffsetPlaceholder() {
    if (fRestoreOffsetStack.isEmpty()) {
        return -1;
    }

    // The RestoreOffset field is initially filled with a placeholder
    // value that points to the offset of the previous RestoreOffset
    // in the current stack level, thus forming a linked list so that
    // the restore offsets can be filled in when the corresponding
    // restore command is recorded.
    int32_t prevOffset = fRestoreOffsetStack.top();

    size_t offset = fWriter.bytesWritten();
    this->addInt(prevOffset);
    fRestoreOffsetStack.top() = SkToU32(offset);
    return offset;
}

void SkPictureRecord::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
    this->INHERITED::onClipRect(rect, op, edgeStyle);
}

size_t SkPictureRecord::recordClipRect(const SkRect& rect, SkClipOp op, bool doAA) {
    // id + rect + clip params
    size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size;
    // recordRestoreOffsetPlaceholder doesn't always write an offset
    if (!fRestoreOffsetStack.isEmpty()) {
        // + restore offset
        size += kUInt32Size;
    }
    size_t initialOffset = this->addDraw(CLIP_RECT, &size);
    this->addRect(rect);
    this->addInt(ClipParams_pack(op, doAA));
    size_t offset = this->recordRestoreOffsetPlaceholder();

    this->validate(initialOffset, size);
    return offset;
}

void SkPictureRecord::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle);
    this->INHERITED::onClipRRect(rrect, op, edgeStyle);
}

size_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) {
    // op + rrect + clip params
    size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size;
    // recordRestoreOffsetPlaceholder doesn't always write an offset
    if (!fRestoreOffsetStack.isEmpty()) {
        // + restore offset
        size += kUInt32Size;
    }
    size_t initialOffset = this->addDraw(CLIP_RRECT, &size);
    this->addRRect(rrect);
    this->addInt(ClipParams_pack(op, doAA));
    size_t offset = recordRestoreOffsetPlaceholder();
    this->validate(initialOffset, size);
    return offset;
}

void SkPictureRecord::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
    int pathID = this->addPathToHeap(path);
    this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle);
    this->INHERITED::onClipPath(path, op, edgeStyle);
}

size_t SkPictureRecord::recordClipPath(int pathID, SkClipOp op, bool doAA) {
    // op + path index + clip params
    size_t size = 3 * kUInt32Size;
    // recordRestoreOffsetPlaceholder doesn't always write an offset
    if (!fRestoreOffsetStack.isEmpty()) {
        // + restore offset
        size += kUInt32Size;
    }
    size_t initialOffset = this->addDraw(CLIP_PATH, &size);
    this->addInt(pathID);
    this->addInt(ClipParams_pack(op, doAA));
    size_t offset = recordRestoreOffsetPlaceholder();
    this->validate(initialOffset, size);
    return offset;
}

void SkPictureRecord::onClipShader(sk_sp<SkShader> cs, SkClipOp op) {
    // Overkill to store a whole paint, but we don't have an existing structure to just store
    // shaders. If size becomes an issue in the future, we can optimize this.
    SkPaint paint;
    paint.setShader(cs);

    // op + paint index + clipop
    size_t size = 3 * kUInt32Size;
    size_t initialOffset = this->addDraw(CLIP_SHADER_IN_PAINT, &size);
    this->addPaint(paint);
    this->addInt((int)op);
    this->validate(initialOffset, size);

    this->INHERITED::onClipShader(std::move(cs), op);
}

void SkPictureRecord::onClipRegion(const SkRegion& region, SkClipOp op) {
    this->recordClipRegion(region, op);
    this->INHERITED::onClipRegion(region, op);
}

size_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkClipOp op) {
    // op + clip params + region
    size_t size = 2 * kUInt32Size + region.writeToMemory(nullptr);
    // recordRestoreOffsetPlaceholder doesn't always write an offset
    if (!fRestoreOffsetStack.isEmpty()) {
        // + restore offset
        size += kUInt32Size;
    }
    size_t initialOffset = this->addDraw(CLIP_REGION, &size);
    this->addRegion(region);
    this->addInt(ClipParams_pack(op, false));
    size_t offset = this->recordRestoreOffsetPlaceholder();

    this->validate(initialOffset, size);
    return offset;
}

void SkPictureRecord::onResetClip() {
    if (!fRestoreOffsetStack.isEmpty()) {
        // Run back through any previous clip ops, and mark their offset to
        // be 0, disabling their ability to trigger a jump-to-restore, otherwise
        // they could hide this expansion of the clip.
        this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0);
    }
    size_t size = sizeof(kUInt32Size);
    size_t initialOffset = this->addDraw(RESET_CLIP, &size);
    this->validate(initialOffset, size);
    this->INHERITED::onResetClip();
}

void SkPictureRecord::onDrawPaint(const SkPaint& paint) {
    // op + paint index
    size_t size = 2 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_PAINT, &size);
    this->addPaint(paint);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawBehind(const SkPaint& paint) {
    // logically the same as drawPaint, but with a diff enum
    // op + paint index
    size_t size = 2 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_BEHIND_PAINT, &size);
    this->addPaint(paint);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
                                   const SkPaint& paint) {
    // op + paint index + mode + count + point data
    size_t size = 4 * kUInt32Size + count * sizeof(SkPoint);
    size_t initialOffset = this->addDraw(DRAW_POINTS, &size);
    this->addPaint(paint);

    this->addInt(mode);
    this->addInt(SkToInt(count));
    fWriter.writeMul4(pts, count * sizeof(SkPoint));
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawOval(const SkRect& oval, const SkPaint& paint) {
    // op + paint index + rect
    size_t size = 2 * kUInt32Size + sizeof(oval);
    size_t initialOffset = this->addDraw(DRAW_OVAL, &size);
    this->addPaint(paint);
    this->addRect(oval);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
                                bool useCenter, const SkPaint& paint) {
    // op + paint index + rect + start + sweep + bool (as int)
    size_t size = 2 * kUInt32Size + sizeof(oval) + sizeof(startAngle) + sizeof(sweepAngle) +
                  sizeof(int);
    size_t initialOffset = this->addDraw(DRAW_ARC, &size);
    this->addPaint(paint);
    this->addRect(oval);
    this->addScalar(startAngle);
    this->addScalar(sweepAngle);
    this->addInt(useCenter);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    // op + paint index + rect
    size_t size = 2 * kUInt32Size + sizeof(rect);
    size_t initialOffset = this->addDraw(DRAW_RECT, &size);
    this->addPaint(paint);
    this->addRect(rect);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
    // op + paint index + region
    size_t regionBytes = region.writeToMemory(nullptr);
    size_t size = 2 * kUInt32Size + regionBytes;
    size_t initialOffset = this->addDraw(DRAW_REGION, &size);
    this->addPaint(paint);
    fWriter.writeRegion(region);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    // op + paint index + rrect
    size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory;
    size_t initialOffset = this->addDraw(DRAW_RRECT, &size);
    this->addPaint(paint);
    this->addRRect(rrect);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
                                   const SkPaint& paint) {
    // op + paint index + rrects
    size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2;
    size_t initialOffset = this->addDraw(DRAW_DRRECT, &size);
    this->addPaint(paint);
    this->addRRect(outer);
    this->addRRect(inner);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawPath(const SkPath& path, const SkPaint& paint) {
    // op + paint index + path index
    size_t size = 3 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_PATH, &size);
    this->addPaint(paint);
    this->addPath(path);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawImage2(const SkImage* image, SkScalar x, SkScalar y,
                                   const SkSamplingOptions& sampling, const SkPaint* paint) {
    // op + paint_index + image_index + x + y
    size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar) + SkSamplingPriv::FlatSize(sampling);
    size_t initialOffset = this->addDraw(DRAW_IMAGE2, &size);
    this->addPaintPtr(paint);
    this->addImage(image);
    this->addScalar(x);
    this->addScalar(y);
    this->addSampling(sampling);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawImageRect2(const SkImage* image, const SkRect& src, const SkRect& dst,
                                       const SkSamplingOptions& sampling, const SkPaint* paint,
                                       SrcRectConstraint constraint) {
    // id + paint_index + image_index + constraint
    size_t size = 3 * kUInt32Size + 2 * sizeof(dst) + SkSamplingPriv::FlatSize(sampling) +
                  kUInt32Size;

    size_t initialOffset = this->addDraw(DRAW_IMAGE_RECT2, &size);
    this->addPaintPtr(paint);
    this->addImage(image);
    this->addRect(src);
    this->addRect(dst);
    this->addSampling(sampling);
    this->addInt(constraint);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawImageLattice2(const SkImage* image, const Lattice& lattice,
                                          const SkRect& dst, SkFilterMode filter,
                                          const SkPaint* paint) {
    size_t latticeSize = SkCanvasPriv::WriteLattice(nullptr, lattice);
    // op + paint index + image index + lattice + dst rect
    size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst) + sizeof(uint32_t); // filter
    size_t initialOffset = this->addDraw(DRAW_IMAGE_LATTICE2, &size);
    this->addPaintPtr(paint);
    this->addImage(image);
    (void)SkCanvasPriv::WriteLattice(fWriter.reservePad(latticeSize), lattice);
    this->addRect(dst);
    this->addInt(static_cast<uint32_t>(filter));
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                     const SkPaint& paint) {

    // op + paint index + blob index + x/y
    size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
    size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size);

    this->addPaint(paint);
    this->addTextBlob(blob);
    this->addScalar(x);
    this->addScalar(y);

    this->validate(initialOffset, size);
}

#if SK_SUPPORT_GPU
void SkPictureRecord::onDrawSlug(const sktext::gpu::Slug* slug) {
    // op + slug id
    size_t size = 2 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_SLUG, &size);

    this->addSlug(slug);
    this->validate(initialOffset, size);
}
#endif

void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                    const SkPaint* paint) {
    // op + picture index
    size_t size = 2 * kUInt32Size;
    size_t initialOffset;

    if (nullptr == matrix && nullptr == paint) {
        initialOffset = this->addDraw(DRAW_PICTURE, &size);
        this->addPicture(picture);
    } else {
        const SkMatrix& m = matrix ? *matrix : SkMatrix::I();
        size += SkMatrixPriv::WriteToMemory(m, nullptr) + kUInt32Size;    // matrix + paint
        initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size);
        this->addPaintPtr(paint);
        this->addMatrix(m);
        this->addPicture(picture);
    }
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
    // op + drawable index
    size_t size = 2 * kUInt32Size;
    size_t initialOffset;

    if (nullptr == matrix) {
        initialOffset = this->addDraw(DRAW_DRAWABLE, &size);
        this->addDrawable(drawable);
    } else {
        size += SkMatrixPriv::WriteToMemory(*matrix, nullptr);    // matrix
        initialOffset = this->addDraw(DRAW_DRAWABLE_MATRIX, &size);
        this->addMatrix(*matrix);
        this->addDrawable(drawable);
    }
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices,
                                           SkBlendMode mode, const SkPaint& paint) {
    // op + paint index + vertices index + zero_bones + mode
    size_t size = 5 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_VERTICES_OBJECT, &size);

    this->addPaint(paint);
    this->addVertices(vertices);
    this->addInt(0);    // legacy bone count
    this->addInt(static_cast<uint32_t>(mode));

    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                                  const SkPoint texCoords[4], SkBlendMode bmode,
                                  const SkPaint& paint) {
    // op + paint index + patch 12 control points + flag + patch 4 colors + 4 texture coordinates
    size_t size = 2 * kUInt32Size + SkPatchUtils::kNumCtrlPts * sizeof(SkPoint) + kUInt32Size;
    uint32_t flag = 0;
    if (colors) {
        flag |= DRAW_VERTICES_HAS_COLORS;
        size += SkPatchUtils::kNumCorners * sizeof(SkColor);
    }
    if (texCoords) {
        flag |= DRAW_VERTICES_HAS_TEXS;
        size += SkPatchUtils::kNumCorners * sizeof(SkPoint);
    }
    if (SkBlendMode::kModulate != bmode) {
        flag |= DRAW_VERTICES_HAS_XFER;
        size += kUInt32Size;
    }

    size_t initialOffset = this->addDraw(DRAW_PATCH, &size);
    this->addPaint(paint);
    this->addPatch(cubics);
    this->addInt(flag);

    // write optional parameters
    if (colors) {
        fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
    }
    if (texCoords) {
        fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
    }
    if (flag & DRAW_VERTICES_HAS_XFER) {
        this->addInt((int)bmode);
    }
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawAtlas2(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
                                   const SkColor colors[], int count, SkBlendMode mode,
                                   const SkSamplingOptions& sampling, const SkRect* cull,
                                   const SkPaint* paint) {
    // [op + paint-index + atlas-index + flags + count] + [xform] + [tex] + [*colors + mode] + cull
    size_t size = 5 * kUInt32Size + count * sizeof(SkRSXform) + count * sizeof(SkRect);
    size += SkSamplingPriv::FlatSize(sampling);
    uint32_t flags = 0;
    if (colors) {
        flags |= DRAW_ATLAS_HAS_COLORS;
        size += count * sizeof(SkColor);
        size += sizeof(uint32_t);   // xfermode::mode
    }
    if (cull) {
        flags |= DRAW_ATLAS_HAS_CULL;
        size += sizeof(SkRect);
    }
    flags |= DRAW_ATLAS_HAS_SAMPLING;

    size_t initialOffset = this->addDraw(DRAW_ATLAS, &size);
    this->addPaintPtr(paint);
    this->addImage(atlas);
    this->addInt(flags);
    this->addInt(count);
    fWriter.write(xform, count * sizeof(SkRSXform));
    fWriter.write(tex, count * sizeof(SkRect));

    // write optional parameters
    if (colors) {
        fWriter.write(colors, count * sizeof(SkColor));
        this->addInt((int)mode);
    }
    if (cull) {
        fWriter.write(cull, sizeof(SkRect));
    }
    this->addSampling(sampling);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    // op + path index + zParams + lightPos + lightRadius + spot/ambient alphas + color + flags
    size_t size = 2 * kUInt32Size + 2 * sizeof(SkPoint3) + 1 * sizeof(SkScalar) + 3 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_SHADOW_REC, &size);

    this->addPath(path);

    fWriter.writePoint3(rec.fZPlaneParams);
    fWriter.writePoint3(rec.fLightPos);
    fWriter.writeScalar(rec.fLightRadius);
    fWriter.write32(rec.fAmbientColor);
    fWriter.write32(rec.fSpotColor);
    fWriter.write32(rec.fFlags);

    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) {
    size_t keyLen = SkWriter32::WriteStringSize(key);
    size_t valueLen = SkWriter32::WriteDataSize(value);
    size_t size = 4 + sizeof(SkRect) + keyLen + valueLen;

    size_t initialOffset = this->addDraw(DRAW_ANNOTATION, &size);
    this->addRect(rect);
    fWriter.writeString(key);
    fWriter.writeData(value);
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
                                       SkCanvas::QuadAAFlags aa, const SkColor4f& color,
                                       SkBlendMode mode) {

    // op + rect + aa flags + color + mode + hasClip(as int) + clipCount*points
    size_t size = 4 * kUInt32Size + sizeof(SkColor4f) + sizeof(rect) +
            (clip ? 4 : 0) * sizeof(SkPoint);
    size_t initialOffset = this->addDraw(DRAW_EDGEAA_QUAD, &size);
    this->addRect(rect);
    this->addInt((int) aa);
    fWriter.write(&color, sizeof(SkColor4f));
    this->addInt((int) mode);
    this->addInt(clip != nullptr);
    if (clip) {
        this->addPoints(clip, 4);
    }
    this->validate(initialOffset, size);
}

void SkPictureRecord::onDrawEdgeAAImageSet2(const SkCanvas::ImageSetEntry set[], int count,
                                            const SkPoint dstClips[],
                                            const SkMatrix preViewMatrices[],
                                            const SkSamplingOptions& sampling,
                                            const SkPaint* paint,
                                            SkCanvas::SrcRectConstraint constraint) {
    static constexpr size_t kMatrixSize = 9 * sizeof(SkScalar); // *not* sizeof(SkMatrix)
    // op + count + paint + constraint + (image index, src rect, dst rect, alpha, aa flags,
    // hasClip(int), matrixIndex) * cnt + totalClipCount + dstClips + totalMatrixCount + matrices
    int totalDstClipCount, totalMatrixCount;
    SkCanvasPriv::GetDstClipAndMatrixCounts(set, count, &totalDstClipCount, &totalMatrixCount);

    size_t size = 6 * kUInt32Size + sizeof(SkPoint) * totalDstClipCount +
                  kMatrixSize * totalMatrixCount +
                  (4 * kUInt32Size + 2 * sizeof(SkRect) + sizeof(SkScalar)) * count +
                  SkSamplingPriv::FlatSize(sampling);
    size_t initialOffset = this->addDraw(DRAW_EDGEAA_IMAGE_SET2, &size);
    this->addInt(count);
    this->addPaintPtr(paint);
    this->addSampling(sampling);
    this->addInt((int) constraint);
    for (int i = 0; i < count; ++i) {
        this->addImage(set[i].fImage.get());
        this->addRect(set[i].fSrcRect);
        this->addRect(set[i].fDstRect);
        this->addInt(set[i].fMatrixIndex);
        this->addScalar(set[i].fAlpha);
        this->addInt((int)set[i].fAAFlags);
        this->addInt(set[i].fHasClip);
    }
    this->addInt(totalDstClipCount);
    this->addPoints(dstClips, totalDstClipCount);
    this->addInt(totalMatrixCount);
    for (int i = 0; i < totalMatrixCount; ++i) {
        this->addMatrix(preViewMatrices[i]);
    }
    this->validate(initialOffset, size);
}

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

// De-duping helper.

template <typename T>
static bool equals(T* a, T* b) { return a->uniqueID() == b->uniqueID(); }

template <>
bool equals(SkDrawable* a, SkDrawable* b) {
    // SkDrawable's generationID is not a stable unique identifier.
    return a == b;
}

template <typename T>
static int find_or_append(SkTArray<sk_sp<T>>& array, T* obj) {
    for (int i = 0; i < array.count(); i++) {
        if (equals(array[i].get(), obj)) {
            return i;
        }
    }

    array.push_back(sk_ref_sp(obj));

    return array.count() - 1;
}

sk_sp<SkSurface> SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
    return nullptr;
}

void SkPictureRecord::addImage(const SkImage* image) {
    // convention for images is 0-based index
    this->addInt(find_or_append(fImages, image));
}

void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
    fWriter.writeMatrix(matrix);
}

void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
    if (paint) {
        fPaints.push_back(*paint);
        this->addInt(fPaints.count());
    } else {
        this->addInt(0);
    }
}

int SkPictureRecord::addPathToHeap(const SkPath& path) {
    if (int* n = fPaths.find(path)) {
        return *n;
    }
    int n = fPaths.count() + 1;  // 0 is reserved for null / error.
    fPaths.set(path, n);
    return n;
}

void SkPictureRecord::addPath(const SkPath& path) {
    this->addInt(this->addPathToHeap(path));
}

void SkPictureRecord::addPatch(const SkPoint cubics[12]) {
    fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
}

void SkPictureRecord::addPicture(const SkPicture* picture) {
    // follow the convention of recording a 1-based index
    this->addInt(find_or_append(fPictures, picture) + 1);
}

void SkPictureRecord::addDrawable(SkDrawable* drawable) {
    // follow the convention of recording a 1-based index
    this->addInt(find_or_append(fDrawables, drawable) + 1);
}

void SkPictureRecord::addPoint(const SkPoint& point) {
    fWriter.writePoint(point);
}

void SkPictureRecord::addPoints(const SkPoint pts[], int count) {
    fWriter.writeMul4(pts, count * sizeof(SkPoint));
}

void SkPictureRecord::addNoOp() {
    size_t size = kUInt32Size; // op
    this->addDraw(NOOP, &size);
}

void SkPictureRecord::addRect(const SkRect& rect) {
    fWriter.writeRect(rect);
}

void SkPictureRecord::addRectPtr(const SkRect* rect) {
    if (fWriter.writeBool(rect != nullptr)) {
        fWriter.writeRect(*rect);
    }
}

void SkPictureRecord::addIRect(const SkIRect& rect) {
    fWriter.write(&rect, sizeof(rect));
}

void SkPictureRecord::addIRectPtr(const SkIRect* rect) {
    if (fWriter.writeBool(rect != nullptr)) {
        *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect;
    }
}

void SkPictureRecord::addRRect(const SkRRect& rrect) {
    fWriter.writeRRect(rrect);
}

void SkPictureRecord::addRegion(const SkRegion& region) {
    fWriter.writeRegion(region);
}

void SkPictureRecord::addSampling(const SkSamplingOptions& sampling) {
    fWriter.writeSampling(sampling);
}

void SkPictureRecord::addText(const void* text, size_t byteLength) {
    addInt(SkToInt(byteLength));
    fWriter.writePad(text, byteLength);
}

void SkPictureRecord::addTextBlob(const SkTextBlob* blob) {
    // follow the convention of recording a 1-based index
    this->addInt(find_or_append(fTextBlobs, blob) + 1);
}

#if SK_SUPPORT_GPU
void SkPictureRecord::addSlug(const sktext::gpu::Slug* slug) {
    // follow the convention of recording a 1-based index
    this->addInt(find_or_append(fSlugs, slug) + 1);
}
#endif

void SkPictureRecord::addVertices(const SkVertices* vertices) {
    // follow the convention of recording a 1-based index
    this->addInt(find_or_append(fVertices, vertices) + 1);
}

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