// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <type_traits>

#include "flutter/flow/display_list.h"
#include "flutter/flow/display_list_canvas.h"
#include "flutter/flow/display_list_utils.h"
#include "flutter/fml/logging.h"

#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRSXform.h"
#include "third_party/skia/include/core/SkTextBlob.h"

namespace flutter {

const SkSamplingOptions DisplayList::NearestSampling =
    SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone);
const SkSamplingOptions DisplayList::LinearSampling =
    SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
const SkSamplingOptions DisplayList::MipmapSampling =
    SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
const SkSamplingOptions DisplayList::CubicSampling =
    SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f});

// Most Ops can be bulk compared using memcmp because they contain
// only numeric values or constructs that are constructed from numeric
// values.
//
// Some contain sk_sp<> references which can also be bulk compared
// to see if they are pointing to the same reference. (Note that
// two sk_sp<> that refer to the same object are themselves ==.)
//
// Only a DLOp that wants to do a deep compare needs to override the
// DLOp::equals() method and return a value of kEqual or kNotEqual.
enum class DisplayListCompare {
  // The Op is deferring comparisons to a bulk memcmp performed lazily
  // across all bulk-comparable ops.
  kUseBulkCompare,

  // The Op provided a specific equals method that spotted a difference
  kNotEqual,

  // The Op provided a specific equals method that saw no differences
  kEqual,
};

#pragma pack(push, DLOp_Alignment, 8)

// Assuming a 64-bit platform (most of our platforms at this time?)
// the following comments are a "worst case" assessment of how well
// these structures pack into memory. They may be packed more tightly
// on some of the 32-bit platforms that we see in older phones.
//
// Struct allocation in the DL memory is aligned to a void* boundary
// which means that the minimum (aligned) struct size will be 8 bytes.
// The DLOp base uses 4 bytes so each Op-specific struct gets 4 bytes
// of data for "free" and works best when it packs well into an 8-byte
// aligned size.
struct DLOp {
  DisplayListOpType type : 8;
  uint32_t size : 24;

  DisplayListCompare equals(const DLOp* other) const {
    return DisplayListCompare::kUseBulkCompare;
  }
};

// 4 byte header + 4 byte payload packs into minimum 8 bytes
#define DEFINE_SET_BOOL_OP(name)                             \
  struct Set##name##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kSet##name; \
                                                             \
    Set##name##Op(bool value) : value(value) {}              \
                                                             \
    const bool value;                                        \
                                                             \
    void dispatch(Dispatcher& dispatcher) const {            \
      dispatcher.set##name(value);                           \
    }                                                        \
  };
DEFINE_SET_BOOL_OP(AA)
DEFINE_SET_BOOL_OP(Dither)
DEFINE_SET_BOOL_OP(InvertColors)
#undef DEFINE_SET_BOOL_OP

// 4 byte header + 4 byte payload packs into minimum 8 bytes
#define DEFINE_SET_ENUM_OP(name)                                \
  struct Set##name##s##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kSet##name##s; \
                                                                \
    Set##name##s##Op(SkPaint::name value) : value(value) {}     \
                                                                \
    const SkPaint::name value;                                  \
                                                                \
    void dispatch(Dispatcher& dispatcher) const {               \
      dispatcher.set##name##s(value);                           \
    }                                                           \
  };
DEFINE_SET_ENUM_OP(Cap)
DEFINE_SET_ENUM_OP(Join)
#undef DEFINE_SET_ENUM_OP

// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetDrawStyleOp final : DLOp {
  static const auto kType = DisplayListOpType::kSetDrawStyle;

  SetDrawStyleOp(SkPaint::Style style) : style(style) {}

  const SkPaint::Style style;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.setDrawStyle(style);
  }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetStrokeWidthOp final : DLOp {
  static const auto kType = DisplayListOpType::kSetStrokeWidth;

  SetStrokeWidthOp(SkScalar width) : width(width) {}

  const SkScalar width;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.setStrokeWidth(width);
  }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetMiterLimitOp final : DLOp {
  static const auto kType = DisplayListOpType::kSetMiterLimit;

  SetMiterLimitOp(SkScalar limit) : limit(limit) {}

  const SkScalar limit;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.setMiterLimit(limit);
  }
};

// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetColorOp final : DLOp {
  static const auto kType = DisplayListOpType::kSetColor;

  SetColorOp(SkColor color) : color(color) {}

  const SkColor color;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.setColor(color); }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetBlendModeOp final : DLOp {
  static const auto kType = DisplayListOpType::kSetBlendMode;

  SetBlendModeOp(SkBlendMode mode) : mode(mode) {}

  const SkBlendMode mode;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.setBlendMode(mode); }
};

// Clear: 4 byte header + unused 4 byte payload uses 8 bytes
//        (4 bytes unused)
// Set: 4 byte header + an sk_sp (ptr) uses 16 bytes due to the
//      alignment of the ptr.
//      (4 bytes unused)
#define DEFINE_SET_CLEAR_SKREF_OP(name, field)                        \
  struct Clear##name##Op final : DLOp {                               \
    static const auto kType = DisplayListOpType::kClear##name;        \
                                                                      \
    Clear##name##Op() {}                                              \
                                                                      \
    void dispatch(Dispatcher& dispatcher) const {                     \
      dispatcher.set##name(nullptr);                                  \
    }                                                                 \
  };                                                                  \
  struct Set##name##Op final : DLOp {                                 \
    static const auto kType = DisplayListOpType::kSet##name;          \
                                                                      \
    Set##name##Op(sk_sp<Sk##name> field) : field(std::move(field)) {} \
                                                                      \
    sk_sp<Sk##name> field;                                            \
                                                                      \
    void dispatch(Dispatcher& dispatcher) const {                     \
      dispatcher.set##name(field);                                    \
    }                                                                 \
  };
DEFINE_SET_CLEAR_SKREF_OP(Blender, blender)
DEFINE_SET_CLEAR_SKREF_OP(Shader, shader)
DEFINE_SET_CLEAR_SKREF_OP(ImageFilter, filter)
DEFINE_SET_CLEAR_SKREF_OP(ColorFilter, filter)
DEFINE_SET_CLEAR_SKREF_OP(MaskFilter, filter)
DEFINE_SET_CLEAR_SKREF_OP(PathEffect, effect)
#undef DEFINE_SET_CLEAR_SKREF_OP

