// 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.

#ifndef FLUTTER_DISPLAY_LIST_DL_OP_RECORDS_H_
#define FLUTTER_DISPLAY_LIST_DL_OP_RECORDS_H_

#include "flutter/display_list/display_list.h"
#include "flutter/display_list/dl_blend_mode.h"
#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/display_list/dl_sampling_options.h"
#include "flutter/display_list/effects/dl_color_source.h"
#include "flutter/fml/macros.h"

#include "flutter/impeller/geometry/path.h"
#include "flutter/impeller/typographer/text_frame.h"
#include "third_party/skia/include/core/SkRSXform.h"

namespace flutter {

// Structure holding the information necessary to dispatch and
// potentially cull the DLOps during playback.
//
// Generally drawing ops will execute as long as |cur_index|
// is at or after |next_render_index|, so setting the latter
// to 0 will render all primitives and setting it to MAX_INT
// will skip all remaining rendering primitives.
//
// Save and saveLayer ops will execute as long as the next
// rendering index is before their closing restore index.
// They will also store their own restore index into the
// |next_restore_index| field for use by clip and transform ops.
//
// Clip and transform ops will only execute if the next
// render index is before the next restore index. Otherwise
// their modified state will not be used before it gets
// restored.
//
// Attribute ops always execute as they are too numerous and
// cheap to deal with a complicated "lifetime" tracking to
// determine if they will be used.
struct DispatchContext {
  DlOpReceiver& receiver;

  int cur_index;
  int next_render_index;

  int next_restore_index;

  struct SaveInfo {
    SaveInfo(int previous_restore_index, bool save_was_needed)
        : previous_restore_index(previous_restore_index),
          save_was_needed(save_was_needed) {}

    int previous_restore_index;
    bool save_was_needed;
  };

  std::vector<SaveInfo> save_infos;
};

// 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,
};

// "DLOpPackLabel" is just a label for the pack pragma so it can be popped
// later.
#pragma pack(push, DLOpPackLabel, 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 {
  static constexpr uint32_t kDepthInc = 0;
  static constexpr uint32_t kRenderOpInc = 0;

  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 constexpr auto kType = DisplayListOpType::kSet##name; \
                                                                 \
    explicit Set##name##Op(bool value) : value(value) {}         \
                                                                 \
    const bool value;                                            \
                                                                 \
    void dispatch(DispatchContext& ctx) const {                  \
      ctx.receiver.set##name(value);                             \
    }                                                            \
  };
DEFINE_SET_BOOL_OP(AntiAlias)
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 SetStroke##name##Op final : DLOp {                              \
    static constexpr auto kType = DisplayListOpType::kSetStroke##name;   \
                                                                         \
    explicit SetStroke##name##Op(DlStroke##name value) : value(value) {} \
                                                                         \
    const DlStroke##name value;                                          \
                                                                         \
    void dispatch(DispatchContext& ctx) const {                          \
      ctx.receiver.setStroke##name(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 SetStyleOp final : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetStyle;

  explicit SetStyleOp(DlDrawStyle style) : style(style) {}

  const DlDrawStyle style;

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

  explicit SetStrokeWidthOp(float width) : width(width) {}

  const float width;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setStrokeWidth(width);
  }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetStrokeMiterOp final : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetStrokeMiter;

  explicit SetStrokeMiterOp(float limit) : limit(limit) {}

  const float limit;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setStrokeMiter(limit);
  }
};

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

  explicit SetColorOp(DlColor color) : color(color) {}

  const DlColor color;

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

  explicit SetBlendModeOp(DlBlendMode mode) : mode(mode) {}

  const DlBlendMode mode;

  void dispatch(DispatchContext& ctx) const {  //
    ctx.receiver.setBlendMode(mode);
  }
};

