/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "RecordingCanvas.h"

#include "VectorDrawable.h"

#include "SkAndroidFrameworkUtils.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkDrawShadowInfo.h"
#include "SkImage.h"
#include "SkImageFilter.h"
#include "SkLatticeIter.h"
#include "SkMath.h"
#include "SkPicture.h"
#include "SkRSXform.h"
#include "SkRegion.h"
#include "SkTextBlob.h"
#include "SkVertices.h"

#include <experimental/type_traits>

namespace android {
namespace uirenderer {

#ifndef SKLITEDL_PAGE
#define SKLITEDL_PAGE 4096
#endif

// A stand-in for an optional SkRect which was not set, e.g. bounds for a saveLayer().
static const SkRect kUnset = {SK_ScalarInfinity, 0, 0, 0};
static const SkRect* maybe_unset(const SkRect& r) {
    return r.left() == SK_ScalarInfinity ? nullptr : &r;
}

// copy_v(dst, src,n, src,n, ...) copies an arbitrary number of typed srcs into dst.
static void copy_v(void* dst) {}

template <typename S, typename... Rest>
static void copy_v(void* dst, const S* src, int n, Rest&&... rest) {
    SkASSERTF(((uintptr_t)dst & (alignof(S) - 1)) == 0,
              "Expected %p to be aligned for at least %zu bytes.", dst, alignof(S));
    sk_careful_memcpy(dst, src, n * sizeof(S));
    copy_v(SkTAddOffset<void>(dst, n * sizeof(S)), std::forward<Rest>(rest)...);
}

// Helper for getting back at arrays which have been copy_v'd together after an Op.
template <typename D, typename T>
static const D* pod(const T* op, size_t offset = 0) {
    return SkTAddOffset<const D>(op + 1, offset);
}

namespace {

#define X(T) T,
enum class Type : uint8_t {
#include "DisplayListOps.in"
};
#undef X

struct Op {
    uint32_t type : 8;
    uint32_t skip : 24;
};
static_assert(sizeof(Op) == 4, "");

struct Flush final : Op {
    static const auto kType = Type::Flush;
    void draw(SkCanvas* c, const SkMatrix&) const { c->flush(); }
};

struct Save final : Op {
    static const auto kType = Type::Save;
    void draw(SkCanvas* c, const SkMatrix&) const { c->save(); }
};
struct Restore final : Op {
    static const auto kType = Type::Restore;
    void draw(SkCanvas* c, const SkMatrix&) const { c->restore(); }
};
struct SaveLayer final : Op {
    static const auto kType = Type::SaveLayer;
    SaveLayer(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
              const SkImage* clipMask, const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
        if (bounds) {
            this->bounds = *bounds;
        }
        if (paint) {
            this->paint = *paint;
        }
        this->backdrop = sk_ref_sp(backdrop);
        this->clipMask = sk_ref_sp(clipMask);
        this->clipMatrix = clipMatrix ? *clipMatrix : SkMatrix::I();
        this->flags = flags;
    }
    SkRect bounds = kUnset;
    SkPaint paint;
    sk_sp<const SkImageFilter> backdrop;
    sk_sp<const SkImage> clipMask;
    SkMatrix clipMatrix;
    SkCanvas::SaveLayerFlags flags;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->saveLayer({maybe_unset(bounds), &paint, backdrop.get(), clipMask.get(),
                      clipMatrix.isIdentity() ? nullptr : &clipMatrix, flags});
    }
};
struct SaveBehind final : Op {
    static const auto kType = Type::SaveBehind;
    SaveBehind(const SkRect* subset) {
        if (subset) { this->subset = *subset; }
    }
    SkRect  subset = kUnset;
    void draw(SkCanvas* c, const SkMatrix&) const {
        SkAndroidFrameworkUtils::SaveBehind(c, &subset);
    }
};

struct Concat final : Op {
    static const auto kType = Type::Concat;
    Concat(const SkMatrix& matrix) : matrix(matrix) {}
    SkMatrix matrix;
    void draw(SkCanvas* c, const SkMatrix&) const { c->concat(matrix); }
};
struct SetMatrix final : Op {
    static const auto kType = Type::SetMatrix;
    SetMatrix(const SkMatrix& matrix) : matrix(matrix) {}
    SkMatrix matrix;
    void draw(SkCanvas* c, const SkMatrix& original) const {
        c->setMatrix(SkMatrix::Concat(original, matrix));
    }
};
struct Translate final : Op {
    static const auto kType = Type::Translate;
    Translate(SkScalar dx, SkScalar dy) : dx(dx), dy(dy) {}
    SkScalar dx, dy;
    void draw(SkCanvas* c, const SkMatrix&) const { c->translate(dx, dy); }
};

struct ClipPath final : Op {
    static const auto kType = Type::ClipPath;
    ClipPath(const SkPath& path, SkClipOp op, bool aa) : path(path), op(op), aa(aa) {}
    SkPath path;
    SkClipOp op;
    bool aa;
    void draw(SkCanvas* c, const SkMatrix&) const { c->clipPath(path, op, aa); }
};
struct ClipRect final : Op {
    static const auto kType = Type::ClipRect;
    ClipRect(const SkRect& rect, SkClipOp op, bool aa) : rect(rect), op(op), aa(aa) {}
    SkRect rect;
    SkClipOp op;
    bool aa;
    void draw(SkCanvas* c, const SkMatrix&) const { c->clipRect(rect, op, aa); }
};
struct ClipRRect final : Op {
    static const auto kType = Type::ClipRRect;
    ClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) : rrect(rrect), op(op), aa(aa) {}
    SkRRect rrect;
    SkClipOp op;
    bool aa;
    void draw(SkCanvas* c, const SkMatrix&) const { c->clipRRect(rrect, op, aa); }
};
struct ClipRegion final : Op {
    static const auto kType = Type::ClipRegion;
    ClipRegion(const SkRegion& region, SkClipOp op) : region(region), op(op) {}
    SkRegion region;
    SkClipOp op;
    void draw(SkCanvas* c, const SkMatrix&) const { c->clipRegion(region, op); }
};

struct DrawPaint final : Op {
    static const auto kType = Type::DrawPaint;
    DrawPaint(const SkPaint& paint) : paint(paint) {}
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
};
struct DrawPath final : Op {
    static const auto kType = Type::DrawPath;
    DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
    SkPath path;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawPath(path, paint); }
};
struct DrawRect final : Op {
    static const auto kType = Type::DrawRect;
    DrawRect(const SkRect& rect, const SkPaint& paint) : rect(rect), paint(paint) {}
    SkRect rect;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawRect(rect, paint); }
};
struct DrawRegion final : Op {
    static const auto kType = Type::DrawRegion;
    DrawRegion(const SkRegion& region, const SkPaint& paint) : region(region), paint(paint) {}
    SkRegion region;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawRegion(region, paint); }
};
struct DrawOval final : Op {
    static const auto kType = Type::DrawOval;
    DrawOval(const SkRect& oval, const SkPaint& paint) : oval(oval), paint(paint) {}
    SkRect oval;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawOval(oval, paint); }
};
struct DrawArc final : Op {
    static const auto kType = Type::DrawArc;
    DrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
            const SkPaint& paint)
            : oval(oval)
            , startAngle(startAngle)
            , sweepAngle(sweepAngle)
            , useCenter(useCenter)
            , paint(paint) {}
    SkRect oval;
    SkScalar startAngle;
    SkScalar sweepAngle;
    bool useCenter;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
    }
};
struct DrawRRect final : Op {
    static const auto kType = Type::DrawRRect;
    DrawRRect(const SkRRect& rrect, const SkPaint& paint) : rrect(rrect), paint(paint) {}
    SkRRect rrect;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawRRect(rrect, paint); }
};
struct DrawDRRect final : Op {
    static const auto kType = Type::DrawDRRect;
    DrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint)
            : outer(outer), inner(inner), paint(paint) {}
    SkRRect outer, inner;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawDRRect(outer, inner, paint); }
};