// 4 byte header + 4 byte payload packs into minimum 8 bytes
// Note that the "blur style" is packed into the OpType to prevent
// needing an additional 8 bytes for a 4-value enum.
#define DEFINE_MASK_BLUR_FILTER_OP(name, style)                            \
  struct SetMaskBlurFilter##name##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kSetMaskBlurFilter##name; \
                                                                           \
    SetMaskBlurFilter##name##Op(SkScalar sigma) : sigma(sigma) {}          \
                                                                           \
    SkScalar sigma;                                                        \
                                                                           \
    void dispatch(Dispatcher& dispatcher) const {                          \
      dispatcher.setMaskBlurFilter(style, sigma);                          \
    }                                                                      \
  };
DEFINE_MASK_BLUR_FILTER_OP(Normal, kNormal_SkBlurStyle)
DEFINE_MASK_BLUR_FILTER_OP(Solid, kSolid_SkBlurStyle)
DEFINE_MASK_BLUR_FILTER_OP(Inner, kInner_SkBlurStyle)
DEFINE_MASK_BLUR_FILTER_OP(Outer, kOuter_SkBlurStyle)
#undef DEFINE_MASK_BLUR_FILTER_OP

// 4 byte header + no payload uses minimum 8 bytes (4 bytes unused)
struct SaveOp final : DLOp {
  static const auto kType = DisplayListOpType::kSave;

  SaveOp() {}

  void dispatch(Dispatcher& dispatcher) const { dispatcher.save(); }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SaveLayerOp final : DLOp {
  static const auto kType = DisplayListOpType::kSaveLayer;

  SaveLayerOp(bool with_paint) : with_paint(with_paint) {}

  bool with_paint;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.saveLayer(nullptr, with_paint);
  }
};
// 4 byte header + 20 byte payload packs evenly into 24 bytes
struct SaveLayerBoundsOp final : DLOp {
  static const auto kType = DisplayListOpType::kSaveLayerBounds;

  SaveLayerBoundsOp(SkRect rect, bool with_paint)
      : with_paint(with_paint), rect(rect) {}

  bool with_paint;
  const SkRect rect;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.saveLayer(&rect, with_paint);
  }
};
// 4 byte header + no payload uses minimum 8 bytes (4 bytes unused)
struct RestoreOp final : DLOp {
  static const auto kType = DisplayListOpType::kRestore;

  RestoreOp() {}

  void dispatch(Dispatcher& dispatcher) const { dispatcher.restore(); }
};

// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct TranslateOp final : DLOp {
  static const auto kType = DisplayListOpType::kTranslate;

  TranslateOp(SkScalar tx, SkScalar ty) : tx(tx), ty(ty) {}

  const SkScalar tx;
  const SkScalar ty;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.translate(tx, ty); }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct ScaleOp final : DLOp {
  static const auto kType = DisplayListOpType::kScale;

  ScaleOp(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {}

  const SkScalar sx;
  const SkScalar sy;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.scale(sx, sy); }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct RotateOp final : DLOp {
  static const auto kType = DisplayListOpType::kRotate;

  RotateOp(SkScalar degrees) : degrees(degrees) {}

  const SkScalar degrees;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.rotate(degrees); }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct SkewOp final : DLOp {
  static const auto kType = DisplayListOpType::kSkew;

  SkewOp(SkScalar sx, SkScalar sy) : sx(sx), sy(sy) {}

  const SkScalar sx;
  const SkScalar sy;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.skew(sx, sy); }
};
// 4 byte header + 24 byte payload uses 28 bytes but is rounded up to 32 bytes
// (4 bytes unused)
struct Transform2x3Op final : DLOp {
  static const auto kType = DisplayListOpType::kTransform2x3;

  Transform2x3Op(SkScalar mxx,
                 SkScalar mxy,
                 SkScalar mxt,
                 SkScalar myx,
                 SkScalar myy,
                 SkScalar myt)
      : mxx(mxx), mxy(mxy), mxt(mxt), myx(myx), myy(myy), myt(myt) {}

  const SkScalar mxx, mxy, mxt;
  const SkScalar myx, myy, myt;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.transform2x3(mxx, mxy, mxt, myx, myy, myt);
  }
};
// 4 byte header + 36 byte payload packs evenly into 40 bytes
struct Transform3x3Op final : DLOp {
  static const auto kType = DisplayListOpType::kTransform3x3;

  Transform3x3Op(SkScalar mxx,
                 SkScalar mxy,
                 SkScalar mxt,
                 SkScalar myx,
                 SkScalar myy,
                 SkScalar myt,
                 SkScalar px,
                 SkScalar py,
                 SkScalar pt)
      : mxx(mxx),
        mxy(mxy),
        mxt(mxt),
        myx(myx),
        myy(myy),
        myt(myt),
        px(px),
        py(py),
        pt(pt) {}

  const SkScalar mxx, mxy, mxt;
  const SkScalar myx, myy, myt;
  const SkScalar px, py, pt;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.transform3x3(mxx, mxy, mxt, myx, myy, myt, px, py, pt);
  }
};

// 4 byte header + 4 byte common payload packs into minimum 8 bytes
// SkRect is 16 more bytes, which packs efficiently into 24 bytes total
// SkRRect is 52 more bytes, which rounds up to 56 bytes (4 bytes unused)
//         which packs into 64 bytes total
// SkPath is 16 more bytes, which packs efficiently into 24 bytes total
//
// We could pack the clip_op and the bool both into the free 4 bytes after
// the header, but the Windows compiler keeps wanting to expand that
// packing into more bytes than needed (even when they are declared as
// packed bit fields!)
#define DEFINE_CLIP_SHAPE_OP(shapetype, clipop)                            \
  struct Clip##clipop##shapetype##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kClip##clipop##shapetype; \
                                                                           \
    Clip##clipop##shapetype##Op(Sk##shapetype shape, bool is_aa)           \
        : is_aa(is_aa), shape(shape) {}                                    \
                                                                           \
    const bool is_aa;                                                      \
    const Sk##shapetype shape;                                             \
                                                                           \
    void dispatch(Dispatcher& dispatcher) const {                          \
      dispatcher.clip##shapetype(shape, is_aa, SkClipOp::k##clipop);       \
    }                                                                      \
  };