// Clear: 4 byte header + unused 4 byte payload uses 8 bytes
//        (4 bytes unused)
// Set: 4 byte header + unused 4 byte struct padding + Dl<name>
//      instance copied to the memory following the record
//      yields a size and efficiency that has somewhere between
//      4 and 8 bytes unused
#define DEFINE_SET_CLEAR_DLATTR_OP(name, sk_name, field)                    \
  struct Clear##name##Op final : DLOp {                                     \
    static constexpr auto kType = DisplayListOpType::kClear##name;          \
                                                                            \
    Clear##name##Op() {}                                                    \
                                                                            \
    void dispatch(DispatchContext& ctx) const {                             \
      ctx.receiver.set##name(nullptr);                                      \
    }                                                                       \
  };                                                                        \
  struct SetPod##name##Op final : DLOp {                                    \
    static constexpr auto kType = DisplayListOpType::kSetPod##name;         \
                                                                            \
    SetPod##name##Op() {}                                                   \
                                                                            \
    void dispatch(DispatchContext& ctx) const {                             \
      const Dl##name* filter = reinterpret_cast<const Dl##name*>(this + 1); \
      ctx.receiver.set##name(filter);                                       \
    }                                                                       \
  };
DEFINE_SET_CLEAR_DLATTR_OP(ColorFilter, ColorFilter, filter)
DEFINE_SET_CLEAR_DLATTR_OP(ImageFilter, ImageFilter, filter)
DEFINE_SET_CLEAR_DLATTR_OP(MaskFilter, MaskFilter, filter)
DEFINE_SET_CLEAR_DLATTR_OP(ColorSource, Shader, source)
DEFINE_SET_CLEAR_DLATTR_OP(PathEffect, PathEffect, effect)
#undef DEFINE_SET_CLEAR_DLATTR_OP

// 4 byte header + 80 bytes for the embedded DlImageColorSource
// uses 84 total bytes (4 bytes unused)
struct SetImageColorSourceOp : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetImageColorSource;

  explicit SetImageColorSourceOp(const DlImageColorSource* source)
      : source(source->image(),
               source->horizontal_tile_mode(),
               source->vertical_tile_mode(),
               source->sampling(),
               source->matrix_ptr()) {}

  const DlImageColorSource source;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setColorSource(&source);
  }
};

// 56 bytes: 4 byte header, 4 byte padding, 8 for vtable, 8 * 2 for sk_sps, 24
// for the std::vector.
struct SetRuntimeEffectColorSourceOp : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetRuntimeEffectColorSource;

  explicit SetRuntimeEffectColorSourceOp(
      const DlRuntimeEffectColorSource* source)
      : source(source->runtime_effect(),
               source->samplers(),
               source->uniform_data()) {}

  const DlRuntimeEffectColorSource source;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setColorSource(&source);
  }

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

#ifdef IMPELLER_ENABLE_3D
struct SetSceneColorSourceOp : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetSceneColorSource;

  explicit SetSceneColorSourceOp(const DlSceneColorSource* source)
      : source(source->scene_node(), source->camera_matrix()) {}

  const DlSceneColorSource source;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setColorSource(&source);
  }

  DisplayListCompare equals(const SetSceneColorSourceOp* other) const {
    return (source == other->source) ? DisplayListCompare::kEqual
                                     : DisplayListCompare::kNotEqual;
  }
};
#endif  // IMPELLER_ENABLE_3D

// 4 byte header + 16 byte payload uses 24 total bytes (4 bytes unused)
struct SetSharedImageFilterOp : DLOp {
  static constexpr auto kType = DisplayListOpType::kSetSharedImageFilter;

  explicit SetSharedImageFilterOp(const DlImageFilter* filter)
      : filter(filter->shared()) {}

  const std::shared_ptr<DlImageFilter> filter;

  void dispatch(DispatchContext& ctx) const {
    ctx.receiver.setImageFilter(filter.get());
  }

  DisplayListCompare equals(const SetSharedImageFilterOp* other) const {
    return Equals(filter, other->filter) ? DisplayListCompare::kEqual
                                         : DisplayListCompare::kNotEqual;
  }
};

// The base struct for all save() and saveLayer() ops
// 4 byte header + 8 byte payload packs into 16 bytes (4 bytes unused)
struct SaveOpBase : DLOp {
  static constexpr uint32_t kDepthInc = 0;
  static constexpr uint32_t kRenderOpInc = 1;

