// 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/lib/gpu/surface.h"

#include <cstdint>

#include "flutter/lib/gpu/formats.h"
#include "flutter/lib/ui/painting/image.h"
#include "fml/logging.h"
#include "impeller/core/allocator.h"
#include "tonic/converter/dart_converter.h"

#if IMPELLER_SUPPORTS_RENDERING
#include "impeller/display_list/dl_image_impeller.h"  // nogncheck
#endif

namespace flutter {
namespace gpu {

IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, Surface);

namespace {

constexpr int64_t kMaxInternalTextureReferences = 3;

}  // namespace

Surface::TextureRecord::TextureRecord(
    std::shared_ptr<impeller::Texture> texture,
    sk_sp<DlImage> image,
    impeller::ISize size,
    impeller::PixelFormat format)
    : texture(std::move(texture)),
      image(std::move(image)),
      size(size),
      format(format) {}

Surface::Surface(std::shared_ptr<impeller::Context> context,
                 impeller::ISize size,
                 impeller::PixelFormat format)
    : context_(std::move(context)), size_(size), format_(format) {}

Surface::~Surface() = default;

std::shared_ptr<Surface::TextureRecord> Surface::CreateTextureRecord() const {
#if !IMPELLER_SUPPORTS_RENDERING
  FML_LOG(ERROR) << "Flutter GPU surfaces require Impeller rendering support.";
  return nullptr;
#else
  impeller::TextureDescriptor desc;
  desc.storage_mode = impeller::StorageMode::kDevicePrivate;
  desc.size = size_;
  desc.format = format_;
  desc.sample_count = impeller::SampleCount::kCount1;
  desc.type = impeller::TextureType::kTexture2D;
  desc.mip_count = 1;
  desc.usage = {};
  desc.usage |= impeller::TextureUsage::kRenderTarget;
  desc.usage |= impeller::TextureUsage::kShaderRead;

  auto texture = context_->GetResourceAllocator()->CreateTexture(desc, true);
  if (!texture) {
    FML_LOG(ERROR) << "Failed to create Flutter GPU surface texture.";
    return nullptr;
  }

  auto image = impeller::DlImageImpeller::Make(texture);
  if (!image) {
    FML_LOG(ERROR) << "Failed to create Flutter GPU surface image.";
    return nullptr;
  }

  return std::make_shared<TextureRecord>(std::move(texture), std::move(image),
                                         size_, format_);
#endif
}

bool Surface::IsReusable(const std::shared_ptr<TextureRecord>& record,
                         size_t index) const {
  if (current_index_.has_value() && current_index_.value() == index) {
    return false;
  }
  return record && record->size.width == size_.width &&
         record->size.height == size_.height && record->format == format_ &&
         !record->acquired && !record->producer_pending.load() &&
         record->image && record->image->unique() &&
         static_cast<int64_t>(record->texture.use_count()) <=
             kMaxInternalTextureReferences;
}

void Surface::PruneTextureRecords() {
  for (size_t i = 0; i < records_.size(); i++) {
    auto& record = records_[i];
    if (!record) {
      continue;
    }

    const bool is_current =
        current_index_.has_value() && current_index_.value() == i;
    const bool matches_surface = record->size.width == size_.width &&
                                 record->size.height == size_.height &&
                                 record->format == format_;
    // The surface record, its image, and the Dart texture wrapper handed out
    // for the completed frame may all still reference an otherwise
    // unreferenced texture.
    const bool has_external_references =
        !record->image || !record->image->unique() ||
        static_cast<int64_t>(record->texture.use_count()) >
            kMaxInternalTextureReferences;

    if (!is_current && !matches_surface && !record->acquired &&
        !record->producer_pending.load() && !has_external_references) {
      record.reset();
    }
  }

  while (!records_.empty() && !records_.back()) {
    records_.pop_back();
  }
}

int Surface::AcquireNextFrame(Dart_Handle texture_wrapper) {
  std::optional<size_t> available_index;
  size_t index = 0;
  for (const auto& record : records_) {
    if (!record && !available_index.has_value()) {
      available_index = index;
    }
    if (IsReusable(record, index)) {
      record->acquired = true;
      auto texture = fml::MakeRefCounted<Texture>(record->texture);
      texture->AssociateWithDartWrapper(texture_wrapper);
      return static_cast<int>(index);
    }
    index++;
  }

  auto record = CreateTextureRecord();
  if (!record) {
    return -1;
  }
  record->acquired = true;

  if (available_index.has_value()) {
    records_[available_index.value()] = record;
    index = available_index.value();
  } else {
    records_.push_back(record);
    index = records_.size() - 1u;
  }

  auto texture = fml::MakeRefCounted<Texture>(record->texture);
  texture->AssociateWithDartWrapper(texture_wrapper);
  return static_cast<int>(index);
}

Dart_Handle Surface::CreateImage(const sk_sp<DlImage>& image) const {
  if (!image) {
    return Dart_Null();
  }
  auto canvas_image = CanvasImage::Create();
  canvas_image->set_image(image);
  return canvas_image->CreateOuterWrapping();
}

Dart_Handle Surface::PresentFrame(size_t texture_index,
                                  CommandBuffer& command_buffer) {
  if (texture_index >= records_.size()) {
    return tonic::ToDart("SurfaceFrame does not belong to this GpuSurface.");
  }

  auto record = records_[texture_index];
  if (!record || !record->acquired) {
    return tonic::ToDart(
        "SurfaceFrame has already been presented or discarded.");
  }

  record->producer_pending.store(true);
  if (!command_buffer.AddCompletionCallback(
          [record]([[maybe_unused]] impeller::CommandBuffer::Status status) {
            record->producer_pending.store(false);
          })) {
    record->producer_pending.store(false);
    return tonic::ToDart(
        "SurfaceFrame.present must be called before submitting the command "
        "buffer.");
  }

  record->acquired = false;
  current_index_ = texture_index;
  PruneTextureRecords();
  // The presented image is read separately via GetCurrentImage, so avoid
  // allocating an image wrapper here on every presented frame.
  return Dart_Null();
}

void Surface::DiscardFrame(size_t texture_index) {
  if (texture_index >= records_.size()) {
    return;
  }
  auto record = records_[texture_index];
  if (record) {
    record->acquired = false;
  }
}

Dart_Handle Surface::GetCurrentImage() const {
  if (!current_index_.has_value() ||
      current_index_.value() >= records_.size()) {
    return Dart_Null();
  }
  auto record = records_[current_index_.value()];
  if (!record) {
    return Dart_Null();
  }
  return CreateImage(record->image);
}

std::optional<std::string> Surface::Resize(impeller::ISize size) {
  for (const auto& record : records_) {
    if (record && record->acquired) {
      return "GpuSurface.resize cannot be called while a SurfaceFrame is "
             "acquired.";
    }
  }
  size_ = size;
  PruneTextureRecords();
  return std::nullopt;
}

size_t Surface::GetBackingTextureCount() const {
  size_t count = 0;
  for (const auto& record : records_) {
    if (record) {
      count++;
    }
  }
  return count;
}

}  // namespace gpu
}  // namespace flutter