struct DrawAnnotation final : Op {
    static const auto kType = Type::DrawAnnotation;
    DrawAnnotation(const SkRect& rect, SkData* value) : rect(rect), value(sk_ref_sp(value)) {}
    SkRect rect;
    sk_sp<SkData> value;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawAnnotation(rect, pod<char>(this), value.get());
    }
};
struct DrawDrawable final : Op {
    static const auto kType = Type::DrawDrawable;
    DrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) : drawable(sk_ref_sp(drawable)) {
        if (matrix) {
            this->matrix = *matrix;
        }
    }
    sk_sp<SkDrawable> drawable;
    SkMatrix matrix = SkMatrix::I();
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get(), &matrix); }
};
struct DrawPicture final : Op {
    static const auto kType = Type::DrawPicture;
    DrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
            : picture(sk_ref_sp(picture)) {
        if (matrix) {
            this->matrix = *matrix;
        }
        if (paint) {
            this->paint = *paint;
            has_paint = true;
        }
    }
    sk_sp<const SkPicture> picture;
    SkMatrix matrix = SkMatrix::I();
    SkPaint paint;
    bool has_paint = false;  // TODO: why is a default paint not the same?
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawPicture(picture.get(), &matrix, has_paint ? &paint : nullptr);
    }
};