  SaveOpBase() : options(), restore_index(0) {}

  explicit SaveOpBase(const SaveLayerOptions& options)
      : options(options), restore_index(0), total_content_depth(0) {}

  // options parameter is only used by saveLayer operations, but since
  // it packs neatly into the empty space created by laying out the 64-bit
  // offsets, it can be stored for free and defaulted to 0 for save operations.
  SaveLayerOptions options;
  int restore_index;
  uint32_t total_content_depth;

  inline bool save_needed(DispatchContext& ctx) const {
    bool needed = ctx.next_render_index <= restore_index;
    ctx.save_infos.emplace_back(ctx.next_restore_index, needed);
    ctx.next_restore_index = restore_index;
    return needed;
  }
};
// 16 byte SaveOpBase with no additional data (options is unsed here)
struct SaveOp final : SaveOpBase {
  static constexpr auto kType = DisplayListOpType::kSave;

  SaveOp() : SaveOpBase() {}

  void dispatch(DispatchContext& ctx) const {
    if (save_needed(ctx)) {
      ctx.receiver.save(total_content_depth);
    }
  }
};
// The base struct for all saveLayer() ops
// 16 byte SaveOpBase + 16 byte payload packs into 32 bytes (4 bytes unused)
struct SaveLayerOpBase : SaveOpBase {
  SaveLayerOpBase(const SaveLayerOptions& options, const SkRect& rect)
      : SaveOpBase(options), rect(rect) {}

  SkRect rect;
};
// 32 byte SaveLayerOpBase with no additional data
struct SaveLayerOp final : SaveLayerOpBase {
  static constexpr auto kType = DisplayListOpType::kSaveLayer;

  SaveLayerOp(const SaveLayerOptions& options, const SkRect& rect)
      : SaveLayerOpBase(options, rect) {}

  void dispatch(DispatchContext& ctx) const {
    if (save_needed(ctx)) {
      ctx.receiver.saveLayer(rect, options, total_content_depth);
    }
  }
};
// 32 byte SaveLayerOpBase + 16 byte payload packs into minimum 48 bytes
struct SaveLayerBackdropOp final : SaveLayerOpBase {
  static constexpr auto kType = DisplayListOpType::kSaveLayerBackdrop;

  SaveLayerBackdropOp(const SaveLayerOptions& options,
                      const SkRect& rect,
                      const DlImageFilter* backdrop)
      : SaveLayerOpBase(options, rect), backdrop(backdrop->shared()) {}

  const std::shared_ptr<DlImageFilter> backdrop;

  void dispatch(DispatchContext& ctx) const {
    if (save_needed(ctx)) {
      ctx.receiver.saveLayer(rect, options, total_content_depth,
                             backdrop.get());
    }
  }

  DisplayListCompare equals(const SaveLayerBackdropOp* other) const {
    return (options == other->options && rect == other->rect &&
            Equals(backdrop, other->backdrop))
               ? DisplayListCompare::kEqual
               : DisplayListCompare::kNotEqual;
  }
};
// 4 byte header + no payload uses minimum 8 bytes (4 bytes unused)
struct RestoreOp final : DLOp {
  static constexpr auto kType = DisplayListOpType::kRestore;
  static constexpr uint32_t kDepthInc = 0;
  static constexpr uint32_t kRenderOpInc = 1;

  RestoreOp() {}

  void dispatch(DispatchContext& ctx) const {
    DispatchContext::SaveInfo& info = ctx.save_infos.back();
    if (info.save_was_needed) {
      ctx.receiver.restore();
    }
    ctx.next_restore_index = info.previous_restore_index;
    ctx.save_infos.pop_back();
  }
};

struct TransformClipOpBase : DLOp {
  static constexpr uint32_t kDepthInc = 0;
  static constexpr uint32_t kRenderOpInc = 1;

  inline bool op_needed(const DispatchContext& context) const {
    return context.next_render_index <= context.next_restore_index;
  }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct TranslateOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kTranslate;

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

  const SkScalar tx;
  const SkScalar ty;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.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 : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kScale;

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

