// 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/shell/platform/embedder/tests/embedder_test_backingstore_producer.h"

#include "flutter/fml/logging.h"
#include "flutter/shell/platform/embedder/pixel_formats.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GpuTypes.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
#include "third_party/skia/include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h"

#include <cstdlib>
#include <memory>
#include <utility>

#ifdef SHELL_ENABLE_VULKAN
#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
#endif  // SHELL_ENABLE_VULKAN

// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
// NOLINTBEGIN(bugprone-unchecked-optional-access)

namespace flutter {
namespace testing {

EmbedderTestBackingStoreProducer::EmbedderTestBackingStoreProducer(
    sk_sp<GrDirectContext> context,
    RenderTargetType type,
    FlutterSoftwarePixelFormat software_pixfmt)
    : context_(std::move(context)),
      type_(type),
      software_pixfmt_(software_pixfmt)
#ifdef SHELL_ENABLE_METAL
      ,
      test_metal_context_(std::make_unique<TestMetalContext>())
#endif
#ifdef SHELL_ENABLE_VULKAN
      ,
      test_vulkan_context_(nullptr)
#endif
{
  if (type == RenderTargetType::kSoftwareBuffer &&
      software_pixfmt_ != kFlutterSoftwarePixelFormatNative32) {
    FML_LOG(ERROR) << "Expected pixel format to be the default "
                      "(kFlutterSoftwarePixelFormatNative32) when"
                      "backing store producer should produce deprecated v1 "
                      "software backing "
                      "stores.";
    std::abort();
  };
}

EmbedderTestBackingStoreProducer::~EmbedderTestBackingStoreProducer() = default;

bool EmbedderTestBackingStoreProducer::Create(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* renderer_out) {
  switch (type_) {
    case RenderTargetType::kSoftwareBuffer:
      return CreateSoftware(config, renderer_out);
    case RenderTargetType::kSoftwareBuffer2:
      return CreateSoftware2(config, renderer_out);
#ifdef SHELL_ENABLE_GL
    case RenderTargetType::kOpenGLTexture:
      return CreateTexture(config, renderer_out);
    case RenderTargetType::kOpenGLFramebuffer:
      return CreateFramebuffer(config, renderer_out);
#endif
#ifdef SHELL_ENABLE_METAL
    case RenderTargetType::kMetalTexture:
      return CreateMTLTexture(config, renderer_out);
#endif
#ifdef SHELL_ENABLE_VULKAN
    case RenderTargetType::kVulkanImage:
      return CreateVulkanImage(config, renderer_out);
#endif
    default:
      return false;
  }
}

bool EmbedderTestBackingStoreProducer::CreateFramebuffer(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
#ifdef SHELL_ENABLE_GL
  const auto image_info =
      SkImageInfo::MakeN32Premul(config->size.width, config->size.height);

  auto surface =
      SkSurfaces::RenderTarget(context_.get(),               // context
                               skgpu::Budgeted::kNo,         // budgeted
                               image_info,                   // image info
                               1,                            // sample count
                               kBottomLeft_GrSurfaceOrigin,  // surface origin
                               nullptr,  // surface properties
                               false     // mipmaps
      );

  if (!surface) {
    FML_LOG(ERROR) << "Could not create render target for compositor layer.";
    return false;
  }

  GrBackendRenderTarget render_target = SkSurfaces::GetBackendRenderTarget(
      surface.get(), SkSurfaces::BackendHandleAccess::kDiscardWrite);

  if (!render_target.isValid()) {
    FML_LOG(ERROR) << "Backend render target was invalid.";
    return false;
  }

  GrGLFramebufferInfo framebuffer_info = {};
  if (!GrBackendRenderTargets::GetGLFramebufferInfo(render_target,
                                                    &framebuffer_info)) {
    FML_LOG(ERROR) << "Could not access backend framebuffer info.";
    return false;
  }

  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
  backing_store_out->user_data = surface.get();
  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
  backing_store_out->open_gl.framebuffer.target = framebuffer_info.fFormat;
  backing_store_out->open_gl.framebuffer.name = framebuffer_info.fFBOID;
  // The balancing unref is in the destruction callback.
  surface->ref();
  backing_store_out->open_gl.framebuffer.user_data = surface.get();
  backing_store_out->open_gl.framebuffer.destruction_callback =
      [](void* user_data) { reinterpret_cast<SkSurface*>(user_data)->unref(); };

  return true;
#else
  return false;
#endif
}

bool EmbedderTestBackingStoreProducer::CreateTexture(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
#ifdef SHELL_ENABLE_GL
  const auto image_info =
      SkImageInfo::MakeN32Premul(config->size.width, config->size.height);

  auto surface =
      SkSurfaces::RenderTarget(context_.get(),               // context
                               skgpu::Budgeted::kNo,         // budgeted
                               image_info,                   // image info
                               1,                            // sample count
                               kBottomLeft_GrSurfaceOrigin,  // surface origin
                               nullptr,  // surface properties
                               false     // mipmaps
      );

  if (!surface) {
    FML_LOG(ERROR) << "Could not create render target for compositor layer.";
    return false;
  }

  GrBackendTexture render_texture = SkSurfaces::GetBackendTexture(
      surface.get(), SkSurfaces::BackendHandleAccess::kDiscardWrite);

  if (!render_texture.isValid()) {
    FML_LOG(ERROR) << "Backend render texture was invalid.";
    return false;
  }

  GrGLTextureInfo texture_info = {};
  if (!GrBackendTextures::GetGLTextureInfo(render_texture, &texture_info)) {
    FML_LOG(ERROR) << "Could not access backend texture info.";
    return false;
  }

  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
  backing_store_out->user_data = surface.get();
  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeTexture;
  backing_store_out->open_gl.texture.target = texture_info.fTarget;
  backing_store_out->open_gl.texture.name = texture_info.fID;
  backing_store_out->open_gl.texture.format = texture_info.fFormat;
  // The balancing unref is in the destruction callback.
  surface->ref();
  backing_store_out->open_gl.texture.user_data = surface.get();
  backing_store_out->open_gl.texture.destruction_callback =
      [](void* user_data) { reinterpret_cast<SkSurface*>(user_data)->unref(); };

  return true;
#else
  return false;
#endif
}

bool EmbedderTestBackingStoreProducer::CreateSoftware(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
  auto surface = SkSurfaces::Raster(
      SkImageInfo::MakeN32Premul(config->size.width, config->size.height));

  if (!surface) {
    FML_LOG(ERROR)
        << "Could not create the render target for compositor layer.";
    return false;
  }

  SkPixmap pixmap;
  if (!surface->peekPixels(&pixmap)) {
    FML_LOG(ERROR) << "Could not peek pixels of pixmap.";
    return false;
  }

  backing_store_out->type = kFlutterBackingStoreTypeSoftware;
  backing_store_out->user_data = surface.get();
  backing_store_out->software.allocation = pixmap.addr();
  backing_store_out->software.row_bytes = pixmap.rowBytes();
  backing_store_out->software.height = pixmap.height();
  // The balancing unref is in the destruction callback.
  surface->ref();
  backing_store_out->software.user_data = surface.get();
  backing_store_out->software.destruction_callback = [](void* user_data) {
    reinterpret_cast<SkSurface*>(user_data)->unref();
  };

  return true;
}

bool EmbedderTestBackingStoreProducer::CreateSoftware2(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
  const auto color_info = getSkColorInfo(software_pixfmt_);
  if (!color_info) {
    return false;
  }

  auto surface = SkSurfaces::Raster(SkImageInfo::Make(
      SkISize::Make(config->size.width, config->size.height), *color_info));
  if (!surface) {
    FML_LOG(ERROR)
        << "Could not create the render target for compositor layer.";
    return false;
  }

  SkPixmap pixmap;
  if (!surface->peekPixels(&pixmap)) {
    FML_LOG(ERROR) << "Could not peek pixels of pixmap.";
    return false;
  }

  backing_store_out->type = kFlutterBackingStoreTypeSoftware2;
  backing_store_out->user_data = surface.get();
  backing_store_out->software2.struct_size =
      sizeof(FlutterSoftwareBackingStore2);
  backing_store_out->software2.user_data = surface.get();
  backing_store_out->software2.allocation = pixmap.writable_addr();
  backing_store_out->software2.row_bytes = pixmap.rowBytes();
  backing_store_out->software2.height = pixmap.height();
  // The balancing unref is in the destruction callback.
  surface->ref();
  backing_store_out->software2.user_data = surface.get();
  backing_store_out->software2.destruction_callback = [](void* user_data) {
    reinterpret_cast<SkSurface*>(user_data)->unref();
  };
  backing_store_out->software2.pixel_format = software_pixfmt_;

  return true;
}

bool EmbedderTestBackingStoreProducer::CreateMTLTexture(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
#ifdef SHELL_ENABLE_METAL
  // TODO(gw280): Use SkSurfaces::RenderTarget instead of generating our
  // own MTLTexture and wrapping it.
  auto surface_size = SkISize::Make(config->size.width, config->size.height);
  auto texture_info = test_metal_context_->CreateMetalTexture(surface_size);

  GrMtlTextureInfo skia_texture_info;
  skia_texture_info.fTexture.reset(SkCFSafeRetain(texture_info.texture));
  GrBackendTexture backend_texture(surface_size.width(), surface_size.height(),
                                   skgpu::Mipmapped::kNo, skia_texture_info);

  sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(
      context_.get(), backend_texture, kTopLeft_GrSurfaceOrigin, 1,
      kBGRA_8888_SkColorType, nullptr, nullptr);

  if (!surface) {
    FML_LOG(ERROR) << "Could not create Skia surface from a Metal texture.";
    return false;
  }

  backing_store_out->type = kFlutterBackingStoreTypeMetal;
  backing_store_out->user_data = surface.get();
  backing_store_out->metal.texture.texture = texture_info.texture;
  // The balancing unref is in the destruction callback.
  surface->ref();
  backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
  backing_store_out->metal.texture.user_data = surface.get();
  backing_store_out->metal.texture.destruction_callback = [](void* user_data) {
    reinterpret_cast<SkSurface*>(user_data)->unref();
  };

  return true;
#else
  return false;
#endif
}

bool EmbedderTestBackingStoreProducer::CreateVulkanImage(
    const FlutterBackingStoreConfig* config,
    FlutterBackingStore* backing_store_out) {
#ifdef SHELL_ENABLE_VULKAN
  if (!test_vulkan_context_) {
    test_vulkan_context_ = fml::MakeRefCounted<TestVulkanContext>();
  }

  auto surface_size = SkISize::Make(config->size.width, config->size.height);
  TestVulkanImage* test_image = new TestVulkanImage(
      std::move(test_vulkan_context_->CreateImage(surface_size).value()));

  GrVkImageInfo image_info = {
      .fImage = test_image->GetImage(),
      .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
      .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
      .fFormat = VK_FORMAT_R8G8B8A8_UNORM,
      .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
                          VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                          VK_IMAGE_USAGE_SAMPLED_BIT,
      .fSampleCount = 1,
      .fLevelCount = 1,
  };
  auto backend_texture = GrBackendTextures::MakeVk(
      surface_size.width(), surface_size.height(), image_info);

  SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);