struct DrawImage final : Op {
    static const auto kType = Type::DrawImage;
    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint,
              BitmapPalette palette)
            : image(std::move(image)), x(x), y(y), palette(palette) {
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> image;
    SkScalar x, y;
    SkPaint paint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawImage(image.get(), x, y, &paint); }
};
struct DrawImageNine final : Op {
    static const auto kType = Type::DrawImageNine;
    DrawImageNine(sk_sp<const SkImage>&& image, const SkIRect& center, const SkRect& dst,
                  const SkPaint* paint)
            : image(std::move(image)), center(center), dst(dst) {
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> image;
    SkIRect center;
    SkRect dst;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawImageNine(image.get(), center, dst, &paint);
    }
};
struct DrawImageRect final : Op {
    static const auto kType = Type::DrawImageRect;
    DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
                  const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
                  BitmapPalette palette)
            : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) {
        this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> image;
    SkRect src, dst;
    SkPaint paint;
    SkCanvas::SrcRectConstraint constraint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawImageRect(image.get(), src, dst, &paint, constraint);
    }
};
struct DrawImageLattice final : Op {
    static const auto kType = Type::DrawImageLattice;
    DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
                     const SkRect& dst, const SkPaint* paint, BitmapPalette palette)
            : image(std::move(image))
            , xs(xs)
            , ys(ys)
            , fs(fs)
            , src(src)
            , dst(dst)
            , palette(palette) {
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> image;
    int xs, ys, fs;
    SkIRect src;
    SkRect dst;
    SkPaint paint;
    BitmapPalette palette;
    void draw(SkCanvas* c, const SkMatrix&) const {
        auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
        auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
        auto flags =
                (0 == fs) ? nullptr : pod<SkCanvas::Lattice::RectType>(
                                              this, (xs + ys) * sizeof(int) + fs * sizeof(SkColor));
        c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, &paint);
    }
};

struct DrawTextBlob final : Op {
    static const auto kType = Type::DrawTextBlob;
    DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
            : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
    sk_sp<const SkTextBlob> blob;
    SkScalar x, y;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawTextBlob(blob.get(), x, y, paint); }
};