  const SkScalar sx;
  const SkScalar sy;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.scale(sx, sy);
    }
  }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct RotateOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kRotate;

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

  const SkScalar degrees;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.rotate(degrees);
    }
  }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct SkewOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kSkew;

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

  const SkScalar sx;
  const SkScalar sy;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.skew(sx, sy);
    }
  }
};
// 4 byte header + 24 byte payload uses 28 bytes but is rounded up to 32 bytes
// (4 bytes unused)
struct Transform2DAffineOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kTransform2DAffine;

  // clang-format off
  Transform2DAffineOp(SkScalar mxx, SkScalar mxy, SkScalar mxt,
                      SkScalar myx, SkScalar myy, SkScalar myt)
      : mxx(mxx), mxy(mxy), mxt(mxt), myx(myx), myy(myy), myt(myt) {}
  // clang-format on

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

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.transform2DAffine(mxx, mxy, mxt,  //
                                     myx, myy, myt);
    }
  }
};
// 4 byte header + 64 byte payload uses 68 bytes which is rounded up to 72 bytes
// (4 bytes unused)
struct TransformFullPerspectiveOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kTransformFullPerspective;

  // clang-format off
  TransformFullPerspectiveOp(
      SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
      SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
      SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
      SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt)
      : mxx(mxx), mxy(mxy), mxz(mxz), mxt(mxt),
        myx(myx), myy(myy), myz(myz), myt(myt),
        mzx(mzx), mzy(mzy), mzz(mzz), mzt(mzt),
        mwx(mwx), mwy(mwy), mwz(mwz), mwt(mwt) {}
  // clang-format on

  const SkScalar mxx, mxy, mxz, mxt;
  const SkScalar myx, myy, myz, myt;
  const SkScalar mzx, mzy, mzz, mzt;
  const SkScalar mwx, mwy, mwz, mwt;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.transformFullPerspective(mxx, mxy, mxz, mxt,  //
                                            myx, myy, myz, myt,  //
                                            mzx, mzy, mzz, mzt,  //
                                            mwx, mwy, mwz, mwt);
    }
  }
};

// 4 byte header with no payload.
struct TransformResetOp final : TransformClipOpBase {
  static constexpr auto kType = DisplayListOpType::kTransformReset;

  TransformResetOp() = default;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.transformReset();
    }
  }
};

// 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
// CacheablePath is 128 more bytes, which packs efficiently into 136 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 : TransformClipOpBase {             \
    static constexpr 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(DispatchContext& ctx) const {                                \
      if (op_needed(ctx)) {                                                    \
        ctx.receiver.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop,       \
                                     is_aa);                                   \
      }                                                                        \
    }                                                                          \
  };
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 : TransformClipOpBase {               \
    static constexpr auto kType = DisplayListOpType::kClip##clipop##Path; \
                                                                          \
    Clip##clipop##PathOp(const SkPath& path, bool is_aa)                  \
        : is_aa(is_aa), cached_path(path) {}                              \
                                                                          \
    const bool is_aa;                                                     \
    const DlOpReceiver::CacheablePath cached_path;                        \
                                                                          \
    void dispatch(DispatchContext& ctx) const {                           \
      if (op_needed(ctx)) {                                               \
        if (ctx.receiver.PrefersImpellerPaths()) {                        \
          ctx.receiver.clipPath(cached_path, DlCanvas::ClipOp::k##clipop, \
                                is_aa);                                   \
        } else {                                                          \
          ctx.receiver.clipPath(cached_path.sk_path,                      \
                                DlCanvas::ClipOp::k##clipop, is_aa);      \
        }                                                                 \
      }                                                                   \
    }                                                                     \
                                                                          \
    DisplayListCompare equals(const Clip##clipop##PathOp* other) const {  \
      return is_aa == other->is_aa && cached_path == other->cached_path   \
                 ? DisplayListCompare::kEqual                             \
                 : DisplayListCompare::kNotEqual;                         \
    }                                                                     \
  };
DEFINE_CLIP_PATH_OP(Intersect)
DEFINE_CLIP_PATH_OP(Difference)
#undef DEFINE_CLIP_PATH_OP

struct DrawOpBase : DLOp {
  static constexpr uint32_t kDepthInc = 1;
  static constexpr uint32_t kRenderOpInc = 1;

  inline bool op_needed(const DispatchContext& ctx) const {
    return ctx.cur_index >= ctx.next_render_index;
  }
};

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

  DrawPaintOp() {}

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.drawPaint();
    }
  }
};
// 4 byte header + 8 byte payload uses 12 bytes but is rounded up to 16 bytes
// (4 bytes unused)
struct DrawColorOp final : DrawOpBase {
  static constexpr auto kType = DisplayListOpType::kDrawColor;

