/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/gpu/vk/VkYcbcrSamplerHelper.h"

#if defined(SK_VULKAN)

#include "include/gpu/vk/VulkanTypes.h"
#include "src/gpu/vk/VulkanInterface.h"

#if defined(SK_GRAPHITE)
#include "include/gpu/GpuTypes.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "src/gpu/graphite/vk/VulkanGraphiteUtils.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#endif

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "src/gpu/ganesh/vk/GrVkUtil.h"
#endif

int VkYcbcrSamplerHelper::GetExpectedY(int x, int y, int width, int height) {
    return 16 + (x + y) * 219 / (width + height - 2);
}

std::pair<int, int> VkYcbcrSamplerHelper::GetExpectedUV(int x, int y, int width, int height) {
    return { 16 + x * 224 / (width - 1), 16 + y * 224 / (height - 1) };
}

namespace {

void populate_ycbcr_image_info(VkImageCreateInfo* outImageInfo, uint32_t width, uint32_t height) {
    outImageInfo->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    outImageInfo->pNext = nullptr;
    outImageInfo->flags = 0;
    outImageInfo->imageType = VK_IMAGE_TYPE_2D;
    outImageInfo->format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    outImageInfo->extent = VkExtent3D{width, height, 1};
    outImageInfo->mipLevels = 1;
    outImageInfo->arrayLayers = 1;
    outImageInfo->samples = VK_SAMPLE_COUNT_1_BIT;
    outImageInfo->tiling = VK_IMAGE_TILING_LINEAR;
    outImageInfo->usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    outImageInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    outImageInfo->queueFamilyIndexCount = 0;
    outImageInfo->pQueueFamilyIndices = nullptr;
    outImageInfo->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
}

bool find_memory_type_index(const VkPhysicalDeviceMemoryProperties& phyDevMemProps,
                            const VkMemoryRequirements& memoryRequirements,
                            uint32_t* memoryTypeIndex) {
    for (uint32_t i = 0; i < phyDevMemProps.memoryTypeCount; ++i) {
        if (memoryRequirements.memoryTypeBits & (1 << i)) {
            // Map host-visible memory.
            if (phyDevMemProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
                *memoryTypeIndex = i;
                return true;
            }
        }
    }
    return false;
}

}