struct DrawPatch final : Op {
    static const auto kType = Type::DrawPatch;
    DrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texs[4],
              SkBlendMode bmode, const SkPaint& paint)
            : xfermode(bmode), paint(paint) {
        copy_v(this->cubics, cubics, 12);
        if (colors) {
            copy_v(this->colors, colors, 4);
            has_colors = true;
        }
        if (texs) {
            copy_v(this->texs, texs, 4);
            has_texs = true;
        }
    }
    SkPoint cubics[12];
    SkColor colors[4];
    SkPoint texs[4];
    SkBlendMode xfermode;
    SkPaint paint;
    bool has_colors = false;
    bool has_texs = false;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawPatch(cubics, has_colors ? colors : nullptr, has_texs ? texs : nullptr, xfermode,
                     paint);
    }
};
struct DrawPoints final : Op {
    static const auto kType = Type::DrawPoints;
    DrawPoints(SkCanvas::PointMode mode, size_t count, const SkPaint& paint)
            : mode(mode), count(count), paint(paint) {}
    SkCanvas::PointMode mode;
    size_t count;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawPoints(mode, count, pod<SkPoint>(this), paint);
    }
};
struct DrawVertices final : Op {
    static const auto kType = Type::DrawVertices;
    DrawVertices(const SkVertices* v, int bc, SkBlendMode m, const SkPaint& p)
            : vertices(sk_ref_sp(const_cast<SkVertices*>(v))), boneCount(bc), mode(m), paint(p) {}
    sk_sp<SkVertices> vertices;
    int boneCount;
    SkBlendMode mode;
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const {
        c->drawVertices(vertices, pod<SkVertices::Bone>(this), boneCount, mode, paint);
    }
};
struct DrawAtlas final : Op {
    static const auto kType = Type::DrawAtlas;
    DrawAtlas(const SkImage* atlas, int count, SkBlendMode xfermode, const SkRect* cull,
              const SkPaint* paint, bool has_colors)
            : atlas(sk_ref_sp(atlas)), count(count), xfermode(xfermode), has_colors(has_colors) {
        if (cull) {
            this->cull = *cull;
        }
        if (paint) {
            this->paint = *paint;
        }
    }
    sk_sp<const SkImage> atlas;
    int count;
    SkBlendMode xfermode;
    SkRect cull = kUnset;
    SkPaint paint;
    bool has_colors;
    void draw(SkCanvas* c, const SkMatrix&) const {
        auto xforms = pod<SkRSXform>(this, 0);
        auto texs = pod<SkRect>(this, count * sizeof(SkRSXform));
        auto colors = has_colors ? pod<SkColor>(this, count * (sizeof(SkRSXform) + sizeof(SkRect)))
                                 : nullptr;
        c->drawAtlas(atlas.get(), xforms, texs, colors, count, xfermode, maybe_unset(cull), &paint);
    }
};
struct DrawShadowRec final : Op {
    static const auto kType = Type::DrawShadowRec;
    DrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) : fPath(path), fRec(rec) {}
    SkPath fPath;
    SkDrawShadowRec fRec;
    void draw(SkCanvas* c, const SkMatrix&) const { c->private_draw_shadow_rec(fPath, fRec); }
};

struct DrawVectorDrawable final : Op {
    static const auto kType = Type::DrawVectorDrawable;
    DrawVectorDrawable(VectorDrawableRoot* tree)
            : mRoot(tree)
            , mBounds(tree->stagingProperties().getBounds())
            , palette(tree->computePalette()) {
        // Recording, so use staging properties
        tree->getPaintFor(&paint, tree->stagingProperties());
    }

    void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); }

    sp<VectorDrawableRoot> mRoot;
    SkRect mBounds;
    SkPaint paint;
    BitmapPalette palette;
};
}

template <typename T, typename... Args>
void* DisplayListData::push(size_t pod, Args&&... args) {
    size_t skip = SkAlignPtr(sizeof(T) + pod);
    SkASSERT(skip < (1 << 24));
    if (fUsed + skip > fReserved) {
        static_assert(SkIsPow2(SKLITEDL_PAGE), "This math needs updating for non-pow2.");
        // Next greater multiple of SKLITEDL_PAGE.
        fReserved = (fUsed + skip + SKLITEDL_PAGE) & ~(SKLITEDL_PAGE - 1);
        fBytes.realloc(fReserved);
    }
    SkASSERT(fUsed + skip <= fReserved);
    auto op = (T*)(fBytes.get() + fUsed);
    fUsed += skip;
    new (op) T{std::forward<Args>(args)...};
    op->type = (uint32_t)T::kType;
    op->skip = skip;
    return op + 1;
}

