// 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 "impeller/entity/geometry/point_field_geometry.h"

#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/compute_command.h"

namespace impeller {

PointFieldGeometry::PointFieldGeometry(std::vector<Point> points,
                                       Scalar radius,
                                       bool round)
    : points_(std::move(points)), radius_(radius), round_(round) {}

PointFieldGeometry::~PointFieldGeometry() = default;

GeometryResult PointFieldGeometry::GetPositionBuffer(
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass) {
  if (renderer.GetDeviceCapabilities().SupportsCompute()) {
    return GetPositionBufferGPU(renderer, entity, pass);
  }
  auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass);
  if (!vtx_builder.has_value()) {
    return {};
  }

  auto& host_buffer = pass.GetTransientsBuffer();
  return {
      .type = PrimitiveType::kTriangle,
      .vertex_buffer = vtx_builder->CreateVertexBuffer(host_buffer),
      .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
                   entity.GetTransformation(),
      .prevent_overdraw = false,
  };
}

GeometryResult PointFieldGeometry::GetPositionUVBuffer(
    Rect texture_coverage,
    Matrix effect_transform,
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass) {
  if (renderer.GetDeviceCapabilities().SupportsCompute()) {
    return GetPositionBufferGPU(renderer, entity, pass, texture_coverage,
                                effect_transform);
  }

  auto vtx_builder = GetPositionBufferCPU(renderer, entity, pass);
  if (!vtx_builder.has_value()) {
    return {};
  }
  auto uv_vtx_builder = ComputeUVGeometryCPU(
      vtx_builder.value(), {0, 0}, texture_coverage.size, effect_transform);

  auto& host_buffer = pass.GetTransientsBuffer();
  return {
      .type = PrimitiveType::kTriangle,
      .vertex_buffer = uv_vtx_builder.CreateVertexBuffer(host_buffer),
      .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
                   entity.GetTransformation(),
      .prevent_overdraw = false,
  };
}

std::optional<VertexBufferBuilder<SolidFillVertexShader::PerVertexData>>
PointFieldGeometry::GetPositionBufferCPU(const ContentContext& renderer,
                                         const Entity& entity,
                                         RenderPass& pass) {
  if (radius_ < 0.0) {
    return std::nullopt;
  }
  auto determinant = entity.GetTransformation().GetDeterminant();
  if (determinant == 0) {
    return std::nullopt;
  }

  Scalar min_size = 1.0f / sqrt(std::abs(determinant));
  Scalar radius = std::max(radius_, min_size);

  auto vertices_per_geom = ComputeCircleDivisions(
      entity.GetTransformation().GetMaxBasisLength() * radius, round_);
  auto points_per_circle = 3 + (vertices_per_geom - 3) * 3;
  auto total = points_per_circle * points_.size();
  auto radian_start = round_ ? 0.0f : 0.785398f;
  auto radian_step = k2Pi / vertices_per_geom;

  VertexBufferBuilder<SolidFillVertexShader::PerVertexData> vtx_builder;
  vtx_builder.Reserve(total);

  /// Precompute all relative points and angles for a fixed geometry size.
  auto elapsed_angle = radian_start;
  std::vector<Point> angle_table(vertices_per_geom);
  for (auto i = 0u; i < vertices_per_geom; i++) {
    angle_table[i] = Point(cos(elapsed_angle), sin(elapsed_angle)) * radius;
    elapsed_angle += radian_step;
  }

  for (auto i = 0u; i < points_.size(); i++) {
    auto center = points_[i];

    auto origin = center + angle_table[0];
    vtx_builder.AppendVertex({origin});

    auto pt1 = center + angle_table[1];
    vtx_builder.AppendVertex({pt1});

    auto pt2 = center + angle_table[2];
    vtx_builder.AppendVertex({pt2});

    for (auto j = 0u; j < vertices_per_geom - 3; j++) {
      vtx_builder.AppendVertex({origin});
      vtx_builder.AppendVertex({pt2});

      pt2 = center + angle_table[j + 3];
      vtx_builder.AppendVertex({pt2});
    }
  }
  return vtx_builder;
}