DEFINE_CLIP_SHAPE_OP(Rect, Intersect)
DEFINE_CLIP_SHAPE_OP(RRect, Intersect)
DEFINE_CLIP_SHAPE_OP(Rect, Difference)
DEFINE_CLIP_SHAPE_OP(RRect, Difference)
#undef DEFINE_CLIP_SHAPE_OP

#define DEFINE_CLIP_PATH_OP(clipop)                                      \
  struct Clip##clipop##PathOp final : DLOp {                             \
    static const auto kType = DisplayListOpType::kClip##clipop##Path;    \
                                                                         \
    Clip##clipop##PathOp(SkPath path, bool is_aa)                        \
        : is_aa(is_aa), path(path) {}                                    \
                                                                         \
    const bool is_aa;                                                    \
    const SkPath path;                                                   \
                                                                         \
    void dispatch(Dispatcher& dispatcher) const {                        \
      dispatcher.clipPath(path, is_aa, SkClipOp::k##clipop);             \
    }                                                                    \
                                                                         \
    DisplayListCompare equals(const Clip##clipop##PathOp* other) const { \
      return is_aa == other->is_aa && path == other->path                \
                 ? DisplayListCompare::kEqual                            \
                 : DisplayListCompare::kNotEqual;                        \
    }                                                                    \
  };
DEFINE_CLIP_PATH_OP(Intersect)
DEFINE_CLIP_PATH_OP(Difference)
#undef DEFINE_CLIP_PATH_OP

// 4 byte header + no payload uses minimum 8 bytes (4 bytes unused)
struct DrawPaintOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawPaint;

  DrawPaintOp() {}

  void dispatch(Dispatcher& dispatcher) const { dispatcher.drawPaint(); }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct DrawColorOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawColor;

  DrawColorOp(SkColor color, SkBlendMode mode) : color(color), mode(mode) {}

  const SkColor color;
  const SkBlendMode mode;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawColor(color, mode);
  }
};

// The common data is a 4 byte header with an unused 4 bytes
// SkRect is 16 more bytes, using 20 bytes which rounds up to 24 bytes total
//        (4 bytes unused)
// SkOval is same as SkRect
// SkRRect is 52 more bytes, which packs efficiently into 56 bytes total
#define DEFINE_DRAW_1ARG_OP(op_name, arg_type, arg_name)         \
  struct Draw##op_name##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kDraw##op_name; \
                                                                 \
    Draw##op_name##Op(arg_type arg_name) : arg_name(arg_name) {} \
                                                                 \
    const arg_type arg_name;                                     \
                                                                 \
    void dispatch(Dispatcher& dispatcher) const {                \
      dispatcher.draw##op_name(arg_name);                        \
    }                                                            \
  };
DEFINE_DRAW_1ARG_OP(Rect, SkRect, rect)
DEFINE_DRAW_1ARG_OP(Oval, SkRect, oval)
DEFINE_DRAW_1ARG_OP(RRect, SkRRect, rrect)
#undef DEFINE_DRAW_1ARG_OP

// 4 byte header + 16 byte payload uses 20 bytes but is rounded up to 24 bytes
// (4 bytes unused)
struct DrawPathOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawPath;

  DrawPathOp(SkPath path) : path(path) {}

  const SkPath path;

  void dispatch(Dispatcher& dispatcher) const { dispatcher.drawPath(path); }

  DisplayListCompare equals(const DrawPathOp* other) const {
    return path == other->path ? DisplayListCompare::kEqual
                               : DisplayListCompare::kNotEqual;
  }
};

// The common data is a 4 byte header with an unused 4 bytes
// 2 x SkPoint is 16 more bytes, using 20 bytes rounding up to 24 bytes total
//             (4 bytes unused)
// SkPoint + SkScalar is 12 more bytes, packing efficiently into 16 bytes total
// 2 x SkRRect is 104 more bytes, using 108 and rounding up to 112 bytes total
//             (4 bytes unused)
#define DEFINE_DRAW_2ARG_OP(op_name, type1, name1, type2, name2) \
  struct Draw##op_name##Op final : DLOp {                        \
    static const auto kType = DisplayListOpType::kDraw##op_name; \
                                                                 \
    Draw##op_name##Op(type1 name1, type2 name2)                  \
        : name1(name1), name2(name2) {}                          \
                                                                 \
    const type1 name1;                                           \
    const type2 name2;                                           \
                                                                 \
    void dispatch(Dispatcher& dispatcher) const {                \
      dispatcher.draw##op_name(name1, name2);                    \
    }                                                            \
  };
DEFINE_DRAW_2ARG_OP(Line, SkPoint, p0, SkPoint, p1)
DEFINE_DRAW_2ARG_OP(Circle, SkPoint, center, SkScalar, radius)
DEFINE_DRAW_2ARG_OP(DRRect, SkRRect, outer, SkRRect, inner)
#undef DEFINE_DRAW_2ARG_OP

// 4 byte header + 28 byte payload packs efficiently into 32 bytes
struct DrawArcOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawArc;

  DrawArcOp(SkRect bounds, SkScalar start, SkScalar sweep, bool center)
      : bounds(bounds), start(start), sweep(sweep), center(center) {}

  const SkRect bounds;
  const SkScalar start;
  const SkScalar sweep;
  const bool center;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawArc(bounds, start, sweep, center);
  }
};

// 4 byte header + 4 byte fixed payload packs efficiently into 8 bytes
// But then there is a list of points following the structure which
// is guaranteed to be a multiple of 8 bytes (SkPoint is 8 bytes)
// so this op will always pack efficiently
// The point type is packed into 3 different OpTypes to avoid expanding
// the fixed payload beyond the 8 bytes
#define DEFINE_DRAW_POINTS_OP(name, mode)                              \
  struct Draw##name##Op final : DLOp {                                 \
    static const auto kType = DisplayListOpType::kDraw##name;          \
                                                                       \
    Draw##name##Op(uint32_t count) : count(count) {}                   \
                                                                       \
    const uint32_t count;                                              \
                                                                       \
    void dispatch(Dispatcher& dispatcher) const {                      \
      const SkPoint* pts = reinterpret_cast<const SkPoint*>(this + 1); \
      dispatcher.drawPoints(SkCanvas::PointMode::mode, count, pts);    \
    }                                                                  \
  };
DEFINE_DRAW_POINTS_OP(Points, kPoints_PointMode);
DEFINE_DRAW_POINTS_OP(Lines, kLines_PointMode);
DEFINE_DRAW_POINTS_OP(Polygon, kPolygon_PointMode);
#undef DEFINE_DRAW_POINTS_OP