template <typename Fn, typename... Args>
inline void DisplayListData::map(const Fn fns[], Args... args) const {
    auto end = fBytes.get() + fUsed;
    for (const uint8_t* ptr = fBytes.get(); ptr < end;) {
        auto op = (const Op*)ptr;
        auto type = op->type;
        auto skip = op->skip;
        if (auto fn = fns[type]) {  // We replace no-op functions with nullptrs
            fn(op, args...);        // to avoid the overhead of a pointless call.
        }
        ptr += skip;
    }
}

void DisplayListData::flush() {
    this->push<Flush>(0);
}

void DisplayListData::save() {
    this->push<Save>(0);
}
void DisplayListData::restore() {
    this->push<Restore>(0);
}
void DisplayListData::saveLayer(const SkRect* bounds, const SkPaint* paint,
                                const SkImageFilter* backdrop, const SkImage* clipMask,
                                const SkMatrix* clipMatrix, SkCanvas::SaveLayerFlags flags) {
    this->push<SaveLayer>(0, bounds, paint, backdrop, clipMask, clipMatrix, flags);
}

void DisplayListData::saveBehind(const SkRect* subset) {
    this->push<SaveBehind>(0, subset);
}

void DisplayListData::concat(const SkMatrix& matrix) {
    this->push<Concat>(0, matrix);
}
void DisplayListData::setMatrix(const SkMatrix& matrix) {
    this->push<SetMatrix>(0, matrix);
}
void DisplayListData::translate(SkScalar dx, SkScalar dy) {
    this->push<Translate>(0, dx, dy);
}

void DisplayListData::clipPath(const SkPath& path, SkClipOp op, bool aa) {
    this->push<ClipPath>(0, path, op, aa);
}
void DisplayListData::clipRect(const SkRect& rect, SkClipOp op, bool aa) {
    this->push<ClipRect>(0, rect, op, aa);
}
void DisplayListData::clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
    this->push<ClipRRect>(0, rrect, op, aa);
}
void DisplayListData::clipRegion(const SkRegion& region, SkClipOp op) {
    this->push<ClipRegion>(0, region, op);
}

void DisplayListData::drawPaint(const SkPaint& paint) {
    this->push<DrawPaint>(0, paint);
}
void DisplayListData::drawPath(const SkPath& path, const SkPaint& paint) {
    this->push<DrawPath>(0, path, paint);
}
void DisplayListData::drawRect(const SkRect& rect, const SkPaint& paint) {
    this->push<DrawRect>(0, rect, paint);
}
void DisplayListData::drawRegion(const SkRegion& region, const SkPaint& paint) {
    this->push<DrawRegion>(0, region, paint);
}
void DisplayListData::drawOval(const SkRect& oval, const SkPaint& paint) {
    this->push<DrawOval>(0, oval, paint);
}
void DisplayListData::drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
                              bool useCenter, const SkPaint& paint) {
    this->push<DrawArc>(0, oval, startAngle, sweepAngle, useCenter, paint);
}
void DisplayListData::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
    this->push<DrawRRect>(0, rrect, paint);
}
void DisplayListData::drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) {
    this->push<DrawDRRect>(0, outer, inner, paint);
}

