// 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.

// FLUTTER_NOLINT: https://github.com/flutter/flutter/issues/68331

#include "vulkan_window.h"

#include <memory>
#include <string>
#include <utility>

#include "flutter/flutter_vma/flutter_skia_vma.h"
#include "flutter/vulkan/vulkan_skia_proc_table.h"
#include "vulkan_application.h"
#include "vulkan_device.h"
#include "vulkan_native_surface.h"
#include "vulkan_surface.h"
#include "vulkan_swapchain.h"

#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/ganesh/vk/GrVkDirectContext.h"
#include "third_party/skia/include/gpu/vk/VulkanExtensions.h"

namespace vulkan {

VulkanWindow::VulkanWindow(fml::RefPtr<VulkanProcTable> proc_table,
                           std::unique_ptr<VulkanNativeSurface> native_surface)
    : VulkanWindow(/*context/*/ nullptr,
                   std::move(proc_table),
                   std::move(native_surface)) {}

VulkanWindow::VulkanWindow(const sk_sp<GrDirectContext>& context,
                           fml::RefPtr<VulkanProcTable> proc_table,
                           std::unique_ptr<VulkanNativeSurface> native_surface)
    : valid_(false), vk_(std::move(proc_table)), skia_gr_context_(context) {
  if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) {
    FML_DLOG(INFO) << "Proc table has not acquired mandatory proc addresses.";
    return;
  }

  if (native_surface && !native_surface->IsValid()) {
    FML_DLOG(INFO) << "Native surface is invalid.";
    return;
  }

  // Create the application instance.

  std::vector<std::string> extensions = {
      VK_KHR_SURFACE_EXTENSION_NAME,      // parent extension
      native_surface->GetExtensionName()  // child extension
  };

  application_ = std::make_unique<VulkanApplication>(*vk_, "Flutter",
                                                     std::move(extensions));

  if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) {
    // Make certain the application instance was created and it set up the
    // instance proc table entries.
    FML_DLOG(INFO) << "Instance proc addresses have not been set up.";
    return;
  }

  // Create the device.

  logical_device_ = application_->AcquireFirstCompatibleLogicalDevice();

  if (logical_device_ == nullptr || !logical_device_->IsValid() ||
      !vk_->AreDeviceProcsSetup()) {
    // Make certain the device was created and it set up the device proc table
    // entries.
    FML_DLOG(INFO) << "Device proc addresses have not been set up.";
    return;
  }

  if (!native_surface) {
    return;
  }

  // Create the logical surface from the native platform surface.
  surface_ = std::make_unique<VulkanSurface>(*vk_, *application_,
                                             std::move(native_surface));

  if (!surface_->IsValid()) {
    FML_DLOG(INFO) << "Vulkan surface is invalid.";
    return;
  }

  // Needs to happen before GrDirectContext is created.
  memory_allocator_ = flutter::FlutterSkiaVulkanMemoryAllocator::Make(
      application_->GetAPIVersion(), application_->GetInstance(),
      logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(),
      vk_, true);

  // Create the Skia GrDirectContext.

  if (!skia_gr_context_ && !CreateSkiaGrContext()) {
    FML_DLOG(INFO) << "Could not create Skia context.";
    return;
  }

  // Create the swapchain.

  if (!RecreateSwapchain()) {
    FML_DLOG(INFO) << "Could not set up the swapchain initially.";
    return;
  }

  valid_ = true;
}

VulkanWindow::~VulkanWindow() = default;

bool VulkanWindow::IsValid() const {
  return valid_;
}

GrDirectContext* VulkanWindow::GetSkiaGrContext() {
  return skia_gr_context_.get();
}

bool VulkanWindow::CreateSkiaGrContext() {
#ifdef SK_VULKAN
  skgpu::VulkanBackendContext backend_context;
  VkPhysicalDeviceFeatures features;
  skgpu::VulkanExtensions extensions;

  if (!this->CreateSkiaBackendContext(&backend_context, &features,
                                      &extensions)) {
    return false;
  }

  GrContextOptions options;
  options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
  sk_sp<GrDirectContext> context =
      GrDirectContexts::MakeVulkan(backend_context, options);

  if (context == nullptr) {
    return false;
  }

  context->setResourceCacheLimit(kGrCacheMaxByteSize);

  skia_gr_context_ = context;

  return true;
#else
  return false;
#endif  // SK_VULKAN
}