// 4 byte header + 12 byte payload packs efficiently into 16 bytes
struct DrawVerticesOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawVertices;

  DrawVerticesOp(sk_sp<SkVertices> vertices, SkBlendMode mode)
      : mode(mode), vertices(std::move(vertices)) {}

  const SkBlendMode mode;
  const sk_sp<SkVertices> vertices;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawVertices(vertices, mode);
  }
};

// 4 byte header + 36 byte payload packs efficiently into 40 bytes
struct DrawImageOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawImage;

  DrawImageOp(const sk_sp<SkImage> image,
              const SkPoint& point,
              const SkSamplingOptions& sampling)
      : point(point), sampling(sampling), image(std::move(image)) {}

  const SkPoint point;
  const SkSamplingOptions sampling;
  const sk_sp<SkImage> image;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawImage(image, point, sampling);
  }
};

// 4 byte header + 60 byte payload packs efficiently into 64 bytes
//
// The constraint could be stored in the struct, but it would not pack
// efficiently so 2 variants are defined instead.
#define DEFINE_DRAW_IMAGE_RECT_OP(name, constraint)                          \
  struct Draw##name##Op final : DLOp {                                       \
    static const auto kType = DisplayListOpType::kDraw##name;                \
                                                                             \
    Draw##name##Op(const sk_sp<SkImage> image,                               \
                   const SkRect& src,                                        \
                   const SkRect& dst,                                        \
                   const SkSamplingOptions& sampling)                        \
        : src(src), dst(dst), sampling(sampling), image(std::move(image)) {} \
                                                                             \
    const SkRect src;                                                        \
    const SkRect dst;                                                        \
    const SkSamplingOptions sampling;                                        \
    const sk_sp<SkImage> image;                                              \
                                                                             \
    void dispatch(Dispatcher& dispatcher) const {                            \
      dispatcher.drawImageRect(image, src, dst, sampling, constraint);       \
    }                                                                        \
  };
DEFINE_DRAW_IMAGE_RECT_OP(ImageRectStrict, SkCanvas::kStrict_SrcRectConstraint)
DEFINE_DRAW_IMAGE_RECT_OP(ImageRectFast, SkCanvas::kFast_SrcRectConstraint)
#undef DEFINE_DRAW_IMAGE_RECT_OP

// 4 byte header + 44 byte payload packs efficiently into 48 bytes
struct DrawImageNineOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawImageNine;

  DrawImageNineOp(const sk_sp<SkImage> image,
                  const SkIRect& center,
                  const SkRect& dst,
                  SkFilterMode filter)
      : center(center), dst(dst), filter(filter), image(std::move(image)) {}

  const SkIRect center;
  const SkRect dst;
  const SkFilterMode filter;
  const sk_sp<SkImage> image;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawImageNine(image, center, dst, filter);
  }
};

// 4 byte header + 60 byte payload packs evenly into 64 bytes
struct DrawImageLatticeOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawImageLattice;

  DrawImageLatticeOp(const sk_sp<SkImage> image,
                     int x_count,
                     int y_count,
                     int cell_count,
                     const SkIRect& src,
                     const SkRect& dst,
                     SkFilterMode filter,
                     bool with_paint)
      : with_paint(with_paint),
        x_count(x_count),
        y_count(y_count),
        cell_count(cell_count),
        filter(filter),
        src(src),
        dst(dst),
        image(std::move(image)) {}

  const bool with_paint;
  const int x_count;
  const int y_count;
  const int cell_count;
  const SkFilterMode filter;
  const SkIRect src;
  const SkRect dst;
  const sk_sp<SkImage> image;

  void dispatch(Dispatcher& dispatcher) const {
    const int* xDivs = reinterpret_cast<const int*>(this + 1);
    const int* yDivs = reinterpret_cast<const int*>(xDivs + x_count);
    const SkColor* colors =
        (cell_count == 0) ? nullptr
                          : reinterpret_cast<const SkColor*>(yDivs + y_count);
    const SkCanvas::Lattice::RectType* types =
        (cell_count == 0)
            ? nullptr
            : reinterpret_cast<const SkCanvas::Lattice::RectType*>(colors +
                                                                   cell_count);
    dispatcher.drawImageLattice(
        image, {xDivs, yDivs, types, x_count, y_count, &src, colors}, dst,
        filter, with_paint);
  }
};

#define DRAW_ATLAS_NO_COLORS_ARRAY(tex, count) nullptr
#define DRAW_ATLAS_HAS_COLORS_ARRAY(tex, count) \
  reinterpret_cast<const SkColor*>(tex + count)

#define DRAW_ATLAS_NO_CULLING_ARGS                         \
  const sk_sp<SkImage> atlas, int count, SkBlendMode mode, \
      const SkSamplingOptions &sampling
#define DRAW_ATLAS_NO_CULLING_INIT \
  count(count), mode(mode), sampling(sampling), atlas(std::move(atlas))
#define DRAW_ATLAS_NO_CULLING_FIELDS \
  const int count;                   \
  const SkBlendMode mode;            \
  const SkSamplingOptions sampling;  \
  const sk_sp<SkImage> atlas
#define DRAW_ATLAS_NO_CULLING_P_ARG nullptr

#define DRAW_ATLAS_HAS_CULLING_ARGS \
  DRAW_ATLAS_NO_CULLING_ARGS, const SkRect& cull
#define DRAW_ATLAS_HAS_CULLING_INIT DRAW_ATLAS_NO_CULLING_INIT, cull(cull)
#define DRAW_ATLAS_HAS_CULLING_FIELDS \
  DRAW_ATLAS_NO_CULLING_FIELDS;       \
  const SkRect cull
#define DRAW_ATLAS_HAS_CULLING_P_ARG &cull