//----------------------------------------------------------------------------
/// Exports
///

Dart_Handle InternalFlutterGpu_Surface_Initialize(
    [[maybe_unused]] Dart_Handle wrapper,
    [[maybe_unused]] flutter::gpu::Context* gpu_context,
    int width,
    int height,
    [[maybe_unused]] int format) {
  if (width <= 0 || height <= 0) {
    return tonic::ToDart("GpuSurface dimensions must be greater than zero.");
  }

#if !IMPELLER_SUPPORTS_RENDERING
  return tonic::ToDart("GpuSurface requires Impeller rendering support.");
#else
  auto pixel_format = flutter::gpu::ToImpellerPixelFormat(format);
  if (pixel_format == impeller::PixelFormat::kUnknown) {
    return tonic::ToDart("Unsupported GpuSurface pixel format.");
  }

  auto res = fml::MakeRefCounted<flutter::gpu::Surface>(
      gpu_context->GetContextShared(), impeller::ISize{width, height},
      pixel_format);
  res->AssociateWithDartWrapper(wrapper);
  return Dart_Null();
#endif
}

int InternalFlutterGpu_Surface_AcquireNextFrame(flutter::gpu::Surface* wrapper,
                                                Dart_Handle texture_wrapper) {
  return wrapper->AcquireNextFrame(texture_wrapper);
}

Dart_Handle InternalFlutterGpu_Surface_PresentFrame(
    flutter::gpu::Surface* wrapper,
    int texture_index,
    flutter::gpu::CommandBuffer* command_buffer) {
  if (texture_index < 0) {
    return tonic::ToDart("Invalid SurfaceFrame texture index.");
  }
  return wrapper->PresentFrame(static_cast<size_t>(texture_index),
                               *command_buffer);
}

void InternalFlutterGpu_Surface_DiscardFrame(flutter::gpu::Surface* wrapper,
                                             int texture_index) {
  if (texture_index < 0) {
    return;
  }
  wrapper->DiscardFrame(static_cast<size_t>(texture_index));
}

Dart_Handle InternalFlutterGpu_Surface_GetCurrentImage(
    flutter::gpu::Surface* wrapper) {
  return wrapper->GetCurrentImage();
}

Dart_Handle InternalFlutterGpu_Surface_Resize(flutter::gpu::Surface* wrapper,
                                              int width,
                                              int height) {
  if (width <= 0 || height <= 0) {
    return tonic::ToDart("GpuSurface dimensions must be greater than zero.");
  }
  auto error = wrapper->Resize(impeller::ISize{width, height});
  if (error.has_value()) {
    return tonic::ToDart(error.value());
  }
  return Dart_Null();
}

int InternalFlutterGpu_Surface_GetBackingTextureCount(
    flutter::gpu::Surface* wrapper) {
  return static_cast<int>(wrapper->GetBackingTextureCount());
}