#ifdef SK_GRAPHITE
// TODO(b/339211930): When graphite and ganesh can share a macro for certain Vulkan driver calls,
// much more code can be shared between this method and createGrBackendTexture.
bool VkYcbcrSamplerHelper::createBackendTexture(uint32_t width, uint32_t height) {
    // Create YCbCr image.
    VkImageCreateInfo vkImageInfo;
    populate_ycbcr_image_info(&vkImageInfo, width, height);
    SkASSERT(fImage == VK_NULL_HANDLE);

    VkResult result;
    VULKAN_CALL_RESULT(fSharedCtxt, result, CreateImage(fSharedCtxt->device(),
                                                        &vkImageInfo,
                                                        /*pAllocator=*/nullptr,
                                                        &fImage));
    if (result != VK_SUCCESS) {
        return false;
    }

    VkMemoryRequirements requirements;
    VULKAN_CALL(fSharedCtxt->interface(), GetImageMemoryRequirements(fSharedCtxt->device(),
                                                                     fImage,
                                                                     &requirements));
    uint32_t memoryTypeIndex = 0;
    const VkPhysicalDeviceMemoryProperties& phyDevMemProps =
            fSharedCtxt->vulkanCaps().physicalDeviceMemoryProperties2().memoryProperties;
    if (!find_memory_type_index(phyDevMemProps, requirements, &memoryTypeIndex)) {
        return false;
    }

    VkMemoryAllocateInfo allocInfo;
    allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    allocInfo.pNext = nullptr;
    allocInfo.allocationSize = requirements.size;
    allocInfo.memoryTypeIndex = memoryTypeIndex;

    SkASSERT(fImageMemory == VK_NULL_HANDLE);
    VULKAN_CALL_RESULT(fSharedCtxt, result, AllocateMemory(fSharedCtxt->device(),
                                                           &allocInfo,
                                                           nullptr,
                                                           &fImageMemory));
    if (result != VK_SUCCESS) {
        return false;
    }

    void* mappedBuffer;
    VULKAN_CALL_RESULT(fSharedCtxt, result, MapMemory(fSharedCtxt->device(),
                                                      fImageMemory,
                                                      /*offset=*/0u,
                                                      requirements.size,
                                                      /*flags=*/0u,
                                                      &mappedBuffer));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Write Y channel.
    VkImageSubresource subresource;
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
    subresource.mipLevel = 0;
    subresource.arrayLayer = 0;

    VkSubresourceLayout yLayout;
    VULKAN_CALL(fSharedCtxt->interface(),
                GetImageSubresourceLayout(fSharedCtxt->device(), fImage, &subresource, &yLayout));
    uint8_t* bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + yLayout.offset;
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            bufferData[y * yLayout.rowPitch + x] = GetExpectedY(x, y, width, height);
        }
    }

    // Write UV channels.
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
    VkSubresourceLayout uvLayout;
    VULKAN_CALL(fSharedCtxt->interface(), GetImageSubresourceLayout(fSharedCtxt->device(),
                                                                    fImage,
                                                                    &subresource,
                                                                    &uvLayout));
    bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + uvLayout.offset;
    for (size_t y = 0; y < height / 2; ++y) {
        for (size_t x = 0; x < width / 2; ++x) {
            auto [u, v] = GetExpectedUV(2*x, 2*y, width, height);
            bufferData[y * uvLayout.rowPitch + x * 2] = u;
            bufferData[y * uvLayout.rowPitch + x * 2 + 1] = v;
        }
    }

    VkMappedMemoryRange flushRange;
    flushRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
    flushRange.pNext = nullptr;
    flushRange.memory = fImageMemory;
    flushRange.offset = 0;
    flushRange.size = VK_WHOLE_SIZE;
    VULKAN_CALL_RESULT(fSharedCtxt, result,  FlushMappedMemoryRanges(fSharedCtxt->device(),
                                                                     /*memoryRangeCount=*/1,
                                                                     &flushRange));
    if (result != VK_SUCCESS) {
        return false;
    }
    VULKAN_CALL(fSharedCtxt->interface(), UnmapMemory(fSharedCtxt->device(), fImageMemory));

    // Bind image memory.
    VULKAN_CALL_RESULT(fSharedCtxt, result, BindImageMemory(fSharedCtxt->device(),
                                                            fImage,
                                                            fImageMemory,
                                                            /*memoryOffset=*/0u));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Wrap the image into SkImage.
    VkFormatProperties formatProperties;
    SkASSERT(fSharedCtxt->physDevice() != VK_NULL_HANDLE);
    VULKAN_CALL(fSharedCtxt->interface(),
                GetPhysicalDeviceFormatProperties(fSharedCtxt->physDevice(),
                                                  VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                  &formatProperties));
    SkDEBUGCODE(auto linFlags = formatProperties.linearTilingFeatures;)
    SkASSERT((linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT));

    skgpu::VulkanYcbcrConversionInfo ycbcrInfo(vkImageInfo.format,
                                               VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
                                               VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_FILTER_LINEAR,
                                               /*forceExplicitReconstruction=*/false,
                                               /*components=*/{},
                                               formatProperties.linearTilingFeatures);
skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    skgpu::graphite::VulkanTextureInfo imageInfo = {
            vkImageInfo.samples,
            skgpu::Mipmapped::kNo,
            VK_IMAGE_CREATE_PROTECTED_BIT,
            vkImageInfo.format,
            vkImageInfo.tiling,
            vkImageInfo.usage,
            vkImageInfo.sharingMode,
            VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT,
            ycbcrInfo};

    fTexture = skgpu::graphite::BackendTextures::MakeVulkan({(int32_t)width, (int32_t)height},
                                                            imageInfo,
                                                            VK_IMAGE_LAYOUT_UNDEFINED,
                                                            /*queueFamilyIndex=*/0,
                                                            fImage,
                                                            alloc);
    return true;
}
#endif // SK_GRAPHITE