// 4 byte header + 36 byte common payload packs efficiently into 40 bytes
// Culling version has an additional 16 bytes of payload for 56 bytes
// So all 4 versions of the base structure pack well.
// Each of these is then followed by a number of lists.
// SkRSXform list is a multiple of 16 bytes so it is always packed well
// SkRect list is also a multiple of 16 bytes so it also packs well
// SkColor list only packs well if the count is even, otherwise there
// can be 4 unusued bytes at the end.
#define DEFINE_DRAW_ATLAS_OP(name, colors, cull)                             \
  struct Draw##name##Op final : DLOp {                                       \
    static const auto kType = DisplayListOpType::kDraw##name;                \
                                                                             \
    Draw##name##Op(DRAW_ATLAS_##cull##_ARGS) : DRAW_ATLAS_##cull##_INIT {}   \
                                                                             \
    DRAW_ATLAS_##cull##_FIELDS;                                              \
                                                                             \
    void dispatch(Dispatcher& dispatcher) const {                            \
      const SkRSXform* xform = reinterpret_cast<const SkRSXform*>(this + 1); \
      const SkRect* tex = reinterpret_cast<const SkRect*>(xform + count);    \
      const SkColor* colors = DRAW_ATLAS_##colors##_ARRAY(tex, count);       \
      dispatcher.drawAtlas(atlas, xform, tex, colors, count, mode, sampling, \
                           DRAW_ATLAS_##cull##_P_ARG);                       \
    }                                                                        \
  };
DEFINE_DRAW_ATLAS_OP(Atlas, NO_COLORS, NO_CULLING)
DEFINE_DRAW_ATLAS_OP(AtlasColored, HAS_COLORS, NO_CULLING)
DEFINE_DRAW_ATLAS_OP(AtlasCulled, NO_COLORS, HAS_CULLING)
DEFINE_DRAW_ATLAS_OP(AtlasColoredCulled, HAS_COLORS, HAS_CULLING)
#undef DEFINE_DRAW_ATLAS_OP
#undef DRAW_ATLAS_NO_COLORS_ARRAY
#undef DRAW_ATLAS_HAS_COLORS_ARRAY
#undef DRAW_ATLAS_NO_CULLING_ARGS
#undef DRAW_ATLAS_NO_CULLING_INIT
#undef DRAW_ATLAS_NO_CULLING_FIELDS
#undef DRAW_ATLAS_NO_CULLING_P_ARG
#undef DRAW_ATLAS_HAS_CULLING_ARGS
#undef DRAW_ATLAS_HAS_CULLING_INIT
#undef DRAW_ATLAS_HAS_CULLING_FIELDS
#undef DRAW_ATLAS_HAS_CULLING_P_ARG

// 4 byte header + 12 byte payload packs evenly into 16 bytes
struct DrawSkPictureOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawSkPicture;

  DrawSkPictureOp(sk_sp<SkPicture> picture, bool with_layer)
      : with_layer(with_layer), picture(std::move(picture)) {}

  const bool with_layer;
  const sk_sp<SkPicture> picture;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawPicture(picture, nullptr, with_layer);
  }
};

// 4 byte header + 52 byte payload packs evenly into 56 bytes
struct DrawSkPictureMatrixOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawSkPictureMatrix;

  DrawSkPictureMatrixOp(sk_sp<SkPicture> picture,
                        const SkMatrix matrix,
                        bool with_layer)
      : with_layer(with_layer), picture(std::move(picture)), matrix(matrix) {}

  const bool with_layer;
  const sk_sp<SkPicture> picture;
  const SkMatrix matrix;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawPicture(picture, &matrix, with_layer);
  }
};

// 4 byte header + ptr aligned payload uses 12 bytes rounde up to 16
// (4 bytes unused)
struct DrawDisplayListOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawDisplayList;

  DrawDisplayListOp(const sk_sp<DisplayList> display_list)
      : display_list(std::move(display_list)) {}

  sk_sp<DisplayList> display_list;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawDisplayList(display_list);
  }
};

// 4 byte header + 8 payload bytes + an aligned pointer take 24 bytes
// (4 unused to align the pointer)
struct DrawTextBlobOp final : DLOp {
  static const auto kType = DisplayListOpType::kDrawTextBlob;

  DrawTextBlobOp(const sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y)
      : x(x), y(y), blob(std::move(blob)) {}

  const SkScalar x;
  const SkScalar y;
  const sk_sp<SkTextBlob> blob;

  void dispatch(Dispatcher& dispatcher) const {
    dispatcher.drawTextBlob(blob, x, y);
  }
};

// 4 byte header + 28 byte payload packs evenly into 32 bytes
#define DEFINE_DRAW_SHADOW_OP(name, occludes)                         \
  struct Draw##name##Op final : DLOp {                                \
    static const auto kType = DisplayListOpType::kDraw##name;         \
                                                                      \
    Draw##name##Op(const SkPath& path,                                \
                   SkColor color,                                     \
                   SkScalar elevation,                                \
                   SkScalar dpr)                                      \
        : color(color), elevation(elevation), dpr(dpr), path(path) {} \
                                                                      \
    const SkColor color;                                              \
    const SkScalar elevation;                                         \
    const SkScalar dpr;                                               \
    const SkPath path;                                                \
                                                                      \
    void dispatch(Dispatcher& dispatcher) const {                     \
      dispatcher.drawShadow(path, color, elevation, occludes, dpr);   \
    }                                                                 \
  };
DEFINE_DRAW_SHADOW_OP(Shadow, false)
DEFINE_DRAW_SHADOW_OP(ShadowOccludes, true)
#undef DEFINE_DRAW_SHADOW_OP

#pragma pack(pop, DLOp_Alignment)

void DisplayList::ComputeBounds() {
  DisplayListBoundsCalculator calculator(bounds_cull_);
  Dispatch(calculator);
  bounds_ = calculator.getBounds();
}

void DisplayList::Dispatch(Dispatcher& dispatcher,
                           uint8_t* ptr,
                           uint8_t* end) const {
  while (ptr < end) {
    auto op = (const DLOp*)ptr;
    ptr += op->size;
    FML_DCHECK(ptr <= end);
    switch (op->type) {
#define DL_OP_DISPATCH(name)                                \
  case DisplayListOpType::k##name:                          \
    static_cast<const name##Op*>(op)->dispatch(dispatcher); \
    break;

      FOR_EACH_DISPLAY_LIST_OP(DL_OP_DISPATCH)

#undef DL_OP_DISPATCH

      default:
        FML_DCHECK(false);
        return;
    }
  }
}

static void DisposeOps(uint8_t* ptr, uint8_t* end) {
  while (ptr < end) {
    auto op = (const DLOp*)ptr;
    ptr += op->size;
    FML_DCHECK(ptr <= end);
    switch (op->type) {
#define DL_OP_DISPOSE(name)                            \
  case DisplayListOpType::k##name:                     \
    if (!std::is_trivially_destructible_v<name##Op>) { \
      static_cast<const name##Op*>(op)->~name##Op();   \
    }                                                  \
    break;

      FOR_EACH_DISPLAY_LIST_OP(DL_OP_DISPOSE)

#undef DL_OP_DISPOSE

      default:
        FML_DCHECK(false);
        return;
    }
  }
}