bool VulkanWindow::CreateSkiaBackendContext(
    skgpu::VulkanBackendContext* context,
    VkPhysicalDeviceFeatures* features,
    skgpu::VulkanExtensions* extensions) {
#ifdef SK_VULKAN
  FML_CHECK(context);
  FML_CHECK(features);
  FML_CHECK(extensions);
  auto getProc = CreateSkiaGetProc(vk_);

  if (getProc == nullptr) {
    return false;
  }

  if (!logical_device_->GetPhysicalDeviceFeatures(features)) {
    return false;
  }

  context->fInstance = application_->GetInstance();
  context->fPhysicalDevice = logical_device_->GetPhysicalDeviceHandle();
  context->fDevice = logical_device_->GetHandle();
  context->fQueue = logical_device_->GetQueueHandle();
  context->fGraphicsQueueIndex = logical_device_->GetGraphicsQueueIndex();
  context->fMaxAPIVersion = application_->GetAPIVersion();
  context->fDeviceFeatures = features;
  context->fGetProc = std::move(getProc);
  context->fMemoryAllocator = memory_allocator_;

  constexpr uint32_t instance_extension_count = 2;
  const char* instance_extensions[instance_extension_count] = {
      // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_surface.html
      VK_KHR_SURFACE_EXTENSION_NAME,
      surface_->GetNativeSurface().GetExtensionName(),
  };
  constexpr uint32_t device_extension_count = 1;
  const char* device_extensions[device_extension_count] = {
      // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_swapchain.html
      VK_KHR_SWAPCHAIN_EXTENSION_NAME,
  };
  extensions->init(context->fGetProc, context->fInstance,
                   context->fPhysicalDevice, instance_extension_count,
                   instance_extensions, device_extension_count,
                   device_extensions);
  context->fVkExtensions = extensions;
  return true;
#else
  return false;
#endif
}

sk_sp<SkSurface> VulkanWindow::AcquireSurface() {
  if (!IsValid()) {
    FML_DLOG(INFO) << "Surface is invalid.";
    return nullptr;
  }

  auto surface_size = surface_->GetSize();

  // This check is theoretically unnecessary as the swapchain should report that
  // the surface is out-of-date and perform swapchain recreation at the new
  // configuration. However, on Android, the swapchain never reports that it is
  // of date. Hence this extra check. Platforms that don't have this issue, or,
  // cant report this information (which is optional anyway), report a zero
  // size.
  if (surface_size != SkISize::Make(0, 0) &&
      surface_size != swapchain_->GetSize()) {
    FML_DLOG(INFO) << "Swapchain and surface sizes are out of sync. Recreating "
                      "swapchain.";
    if (!RecreateSwapchain()) {
      FML_DLOG(INFO) << "Could not recreate swapchain.";
      valid_ = false;
      return nullptr;
    }
  }

  while (true) {
    sk_sp<SkSurface> surface;
    auto acquire_result = VulkanSwapchain::AcquireStatus::ErrorSurfaceLost;

    std::tie(acquire_result, surface) = swapchain_->AcquireSurface();

    if (acquire_result == VulkanSwapchain::AcquireStatus::Success) {
      // Successfully acquired a surface from the swapchain. Nothing more to do.
      return surface;
    }

    if (acquire_result == VulkanSwapchain::AcquireStatus::ErrorSurfaceLost) {
      // Surface is lost. This is an unrecoverable error.
      FML_DLOG(INFO) << "Swapchain reported surface was lost.";
      return nullptr;
    }

    if (acquire_result ==
        VulkanSwapchain::AcquireStatus::ErrorSurfaceOutOfDate) {
      // Surface out of date. Recreate the swapchain at the new configuration.
      if (RecreateSwapchain()) {
        // Swapchain was recreated, try surface acquisition again.
        continue;
      } else {
        // Could not recreate the swapchain at the new configuration.
        FML_DLOG(INFO) << "Swapchain reported surface was out of date but "
                          "could not recreate the swapchain at the new "
                          "configuration.";
        valid_ = false;
        return nullptr;
      }
    }

    break;
  }

  FML_DCHECK(false) << "Unhandled VulkanSwapchain::AcquireResult";
  return nullptr;
}

bool VulkanWindow::SwapBuffers() {
  if (!IsValid()) {
    FML_DLOG(INFO) << "Window was invalid.";
    return false;
  }

  return swapchain_->Submit();
}

bool VulkanWindow::RecreateSwapchain() {
  // This way, we always lose our reference to the old swapchain. Even if we
  // cannot create a new one to replace it.
  auto old_swapchain = std::move(swapchain_);

  if (!vk_->IsValid()) {
    return false;
  }

  if (logical_device_ == nullptr || !logical_device_->IsValid()) {
    return false;
  }

  if (surface_ == nullptr || !surface_->IsValid()) {
    return false;
  }

  if (skia_gr_context_ == nullptr) {
    return false;
  }

  auto swapchain = std::make_unique<VulkanSwapchain>(
      *vk_, *logical_device_, *surface_, skia_gr_context_.get(),
      std::move(old_swapchain), logical_device_->GetGraphicsQueueIndex());

  if (!swapchain->IsValid()) {
    return false;
  }

  swapchain_ = std::move(swapchain);
  return true;
}

}  // namespace vulkan