#if defined(SK_GANESH)
bool VkYcbcrSamplerHelper::createGrBackendTexture(uint32_t width, uint32_t height) {
    GrVkGpu* vkGpu = this->vkGpu();
    VkResult result;

    // Create YCbCr image.
    VkImageCreateInfo vkImageInfo;
    populate_ycbcr_image_info(&vkImageInfo, width, height);
    SkASSERT(fImage == VK_NULL_HANDLE);

    GR_VK_CALL_RESULT(vkGpu, result, CreateImage(vkGpu->device(), &vkImageInfo, nullptr, &fImage));
    if (result != VK_SUCCESS) {
        return false;
    }

    VkMemoryRequirements requirements;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageMemoryRequirements(vkGpu->device(),
                                                                fImage,
                                                                &requirements));

    uint32_t memoryTypeIndex = 0;
    VkPhysicalDeviceMemoryProperties phyDevMemProps;
    GR_VK_CALL(vkGpu->vkInterface(), GetPhysicalDeviceMemoryProperties(vkGpu->physicalDevice(),
                                                                       &phyDevMemProps));
    if (!find_memory_type_index(phyDevMemProps, requirements, &memoryTypeIndex)) {
        return false;
    }

    VkMemoryAllocateInfo allocInfo = {};
    allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    allocInfo.allocationSize = requirements.size;
    allocInfo.memoryTypeIndex = memoryTypeIndex;

    SkASSERT(fImageMemory == VK_NULL_HANDLE);
    GR_VK_CALL_RESULT(vkGpu, result, AllocateMemory(vkGpu->device(), &allocInfo,
                                                    nullptr, &fImageMemory));
    if (result != VK_SUCCESS) {
        return false;
    }

    void* mappedBuffer;
    GR_VK_CALL_RESULT(vkGpu, result, MapMemory(vkGpu->device(), fImageMemory, 0u,
                                               requirements.size, 0u, &mappedBuffer));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Write Y channel.
    VkImageSubresource subresource;
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
    subresource.mipLevel = 0;
    subresource.arrayLayer = 0;

    VkSubresourceLayout yLayout;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
                                                               &subresource, &yLayout));
    uint8_t* bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + yLayout.offset;
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            bufferData[y * yLayout.rowPitch + x] = GetExpectedY(x, y, width, height);
        }
    }

    // Write UV channels.
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
    VkSubresourceLayout uvLayout;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
                                                               &subresource, &uvLayout));
    bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + uvLayout.offset;
    for (size_t y = 0; y < height / 2; ++y) {
        for (size_t x = 0; x < width / 2; ++x) {
            auto [u, v] = GetExpectedUV(2*x, 2*y, width, height);
            bufferData[y * uvLayout.rowPitch + x * 2] = u;
            bufferData[y * uvLayout.rowPitch + x * 2 + 1] = v;
        }
    }

    VkMappedMemoryRange flushRange;
    flushRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
    flushRange.pNext = nullptr;
    flushRange.memory = fImageMemory;
    flushRange.offset = 0;
    flushRange.size = VK_WHOLE_SIZE;
    GR_VK_CALL_RESULT(vkGpu, result, FlushMappedMemoryRanges(vkGpu->device(), 1, &flushRange));
    if (result != VK_SUCCESS) {
        return false;
    }
    GR_VK_CALL(vkGpu->vkInterface(), UnmapMemory(vkGpu->device(), fImageMemory));

    // Bind image memory.
    GR_VK_CALL_RESULT(vkGpu, result, BindImageMemory(vkGpu->device(), fImage, fImageMemory, 0u));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Wrap the image into SkImage.
    VkFormatProperties formatProperties;
    GR_VK_CALL(vkGpu->vkInterface(),
               GetPhysicalDeviceFormatProperties(vkGpu->physicalDevice(),
                                                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                 &formatProperties));
    SkDEBUGCODE(auto linFlags = formatProperties.linearTilingFeatures;)
    SkASSERT((linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT));

    skgpu::VulkanYcbcrConversionInfo ycbcrInfo(vkImageInfo.format,
                                               VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
                                               VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_FILTER_LINEAR,
                                               /*forceExplicitReconstruction=*/false,
                                               /*components=*/{},
                                               formatProperties.linearTilingFeatures);
    skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    GrVkImageInfo imageInfo = {fImage,
                               alloc,
                               VK_IMAGE_TILING_LINEAR,
                               VK_IMAGE_LAYOUT_UNDEFINED,
                               vkImageInfo.format,
                               vkImageInfo.usage,
                               1 /* sample count */,
                               1 /* levelCount */,
                               VK_QUEUE_FAMILY_IGNORED,
                               GrProtected::kNo,
                               ycbcrInfo};

    fGrTexture = GrBackendTextures::MakeVk(width, height, imageInfo);
    return true;
}