static bool CompareOps(uint8_t* ptrA,
                       uint8_t* endA,
                       uint8_t* ptrB,
                       uint8_t* endB) {
  // These conditions are checked by the caller...
  FML_DCHECK((endA - ptrA) == (endB - ptrB));
  FML_DCHECK(ptrA != ptrB);
  uint8_t* bulkStartA = ptrA;
  uint8_t* bulkStartB = ptrB;
  while (ptrA < endA && ptrB < endB) {
    auto opA = (const DLOp*)ptrA;
    auto opB = (const DLOp*)ptrB;
    if (opA->type != opB->type || opA->size != opB->size) {
      return false;
    }
    ptrA += opA->size;
    ptrB += opB->size;
    FML_DCHECK(ptrA <= endA);
    FML_DCHECK(ptrB <= endB);
    DisplayListCompare result;
    switch (opA->type) {
#define DL_OP_EQUALS(name)                              \
  case DisplayListOpType::k##name:                      \
    result = static_cast<const name##Op*>(opA)->equals( \
        static_cast<const name##Op*>(opB));             \
    break;

      FOR_EACH_DISPLAY_LIST_OP(DL_OP_EQUALS)

#undef DL_OP_EQUALS

      default:
        FML_DCHECK(false);
        return false;
    }
    switch (result) {
      case DisplayListCompare::kNotEqual:
        return false;
      case DisplayListCompare::kUseBulkCompare:
        break;
      case DisplayListCompare::kEqual:
        // Check if we have a backlog of bytes to bulk compare and then
        // reset the bulk compare pointers to the address following this op
        auto bulkBytes = reinterpret_cast<const uint8_t*>(opA) - bulkStartA;
        if (bulkBytes > 0) {
          if (memcmp(bulkStartA, bulkStartB, bulkBytes) != 0) {
            return false;
          }
        }
        bulkStartA = ptrA;
        bulkStartB = ptrB;
        break;
    }
  }
  if (ptrA != endA || ptrB != endB) {
    return false;
  }
  if (bulkStartA < ptrA) {
    // Perform a final bulk compare if we have remaining bytes waiting
    if (memcmp(bulkStartA, bulkStartB, ptrA - bulkStartA) != 0) {
      return false;
    }
  }
  return true;
}

void DisplayList::RenderTo(SkCanvas* canvas) const {
  DisplayListCanvasDispatcher dispatcher(canvas);
  Dispatch(dispatcher);
}

bool DisplayList::Equals(const DisplayList& other) const {
  if (used_ != other.used_ || op_count_ != other.op_count_) {
    return false;
  }
  if (ptr_ == other.ptr_) {
    return true;
  }
  return CompareOps(ptr_, ptr_ + used_, other.ptr_, other.ptr_ + other.used_);
}

DisplayList::DisplayList(uint8_t* ptr,
                         size_t used,
                         int op_count,
                         const SkRect& cull)
    : ptr_(ptr),
      used_(used),
      op_count_(op_count),
      bounds_({0, 0, -1, -1}),
      bounds_cull_(cull) {
  static std::atomic<uint32_t> nextID{1};
  do {
    unique_id_ = nextID.fetch_add(+1, std::memory_order_relaxed);
  } while (unique_id_ == 0);
}

DisplayList::~DisplayList() {
  DisposeOps(ptr_, ptr_ + used_);
}

#define DL_BUILDER_PAGE 4096

// CopyV(dst, src,n, src,n, ...) copies any number of typed srcs into dst.
static void CopyV(void* dst) {}

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

template <typename T, typename... Args>
void* DisplayListBuilder::Push(size_t pod, Args&&... args) {
  size_t size = SkAlignPtr(sizeof(T) + pod);
  FML_DCHECK(size < (1 << 24));
  if (used_ + size > allocated_) {
    static_assert(SkIsPow2(DL_BUILDER_PAGE),
                  "This math needs updating for non-pow2.");
    // Next greater multiple of DL_BUILDER_PAGE.
    allocated_ = (used_ + size + DL_BUILDER_PAGE) & ~(DL_BUILDER_PAGE - 1);
    storage_.realloc(allocated_);
    FML_DCHECK(storage_.get());
    memset(storage_.get() + used_, 0, allocated_ - used_);
  }
  FML_DCHECK(used_ + size <= allocated_);
  auto op = (T*)(storage_.get() + used_);
  used_ += size;
  new (op) T{std::forward<Args>(args)...};
  op->type = T::kType;
  op->size = size;
  op_count_++;
  return op + 1;
}

sk_sp<DisplayList> DisplayListBuilder::Build() {
  while (save_level_ > 0) {
    restore();
  }
  size_t used = used_;
  int count = op_count_;
  used_ = allocated_ = op_count_ = 0;
  storage_.realloc(used);
  return sk_sp<DisplayList>(
      new DisplayList(storage_.release(), used, count, cull_));
}

DisplayListBuilder::DisplayListBuilder(const SkRect& cull) : cull_(cull) {}

DisplayListBuilder::~DisplayListBuilder() {
  uint8_t* ptr = storage_.get();
  if (ptr) {
    DisposeOps(ptr, ptr + used_);
  }
}