void DisplayListData::drawAnnotation(const SkRect& rect, const char* key, SkData* value) {
    size_t bytes = strlen(key) + 1;
    void* pod = this->push<DrawAnnotation>(bytes, rect, value);
    copy_v(pod, key, bytes);
}
void DisplayListData::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
    this->push<DrawDrawable>(0, drawable, matrix);
}
void DisplayListData::drawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                  const SkPaint* paint) {
    this->push<DrawPicture>(0, picture, matrix, paint);
}
void DisplayListData::drawImage(sk_sp<const SkImage> image, SkScalar x, SkScalar y,
                                const SkPaint* paint, BitmapPalette palette) {
    this->push<DrawImage>(0, std::move(image), x, y, paint, palette);
}
void DisplayListData::drawImageNine(sk_sp<const SkImage> image, const SkIRect& center,
                                    const SkRect& dst, const SkPaint* paint) {
    this->push<DrawImageNine>(0, std::move(image), center, dst, paint);
}
void DisplayListData::drawImageRect(sk_sp<const SkImage> image, const SkRect* src,
                                    const SkRect& dst, const SkPaint* paint,
                                    SkCanvas::SrcRectConstraint constraint, BitmapPalette palette) {
    this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
}
void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
                                       const SkRect& dst, const SkPaint* paint,
                                       BitmapPalette palette) {
    int xs = lattice.fXCount, ys = lattice.fYCount;
    int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
    size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
                   fs * sizeof(SkColor);
    SkASSERT(lattice.fBounds);
    void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
                                             dst, paint, palette);
    copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
           fs);
}

void DisplayListData::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                   const SkPaint& paint) {
    this->push<DrawTextBlob>(0, blob, x, y, paint);
    mHasText = true;
}

void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
                                const SkPoint texs[4], SkBlendMode bmode, const SkPaint& paint) {
    this->push<DrawPatch>(0, points, colors, texs, bmode, paint);
}
void DisplayListData::drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint points[],
                                 const SkPaint& paint) {
    void* pod = this->push<DrawPoints>(count * sizeof(SkPoint), mode, count, paint);
    copy_v(pod, points, count);
}
void DisplayListData::drawVertices(const SkVertices* vertices, const SkVertices::Bone bones[],
                                   int boneCount, SkBlendMode mode, const SkPaint& paint) {
    void* pod = this->push<DrawVertices>(boneCount * sizeof(SkVertices::Bone), vertices, boneCount,
                                         mode, paint);
    copy_v(pod, bones, boneCount);
}
void DisplayListData::drawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
                                const SkColor colors[], int count, SkBlendMode xfermode,
                                const SkRect* cull, const SkPaint* paint) {
    size_t bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
    if (colors) {
        bytes += count * sizeof(SkColor);
    }
    void* pod =
            this->push<DrawAtlas>(bytes, atlas, count, xfermode, cull, paint, colors != nullptr);
    copy_v(pod, xforms, count, texs, count, colors, colors ? count : 0);
}
void DisplayListData::drawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    this->push<DrawShadowRec>(0, path, rec);
}
void DisplayListData::drawVectorDrawable(VectorDrawableRoot* tree) {
    this->push<DrawVectorDrawable>(0, tree);
}

typedef void (*draw_fn)(const void*, SkCanvas*, const SkMatrix&);
typedef void (*void_fn)(const void*);
typedef void (*color_transform_fn)(const void*, ColorTransform);

// All ops implement draw().
#define X(T)                                                    \
    [](const void* op, SkCanvas* c, const SkMatrix& original) { \
        ((const T*)op)->draw(c, original);                      \
    },
static const draw_fn draw_fns[] = {
#include "DisplayListOps.in"
};
#undef X

// Most state ops (matrix, clip, save, restore) have a trivial destructor.
#define X(T)                                                                                 \
    !std::is_trivially_destructible<T>::value ? [](const void* op) { ((const T*)op)->~T(); } \
                                              : (void_fn) nullptr,

static const void_fn dtor_fns[] = {
#include "DisplayListOps.in"
};
#undef X

void DisplayListData::draw(SkCanvas* canvas) const {
    SkAutoCanvasRestore acr(canvas, false);
    this->map(draw_fns, canvas, canvas->getTotalMatrix());
}

DisplayListData::~DisplayListData() {
    this->reset();
}

