// 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 "flutter/display_list/dl_vertices.h"

#include "flutter/display_list/utils/dl_bounds_accumulator.h"
#include "flutter/fml/logging.h"

namespace flutter {

using Flags = DlVertices::Builder::Flags;

static void DlVerticesDeleter(void* p) {
  // Some of our target environments would prefer a sized delete,
  // but other target environments do not have that operator.
  // Use an unsized delete until we get better agreement in the
  // environments.
  // See https://github.com/flutter/flutter/issues/100327
  ::operator delete(p);
}

static size_t bytes_needed(int vertex_count, Flags flags, int index_count) {
  int needed = sizeof(DlVertices);
  // We always have vertices
  needed += vertex_count * sizeof(SkPoint);
  if (flags.has_texture_coordinates) {
    needed += vertex_count * sizeof(SkPoint);
  }
  if (flags.has_colors) {
    needed += vertex_count * sizeof(DlColor);
  }
  if (index_count > 0) {
    needed += index_count * sizeof(uint16_t);
  }
  return needed;
}

std::shared_ptr<DlVertices> DlVertices::Make(
    DlVertexMode mode,
    int vertex_count,
    const SkPoint vertices[],
    const SkPoint texture_coordinates[],
    const DlColor colors[],
    int index_count,
    const uint16_t indices[]) {
  if (!vertices || vertex_count <= 0) {
    vertex_count = 0;
    texture_coordinates = nullptr;
    colors = nullptr;
  }
  if (!indices || index_count <= 0) {
    index_count = 0;
    indices = nullptr;
  }

  Flags flags;
  FML_DCHECK(!flags.has_texture_coordinates);
  FML_DCHECK(!flags.has_colors);
  if (texture_coordinates) {
    flags |= Builder::kHasTextureCoordinates;
  }
  if (colors) {
    flags |= Builder::kHasColors;
  }
  Builder builder(mode, vertex_count, flags, index_count);

  builder.store_vertices(vertices);
  if (texture_coordinates) {
    builder.store_texture_coordinates(texture_coordinates);
  }
  if (colors) {
    builder.store_colors(colors);
  }
  if (indices) {
    builder.store_indices(indices);
  }

  return builder.build();
}

size_t DlVertices::size() const {
  return bytes_needed(vertex_count_,
                      {{texture_coordinates_offset_ > 0, colors_offset_ > 0}},
                      index_count_);
}

static SkRect compute_bounds(const SkPoint* points, int count) {
  RectBoundsAccumulator accumulator;
  for (int i = 0; i < count; i++) {
    accumulator.accumulate(points[i]);
  }
  return accumulator.bounds();
}

DlVertices::DlVertices(DlVertexMode mode,
                       int unchecked_vertex_count,
                       const SkPoint* vertices,
                       const SkPoint* texture_coordinates,
                       const DlColor* colors,
                       int unchecked_index_count,
                       const uint16_t* indices,
                       const SkRect* bounds)
    : mode_(mode),
      vertex_count_(std::max(unchecked_vertex_count, 0)),
      index_count_(indices ? std::max(unchecked_index_count, 0) : 0) {
  bounds_ = bounds ? *bounds : compute_bounds(vertices, vertex_count_);

  char* pod = reinterpret_cast<char*>(this);
  size_t offset = sizeof(DlVertices);

  auto advance = [pod, &offset](auto* src, int count) {
    if (src != nullptr && count > 0) {
      size_t bytes = count * sizeof(*src);
      memcpy(pod + offset, src, bytes);
      size_t ret = offset;
      offset += bytes;
      return ret;
    } else {
      return static_cast<size_t>(0);
    }
  };

  vertices_offset_ = advance(vertices, vertex_count_);
  texture_coordinates_offset_ = advance(texture_coordinates, vertex_count_);
  colors_offset_ = advance(colors, vertex_count_);
  indices_offset_ = advance(indices, index_count_);
  FML_DCHECK(offset == bytes_needed(vertex_count_,
                                    {{!!texture_coordinates, !!colors}},
                                    index_count_));
}

DlVertices::DlVertices(const DlVertices* other)
    : DlVertices(other->mode_,
                 other->vertex_count_,
                 other->vertices(),
                 other->texture_coordinates(),
                 other->colors(),
                 other->index_count_,
                 other->indices(),
                 &other->bounds_) {}

DlVertices::DlVertices(DlVertexMode mode,
                       int unchecked_vertex_count,
                       Flags flags,
                       int unchecked_index_count)
    : mode_(mode),
      vertex_count_(std::max(unchecked_vertex_count, 0)),
      index_count_(std::max(unchecked_index_count, 0)) {
  char* pod = reinterpret_cast<char*>(this);
  size_t offset = sizeof(DlVertices);

  auto advance = [pod, &offset](size_t size, int count) {
    if (count > 0) {
      size_t bytes = count * size;
      memset(pod + offset, 0, bytes);
      size_t ret = offset;
      offset += bytes;
      return ret;
    } else {
      return static_cast<size_t>(0);
    }
  };

  vertices_offset_ = advance(sizeof(SkPoint), vertex_count_);
  texture_coordinates_offset_ = advance(
      sizeof(SkPoint), flags.has_texture_coordinates ? vertex_count_ : 0);
  colors_offset_ =
      advance(sizeof(DlColor), flags.has_colors ? vertex_count_ : 0);
  indices_offset_ = advance(sizeof(uint16_t), index_count_);
  FML_DCHECK(offset == bytes_needed(vertex_count_, flags, index_count_));
  FML_DCHECK((vertex_count_ != 0) == (vertices() != nullptr));
  FML_DCHECK((vertex_count_ != 0 && flags.has_texture_coordinates) ==
             (texture_coordinates() != nullptr));
  FML_DCHECK((vertex_count_ != 0 && flags.has_colors) == (colors() != nullptr));
  FML_DCHECK((index_count_ != 0) == (indices() != nullptr));
}

bool DlVertices::operator==(DlVertices const& other) const {
  auto lists_equal = [](auto* a, auto* b, int count) {
    if (a == nullptr || b == nullptr) {
      return a == b;
    }
    for (int i = 0; i < count; i++) {
      if (a[i] != b[i]) {
        return false;
      }
    }
    return true;
  };
  return                                                               //
      mode_ == other.mode_ &&                                          //
      vertex_count_ == other.vertex_count_ &&                          //
      lists_equal(vertices(), other.vertices(), vertex_count_) &&      //
      lists_equal(texture_coordinates(), other.texture_coordinates(),  //
                  vertex_count_) &&                                    //
      lists_equal(colors(), other.colors(), vertex_count_) &&          //
      index_count_ == other.index_count_ &&                            //
      lists_equal(indices(), other.indices(), index_count_);
}

DlVertices::Builder::Builder(DlVertexMode mode,
                             int vertex_count,
                             Flags flags,
                             int index_count)
    : needs_texture_coords_(flags.has_texture_coordinates),
      needs_colors_(flags.has_colors),
      needs_indices_(index_count > 0) {
  vertex_count = std::max(vertex_count, 0);
  index_count = std::max(index_count, 0);
  void* storage =
      ::operator new(bytes_needed(vertex_count, flags, index_count));
  vertices_.reset(new (storage)
                      DlVertices(mode, vertex_count, flags, index_count),
                  DlVerticesDeleter);
}

static void store_points(char* dst, int offset, const float* src, int count) {
  SkPoint* points = reinterpret_cast<SkPoint*>(dst + offset);
  for (int i = 0; i < count; i++) {
    points[i] = SkPoint::Make(src[i * 2], src[i * 2 + 1]);
  }
}

void DlVertices::Builder::store_vertices(const SkPoint vertices[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_vertices_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  size_t bytes = vertices_->vertex_count_ * sizeof(vertices[0]);
  memcpy(pod + vertices_->vertices_offset_, vertices, bytes);
  needs_vertices_ = false;
}

void DlVertices::Builder::store_vertices(const float vertices[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_vertices_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  store_points(pod, vertices_->vertices_offset_, vertices,
               vertices_->vertex_count_);
  needs_vertices_ = false;
}

void DlVertices::Builder::store_texture_coordinates(const SkPoint coords[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_texture_coords_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  size_t bytes = vertices_->vertex_count_ * sizeof(coords[0]);
  memcpy(pod + vertices_->texture_coordinates_offset_, coords, bytes);
  needs_texture_coords_ = false;
}

void DlVertices::Builder::store_texture_coordinates(const float coords[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_texture_coords_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  store_points(pod, vertices_->texture_coordinates_offset_, coords,
               vertices_->vertex_count_);
  needs_texture_coords_ = false;
}

void DlVertices::Builder::store_colors(const DlColor colors[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_colors_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  size_t bytes = vertices_->vertex_count_ * sizeof(colors[0]);
  memcpy(pod + vertices_->colors_offset_, colors, bytes);
  needs_colors_ = false;
}

void DlVertices::Builder::store_indices(const uint16_t indices[]) {
  FML_CHECK(is_valid());
  FML_CHECK(needs_indices_);
  char* pod = reinterpret_cast<char*>(vertices_.get());
  size_t bytes = vertices_->index_count_ * sizeof(indices[0]);
  memcpy(pod + vertices_->indices_offset_, indices, bytes);
  needs_indices_ = false;
}

std::shared_ptr<DlVertices> DlVertices::Builder::build() {
  FML_CHECK(is_valid());
  if (vertices_->vertex_count() <= 0) {
    // We set this to true in the constructor to make sure that they
    // call store_vertices() only once, but if there are no vertices
    // then we will not object to them never having stored any vertices
    needs_vertices_ = false;
  }
  FML_CHECK(!needs_vertices_);
  FML_CHECK(!needs_texture_coords_);
  FML_CHECK(!needs_colors_);
  FML_CHECK(!needs_indices_);

  vertices_->bounds_ =
      compute_bounds(vertices_->vertices(), vertices_->vertex_count_);

  return std::move(vertices_);
}

}  // namespace flutter