GrVkGpu* VkYcbcrSamplerHelper::vkGpu() {
    return fDContext ? (GrVkGpu*) fDContext->priv().getGpu() : nullptr;
}

VkYcbcrSamplerHelper::VkYcbcrSamplerHelper(GrDirectContext* dContext) : fDContext(dContext) {
    SkASSERT_RELEASE(dContext->backend() == GrBackendApi::kVulkan);
}
#endif  // SK_GANESH

VkYcbcrSamplerHelper::~VkYcbcrSamplerHelper() {
#ifdef SK_GRAPHITE
    if (fSharedCtxt) {
        if (fImage != VK_NULL_HANDLE) {
            VULKAN_CALL(fSharedCtxt->interface(),
                        DestroyImage(fSharedCtxt->device(), fImage, nullptr));
            fImage = VK_NULL_HANDLE;
        }
        if (fImageMemory != VK_NULL_HANDLE) {
            VULKAN_CALL(fSharedCtxt->interface(),
                        FreeMemory(fSharedCtxt->device(), fImageMemory, nullptr));
            fImageMemory = VK_NULL_HANDLE;
        }
    }
#endif // SK_GRAPHITE
#if defined (SK_GANESH)
    if (GrVkGpu* vkGpu = this->vkGpu()) {
        if (fImage != VK_NULL_HANDLE) {
            GR_VK_CALL(vkGpu->vkInterface(), DestroyImage(vkGpu->device(), fImage, nullptr));
            fImage = VK_NULL_HANDLE;
        }
        if (fImageMemory != VK_NULL_HANDLE) {
            GR_VK_CALL(vkGpu->vkInterface(), FreeMemory(vkGpu->device(), fImageMemory, nullptr));
            fImageMemory = VK_NULL_HANDLE;
        }
    }
#endif
}

bool VkYcbcrSamplerHelper::isYCbCrSupported() {
    VkFormatProperties formatProperties;
#ifdef SK_GRAPHITE
    if (fSharedCtxt) {
        if (!fSharedCtxt->vulkanCaps().supportsYcbcrConversion()) {
            return false;
        }

        SkASSERT(fSharedCtxt->physDevice() != VK_NULL_HANDLE);
        VULKAN_CALL(fSharedCtxt->interface(),
                    GetPhysicalDeviceFormatProperties(fSharedCtxt->physDevice(),
                                                      VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                      &formatProperties));
    }
#endif
#if defined(SK_GANESH)
    if (GrVkGpu* vkGpu = this->vkGpu()) {
        if (!vkGpu->vkCaps().supportsYcbcrConversion()) {
            return false;
        }

        GR_VK_CALL(vkGpu->vkInterface(),
                GetPhysicalDeviceFormatProperties(vkGpu->physicalDevice(),
                                                    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                    &formatProperties));
    }
#endif  // SK_GANESH

    // The createBackendTexture call (which is the point of this helper class) requires linear
    // support for VK_FORMAT_G8_B8R8_2PLANE_420_UNORM including sampling and cosited chroma.
    // Verify that the image format is supported.
    auto linFlags = formatProperties.linearTilingFeatures;
    if (!(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) {
        // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM is not supported
        return false;
    }
    return true;
}
#endif // SK_VULKAN