  DrawColorOp(DlColor color, DlBlendMode mode) : color(color), mode(mode) {}

  const DlColor color;
  const DlBlendMode mode;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.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 : DrawOpBase {                           \
    static constexpr auto kType = DisplayListOpType::kDraw##op_name;      \
                                                                          \
    explicit Draw##op_name##Op(arg_type arg_name) : arg_name(arg_name) {} \
                                                                          \
    const arg_type arg_name;                                              \
                                                                          \
    void dispatch(DispatchContext& ctx) const {                           \
      if (op_needed(ctx)) {                                               \
        ctx.receiver.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 + 128 byte payload uses 132 bytes but is rounded
// up to 136 bytes (4 bytes unused)
struct DrawPathOp final : DrawOpBase {
  static constexpr auto kType = DisplayListOpType::kDrawPath;

  explicit DrawPathOp(const SkPath& path) : cached_path(path) {}

  const DlOpReceiver::CacheablePath cached_path;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      if (ctx.receiver.PrefersImpellerPaths()) {
        ctx.receiver.drawPath(cached_path);
      } else {
        ctx.receiver.drawPath(cached_path.sk_path);
      }
    }
  }

  DisplayListCompare equals(const DrawPathOp* other) const {
    return cached_path == other->cached_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 : DrawOpBase {                      \
    static constexpr 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(DispatchContext& ctx) const {                      \
      if (op_needed(ctx)) {                                          \
        ctx.receiver.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 : DrawOpBase {
  static constexpr 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(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.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 : DrawOpBase {                             \
    static constexpr auto kType = DisplayListOpType::kDraw##name;        \
                                                                         \
    explicit Draw##name##Op(uint32_t count) : count(count) {}            \
                                                                         \
    const uint32_t count;                                                \
                                                                         \
    void dispatch(DispatchContext& ctx) const {                          \
      if (op_needed(ctx)) {                                              \
        const SkPoint* pts = reinterpret_cast<const SkPoint*>(this + 1); \
        ctx.receiver.drawPoints(DlCanvas::PointMode::mode, count, pts);  \
      }                                                                  \
    }                                                                    \
  };
DEFINE_DRAW_POINTS_OP(Points, kPoints);
DEFINE_DRAW_POINTS_OP(Lines, kLines);
DEFINE_DRAW_POINTS_OP(Polygon, kPolygon);
#undef DEFINE_DRAW_POINTS_OP

// 4 byte header + 4 byte payload packs efficiently into 8 bytes
// The DlVertices object will be pod-allocated after this structure
// and can take any number of bytes so the final efficiency will
// depend on the size of the DlVertices.
// Note that the DlVertices object ends with an array of 16-bit
// indices so the alignment can be up to 6 bytes off leading to
// up to 6 bytes of overhead
struct DrawVerticesOp final : DrawOpBase {
  static constexpr auto kType = DisplayListOpType::kDrawVertices;

  explicit DrawVerticesOp(DlBlendMode mode) : mode(mode) {}

  const DlBlendMode mode;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      const DlVertices* vertices =
          reinterpret_cast<const DlVertices*>(this + 1);
      ctx.receiver.drawVertices(vertices, mode);
    }
  }
};

// 4 byte header + 40 byte payload uses 44 bytes but is rounded up to 48 bytes
// (4 bytes unused)
#define DEFINE_DRAW_IMAGE_OP(name, with_attributes)                      \
  struct name##Op final : DrawOpBase {                                   \
    static constexpr auto kType = DisplayListOpType::k##name;            \
                                                                         \
    name##Op(const sk_sp<DlImage>& image,                                \
             const SkPoint& point,                                       \
             DlImageSampling sampling)                                   \
        : point(point), sampling(sampling), image(std::move(image)) {}   \
                                                                         \
    const SkPoint point;                                                 \
    const DlImageSampling sampling;                                      \
    const sk_sp<DlImage> image;                                          \
                                                                         \
    void dispatch(DispatchContext& ctx) const {                          \
      if (op_needed(ctx)) {                                              \
        ctx.receiver.drawImage(image, point, sampling, with_attributes); \
      }                                                                  \
    }                                                                    \
                                                                         \
    DisplayListCompare equals(const name##Op* other) const {             \
      return (point == other->point && sampling == other->sampling &&    \
              image->Equals(other->image))                               \
                 ? DisplayListCompare::kEqual                            \
                 : DisplayListCompare::kNotEqual;                        \
    }                                                                    \
  };
DEFINE_DRAW_IMAGE_OP(DrawImage, false)
DEFINE_DRAW_IMAGE_OP(DrawImageWithAttr, true)
#undef DEFINE_DRAW_IMAGE_OP

// 4 byte header + 72 byte payload uses 76 bytes but is rounded up to 80 bytes
// (4 bytes unused)
struct DrawImageRectOp final : DrawOpBase {
  static constexpr auto kType = DisplayListOpType::kDrawImageRect;

  DrawImageRectOp(const sk_sp<DlImage>& image,
                  const SkRect& src,
                  const SkRect& dst,
                  DlImageSampling sampling,
                  bool render_with_attributes,
                  DlCanvas::SrcRectConstraint constraint)
      : src(src),
        dst(dst),
        sampling(sampling),
        render_with_attributes(render_with_attributes),
        constraint(constraint),
        image(image) {}

  const SkRect src;
  const SkRect dst;
  const DlImageSampling sampling;
  const bool render_with_attributes;
  const DlCanvas::SrcRectConstraint constraint;
  const sk_sp<DlImage> image;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.drawImageRect(image, src, dst, sampling,
                                 render_with_attributes, constraint);
    }
  }

  DisplayListCompare equals(const DrawImageRectOp* other) const {
    return (src == other->src && dst == other->dst &&
            sampling == other->sampling &&
            render_with_attributes == other->render_with_attributes &&
            constraint == other->constraint && image->Equals(other->image))
               ? DisplayListCompare::kEqual
               : DisplayListCompare::kNotEqual;
  }
};

// 4 byte header + 44 byte payload packs efficiently into 48 bytes
#define DEFINE_DRAW_IMAGE_NINE_OP(name, render_with_attributes)            \
  struct name##Op final : DrawOpBase {                                     \
    static constexpr auto kType = DisplayListOpType::k##name;              \
                                                                           \
    name##Op(const sk_sp<DlImage>& image,                                  \
             const SkIRect& center,                                        \
             const SkRect& dst,                                            \
             DlFilterMode mode)                                            \
        : center(center), dst(dst), mode(mode), image(std::move(image)) {} \
                                                                           \
    const SkIRect center;                                                  \
    const SkRect dst;                                                      \
    const DlFilterMode mode;                                               \
    const sk_sp<DlImage> image;                                            \
                                                                           \
    void dispatch(DispatchContext& ctx) const {                            \
      if (op_needed(ctx)) {                                                \
        ctx.receiver.drawImageNine(image, center, dst, mode,               \
                                   render_with_attributes);                \
      }                                                                    \
    }                                                                      \
                                                                           \
    DisplayListCompare equals(const name##Op* other) const {               \
      return (center == other->center && dst == other->dst &&              \
              mode == other->mode && image->Equals(other->image))          \
                 ? DisplayListCompare::kEqual                              \
                 : DisplayListCompare::kNotEqual;                          \
    }                                                                      \
  };
DEFINE_DRAW_IMAGE_NINE_OP(DrawImageNine, false)
DEFINE_DRAW_IMAGE_NINE_OP(DrawImageNineWithAttr, true)
#undef DEFINE_DRAW_IMAGE_NINE_OP

// 4 byte header + 40 byte payload uses 44 bytes but is rounded up to 48 bytes
// (4 bytes unused)
// 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
// DlColor list only packs well if the count is even, otherwise there
// can be 4 unusued bytes at the end.
struct DrawAtlasBaseOp : DrawOpBase {
  DrawAtlasBaseOp(const sk_sp<DlImage>& atlas,
                  int count,
                  DlBlendMode mode,
                  DlImageSampling sampling,
                  bool has_colors,
                  bool render_with_attributes)
      : count(count),
        mode_index(static_cast<uint16_t>(mode)),
        has_colors(has_colors),
        render_with_attributes(render_with_attributes),
        sampling(sampling),
        atlas(atlas) {}

