/*
 * 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/SkBlendMode.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRect.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTileMode.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTo.h"
#include "include/private/chromium/Slug.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkSamplingPriv.h"
#include "src/utils/SkPatchUtils.h"

#include <utility>

class SkSurfaceProps;
enum class SkClipOp;
struct SkISize;
struct SkImageInfo;

using namespace skia_private;

#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)
    : SkCanvasVirtualEnforcer<SkCanvas>(dimensions)
    , fRecordFlags(flags)
    , fInitialSaveCount(kNoInitialSave) {
}

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

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->SkCanvasVirtualEnforcer<SkCanvas>::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->SkCanvasVirtualEnforcer<SkCanvas>::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;
    uint32_t filterCount = SkToU32(rec.fFilters.size());

    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);
    }
    if (filterCount) {
        flatFlags |= SAVELAYERREC_HAS_MULTIPLE_FILTERS;
        size += sizeof(uint32_t);  // count
        size += sizeof(uint32_t) * filterCount;  // N (paint) indices
    }
    if (rec.fBackdropTileMode != SkTileMode::kClamp) {
        flatFlags |= SAVELAYERREC_HAS_BACKDROP_TILEMODE;
        size += sizeof(uint32_t); // SkTileMode
    }

    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));
    }
    if (flatFlags & SAVELAYERREC_HAS_MULTIPLE_FILTERS) {
        this->addInt(filterCount);
        for (uint32_t i = 0; i < filterCount; ++i) {
            // overkill to store a paint, oh well.
            SkPaint paint;
            paint.setImageFilter(rec.fFilters[i]);
            this->addPaint(paint);
        }
    }
    if (rec.fBackdropTileMode != SkTileMode::kClamp) {
        this->addInt((int) rec.fBackdropTileMode);
    }
    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.empty()) {
        return;
    }

    this->recordRestore();

    fRestoreOffsetStack.pop_back();

    this->SkCanvasVirtualEnforcer<SkCanvas>::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->SkCanvasVirtualEnforcer<SkCanvas>::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->SkCanvasVirtualEnforcer<SkCanvas>::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.back();
    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.empty()) {
        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.back();

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

void SkPictureRecord::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle);
    this->SkCanvasVirtualEnforcer<SkCanvas>::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.empty()) {
        // + 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->SkCanvasVirtualEnforcer<SkCanvas>::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.empty()) {
        // + 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->SkCanvasVirtualEnforcer<SkCanvas>::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.empty()) {
        // + 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->SkCanvasVirtualEnforcer<SkCanvas>::onClipShader(std::move(cs), op);
}

void SkPictureRecord::onClipRegion(const SkRegion& region, SkClipOp op) {
    this->recordClipRegion(region, op);
    this->SkCanvasVirtualEnforcer<SkCanvas>::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.empty()) {
        // + 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.empty()) {
        // 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->SkCanvasVirtualEnforcer<SkCanvas>::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);
}

void SkPictureRecord::onDrawSlug(const sktext::gpu::Slug* slug, const SkPaint& paint) {
    // op + paint index + slug id
    size_t size = 3 * kUInt32Size;
    size_t initialOffset = this->addDraw(DRAW_SLUG, &size);

    this->addPaint(paint);
    this->addSlug(slug);
    this->validate(initialOffset, size);
}

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(TArray<sk_sp<T>>& array, T* obj) {
    for (int i = 0; i < array.size(); i++) {
        if (equals(array[i].get(), obj)) {
            return i;
        }
    }

    array.push_back(sk_ref_sp(obj));

    return array.size() - 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.size());
    } 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);
}

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

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