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

#include "src/gpu/graphite/vk/VulkanResourceProvider.h"

#include "include/core/SkSpan.h"
#include "include/gpu/MutableTextureState.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "include/gpu/vk/VulkanMutableTextureState.h"
#include "src/gpu/graphite/Buffer.h"
#include "src/gpu/graphite/ComputePipeline.h"
#include "src/gpu/graphite/GraphicsPipeline.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/Sampler.h"
#include "src/gpu/graphite/StorageContext.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "src/gpu/graphite/vk/VulkanBuffer.h"
#include "src/gpu/graphite/vk/VulkanCommandBuffer.h"
#include "src/gpu/graphite/vk/VulkanComputePipeline.h"
#include "src/gpu/graphite/vk/VulkanDescriptorPool.h"
#include "src/gpu/graphite/vk/VulkanDescriptorSet.h"
#include "src/gpu/graphite/vk/VulkanFramebuffer.h"
#include "src/gpu/graphite/vk/VulkanGraphicsPipeline.h"
#include "src/gpu/graphite/vk/VulkanGraphiteUtils.h"
#include "src/gpu/graphite/vk/VulkanRenderPass.h"
#include "src/gpu/graphite/vk/VulkanSampler.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#include "src/gpu/graphite/vk/VulkanTexture.h"
#include "src/gpu/graphite/vk/VulkanYcbcrConversion.h"
#include "src/gpu/vk/VulkanMemory.h"
#include "src/sksl/SkSLCompiler.h"

#ifdef  SK_BUILD_FOR_ANDROID
#include "src/gpu/vk/VulkanUtilsPriv.h"
#include <android/hardware_buffer.h>
#endif