  const int count;
  const uint16_t mode_index;
  const uint8_t has_colors;
  const uint8_t render_with_attributes;
  const DlImageSampling sampling;
  const sk_sp<DlImage> atlas;

  bool equals(const DrawAtlasBaseOp* other,
              const void* pod_this,
              const void* pod_other) const {
    bool ret = (count == other->count && mode_index == other->mode_index &&
                has_colors == other->has_colors &&
                render_with_attributes == other->render_with_attributes &&
                sampling == other->sampling && atlas->Equals(other->atlas));
    if (ret) {
      size_t bytes = count * (sizeof(SkRSXform) + sizeof(SkRect));
      if (has_colors) {
        bytes += count * sizeof(DlColor);
      }
      ret = (memcmp(pod_this, pod_other, bytes) == 0);
    }
    return ret;
  }
};

// Packs into 48 bytes as per DrawAtlasBaseOp
// with array data following the struct also as per DrawAtlasBaseOp
struct DrawAtlasOp final : DrawAtlasBaseOp {
  static constexpr auto kType = DisplayListOpType::kDrawAtlas;

  DrawAtlasOp(const sk_sp<DlImage>& atlas,
              int count,
              DlBlendMode mode,
              DlImageSampling sampling,
              bool has_colors,
              bool render_with_attributes)
      : DrawAtlasBaseOp(atlas,
                        count,
                        mode,
                        sampling,
                        has_colors,
                        render_with_attributes) {}

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      const SkRSXform* xform = reinterpret_cast<const SkRSXform*>(this + 1);
      const SkRect* tex = reinterpret_cast<const SkRect*>(xform + count);
      const DlColor* colors =
          has_colors ? reinterpret_cast<const DlColor*>(tex + count) : nullptr;
      const DlBlendMode mode = static_cast<DlBlendMode>(mode_index);
      ctx.receiver.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
                             nullptr, render_with_attributes);
    }
  }

  DisplayListCompare equals(const DrawAtlasOp* other) const {
    const void* pod_this = reinterpret_cast<const void*>(this + 1);
    const void* pod_other = reinterpret_cast<const void*>(other + 1);
    return (DrawAtlasBaseOp::equals(other, pod_this, pod_other))
               ? DisplayListCompare::kEqual
               : DisplayListCompare::kNotEqual;
  }
};