  SkSurfaces::TextureReleaseProc release_vktexture = [](void* user_data) {
    delete reinterpret_cast<TestVulkanImage*>(user_data);
  };

  sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(
      context_.get(),            // context
      backend_texture,           // back-end texture
      kTopLeft_GrSurfaceOrigin,  // surface origin
      1,                         // sample count
      kRGBA_8888_SkColorType,    // color type
      SkColorSpace::MakeSRGB(),  // color space
      &surface_properties,       // surface properties
      release_vktexture,         // texture release proc
      test_image                 // release context
  );

  if (!surface) {
    FML_LOG(ERROR) << "Could not create Skia surface from Vulkan image.";
    return false;
  }
  backing_store_out->type = kFlutterBackingStoreTypeVulkan;

  FlutterVulkanImage* image = new FlutterVulkanImage();
  image->image = reinterpret_cast<uint64_t>(image_info.fImage);
  image->format = VK_FORMAT_R8G8B8A8_UNORM;
  backing_store_out->vulkan.image = image;

  // Collect all allocated resources in the destruction_callback.
  {
    UserData* user_data = new UserData();
    user_data->image = image;
    user_data->surface = surface.get();

    backing_store_out->user_data = user_data;
    backing_store_out->vulkan.user_data = user_data;
    backing_store_out->vulkan.destruction_callback = [](void* user_data) {
      UserData* d = reinterpret_cast<UserData*>(user_data);
      d->surface->unref();
      delete d->image;
      delete d;
    };

    // The balancing unref is in the destruction callback.
    surface->ref();
  }

  return true;
#else
  return false;
#endif
}

}  // namespace testing
}  // namespace flutter

// NOLINTEND(bugprone-unchecked-optional-access)
