// 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_DISPLAY_LIST_VERTICES_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_VERTICES_H_

#include "flutter/display_list/types.h"

namespace flutter {

//------------------------------------------------------------------------------
/// @brief      Defines the way in which the vertices of a DlVertices object
///             are separated into triangles into which to render.
///
enum class DlVertexMode {
  /// The vertices are taken 3 at a time to form a triangle.
  kTriangles,

  /// The vertices are taken in overlapping triplets to form triangles, with
  /// each triplet sharing 2 of its vertices with the preceding and following
  /// triplets.
  /// vertices [ABCDE] yield 3 triangles ABC,BCD,CDE
  kTriangleStrip,

  /// The vertices are taken in overlapping pairs and combined with the first
  /// vertex to form triangles that radiate outward from the initial point.
  /// vertices [ABCDE] yield 3 triangles ABC,ACD,ADE
  kTriangleFan,
};

inline SkVertices::VertexMode ToSk(DlVertexMode dl_mode) {
  return static_cast<SkVertices::VertexMode>(dl_mode);
}

inline DlVertexMode ToDl(SkVertices::VertexMode sk_mode) {
  return static_cast<DlVertexMode>(sk_mode);
}

//------------------------------------------------------------------------------
/// @brief      Holds all of the data (both required and optional) for a
///             DisplayList drawVertices call.
///
/// There are 4 main pices of data:
///   - vertices():
///       the points on the rendering surface that define the pixels
///       being rendered to in a series of triangles. These points
///       can map to triangles in various ways depending on the
///       supplied |DlVertexMode|.
///   - texture_coordinates():
///       the points in the DlColorSource to map to the coordinates
///       of the triangles in the vertices(). If missing, the
///       vertex coordinates themselves will be used to map the
///       source colors to the vertices.
///   - colors():
///       colors to map to each triangle vertex. Note that each
///       vertex is mapped to exactly 1 color even if the DlVertex
///   - indices():
///       An indirection based on indices into the array of vertices
///       (and by extension, their associated texture_coordinates and
///       colors). Note that the DLVertexMode will still apply to the
///       indices in the same way (and instead of the way) that it
///       would normally be applied to the vertices themselves. The
///       indices are useful, for example, to fill the vertices with
///       a grid of points and then use the indices to define a
///       triangular mesh that covers that grid without having to
///       repeat the vertex (and texture coordinate and color)
///       information for the times when a given grid coordinate
///       gets reused in up to 4 mesh triangles.
///
/// Note that each vertex is mapped to exactly 1 texture_coordinate and
/// color even if the DlVertexMode or indices specify that it contributes
/// to more than one output triangle.
///
class DlVertices {
 public:
  /// @brief     A utility class to build up a |DlVertices| object
  ///            one set of data at a time.
  class Builder {
   public:
    /// @brief     flags to indicate/promise which of the optional
    ///            texture coordinates or colors will be supplied
    ///            during the build phase.
    union Flags {
      struct {
        unsigned has_texture_coordinates : 1;
        unsigned has_colors : 1;
      };
      uint32_t mask = 0;

      inline Flags operator|(const Flags& rhs) const {
        return {.mask = (mask | rhs.mask)};
      }

      inline Flags& operator|=(const Flags& rhs) {
        mask = mask | rhs.mask;
        return *this;
      }
    };
    static constexpr Flags kNone = {{false, false}};
    static constexpr Flags kHasTextureCoordinates = {{true, false}};
    static constexpr Flags kHasColors = {{false, true}};

    //--------------------------------------------------------------------------
    /// @brief     Constructs a Builder and prepares room for the
    ///            required and optional data.
    ///
    /// Vertices are always required. Optional texture coordinates
    /// and optional colors are reserved depending on the |Flags|.
    /// Optional indices will be reserved iff the index_count is
    /// positive (>0).
    ///
    /// The caller must provide all data that is promised by the
    /// supplied |flags| and |index_count| parameters before
    /// calling the |build()| method.
    Builder(DlVertexMode mode, int vertex_count, Flags flags, int index_count);

    /// Returns true iff the underlying object was successfully allocated.
    bool is_valid() { return vertices_ != nullptr; }

    /// @brief Copies the indicated list of points as vertices.
    ///
    /// fails if vertices have already been supplied.
    void store_vertices(const SkPoint points[]);

    /// @brief Copies the indicated list of float pairs as vertices.
    ///
    /// fails if vertices have already been supplied.
    void store_vertices(const float coordinates[]);

    /// @brief Copies the indicated list of points as texture coordinates.
    ///
    /// fails if texture coordinates have already been supplied or if they
    /// were not promised by the flags.has_texture_coordinates.
    void store_texture_coordinates(const SkPoint points[]);