// Packs into 48 bytes as per DrawAtlasBaseOp plus
// an additional 16 bytes for the cull rect resulting in a total
// of 56 bytes for the Culled drawAtlas.
// Also with array data following the struct as per DrawAtlasBaseOp
struct DrawAtlasCulledOp final : DrawAtlasBaseOp {
  static constexpr auto kType = DisplayListOpType::kDrawAtlasCulled;

  DrawAtlasCulledOp(const sk_sp<DlImage>& atlas,
                    int count,
                    DlBlendMode mode,
                    DlImageSampling sampling,
                    bool has_colors,
                    const SkRect& cull_rect,
                    bool render_with_attributes)
      : DrawAtlasBaseOp(atlas,
                        count,
                        mode,
                        sampling,
                        has_colors,
                        render_with_attributes),
        cull_rect(cull_rect) {}

  const SkRect cull_rect;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      const SkRSXform* xform = reinterpret_cast<const SkRSXform*>(this + 1);
      const SkRect* tex = reinterpret_cast<const SkRect*>(xform + count);
      const DlColor* colors =
          has_colors ? reinterpret_cast<const DlColor*>(tex + count) : nullptr;
      const DlBlendMode mode = static_cast<DlBlendMode>(mode_index);
      ctx.receiver.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
                             &cull_rect, render_with_attributes);
    }
  }

  DisplayListCompare equals(const DrawAtlasCulledOp* other) const {
    const void* pod_this = reinterpret_cast<const void*>(this + 1);
    const void* pod_other = reinterpret_cast<const void*>(other + 1);
    return (cull_rect == other->cull_rect &&
            DrawAtlasBaseOp::equals(other, pod_this, pod_other))
               ? DisplayListCompare::kEqual
               : DisplayListCompare::kNotEqual;
  }
};

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

  explicit DrawDisplayListOp(const sk_sp<DisplayList>& display_list,
                             SkScalar opacity)
      : opacity(opacity), display_list(display_list) {}

  SkScalar opacity;
  const sk_sp<DisplayList> display_list;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.drawDisplayList(display_list, opacity);
    }
  }

  DisplayListCompare equals(const DrawDisplayListOp* other) const {
    return (opacity == other->opacity &&
            display_list->Equals(other->display_list))
               ? DisplayListCompare::kEqual
               : DisplayListCompare::kNotEqual;
  }
};

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

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

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

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.drawTextBlob(blob, x, y);
    }
  }
};