void DisplayListData::reset() {
    this->map(dtor_fns);

    // Leave fBytes and fReserved alone.
    fUsed = 0;
}

template <class T>
using has_paint_helper = decltype(std::declval<T>().paint);

template <class T>
constexpr bool has_paint = std::experimental::is_detected_v<has_paint_helper, T>;

template <class T>
using has_palette_helper = decltype(std::declval<T>().palette);

template <class T>
constexpr bool has_palette = std::experimental::is_detected_v<has_palette_helper, T>;

template <class T>
constexpr color_transform_fn colorTransformForOp() {
    if
        constexpr(has_paint<T> && has_palette<T>) {
            // It's a bitmap
            return [](const void* opRaw, ColorTransform transform) {
                // TODO: We should be const. Or not. Or just use a different map
                // Unclear, but this is the quick fix
                const T* op = reinterpret_cast<const T*>(opRaw);
                transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
            };
        }
    else if
        constexpr(has_paint<T>) {
            return [](const void* opRaw, ColorTransform transform) {
                // TODO: We should be const. Or not. Or just use a different map
                // Unclear, but this is the quick fix
                const T* op = reinterpret_cast<const T*>(opRaw);
                transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
            };
        }
    else {
        return nullptr;
    }
}

#define X(T) colorTransformForOp<T>(),
static const color_transform_fn color_transform_fns[] = {
#include "DisplayListOps.in"
};
#undef X

void DisplayListData::applyColorTransform(ColorTransform transform) {
    this->map(color_transform_fns, transform);
}

RecordingCanvas::RecordingCanvas() : INHERITED(1, 1), fDL(nullptr) {}

void RecordingCanvas::reset(DisplayListData* dl, const SkIRect& bounds) {
    this->resetCanvas(bounds.right(), bounds.bottom());
    fDL = dl;
    mClipMayBeComplex = false;
    mSaveCount = mComplexSaveCount = 0;
}

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

void RecordingCanvas::onFlush() {
    fDL->flush();
}

void RecordingCanvas::willSave() {
    mSaveCount++;
    fDL->save();
}
SkCanvas::SaveLayerStrategy RecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
    fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fClipMask, rec.fClipMatrix,
                   rec.fSaveLayerFlags);
    return SkCanvas::kNoLayer_SaveLayerStrategy;
}
void RecordingCanvas::willRestore() {
    mSaveCount--;
    if (mSaveCount < mComplexSaveCount) {
        mClipMayBeComplex = false;
        mComplexSaveCount = 0;
    }
    fDL->restore();
}

bool RecordingCanvas::onDoSaveBehind(const SkRect* subset) {
    fDL->saveBehind(subset);
    return false;
}

void RecordingCanvas::didConcat(const SkMatrix& matrix) {
    fDL->concat(matrix);
}
void RecordingCanvas::didSetMatrix(const SkMatrix& matrix) {
    fDL->setMatrix(matrix);
}
void RecordingCanvas::didTranslate(SkScalar dx, SkScalar dy) {
    fDL->translate(dx, dy);
}

void RecordingCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle style) {
    fDL->clipRect(rect, op, style == kSoft_ClipEdgeStyle);
    if (!getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    this->INHERITED::onClipRect(rect, op, style);
}
void RecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle style) {
    if (rrect.getType() > SkRRect::kRect_Type || !getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    fDL->clipRRect(rrect, op, style == kSoft_ClipEdgeStyle);
    this->INHERITED::onClipRRect(rrect, op, style);
}
void RecordingCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle style) {
    setClipMayBeComplex();
    fDL->clipPath(path, op, style == kSoft_ClipEdgeStyle);
    this->INHERITED::onClipPath(path, op, style);
}
void RecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp op) {
    if (region.isComplex() || !getTotalMatrix().isScaleTranslate()) {
        setClipMayBeComplex();
    }
    fDL->clipRegion(region, op);
    this->INHERITED::onClipRegion(region, op);
}