void DisplayListBuilder::setAA(bool aa) {
  Push<SetAAOp>(0, aa);
}
void DisplayListBuilder::setDither(bool dither) {
  Push<SetDitherOp>(0, dither);
}
void DisplayListBuilder::setInvertColors(bool invert) {
  Push<SetInvertColorsOp>(0, invert);
}
void DisplayListBuilder::setCaps(SkPaint::Cap cap) {
  Push<SetCapsOp>(0, cap);
}
void DisplayListBuilder::setJoins(SkPaint::Join join) {
  Push<SetJoinsOp>(0, join);
}
void DisplayListBuilder::setDrawStyle(SkPaint::Style style) {
  Push<SetDrawStyleOp>(0, style);
}
void DisplayListBuilder::setStrokeWidth(SkScalar width) {
  Push<SetStrokeWidthOp>(0, width);
}
void DisplayListBuilder::setMiterLimit(SkScalar limit) {
  Push<SetMiterLimitOp>(0, limit);
}
void DisplayListBuilder::setColor(SkColor color) {
  Push<SetColorOp>(0, color);
}
void DisplayListBuilder::setBlendMode(SkBlendMode mode) {
  Push<SetBlendModeOp>(0, mode);
}
void DisplayListBuilder::setBlender(sk_sp<SkBlender> blender) {
  blender  //
      ? Push<SetBlenderOp>(0, std::move(blender))
      : Push<ClearBlenderOp>(0);
}
void DisplayListBuilder::setShader(sk_sp<SkShader> shader) {
  shader  //
      ? Push<SetShaderOp>(0, std::move(shader))
      : Push<ClearShaderOp>(0);
}
void DisplayListBuilder::setImageFilter(sk_sp<SkImageFilter> filter) {
  filter  //
      ? Push<SetImageFilterOp>(0, std::move(filter))
      : Push<ClearImageFilterOp>(0);
}
void DisplayListBuilder::setColorFilter(sk_sp<SkColorFilter> filter) {
  filter  //
      ? Push<SetColorFilterOp>(0, std::move(filter))
      : Push<ClearColorFilterOp>(0);
}
void DisplayListBuilder::setPathEffect(sk_sp<SkPathEffect> effect) {
  effect  //
      ? Push<SetPathEffectOp>(0, std::move(effect))
      : Push<ClearPathEffectOp>(0);
}
void DisplayListBuilder::setMaskFilter(sk_sp<SkMaskFilter> filter) {
  Push<SetMaskFilterOp>(0, std::move(filter));
}
void DisplayListBuilder::setMaskBlurFilter(SkBlurStyle style, SkScalar sigma) {
  switch (style) {
    case kNormal_SkBlurStyle:
      Push<SetMaskBlurFilterNormalOp>(0, sigma);
      break;
    case kSolid_SkBlurStyle:
      Push<SetMaskBlurFilterSolidOp>(0, sigma);
      break;
    case kOuter_SkBlurStyle:
      Push<SetMaskBlurFilterOuterOp>(0, sigma);
      break;
    case kInner_SkBlurStyle:
      Push<SetMaskBlurFilterInnerOp>(0, sigma);
      break;
  }
}

void DisplayListBuilder::save() {
  save_level_++;
  Push<SaveOp>(0);
}
void DisplayListBuilder::restore() {
  if (save_level_ > 0) {
    Push<RestoreOp>(0);
    save_level_--;
  }
}
void DisplayListBuilder::saveLayer(const SkRect* bounds, bool with_paint) {
  save_level_++;
  bounds  //
      ? Push<SaveLayerBoundsOp>(0, *bounds, with_paint)
      : Push<SaveLayerOp>(0, with_paint);
}

void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
  Push<TranslateOp>(0, tx, ty);
}
void DisplayListBuilder::scale(SkScalar sx, SkScalar sy) {
  Push<ScaleOp>(0, sx, sy);
}
void DisplayListBuilder::rotate(SkScalar degrees) {
  Push<RotateOp>(0, degrees);
}
void DisplayListBuilder::skew(SkScalar sx, SkScalar sy) {
  Push<SkewOp>(0, sx, sy);
}
void DisplayListBuilder::transform2x3(SkScalar mxx,
                                      SkScalar mxy,
                                      SkScalar mxt,
                                      SkScalar myx,
                                      SkScalar myy,
                                      SkScalar myt) {
  Push<Transform2x3Op>(0, mxx, mxy, mxt, myx, myy, myt);
}
void DisplayListBuilder::transform3x3(SkScalar mxx,
                                      SkScalar mxy,
                                      SkScalar mxt,
                                      SkScalar myx,
                                      SkScalar myy,
                                      SkScalar myt,
                                      SkScalar px,
                                      SkScalar py,
                                      SkScalar pt) {
  Push<Transform3x3Op>(0, mxx, mxy, mxt, myx, myy, myt, px, py, pt);
}

void DisplayListBuilder::clipRect(const SkRect& rect,
                                  bool is_aa,
                                  SkClipOp clip_op) {
  clip_op == SkClipOp::kIntersect  //
      ? Push<ClipIntersectRectOp>(0, rect, is_aa)
      : Push<ClipDifferenceRectOp>(0, rect, is_aa);
}
void DisplayListBuilder::clipRRect(const SkRRect& rrect,
                                   bool is_aa,
                                   SkClipOp clip_op) {
  if (rrect.isRect()) {
    clipRect(rrect.rect(), is_aa, clip_op);
  } else {
    clip_op == SkClipOp::kIntersect  //
        ? Push<ClipIntersectRRectOp>(0, rrect, is_aa)
        : Push<ClipDifferenceRRectOp>(0, rrect, is_aa);
  }
}
void DisplayListBuilder::clipPath(const SkPath& path,
                                  bool is_aa,
                                  SkClipOp clip_op) {
  if (!path.isInverseFillType()) {
    SkRect rect;
    if (path.isRect(&rect)) {
      this->clipRect(rect, is_aa, clip_op);
      return;
    }
    SkRRect rrect;
    if (path.isOval(&rect)) {
      rrect.setOval(rect);
      this->clipRRect(rrect, is_aa, clip_op);
      return;
    }
    if (path.isRRect(&rrect)) {
      this->clipRRect(rrect, is_aa, clip_op);
      return;
    }
  }
  clip_op == SkClipOp::kIntersect  //
      ? Push<ClipIntersectPathOp>(0, path, is_aa)
      : Push<ClipDifferencePathOp>(0, path, is_aa);
}

void DisplayListBuilder::drawPaint() {
  Push<DrawPaintOp>(0);
}
void DisplayListBuilder::drawColor(SkColor color, SkBlendMode mode) {
  Push<DrawColorOp>(0, color, mode);
}
void DisplayListBuilder::drawLine(const SkPoint& p0, const SkPoint& p1) {
  Push<DrawLineOp>(0, p0, p1);
}
void DisplayListBuilder::drawRect(const SkRect& rect) {
  Push<DrawRectOp>(0, rect);
}
void DisplayListBuilder::drawOval(const SkRect& bounds) {
  Push<DrawOvalOp>(0, bounds);
}
void DisplayListBuilder::drawCircle(const SkPoint& center, SkScalar radius) {
  Push<DrawCircleOp>(0, center, radius);
}
void DisplayListBuilder::drawRRect(const SkRRect& rrect) {
  if (rrect.isRect()) {
    drawRect(rrect.rect());
  } else if (rrect.isOval()) {
    drawOval(rrect.rect());
  } else {
    Push<DrawRRectOp>(0, rrect);
  }
}
void DisplayListBuilder::drawDRRect(const SkRRect& outer,
                                    const SkRRect& inner) {
  Push<DrawDRRectOp>(0, outer, inner);
}
void DisplayListBuilder::drawPath(const SkPath& path) {
  Push<DrawPathOp>(0, path);
}