GeometryResult PointFieldGeometry::GetPositionBufferGPU(
    const ContentContext& renderer,
    const Entity& entity,
    RenderPass& pass,
    std::optional<Rect> texture_coverage,
    std::optional<Matrix> effect_transform) {
  FML_DCHECK(renderer.GetDeviceCapabilities().SupportsCompute());
  if (radius_ < 0.0) {
    return {};
  }
  auto determinant = entity.GetTransformation().GetDeterminant();
  if (determinant == 0) {
    return {};
  }

  Scalar min_size = 1.0f / sqrt(std::abs(determinant));
  Scalar radius = std::max(radius_, min_size);

  auto vertices_per_geom = ComputeCircleDivisions(
      entity.GetTransformation().GetMaxBasisLength() * radius, round_);

  auto points_per_circle = 3 + (vertices_per_geom - 3) * 3;
  auto total = points_per_circle * points_.size();

  auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer();
  auto compute_pass = cmd_buffer->CreateComputePass();
  auto& host_buffer = compute_pass->GetTransientsBuffer();

  auto points_data =
      host_buffer.Emplace(points_.data(), points_.size() * sizeof(Point),
                          DefaultUniformAlignment());

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total * sizeof(Point);
  buffer_desc.storage_mode = StorageMode::kDevicePrivate;

  auto geometry_buffer = renderer.GetContext()
                             ->GetResourceAllocator()
                             ->CreateBuffer(buffer_desc)
                             ->AsBufferView();

  BufferView output;
  {
    using PS = PointsComputeShader;
    ComputeCommand cmd;
    DEBUG_COMMAND_INFO(cmd, "Points Geometry");
    cmd.pipeline = renderer.GetPointComputePipeline();

    PS::FrameInfo frame_info;
    frame_info.count = points_.size();
    frame_info.radius = radius;
    frame_info.radian_start = round_ ? 0.0f : kPiOver4;
    frame_info.radian_step = k2Pi / vertices_per_geom;
    frame_info.points_per_circle = points_per_circle;
    frame_info.divisions_per_circle = vertices_per_geom;

    PS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
    PS::BindGeometryData(cmd, geometry_buffer);
    PS::BindPointData(cmd, points_data);

    if (!compute_pass->AddCommand(std::move(cmd))) {
      return {};
    }
    output = geometry_buffer;
  }

  if (texture_coverage.has_value() && effect_transform.has_value()) {
    DeviceBufferDescriptor buffer_desc;
    buffer_desc.size = total * sizeof(Vector4);
    buffer_desc.storage_mode = StorageMode::kDevicePrivate;

    auto geometry_uv_buffer = renderer.GetContext()
                                  ->GetResourceAllocator()
                                  ->CreateBuffer(buffer_desc)
                                  ->AsBufferView();

    using UV = UvComputeShader;

    ComputeCommand cmd;
    DEBUG_COMMAND_INFO(cmd, "UV Geometry");
    cmd.pipeline = renderer.GetUvComputePipeline();

    UV::FrameInfo frame_info;
    frame_info.count = total;
    frame_info.effect_transform = effect_transform.value();
    frame_info.texture_origin = {0, 0};
    frame_info.texture_size = Vector2(texture_coverage.value().size);

    UV::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
    UV::BindGeometryData(cmd, geometry_buffer);
    UV::BindGeometryUVData(cmd, geometry_uv_buffer);

    if (!compute_pass->AddCommand(std::move(cmd))) {
      return {};
    }
    output = geometry_uv_buffer;
  }

  compute_pass->SetGridSize(ISize(total, 1));
  compute_pass->SetThreadGroupSize(ISize(total, 1));

  if (!compute_pass->EncodeCommands() || !cmd_buffer->SubmitCommands()) {
    return {};
  }

  return {
      .type = PrimitiveType::kTriangle,
      .vertex_buffer = {.vertex_buffer = output,
                        .vertex_count = total,
                        .index_type = IndexType::kNone},
      .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
                   entity.GetTransformation(),
      .prevent_overdraw = false,
  };
}

/// @brief Compute the number of vertices to divide each circle into.
///
/// @return the number of vertices.
size_t PointFieldGeometry::ComputeCircleDivisions(Scalar scaled_radius,
                                                  bool round) {
  if (!round) {
    return 4;
  }

  // Note: these values are approximated based on the values returned from
  // the decomposition of 4 cubics performed by Path::CreatePolyline.
  if (scaled_radius < 1.0) {
    return 4;
  }
  if (scaled_radius < 2.0) {
    return 8;
  }
  if (scaled_radius < 12.0) {
    return 24;
  }
  if (scaled_radius < 22.0) {
    return 34;
  }
  return std::min(scaled_radius, 140.0f);
}

// |Geometry|
GeometryVertexType PointFieldGeometry::GetVertexType() const {
  return GeometryVertexType::kPosition;
}

// |Geometry|
std::optional<Rect> PointFieldGeometry::GetCoverage(
    const Matrix& transform) const {
  if (points_.size() > 0) {
    // Doesn't use MakePointBounds as this isn't resilient to points that
    // all lie along the same axis.
    auto first = points_.begin();
    auto last = points_.end();
    auto left = first->x;
    auto top = first->y;
    auto right = first->x;
    auto bottom = first->y;
    for (auto it = first + 1; it < last; ++it) {
      left = std::min(left, it->x);
      top = std::min(top, it->y);
      right = std::max(right, it->x);
      bottom = std::max(bottom, it->y);
    }
    return Rect::MakeLTRB(left - radius_, top - radius_, right + radius_,
                          bottom + radius_);
  }
  return std::nullopt;
}

}  // namespace impeller