void RecordingCanvas::onDrawPaint(const SkPaint& paint) {
    fDL->drawPaint(paint);
}
void RecordingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    fDL->drawPath(path, paint);
}
void RecordingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    fDL->drawRect(rect, paint);
}
void RecordingCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
    fDL->drawRegion(region, paint);
}
void RecordingCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
    fDL->drawOval(oval, paint);
}
void RecordingCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
                                bool useCenter, const SkPaint& paint) {
    fDL->drawArc(oval, startAngle, sweepAngle, useCenter, paint);
}
void RecordingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    fDL->drawRRect(rrect, paint);
}
void RecordingCanvas::onDrawDRRect(const SkRRect& out, const SkRRect& in, const SkPaint& paint) {
    fDL->drawDRRect(out, in, paint);
}

void RecordingCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
    fDL->drawDrawable(drawable, matrix);
}
void RecordingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                    const SkPaint* paint) {
    fDL->drawPicture(picture, matrix, paint);
}
void RecordingCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* val) {
    fDL->drawAnnotation(rect, key, val);
}

void RecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                     const SkPaint& paint) {
    fDL->drawTextBlob(blob, x, y, paint);
}

void RecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y,
                                   const SkPaint* paint) {
    fDL->drawImage(SkImage::MakeFromBitmap(bm), x, y, paint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, const SkRect& dst,
                                       const SkPaint* paint) {
    fDL->drawImageNine(SkImage::MakeFromBitmap(bm), center, dst, paint);
}
void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
                                       const SkPaint* paint, SrcRectConstraint constraint) {
    fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint,
                       BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice,
                                          const SkRect& dst, const SkPaint* paint) {
    fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown);
}

void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
                                const SkPaint* paint, BitmapPalette palette) {
    fDL->drawImage(image, x, y, paint, palette);
}

void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
                                    const SkRect& dst, const SkPaint* paint,
                                    SrcRectConstraint constraint, BitmapPalette palette) {
    fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
}

void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
                                       const SkRect& dst, const SkPaint* paint,
                                       BitmapPalette palette) {
    if (!image || dst.isEmpty()) {
        return;
    }

    SkIRect bounds;
    Lattice latticePlusBounds = lattice;
    if (!latticePlusBounds.fBounds) {
        bounds = SkIRect::MakeWH(image->width(), image->height());
        latticePlusBounds.fBounds = &bounds;
    }

    if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
        fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette);
    } else {
        fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint,
                           palette);
    }
}

void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
                                  const SkPaint* paint) {
    fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst,
                                      const SkPaint* paint) {
    fDL->drawImageNine(sk_ref_sp(img), center, dst, paint);
}
void RecordingCanvas::onDrawImageRect(const SkImage* img, const SkRect* src, const SkRect& dst,
                                      const SkPaint* paint, SrcRectConstraint constraint) {
    fDL->drawImageRect(sk_ref_sp(img), src, dst, paint, constraint, BitmapPalette::Unknown);
}
void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
                                         const SkRect& dst, const SkPaint* paint) {
    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown);
}

void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                                  const SkPoint texCoords[4], SkBlendMode bmode,
                                  const SkPaint& paint) {
    fDL->drawPatch(cubics, colors, texCoords, bmode, paint);
}
void RecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
                                   const SkPaint& paint) {
    fDL->drawPoints(mode, count, pts, paint);
}
void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices,
                                           const SkVertices::Bone bones[], int boneCount,
                                           SkBlendMode mode, const SkPaint& paint) {
    fDL->drawVertices(vertices, bones, boneCount, mode, paint);
}
void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[],
                                  const SkRect texs[], const SkColor colors[], int count,
                                  SkBlendMode bmode, const SkRect* cull, const SkPaint* paint) {
    fDL->drawAtlas(atlas, xforms, texs, colors, count, bmode, cull, paint);
}
void RecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    fDL->drawShadowRec(path, rec);
}

void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
    fDL->drawVectorDrawable(tree);
}

}  // namespace uirenderer
}  // namespace android