void DisplayListBuilder::drawArc(const SkRect& bounds,
                                 SkScalar start,
                                 SkScalar sweep,
                                 bool useCenter) {
  Push<DrawArcOp>(0, bounds, start, sweep, useCenter);
}
void DisplayListBuilder::drawPoints(SkCanvas::PointMode mode,
                                    uint32_t count,
                                    const SkPoint pts[]) {
  void* data_ptr;
  FML_DCHECK(count < kMaxDrawPointsCount);
  int bytes = count * sizeof(SkPoint);
  switch (mode) {
    case SkCanvas::PointMode::kPoints_PointMode:
      data_ptr = Push<DrawPointsOp>(bytes, count);
      break;
    case SkCanvas::PointMode::kLines_PointMode:
      data_ptr = Push<DrawLinesOp>(bytes, count);
      break;
    case SkCanvas::PointMode::kPolygon_PointMode:
      data_ptr = Push<DrawPolygonOp>(bytes, count);
      break;
    default:
      FML_DCHECK(false);
      return;
  }
  CopyV(data_ptr, pts, count);
}
void DisplayListBuilder::drawVertices(const sk_sp<SkVertices> vertices,
                                      SkBlendMode mode) {
  Push<DrawVerticesOp>(0, std::move(vertices), mode);
}

void DisplayListBuilder::drawImage(const sk_sp<SkImage> image,
                                   const SkPoint point,
                                   const SkSamplingOptions& sampling) {
  Push<DrawImageOp>(0, std::move(image), point, sampling);
}
void DisplayListBuilder::drawImageRect(const sk_sp<SkImage> image,
                                       const SkRect& src,
                                       const SkRect& dst,
                                       const SkSamplingOptions& sampling,
                                       SkCanvas::SrcRectConstraint constraint) {
  constraint == SkCanvas::kFast_SrcRectConstraint  //
      ? Push<DrawImageRectFastOp>(0, std::move(image), src, dst, sampling)
      : Push<DrawImageRectStrictOp>(0, std::move(image), src, dst, sampling);
}
void DisplayListBuilder::drawImageNine(const sk_sp<SkImage> image,
                                       const SkIRect& center,
                                       const SkRect& dst,
                                       SkFilterMode filter) {
  Push<DrawImageNineOp>(0, std::move(image), center, dst, filter);
}
void DisplayListBuilder::drawImageLattice(const sk_sp<SkImage> image,
                                          const SkCanvas::Lattice& lattice,
                                          const SkRect& dst,
                                          SkFilterMode filter,
                                          bool with_paint) {
  int xDivCount = lattice.fXCount;
  int yDivCount = lattice.fYCount;
  FML_DCHECK((lattice.fRectTypes == nullptr) || (lattice.fColors != nullptr));
  int cellCount = lattice.fRectTypes && lattice.fColors
                      ? (xDivCount + 1) * (yDivCount + 1)
                      : 0;
  size_t bytes =
      (xDivCount + yDivCount) * sizeof(int) +
      cellCount * (sizeof(SkColor) + sizeof(SkCanvas::Lattice::RectType));
  SkIRect src = lattice.fBounds ? *lattice.fBounds : image->bounds();
  void* pod = this->Push<DrawImageLatticeOp>(bytes, std::move(image), xDivCount,
                                             yDivCount, cellCount, src, dst,
                                             filter, with_paint);
  CopyV(pod, lattice.fXDivs, xDivCount, lattice.fYDivs, yDivCount,
        lattice.fColors, cellCount, lattice.fRectTypes, cellCount);
}
void DisplayListBuilder::drawAtlas(const sk_sp<SkImage> atlas,
                                   const SkRSXform xform[],
                                   const SkRect tex[],
                                   const SkColor colors[],
                                   int count,
                                   SkBlendMode mode,
                                   const SkSamplingOptions& sampling,
                                   const SkRect* cullRect) {
  int bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
  void* data_ptr;
  if (colors) {
    bytes += count * sizeof(SkColor);
    if (cullRect) {
      data_ptr = Push<DrawAtlasColoredCulledOp>(bytes, std::move(atlas), count,
                                                mode, sampling, *cullRect);
    } else {
      data_ptr = Push<DrawAtlasColoredOp>(bytes, std::move(atlas), count, mode,
                                          sampling);
    }
    CopyV(data_ptr, xform, count, tex, count, colors, count);
  } else {
    if (cullRect) {
      data_ptr = Push<DrawAtlasCulledOp>(bytes, std::move(atlas), count, mode,
                                         sampling, *cullRect);
    } else {
      data_ptr =
          Push<DrawAtlasOp>(bytes, std::move(atlas), count, mode, sampling);
    }
    CopyV(data_ptr, xform, count, tex, count);
  }
}

void DisplayListBuilder::drawPicture(const sk_sp<SkPicture> picture,
                                     const SkMatrix* matrix,
                                     bool with_layer) {
  matrix  //
      ? Push<DrawSkPictureMatrixOp>(0, std::move(picture), *matrix, with_layer)
      : Push<DrawSkPictureOp>(0, std::move(picture), with_layer);
}
void DisplayListBuilder::drawDisplayList(
    const sk_sp<DisplayList> display_list) {
  Push<DrawDisplayListOp>(0, std::move(display_list));
}
void DisplayListBuilder::drawTextBlob(const sk_sp<SkTextBlob> blob,
                                      SkScalar x,
                                      SkScalar y) {
  Push<DrawTextBlobOp>(0, std::move(blob), x, y);
}
void DisplayListBuilder::drawShadow(const SkPath& path,
                                    const SkColor color,
                                    const SkScalar elevation,
                                    bool occludes,
                                    SkScalar dpr) {
  occludes  //
      ? Push<DrawShadowOccludesOp>(0, path, color, elevation, dpr)
      : Push<DrawShadowOp>(0, path, color, elevation, dpr);
}

}  // namespace flutter