    /// @brief Copies the indicated list of float pairs as texture coordinates.
    ///
    /// fails if texture coordinates have already been supplied or if they
    /// were not promised by the flags.has_texture_coordinates.
    void store_texture_coordinates(const float coordinates[]);

    /// @brief Copies the indicated list of colors as vertex colors.
    ///
    /// fails if colors have already been supplied or if they were not
    /// promised by the flags.has_colors.
    void store_colors(const SkColor colors[]);

    /// @brief Copies the indicated list of 16-bit indices as vertex indices.
    ///
    /// fails if indices have already been supplied or if they were not
    /// promised by (index_count > 0).
    void store_indices(const uint16_t indices[]);

    /// @brief Finalizes and the constructed DlVertices object.
    ///
    /// fails if any of the optional data promised in the constructor is
    /// missing.
    std::shared_ptr<DlVertices> build();

   private:
    std::shared_ptr<DlVertices> vertices_;
    bool needs_vertices_;
    bool needs_texture_coords_;
    bool needs_colors_;
    bool needs_indices_;
  };

  //--------------------------------------------------------------------------
  /// @brief     Constructs a DlVector with compact inline storage for all
  ///            of its required and optional lists of data.
  ///
  /// Vertices are always required. Optional texture coordinates
  /// and optional colors are stored if the arguments are non-null.
  /// Optional indices will be stored iff the array argument is
  /// non-null and the index_count is positive (>0).
  static std::shared_ptr<DlVertices> Make(DlVertexMode mode,
                                          int vertex_count,
                                          const SkPoint vertices[],
                                          const SkPoint texture_coordinates[],
                                          const SkColor colors[],
                                          int index_count = 0,
                                          const uint16_t indices[] = nullptr);

  /// Returns the size of the object including all of the inlined data.
  size_t size() const;

  /// Returns the bounds of the vertices.
  SkRect bounds() const { return bounds_; }

  /// Returns the vertex mode that defines how the vertices (or the indices)
  /// are turned into triangles.
  DlVertexMode mode() const { return mode_; }

  /// Returns the number of vertices, which also applies to the number of
  /// texture coordinate and colors if they are provided.
  int vertex_count() const { return vertex_count_; }

  /// Returns a pointer to the vertex information. Should be non-null.
  const SkPoint* vertices() const {
    return static_cast<const SkPoint*>(pod(vertices_offset_));
  }

  /// Returns a pointer to the vertex texture coordinate
  /// or null if none were provided.
  const SkPoint* texture_coordinates() const {
    return static_cast<const SkPoint*>(pod(texture_coordinates_offset_));
  }

  /// Returns a pointer to the vertex colors
  /// or null if none were provided.
  const SkColor* colors() const {
    return static_cast<const SkColor*>(pod(colors_offset_));
  }

  /// Returns a pointer to the count of vertex indices
  /// or 0 if none were provided.
  int index_count() const { return index_count_; }

  /// Returns a pointer to the vertex indices
  /// or null if none were provided.
  const uint16_t* indices() const {
    return static_cast<const uint16_t*>(pod(indices_offset_));
  }

  // Returns an equivalent sk_sp<SkVertices> analog to this object.
  sk_sp<SkVertices> skia_object() const;

  bool operator==(DlVertices const& other) const;

  bool operator!=(DlVertices const& other) const { return !(*this == other); }

 private:
  // Constructors are designed to encapsulate arrays sequentially in memory
  // which means they can only be called by intantiations that use the
  // new (ptr) paradigm which precomputes and preallocates the memory for
  // the class body and all of its arrays, such as in Builder.
  DlVertices(DlVertexMode mode,
             int vertex_count,
             const SkPoint vertices[],
             const SkPoint texture_coordinates[],
             const SkColor colors[],
             int index_count,
             const uint16_t indices[],
             const SkRect* bounds = nullptr);

  // This constructor is specifically used by the DlVertices::Builder to
  // establish the object before the copying of data is requested.
  DlVertices(DlVertexMode mode,
             int vertex_count,
             Builder::Flags flags,
             int index_count);

  // The copy constructor has the same memory pre-allocation requirements
  // as this other constructors. This particular version is used by the
  // DisplaylistBuilder to copy the instance into pre-allocated pod memory
  // in the display list buffer.
  explicit DlVertices(const DlVertices* other);

  DlVertexMode mode_;

  int vertex_count_;
  size_t vertices_offset_;
  size_t texture_coordinates_offset_;
  size_t colors_offset_;

  int index_count_;
  size_t indices_offset_;

  SkRect bounds_;

  const void* pod(int offset) const {
    if (offset <= 0) {
      return nullptr;
    }
    const void* base = static_cast<const void*>(this);
    return static_cast<const char*>(base) + offset;
  }

  friend class DisplayListBuilder;
};

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_VERTICES_H_
