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

#include "src/gpu/ganesh/vk/GrVkTextureRenderTarget.h"

#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "src/gpu/ganesh/vk/GrVkImage.h"
#include "src/gpu/ganesh/vk/GrVkImageView.h"
#include "src/gpu/ganesh/vk/GrVkUtil.h"

#include "src/core/SkMipmap.h"

#include "include/gpu/vk/GrVkTypes.h"

#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)

GrVkTextureRenderTarget::GrVkTextureRenderTarget(GrVkGpu* gpu,
                                                 skgpu::Budgeted budgeted,
                                                 SkISize dimensions,
                                                 sk_sp<GrVkImage> texture,
                                                 sk_sp<GrVkImage> colorAttachment,
                                                 sk_sp<GrVkImage> resolveAttachment,
                                                 GrMipmapStatus mipmapStatus,
                                                 std::string_view label)
        : GrSurface(gpu,
                    dimensions,
                    texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
                    label)
        , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus, label)
        , GrVkRenderTarget(gpu,
                           dimensions,
                           std::move(colorAttachment),
                           std::move(resolveAttachment),
                           CreateType::kFromTextureRT,
                           label) {
    this->registerWithCache(budgeted);
}

GrVkTextureRenderTarget::GrVkTextureRenderTarget(
        GrVkGpu* gpu,
        SkISize dimensions,
        sk_sp<GrVkImage> texture,
        sk_sp<GrVkImage> colorAttachment,
        sk_sp<GrVkImage> resolveAttachment,
        GrMipmapStatus mipmapStatus,
        GrWrapCacheable cacheable,
        std::string_view label)
        : GrSurface(gpu,
                    dimensions,
                    texture->isProtected() ? GrProtected::kYes : GrProtected::kNo,
                    label)
        , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus, label)
        , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment),
                           std::move(resolveAttachment), CreateType::kFromTextureRT, label) {
    this->registerWithCacheWrapped(cacheable);
}

bool create_rt_attachments(GrVkGpu* gpu, SkISize dimensions, VkFormat format, int sampleCnt,
                           GrProtected isProtected,
                           sk_sp<GrVkImage> texture,
                           sk_sp<GrVkImage>* colorAttachment,
                           sk_sp<GrVkImage>* resolveAttachment) {
    if (sampleCnt > 1) {
        auto rp = gpu->getContext()->priv().resourceProvider();
        sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment(
                dimensions, GrBackendFormat::MakeVk(format), sampleCnt, isProtected,
                GrMemoryless::kNo);
        if (!msaaAttachment) {
            return false;
        }
        *colorAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release()));
        *resolveAttachment = std::move(texture);
    } else {
        *colorAttachment = std::move(texture);
    }
    return true;
}

sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeNewTextureRenderTarget(
        GrVkGpu* gpu,
        skgpu::Budgeted budgeted,
        SkISize dimensions,
        VkFormat format,
        uint32_t mipLevels,
        int sampleCnt,
        GrMipmapStatus mipmapStatus,
        GrProtected isProtected,
        std::string_view label) {
    sk_sp<GrVkImage> texture = GrVkImage::MakeTexture(gpu,
                                                      dimensions,
                                                      format,
                                                      mipLevels,
                                                      GrRenderable::kYes,
                                                      /*numSamples=*/1,
                                                      budgeted,
                                                      isProtected);
    if (!texture) {
        return nullptr;
    }

    sk_sp<GrVkImage> colorAttachment;
    sk_sp<GrVkImage> resolveAttachment;
    if (!create_rt_attachments(gpu, dimensions, format, sampleCnt, isProtected, texture,
                               &colorAttachment, &resolveAttachment)) {
        return nullptr;
    }
    SkASSERT(colorAttachment);
    SkASSERT(sampleCnt == 1 || resolveAttachment);
    return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget(gpu,
                                                                      budgeted,
                                                                      dimensions,
                                                                      std::move(texture),
                                                                      std::move(colorAttachment),
                                                                      std::move(resolveAttachment),
                                                                      mipmapStatus,
                                                                      label));
}

sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(
        GrVkGpu* gpu,
        SkISize dimensions,
        int sampleCnt,
        GrWrapOwnership wrapOwnership,
        GrWrapCacheable cacheable,
        const GrVkImageInfo& info,
        sk_sp<skgpu::MutableTextureStateRef> mutableState) {
    // Adopted textures require both image and allocation because we're responsible for freeing
    SkASSERT(VK_NULL_HANDLE != info.fImage &&
             (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory));

    GrAttachment::UsageFlags textureUsageFlags = GrAttachment::UsageFlags::kTexture;
    if (info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
        textureUsageFlags |= GrAttachment::UsageFlags::kColorAttachment;
    }

    sk_sp<GrVkImage> texture = GrVkImage::MakeWrapped(gpu,
                                                      dimensions,
                                                      info,
                                                      std::move(mutableState),
                                                      textureUsageFlags,
                                                      wrapOwnership,
                                                      cacheable,
                                                      "VkImage_MakeWrappedTextureRenderTarget");
    if (!texture) {
        return nullptr;
    }

    sk_sp<GrVkImage> colorAttachment;
    sk_sp<GrVkImage> resolveAttachment;
    if (!create_rt_attachments(gpu, dimensions, info.fFormat, sampleCnt, info.fProtected, texture,
                               &colorAttachment, &resolveAttachment)) {
        return nullptr;
    }
    SkASSERT(colorAttachment);
    SkASSERT(sampleCnt == 1 || resolveAttachment);

    GrMipmapStatus mipmapStatus =
            info.fLevelCount > 1 ? GrMipmapStatus::kDirty : GrMipmapStatus::kNotAllocated;

    return sk_sp<GrVkTextureRenderTarget>(
            new GrVkTextureRenderTarget(gpu,
                                        dimensions,
                                        std::move(texture),
                                        std::move(colorAttachment),
                                        std::move(resolveAttachment),
                                        mipmapStatus,
                                        cacheable,
                                        /*label=*/"Vk_MakeWrappedTextureRenderTarget"));
}

size_t GrVkTextureRenderTarget::onGpuMemorySize() const {
    // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their
    // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture
    // would just merge with the new GrSurface/Attachment world. Then we could just depend on each
    // attachment to give its own size since we don't have GrGpuResources owning other
    // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let
    // the msaa and stencil attachments track their own size because they do get cached separately.
    // For all GrTexture* based things we will continue to to use the GrTexture* to report size and
    // the owned attachments will have no size and be uncached.
#ifdef SK_DEBUG
    // The nonMSAA attachment (either color or resolve depending on numSamples should have size of
    // zero since it is a texture attachment.
    SkASSERT(this->nonMSAAAttachment()->gpuMemorySize() == 0);
    if (this->numSamples() > 1) {
        // Msaa attachment should have a valid size
        SkASSERT(this->colorAttachment()->gpuMemorySize() ==
                 GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
                                        this->numSamples(), GrMipmapped::kNo));
    }
#endif
    return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
                                  1 /*colorSamplesPerPixel*/, this->mipmapped());
}
