// 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/renderer/backend/vulkan/swapchain_details_vk.h"

#include "impeller/base/validation.h"

namespace impeller {

std::unique_ptr<SwapchainDetailsVK> SwapchainDetailsVK::Create(
    vk::PhysicalDevice physical_device,
    vk::SurfaceKHR surface) {
  FML_DCHECK(surface) << "surface provided as nullptr";

  auto capabilities_res = physical_device.getSurfaceCapabilitiesKHR(surface);
  if (capabilities_res.result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Failed to get surface capabilities: "
                   << vk::to_string(capabilities_res.result);
    return nullptr;
  }
  vk::SurfaceCapabilitiesKHR capabilities = capabilities_res.value;

  auto surface_formats_res = physical_device.getSurfaceFormatsKHR(surface);
  if (surface_formats_res.result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Failed to get surface formats: "
                   << vk::to_string(surface_formats_res.result);
    return nullptr;
  }
  std::vector<vk::SurfaceFormatKHR> surface_formats = surface_formats_res.value;

  auto surface_present_modes_res =
      physical_device.getSurfacePresentModesKHR(surface);
  if (surface_present_modes_res.result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Failed to get surface present modes: "
                   << vk::to_string(surface_present_modes_res.result);
    return nullptr;
  }
  std::vector<vk::PresentModeKHR> surface_present_modes =
      surface_present_modes_res.value;

  return std::make_unique<SwapchainDetailsVK>(capabilities, surface_formats,
                                              surface_present_modes);
}

vk::SurfaceFormatKHR SwapchainDetailsVK::PickSurfaceFormat() const {
  for (const auto& format : surface_formats_) {
    if ((format.format == vk::Format::eR8G8B8A8Unorm ||
         format.format == vk::Format::eB8G8R8A8Unorm) &&
        format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) {
      return format;
    }
  }

  VALIDATION_LOG << "Picking a sub-optimal surface format.";
  return surface_formats_[0];
}

vk::PresentModeKHR SwapchainDetailsVK::PickPresentationMode() const {
  for (const auto& mode : present_modes_) {
    if (mode == vk::PresentModeKHR::eMailbox) {
      return mode;
    }
  }

  VALIDATION_LOG << "Picking a sub-optimal presentation mode.";
  // Vulkan spec dictates that FIFO is always available.
  return vk::PresentModeKHR::eFifo;
}

vk::Extent2D SwapchainDetailsVK::PickExtent() const {
  if (surface_capabilities_.currentExtent.width !=
      std::numeric_limits<uint32_t>::max()) {
    return surface_capabilities_.currentExtent;
  }

  vk::Extent2D actual_extent = {
      std::max(surface_capabilities_.minImageExtent.width,
               std::min(surface_capabilities_.maxImageExtent.width,
                        surface_capabilities_.currentExtent.width)),
      std::max(surface_capabilities_.minImageExtent.height,
               std::min(surface_capabilities_.maxImageExtent.height,
                        surface_capabilities_.currentExtent.height))};
  return actual_extent;
}

uint32_t SwapchainDetailsVK::GetImageCount() const {
  uint32_t image_count = surface_capabilities_.minImageCount;
  // for triple buffering
  return image_count + 1;
}

vk::SurfaceTransformFlagBitsKHR SwapchainDetailsVK::GetTransform() const {
  return surface_capabilities_.currentTransform;
}

SwapchainDetailsVK::SwapchainDetailsVK(
    vk::SurfaceCapabilitiesKHR capabilities,
    std::vector<vk::SurfaceFormatKHR> surface_formats,
    std::vector<vk::PresentModeKHR> surface_present_modes)
    : surface_capabilities_(capabilities),
      surface_formats_(surface_formats),
      present_modes_(surface_present_modes) {}

SwapchainDetailsVK::~SwapchainDetailsVK() = default;

}  // namespace impeller