struct DrawTextFrameOp final : DrawOpBase {
  static constexpr auto kType = DisplayListOpType::kDrawTextFrame;

  DrawTextFrameOp(const std::shared_ptr<impeller::TextFrame>& text_frame,
                  SkScalar x,
                  SkScalar y)
      : x(x), y(y), text_frame(text_frame) {}

  const SkScalar x;
  const SkScalar y;
  const std::shared_ptr<impeller::TextFrame> text_frame;

  void dispatch(DispatchContext& ctx) const {
    if (op_needed(ctx)) {
      ctx.receiver.drawTextFrame(text_frame, x, y);
    }
  }
};

// 4 byte header + 140 byte payload packs evenly into 140 bytes
#define DEFINE_DRAW_SHADOW_OP(name, transparent_occluder)                    \
  struct Draw##name##Op final : DrawOpBase {                                 \
    static constexpr auto kType = DisplayListOpType::kDraw##name;            \
                                                                             \
    Draw##name##Op(const SkPath& path,                                       \
                   DlColor color,                                            \
                   SkScalar elevation,                                       \
                   SkScalar dpr)                                             \
        : color(color), elevation(elevation), dpr(dpr), cached_path(path) {} \
                                                                             \
    const DlColor color;                                                     \
    const SkScalar elevation;                                                \
    const SkScalar dpr;                                                      \
    const DlOpReceiver::CacheablePath cached_path;                           \
                                                                             \
    void dispatch(DispatchContext& ctx) const {                              \
      if (op_needed(ctx)) {                                                  \
        if (ctx.receiver.PrefersImpellerPaths()) {                           \
          ctx.receiver.drawShadow(cached_path, color, elevation,             \
                                  transparent_occluder, dpr);                \
        } else {                                                             \
          ctx.receiver.drawShadow(cached_path.sk_path, color, elevation,     \
                                  transparent_occluder, dpr);                \
        }                                                                    \
      }                                                                      \
    }                                                                        \
                                                                             \
    DisplayListCompare equals(const Draw##name##Op* other) const {           \
      return color == other->color && elevation == other->elevation &&       \
                     dpr == other->dpr && cached_path == other->cached_path  \
                 ? DisplayListCompare::kEqual                                \
                 : DisplayListCompare::kNotEqual;                            \
    }                                                                        \
  };
DEFINE_DRAW_SHADOW_OP(Shadow, false)
DEFINE_DRAW_SHADOW_OP(ShadowTransparentOccluder, true)
#undef DEFINE_DRAW_SHADOW_OP

#pragma pack(pop, DLOpPackLabel)

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_DL_OP_RECORDS_H_
