/*
 * 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 "pipeline/skia/FunctorDrawable.h"
#include "VectorDrawable.h"

#include "SkAndroidFrameworkUtils.h"
#include "SkCanvas.h"
#include "SkCanvasPriv.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 Concat44 final : Op {
    static const auto kType = Type::Concat44;
    Concat44(const SkScalar m[16]) { memcpy(colMajor, m, sizeof(colMajor)); }
    SkScalar colMajor[16];
    void draw(SkCanvas* c, const SkMatrix&) const { c->experimental_concat44(colMajor); }
};
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 Scale final : Op {
    static const auto kType = Type::Scale;
    Scale(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {}
    SkScalar sx, sy;
    void draw(SkCanvas* c, const SkMatrix&) const { c->scale(sx, sy); }
};
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 DrawBehind final : Op {
    static const auto kType = Type::DrawBehind;
    DrawBehind(const SkPaint& paint) : paint(paint) {}
    SkPaint paint;
    void draw(SkCanvas* c, const SkMatrix&) const { SkCanvasPriv::DrawBehind(c, 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();
    // It is important that we call drawable->draw(c) here instead of c->drawDrawable(drawable).
    // Drawables are mutable and in cases, like RenderNodeDrawable, are not expected to produce the
    // same content if retained outside the duration of the frame. Therefore we resolve
    // them now and do not allow the canvas to take a reference to the drawable and potentially
    // keep it alive for longer than the frames duration (e.g. SKP serialization).
    void draw(SkCanvas* c, const SkMatrix&) const { drawable->draw(c, &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;
};
struct DrawWebView final : Op {
    static const auto kType = Type::DrawWebView;
    DrawWebView(skiapipeline::FunctorDrawable* drawable) : drawable(sk_ref_sp(drawable)) {}
    sk_sp<skiapipeline::FunctorDrawable> drawable;
    // We can't invoke SkDrawable::draw directly, because VkFunctorDrawable expects
    // SkDrawable::onSnapGpuDrawHandler callback instead of SkDrawable::onDraw.
    // SkCanvas::drawDrawable/SkGpuDevice::drawDrawable has the logic to invoke
    // onSnapGpuDrawHandler.
    void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get()); }
};
}

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::concat44(const SkScalar colMajor[16]) {
    this->push<Concat44>(0, colMajor);
}
void DisplayListData::concat(const SkMatrix& matrix) {
    this->push<Concat>(0, matrix);
}
void DisplayListData::setMatrix(const SkMatrix& matrix) {
    this->push<SetMatrix>(0, matrix);
}
void DisplayListData::scale(SkScalar sx, SkScalar sy) {
    this->push<Scale>(0, sx, sy);
}
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::drawBehind(const SkPaint& paint) {
    this->push<DrawBehind>(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);
}
void DisplayListData::drawWebView(skiapipeline::FunctorDrawable* drawable) {
    this->push<DrawWebView>(0, drawable);
}

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::didConcat44(const SkScalar colMajor[16]) {
    fDL->concat44(colMajor);
}
void RecordingCanvas::didConcat(const SkMatrix& matrix) {
    fDL->concat(matrix);
}
void RecordingCanvas::didSetMatrix(const SkMatrix& matrix) {
    fDL->setMatrix(matrix);
}
void RecordingCanvas::didScale(SkScalar sx, SkScalar sy) {
    fDL->scale(sx, sy);
}
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::onDrawBehind(const SkPaint& paint) {
    fDL->drawBehind(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);
}

void RecordingCanvas::drawWebView(skiapipeline::FunctorDrawable* drawable) {
    fDL->drawWebView(drawable);
}

}  // namespace uirenderer
}  // namespace android