namespace skgpu::graphite {
namespace {
// Create a mock pipeline layout that has a compatible input attachment descriptor set layout and
// push constant parameters with all other real pipeline layouts. This allows us to perform
// once-per-renderpass operations even before a real pipeline is bound by the command buffer.
VkPipelineLayout create_mock_layout(const VulkanSharedContext* sharedContext) {
    SkASSERT(sharedContext);
    VkPushConstantRange pushConstantRange;
    pushConstantRange.offset = 0;
    pushConstantRange.size = VulkanResourceProvider::kIntrinsicConstantSize;
    pushConstantRange.stageFlags = VulkanResourceProvider::kIntrinsicConstantStageFlags;

    skia_private::STArray<1, DescriptorData> inputDesc {
            VulkanGraphicsPipeline::GetInputAttachmentDescriptor()};
    VkDescriptorSetLayout setLayout;
    DescriptorDataToVkDescSetLayout(sharedContext, inputDesc, &setLayout);

    VkPipelineLayoutCreateInfo layoutCreateInfo = {};
    layoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
    layoutCreateInfo.setLayoutCount = 1;
    layoutCreateInfo.pSetLayouts = &setLayout;
    layoutCreateInfo.pushConstantRangeCount = 1;
    layoutCreateInfo.pPushConstantRanges = &pushConstantRange;

    VkResult result;
    VkPipelineLayout pipelineLayout;
    VULKAN_CALL_RESULT(sharedContext,
                       result,
                       CreatePipelineLayout(sharedContext->device(),
                                            &layoutCreateInfo,
                                            /*const VkAllocationCallbacks*=*/nullptr,
                                            &pipelineLayout));

    // Once the pipeline layout is created, we can clean up the VkDescriptorSetLayout.
    VULKAN_CALL(sharedContext->interface(),
                DestroyDescriptorSetLayout(sharedContext->device(), setLayout, nullptr));

    return pipelineLayout;
}
} // anonymous namespace

VulkanResourceProvider::VulkanResourceProvider(SharedContext* sharedContext,
                                               SingleOwner* singleOwner,
                                               uint32_t recorderID,
                                               size_t resourceBudget)
        : ResourceProvider(sharedContext, singleOwner, recorderID, resourceBudget)
        , fMockPipelineLayout(
                create_mock_layout(static_cast<const VulkanSharedContext*>(sharedContext))) {}

VulkanResourceProvider::~VulkanResourceProvider() {
    if (fMockPipelineLayout) {
        VULKAN_CALL(this->vulkanSharedContext()->interface(),
                    DestroyPipelineLayout(this->vulkanSharedContext()->device(),
                                          fMockPipelineLayout,
                                          nullptr));
    }
}

const VulkanSharedContext* VulkanResourceProvider::vulkanSharedContext() const {
    return static_cast<const VulkanSharedContext*>(fSharedContext);
}

VulkanSharedContext* VulkanResourceProvider::nonConstVulkanSharedContext() {
    return static_cast<VulkanSharedContext*>(fSharedContext);
}

sk_sp<Texture> VulkanResourceProvider::onCreateWrappedTexture(const BackendTexture& texture,
                                                              std::string_view label) {
    sk_sp<VulkanYcbcrConversion> ycbcrConversion;
    const auto& vkInfo = TextureInfoPriv::Get<VulkanTextureInfo>(texture.info());
    if (vkInfo.fYcbcrConversionInfo.isValid()) {
        ycbcrConversion = this->findOrCreateCompatibleYcbcrConversion(vkInfo.fYcbcrConversionInfo);
        if (!ycbcrConversion) {
            return nullptr;
        }
    }

    return VulkanTexture::MakeWrapped(this->vulkanSharedContext(),
                                      texture.dimensions(),
                                      texture.info(),
                                      BackendTextures::GetMutableState(texture),
                                      BackendTextures::GetVkImage(texture),
                                      /*alloc=*/{} /*Skia does not own wrapped texture memory*/,
                                      std::move(ycbcrConversion),
                                      label);
}

sk_sp<ComputePipeline> VulkanResourceProvider::createComputePipeline(
        const ComputePipelineDesc& desc) {
    return VulkanComputePipeline::Make(this->nonConstVulkanSharedContext(), desc);
}

const VulkanTexture* VulkanResourceProvider::getOrCreateNullTexture() {
    if (!fNullTexture) {
        TextureInfo info = this->vulkanSharedContext()->caps()->getDefaultReadableTextureInfo(
                StorageContext::kTextureFormat,
                Protected::kNo);
        fNullTexture = this->createTexture(
                SkISize::Make(1, 1), info, "UnusedTextureSlot");
        SkASSERT(fNullTexture);
    }
    return static_cast<const VulkanTexture*>(fNullTexture.get());
}

sk_sp<Texture> VulkanResourceProvider::createTexture(SkISize size,
                                                     const TextureInfo& info,
                                                     std::string_view label) {
    sk_sp<VulkanYcbcrConversion> ycbcrConversion;
    const auto& vkInfo = TextureInfoPriv::Get<VulkanTextureInfo>(info);
    if (vkInfo.fYcbcrConversionInfo.isValid()) {
        ycbcrConversion = this->findOrCreateCompatibleYcbcrConversion(vkInfo.fYcbcrConversionInfo);
        if (!ycbcrConversion) {
            return nullptr;
        }
    }

    return VulkanTexture::Make(this->vulkanSharedContext(),
                               size,
                               info,
                               std::move(ycbcrConversion),
                               label);
}

sk_sp<Buffer> VulkanResourceProvider::createBuffer(size_t size,
                                                   BufferType type,
                                                   AccessPattern accessPattern,
                                                   std::string_view label) {
    return VulkanBuffer::Make(this->vulkanSharedContext(), size, type, accessPattern, label);
}

sk_sp<Sampler> VulkanResourceProvider::createSampler(const SamplerDesc& samplerDesc) {
    sk_sp<VulkanYcbcrConversion> ycbcrConversion = nullptr;

    // Non-zero conversion information means the sampler utilizes a ycbcr conversion.
    const bool usesYcbcrConversion = samplerDesc.isImmutable();
    if (usesYcbcrConversion) {
        VulkanYcbcrConversionInfo ycbcrInfo = VulkanYcbcrConversion::FromImmutableSamplerInfo(
                samplerDesc.immutableSamplerInfo());
        ycbcrConversion = this->findOrCreateCompatibleYcbcrConversion(ycbcrInfo);
        if (!ycbcrConversion) {
            return nullptr;
        }
    }

    return VulkanSampler::Make(this->vulkanSharedContext(),
                               samplerDesc,
                               std::move(ycbcrConversion));
}

BackendTexture VulkanResourceProvider::onCreateBackendTexture(SkISize dimensions,
                                                              const TextureInfo& info) {
    const auto& vkTexInfo = TextureInfoPriv::Get<VulkanTextureInfo>(info);
    VulkanTexture::CreatedImageInfo createdTextureInfo;
    if (!VulkanTexture::MakeVkImage(this->vulkanSharedContext(), dimensions, info,
                                    &createdTextureInfo)) {
        return {};
    }
    return BackendTextures::MakeVulkan(
            dimensions,
            vkTexInfo,
            skgpu::MutableTextureStates::GetVkImageLayout(createdTextureInfo.fMutableState.get()),
            skgpu::MutableTextureStates::GetVkQueueFamilyIndex(
                    createdTextureInfo.fMutableState.get()),
            createdTextureInfo.fImage,
            createdTextureInfo.fMemoryAlloc);
}

namespace {
GraphiteResourceKey build_desc_set_key(const SkSpan<const DescriptorData>& requestedDescriptors) {
    static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();

    // The number of int32s needed for a key can depend on whether we use immutable samplers or not.
    // So, accumulate key data while passing through to check for that quantity and simply copy into
    // builder afterwards.
    skia_private::TArray<uint32_t> keyData(requestedDescriptors.size() + 1);

    keyData.push_back(requestedDescriptors.size());
    for (const DescriptorData& desc : requestedDescriptors) {
        // Pack into 32 bits:
        // - fType: 4 bits (bits 28..31, max 15)
        // - fPipelineStageFlags: 4 bits (bits 24..27, max 15)
        // - fBindingIndex: 8 bits (bits 16..23, max 255)
        // - fCount: 16 bits (bits 0..15, max 65535)
        // Including stage flags prevents sets from colliding across incompatible shader stages
        // (e.g. compute vs fragment textures).
        // https://docs.vulkan.org/spec/latest/chapters/descriptorsets.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-00358
        SkASSERT(static_cast<uint32_t>(desc.fType) < 16);
        SkASSERT(desc.fPipelineStageFlags.value() > 0 && desc.fPipelineStageFlags.value() < 16);
        SkASSERT(desc.fBindingIndex >= 0 && desc.fBindingIndex <= 255);
        SkASSERT(desc.fCount > 0 && desc.fCount <= 0xFFFF);

        uint32_t packedDesc = (static_cast<uint32_t>(desc.fType) << 28) |
                              (static_cast<uint32_t>(desc.fPipelineStageFlags.value()) << 24) |
                              (static_cast<uint32_t>(desc.fBindingIndex) << 16) |
                              static_cast<uint16_t>(desc.fCount);
        keyData.push_back(packedDesc);
        if (desc.fImmutableSampler) {
            const VulkanSampler* sampler =
                    static_cast<const VulkanSampler*>(desc.fImmutableSampler);
            SkASSERT(sampler);
            keyData.push_back_n(sampler->samplerDesc().asSpan().size(),
                                sampler->samplerDesc().asSpan().data());
        }
    }

    GraphiteResourceKey key;
    GraphiteResourceKey::Builder builder(&key, kType, SkTo<uint16_t>(keyData.size()));

    for (int i = 0; i < keyData.size(); i++) {
        builder[i] = keyData[i];
    }

    builder.finish();
    return key;
}

sk_sp<VulkanDescriptorSet> add_new_desc_set_to_cache(const VulkanSharedContext* context,
                                                     const sk_sp<VulkanDescriptorPool>& pool,
                                                     const GraphiteResourceKey& descSetKey,
                                                     ResourceCache* resourceCache) {
    sk_sp<VulkanDescriptorSet> descSet = VulkanDescriptorSet::Make(context, pool);
    if (!descSet) {
        return nullptr;
    }
    resourceCache->insertResource(descSet.get(), descSetKey, Budgeted::kYes, Shareable::kNo);

    return descSet;
}
} // anonymous namespace

sk_sp<VulkanDescriptorSet> VulkanResourceProvider::findOrCreateDescriptorSet(
        SkSpan<const DescriptorData> requestedDescriptors) {
    if (requestedDescriptors.empty()) {
        return nullptr;
    }

    // Search for available descriptor sets by assembling a key based upon the set's structure.
    GraphiteResourceKey key = build_desc_set_key(requestedDescriptors);
    if (auto descSet =
            fResourceCache->findAndRefResource(key, skgpu::Budgeted::kYes, Shareable::kNo)) {
        return sk_sp<VulkanDescriptorSet>(static_cast<VulkanDescriptorSet*>(descSet));
    }


    // If we did not find an existing avilable desc set, allocate sets with the appropriate layout
    // and add them to the cache.
    VkDescriptorSetLayout layout;
    const VulkanSharedContext* context = this->vulkanSharedContext();
    DescriptorDataToVkDescSetLayout(context, requestedDescriptors, &layout);
    if (!layout) {
        return nullptr;
    }

    static constexpr uint32_t kStartNumSets = 16;
    static constexpr uint32_t kMaxNumSets = 512;

    uint32_t numSets = kStartNumSets;
    for (int i = 0; i < fCurrentPoolSizes.size(); i++) {
        if (key == fCurrentPoolSizes.at(i).first) {
            uint32_t& poolSize = fCurrentPoolSizes.at(i).second;
            numSets = poolSize + ((poolSize + 1) >> 1);
            numSets = std::min(numSets, kMaxNumSets);
            poolSize = numSets;
            break;
        }
    }
    if (numSets == kStartNumSets) {
        fCurrentPoolSizes.push_back(std::make_pair(key, numSets));
    }

    auto pool = VulkanDescriptorPool::Make(context, requestedDescriptors, layout, numSets);
    if (!pool) {
        VULKAN_CALL(context->interface(), DestroyDescriptorSetLayout(context->device(),
                                                                     layout,
                                                                     nullptr));
        return nullptr;
    }

    // Start with allocating one descriptor set. If one cannot be successfully created, then we can
    // return early before attempting to allocate more. Storing a ptr to the first set also
    // allows us to return that later without having to perform a find operation on the cache once
    // all the sets are added.
    auto firstDescSet =
            add_new_desc_set_to_cache(context, pool, key, fResourceCache.get());
    if (!firstDescSet) {
        return nullptr;
    }

    // Continue to allocate & cache the maximum number of sets so they can be easily accessed as
    // they're needed.
    for (uint32_t i = 1; i < numSets ; i++) {
        auto descSet =
                add_new_desc_set_to_cache(context, pool, key, fResourceCache.get());
        if (!descSet) {
            SKIA_LOG_W("Descriptor set allocation %u of %u was unsuccessful; no more sets will be"
                        "allocated from this pool.", i, numSets);
            break;
        }
    }

    return firstDescSet;
}

sk_sp<VulkanRenderPass> VulkanResourceProvider::findOrCreateRenderPass(
        const RenderPassDesc& originalRenderPassDesc, bool compatibleOnly) {
    static constexpr Budgeted kBudgeted = Budgeted::kYes;
    static constexpr Shareable kShareable = Shareable::kYes;
    static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();

    const RenderPassDesc renderPassDesc =
            compatibleOnly ? MakePipelineCompatibleRenderPass(originalRenderPassDesc)
                           : originalRenderPassDesc;

    GraphiteResourceKey key;
    {
        GraphiteResourceKey::Builder builder(&key, kType, 1);
        builder[0] = VulkanRenderPass::GetRenderPassKey(renderPassDesc,
                                                        /*compatibleForPipelineKey=*/false);
    }
    if (Resource* resource = fResourceCache->findAndRefResource(key, kBudgeted, kShareable)) {
        return sk_sp<VulkanRenderPass>(static_cast<VulkanRenderPass*>(resource));
    }

    sk_sp<VulkanRenderPass> renderPass =
            VulkanRenderPass::Make(this->vulkanSharedContext(), renderPassDesc);
    if (!renderPass) {
        return nullptr;
    }

    fResourceCache->insertResource(renderPass.get(), key, kBudgeted, kShareable);

    return renderPass;
}

namespace {

void gather_attachment_views(skia_private::TArray<VkImageView>& attachmentViews,
                             VulkanTexture* colorTexture,
                             VulkanTexture* resolveTexture,
                             VulkanTexture* depthStencilTexture) {
    if (colorTexture) {
        VkImageView& colorAttachmentView = attachmentViews.push_back();
        colorAttachmentView =
                colorTexture->getImageView(VulkanImageView::Usage::kAttachment)->imageView();

        if (resolveTexture) {
            VkImageView& resolveView = attachmentViews.push_back();
            resolveView =
                    resolveTexture->getImageView(VulkanImageView::Usage::kAttachment)->imageView();
        }
    }

    if (depthStencilTexture) {
        VkImageView& stencilView = attachmentViews.push_back();
        stencilView =
                depthStencilTexture->getImageView(VulkanImageView::Usage::kAttachment)->imageView();
    }
}

} // anonymous namespace

sk_sp<VulkanFramebuffer> VulkanResourceProvider::findOrCreateFramebuffer(
        const VulkanSharedContext* context,
        VulkanTexture* colorTexture,
        VulkanTexture* resolveTexture,
        VulkanTexture* depthStencilTexture,
        const RenderPassDesc& renderPassDesc,
        const VulkanRenderPass& renderPass) {

    VulkanTexture* mainTexture = resolveTexture ? resolveTexture :
                                 colorTexture   ? colorTexture
                                                : depthStencilTexture;
    SkASSERT(mainTexture);
    VulkanTexture* msaaTexture = resolveTexture ? colorTexture : nullptr;

    // First check for a cached frame buffer, which are kept alive by the main texture
    sk_sp<VulkanFramebuffer> fb = mainTexture->getCachedFramebuffer(renderPassDesc,
                                                                    msaaTexture,
                                                                    depthStencilTexture);
    if (fb) {
        return fb;
    }

    // Gather attachment views neeeded for frame buffer creation.
    skia_private::TArray<VkImageView> attachmentViews;
    gather_attachment_views(attachmentViews, colorTexture, resolveTexture, depthStencilTexture);

    VkFramebufferCreateInfo framebufferInfo = {};
    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    framebufferInfo.renderPass = renderPass.renderPass();
    framebufferInfo.attachmentCount = attachmentViews.size();
    framebufferInfo.pAttachments = attachmentViews.begin();
    framebufferInfo.width = mainTexture->dimensions().width();
    framebufferInfo.height = mainTexture->dimensions().height();
    framebufferInfo.layers = 1;
    fb = VulkanFramebuffer::Make(context,
                                 framebufferInfo,
                                 renderPassDesc,
                                 sk_ref_sp(msaaTexture),
                                 sk_ref_sp(depthStencilTexture));
    mainTexture->addCachedFramebuffer(fb);
    return fb;
}

void VulkanResourceProvider::onDeleteBackendTexture(const BackendTexture& texture) {
    SkASSERT(texture.isValid());
    SkASSERT(texture.backend() == BackendApi::kVulkan);

    VULKAN_CALL(this->vulkanSharedContext()->interface(),
                DestroyImage(this->vulkanSharedContext()->device(),
                             BackendTextures::GetVkImage(texture),
                             /*VkAllocationCallbacks=*/nullptr));

    VulkanAlloc alloc = BackendTextures::GetMemoryAlloc(texture);
    // Free the image memory used for the BackendTexture's VkImage.
    //
    // How we do this is dependent upon on how the image was allocated (via the memory allocator or
    // with a direct call to the Vulkan driver) . If the VulkanAlloc's fBackendMemory is != 0, then
    // that means the allocator was used. Otherwise, a direct driver call was used and we should
    // free the VkDeviceMemory (fMemory).
    if (alloc.fBackendMemory) {
        skgpu::VulkanMemory::FreeImageMemory(this->vulkanSharedContext()->memoryAllocator(), alloc);
    } else {
        SkASSERT(alloc.fMemory != VK_NULL_HANDLE);
        VULKAN_CALL(this->vulkanSharedContext()->interface(),
                    FreeMemory(this->vulkanSharedContext()->device(), alloc.fMemory, nullptr));
    }
}

sk_sp<VulkanYcbcrConversion> VulkanResourceProvider::findOrCreateCompatibleYcbcrConversion(
        const VulkanYcbcrConversionInfo& ycbcrInfo) const {
    static constexpr Budgeted kBudgeted = Budgeted::kYes;
    static constexpr Shareable kShareable = Shareable::kYes;
    if (!ycbcrInfo.isValid()) {
        return nullptr;
    }

    GraphiteResourceKey key;
    {
        static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
        static constexpr uint16_t kKeySize = 3;

        GraphiteResourceKey::Builder builder(&key, kType, kKeySize);
        ImmutableSamplerInfo packedInfo = VulkanYcbcrConversion::ToImmutableSamplerInfo(ycbcrInfo);
        builder[0] = packedInfo.fNonFormatYcbcrConversionInfo;
        builder[1] = (uint32_t) packedInfo.fFormat;
        builder[2] = (uint32_t) (packedInfo.fFormat >> 32);
    }

    if (Resource* resource = fResourceCache->findAndRefResource(key, kBudgeted, kShareable)) {
        return sk_sp(static_cast<VulkanYcbcrConversion*>(resource));
    }

    auto ycbcrConversion = VulkanYcbcrConversion::Make(this->vulkanSharedContext(), ycbcrInfo);
    if (!ycbcrConversion) {
        return nullptr;
    }

    fResourceCache->insertResource(ycbcrConversion.get(), key, kBudgeted, kShareable);
    return ycbcrConversion;
}

sk_sp<VulkanGraphicsPipeline> VulkanResourceProvider::findOrCreateLoadMSAAPipeline(
        const RenderPassDesc& renderPassDesc) {
    if (renderPassDesc.fColorResolveAttachment.fFormat == TextureFormat::kUnsupported ||
        renderPassDesc.fColorAttachment.fFormat == TextureFormat::kUnsupported) {
        SKIA_LOG_E("Loading MSAA from resolve texture requires valid color & resolve attachment");
        return nullptr;
    }

    // Check to see if we already have a suitable pipeline that we can use.
    const uint32_t compatibleRenderPassHash =
            VulkanRenderPass::GetRenderPassKey(renderPassDesc, /*compatibleForPipelineKey=*/true);
    for (int i = 0; i < fLoadMSAAPipelines.size(); i++) {
        if (compatibleRenderPassHash == fLoadMSAAPipelines.at(i).first) {
            return fLoadMSAAPipelines.at(i).second;
        }
    }

    if (!fLoadMSAAProgram) {
        // Lazily create the modules and pipeline layout the first time we need to load MSAA
        fLoadMSAAProgram =
                VulkanGraphicsPipeline::CreateLoadMSAAProgram(this->vulkanSharedContext());
        if (!fLoadMSAAProgram) {
            SKIA_LOG_E("Failed to initialize MSAA load pipeline creation structure(s)");
            return nullptr;
        }
    }

    sk_sp<VulkanGraphicsPipeline> pipeline = VulkanGraphicsPipeline::MakeLoadMSAAPipeline(
            this->nonConstVulkanSharedContext(), *fLoadMSAAProgram, renderPassDesc);
    if (!pipeline) {
        SKIA_LOG_E("Failed to create MSAA load pipeline");
        return nullptr;
    }

    fLoadMSAAPipelines.push_back(std::make_pair(compatibleRenderPassHash, pipeline));
    return pipeline;
}

VulkanThreadSafeResourceProvider::VulkanThreadSafeResourceProvider(
        std::unique_ptr<ResourceProvider> resourceProvider)
    : ThreadSafeResourceProvider(std::move(resourceProvider)) {}

sk_sp<VulkanRenderPass> VulkanThreadSafeResourceProvider::findOrCreateRenderPass(
        const RenderPassDesc& renderPassDesc,
        bool compatibleOnly) {
    SkAutoSpinlock lock{fSpinLock};

    VulkanResourceProvider* vkResourceProvider =
        static_cast<VulkanResourceProvider*>(fWrappedProvider.get());

    sk_sp<VulkanRenderPass> renderPass =
        vkResourceProvider->findOrCreateRenderPass(renderPassDesc, compatibleOnly);
    SkAssertResult(renderPass->gpuMemorySize() == 0);

    return renderPass;
}

#ifdef SK_BUILD_FOR_ANDROID

BackendTexture VulkanResourceProvider::onCreateBackendTexture(AHardwareBuffer* hardwareBuffer,
                                                              bool isRenderable,
                                                              bool isProtectedContent,
                                                              SkISize dimensions,
                                                              bool fromAndroidWindow) const {

    const VulkanSharedContext* vkContext = this->vulkanSharedContext();
    VkDevice device = vkContext->device();
    const VulkanCaps& vkCaps = vkContext->vulkanCaps();

    VkAndroidHardwareBufferFormatPropertiesANDROID hwbFormatProps;
    VkAndroidHardwareBufferPropertiesANDROID hwbProps;
    if (!skgpu::GetAHardwareBufferProperties(
                &hwbFormatProps, &hwbProps, vkContext->interface(), hardwareBuffer, device)) {
        return {};
    }

    // Import as external if the AHardwareBuffer has an undefined format or if the VkFormat does not
    // map back to a TextureFormat.
    bool importAsExternalFormat = hwbFormatProps.format == VK_FORMAT_UNDEFINED ||
            VkFormatToTextureFormat(hwbFormatProps.format) == TextureFormat::kUnsupported;
#if defined(SK_DEBUG)
    if (importAsExternalFormat && hwbFormatProps.format != VK_FORMAT_UNDEFINED) {
        SKIA_LOG_D("Ignoring AHardwareBuffer VkFormat(%d) because it is not supported by graphite."
                    " Falling back to importing as external format.\n", hwbFormatProps.format);
    }
#endif

    // Start to assemble VulkanTextureInfo which is needed later on to create the VkImage but can
    // sooner help us query VulkanCaps for certain format feature support.
    //
    // Note that the optimal tiling is always the right choice, including for external formats
    // (which always require optimal) and AHBs (where the real layout is determined by AHB usage
    // flags, and optimal tiling would automatically mean linear if it has to).
    VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
    VkImageCreateFlags imgCreateflags = isProtectedContent ? VK_IMAGE_CREATE_PROTECTED_BIT : 0;
    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
    // When importing as an external format the image usage can only be VK_IMAGE_USAGE_SAMPLED_BIT.
    if (!importAsExternalFormat) {
        usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
        if (!isProtectedContent) {
            usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
        }
        if (isRenderable) {
            // Renderable attachments can be used as input attachments if we are loading from MSAA.
            usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
            // Opt into MSAA-render-to-SS to match getDefaultSampled/AttachmentInfo in VulkanCaps
            if (vkCaps.msaaRenderToSingleSampledSupport()) {
                imgCreateflags |= VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT;
            }
        }
        // For non-renderable Graphite-created textures, VulkanCaps also attempts to use
        // VK_IMAGE_USAGE_HOST_TRANSFER_BIT, but if we are wrapping an AHardwareBuffer, its contents
        // are presumably managed by the client and we aren't expecting to have to write directly
        // to it from CPU memory.
    }
    VulkanTextureInfo vkTexInfo {
            VK_SAMPLE_COUNT_1_BIT,
            Mipmapped::kNo,
            imgCreateflags,
            importAsExternalFormat ? VK_FORMAT_UNDEFINED : hwbFormatProps.format,
            tiling,
            usageFlags,
            VK_SHARING_MODE_EXCLUSIVE,
            VK_IMAGE_ASPECT_COLOR_BIT,
            VulkanYcbcrConversionInfo() };

    // Wrap in TextureInfo for Caps checks, although it will be invalidated if we modify vkTexInfo
    // later on as a result of those checks.
    TextureInfo texInfo = TextureInfos::MakeVulkan(vkTexInfo);
    if (isRenderable && (importAsExternalFormat || !vkCaps.isRenderable(texInfo))) {
        SKIA_LOG_W("Renderable texture requested from an AHardwareBuffer which uses a VkFormat "
                    "that Skia cannot render to (VkFormat: %d).\n",  hwbFormatProps.format);
        return {};
    }

    // We don't require copyable-src if it's protected content
    if (!importAsExternalFormat && (!(vkCaps.isCopyableSrc(texInfo) || isProtectedContent) ||
                                    !vkCaps.isCopyableDst(texInfo) ||
                                    !vkCaps.isTexturable(texInfo))) {
        if (isRenderable) {
            SKIA_LOG_W("VkFormat %d does not support the necessary format features. Because a "
                        "renderable texture was requested, we cannot fall back to importing with "
                        "an external format.\n", hwbFormatProps.format);
            return {};
        }
        // If the VkFormat does not support the features we need, then import as an external format.
        importAsExternalFormat = true;
        // If we use VkExternalFormatANDROID with an externalFormat != 0, then format must =
        // VK_FORMAT_UNDEFINED.
        vkTexInfo.fFormat = VK_FORMAT_UNDEFINED;
        vkTexInfo.fImageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT;
    }

    VulkanYcbcrConversionInfo ycbcrInfo;
    VkExternalFormatANDROID externalFormat;
    externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
    externalFormat.pNext = nullptr;
    externalFormat.externalFormat = 0;  // If this is zero it is as if we aren't using this struct.
    if (importAsExternalFormat || skgpu::VkFormatNeedsYcbcrSampler(hwbFormatProps.format)) {
        GetYcbcrConversionInfoFromFormatProps(&ycbcrInfo, hwbFormatProps);
        if (!ycbcrInfo.isValid()) {
            SKIA_LOG_W("Failed to create valid YCbCr conversion information from hardware buffer"
                        "format properties.\n");
            return {};
        }
        vkTexInfo.fYcbcrConversionInfo = ycbcrInfo;
        externalFormat.externalFormat = hwbFormatProps.externalFormat;
    }
    const VkExternalMemoryImageCreateInfo externalMemoryImageInfo{
            VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,                 // sType
            &externalFormat,                                                     // pNext
            VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,  // handleTypes
    };

    SkASSERT(!(vkTexInfo.fFlags & VK_IMAGE_CREATE_PROTECTED_BIT) ||
             fSharedContext->isProtected() == Protected::kYes);

    const VkImageCreateInfo imageCreateInfo = {
        VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                 // sType
        &externalMemoryImageInfo,                                            // pNext
        vkTexInfo.fFlags,                                                    // VkImageCreateFlags
        VK_IMAGE_TYPE_2D,                                                    // VkImageType
        vkTexInfo.fFormat,                                                   // VkFormat
        { (uint32_t)dimensions.fWidth, (uint32_t)dimensions.fHeight, 1 },    // VkExtent3D
        1,                                                                   // mipLevels
        1,                                                                   // arrayLayers
        VK_SAMPLE_COUNT_1_BIT,                                               // samples
        vkTexInfo.fImageTiling,                                              // VkImageTiling
        vkTexInfo.fImageUsageFlags,                                          // VkImageUsageFlags
        vkTexInfo.fSharingMode,                                              // VkSharingMode
        0,                                                                   // queueFamilyCount
        nullptr,                                                             // pQueueFamilyIndices
        VK_IMAGE_LAYOUT_UNDEFINED,                                           // initialLayout
    };

    VkResult result;
    VkImage image;
    VULKAN_CALL_RESULT(vkContext, result, CreateImage(device, &imageCreateInfo, nullptr, &image));
    if (result != VK_SUCCESS) {
        return {};
    }

    const VkPhysicalDeviceMemoryProperties2& phyDevMemProps =
            vkContext->vulkanCaps().physicalDeviceMemoryProperties2();
    VulkanAlloc alloc;
    if (!AllocateAndBindImageMemory(&alloc, image, phyDevMemProps, hwbProps, hardwareBuffer,
                                    vkContext->interface(), device)) {
        VULKAN_CALL(vkContext->interface(), DestroyImage(device, image, nullptr));
        return {};
    }

    return BackendTextures::MakeVulkan(dimensions,
                                       vkTexInfo,
                                       VK_IMAGE_LAYOUT_UNDEFINED,
                                       VK_QUEUE_FAMILY_FOREIGN_EXT,
                                       image,
                                       alloc);
}

#endif // SK_BUILD_FOR_ANDROID

} // namespace skgpu::graphite
