// 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/sampler_vk.h"

#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/yuv_conversion_vk.h"

namespace impeller {

static vk::UniqueSampler CreateSampler(
    const vk::Device& device,
    const SamplerDescriptor& desc,
    const std::shared_ptr<YUVConversionVK>& yuv_conversion) {
  const auto mip_map = ToVKSamplerMipmapMode(desc.mip_filter);

  const auto min_filter = ToVKSamplerMinMagFilter(desc.min_filter);
  const auto mag_filter = ToVKSamplerMinMagFilter(desc.mag_filter);

  const auto address_mode_u = ToVKSamplerAddressMode(desc.width_address_mode);
  const auto address_mode_v = ToVKSamplerAddressMode(desc.height_address_mode);
  const auto address_mode_w = ToVKSamplerAddressMode(desc.depth_address_mode);

  vk::StructureChain<vk::SamplerCreateInfo,
                     // For VK_KHR_sampler_ycbcr_conversion
                     vk::SamplerYcbcrConversionInfo>
      sampler_chain;

  auto& sampler_info = sampler_chain.get();

  sampler_info.magFilter = mag_filter;
  sampler_info.minFilter = min_filter;
  sampler_info.addressModeU = address_mode_u;
  sampler_info.addressModeV = address_mode_v;
  sampler_info.addressModeW = address_mode_w;
  sampler_info.borderColor = vk::BorderColor::eFloatTransparentBlack;
  sampler_info.mipmapMode = mip_map;
  sampler_info.maxLod = VK_LOD_CLAMP_NONE;

  if (yuv_conversion && yuv_conversion->IsValid()) {
    sampler_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
        yuv_conversion->GetConversion();

    //
    // TL;DR: When using YUV conversion, our samplers are somewhat hobbled and
    // not all options configurable in Impeller (especially the linear
    // filtering which is by far the most used form of filtering) can be
    // supported. Switch to safe defaults.
    //
    // Spec: If sampler Y'CBCR conversion is enabled and the potential format
    // features of the sampler Y'CBCR conversion do not support or enable
    // separate reconstruction filters, minFilter and magFilter must be equal to
    // the sampler Y'CBCR conversion's chromaFilter.
    //
    // Thing is, we don't enable separate reconstruction filters. By the time we
    // are here, we also don't have access to the descriptor used to create this
    // conversion. So we don't yet know what the chromaFilter is. But eNearest
    // is a safe bet since the `AndroidHardwareBufferTextureSourceVK` defaults
    // to that safe value. So just use that.
    //
    // See the validation VUID-VkSamplerCreateInfo-minFilter-01645 for more.
    //
    sampler_info.magFilter = vk::Filter::eNearest;
    sampler_info.minFilter = vk::Filter::eNearest;

    // Spec: If sampler Y′CBCR conversion is enabled, addressModeU,
    // addressModeV, and addressModeW must be
    // VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, anisotropyEnable must be VK_FALSE,
    // and unnormalizedCoordinates must be VK_FALSE.
    //
    // See the validation VUID-VkSamplerCreateInfo-addressModeU-01646 for more.
    //
    sampler_info.addressModeU = vk::SamplerAddressMode::eClampToEdge;
    sampler_info.addressModeV = vk::SamplerAddressMode::eClampToEdge;
    sampler_info.addressModeW = vk::SamplerAddressMode::eClampToEdge;
    sampler_info.anisotropyEnable = false;
    sampler_info.unnormalizedCoordinates = false;
  } else {
    sampler_chain.unlink<vk::SamplerYcbcrConversionInfo>();
  }

  auto sampler = device.createSamplerUnique(sampler_chain.get());
  if (sampler.result != vk::Result::eSuccess) {
    VALIDATION_LOG << "Could not create sampler: "
                   << vk::to_string(sampler.result);
    return {};
  }

  if (!desc.label.empty()) {
    ContextVK::SetDebugName(device, sampler.value.get(), desc.label.c_str());
  }

  return std::move(sampler.value);
}

SamplerVK::SamplerVK(const vk::Device& device,
                     SamplerDescriptor desc,
                     std::shared_ptr<YUVConversionVK> yuv_conversion)
    : Sampler(std::move(desc)),
      device_(device),
      sampler_(MakeSharedVK<vk::Sampler>(
          CreateSampler(device, desc_, yuv_conversion))),
      yuv_conversion_(std::move(yuv_conversion)) {
  is_valid_ = sampler_ && !!sampler_->Get();
}

SamplerVK::~SamplerVK() = default;

vk::Sampler SamplerVK::GetSampler() const {
  return *sampler_;
}

std::shared_ptr<SamplerVK> SamplerVK::CreateVariantForConversion(
    std::shared_ptr<YUVConversionVK> conversion) const {
  if (!conversion || !is_valid_) {
    return nullptr;
  }
  return std::make_shared<SamplerVK>(device_, desc_, std::move(conversion));
}

const std::shared_ptr<YUVConversionVK>& SamplerVK::GetYUVConversion() const {
  return yuv_conversion_;
}

}  // namespace impeller
