/*
 * Copyright 2020 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/ganesh/d3d/GrD3DRenderTarget.h"

#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/d3d/GrD3DTypes.h"
#include "src/gpu/KeyBuilder.h"
#include "src/gpu/ganesh/GrRenderTarget.h"
#include "src/gpu/ganesh/d3d/GrD3DGpu.h"
#include "src/gpu/ganesh/d3d/GrD3DResourceProvider.h"
#include "src/gpu/ganesh/d3d/GrD3DTextureResource.h"
#include "src/gpu/ganesh/d3d/GrD3DUtil.h"

// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
                                     SkISize dimensions,
                                     const GrD3DTextureResourceInfo& info,
                                     sk_sp<GrD3DResourceState> state,
                                     const GrD3DTextureResourceInfo& msaaInfo,
                                     sk_sp<GrD3DResourceState> msaaState,
                                     const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
                                     const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
                                     Wrapped,
                                     std::string_view label)
        : GrSurface(gpu, dimensions, info.fProtected, label)
        , GrD3DTextureResource(info, std::move(state))
        // for the moment we only support 1:1 color to stencil
        , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected, label)
        , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
        , fColorRenderTargetView(colorRenderTargetView)
        , fResolveRenderTargetView(resolveRenderTargetView) {
    SkASSERT(info.fProtected == msaaInfo.fProtected);
    SkASSERT(msaaInfo.fSampleCount > 1);
    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
}

// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
                                     SkISize dimensions,
                                     const GrD3DTextureResourceInfo& info,
                                     sk_sp<GrD3DResourceState> state,
                                     const GrD3DTextureResourceInfo& msaaInfo,
                                     sk_sp<GrD3DResourceState> msaaState,
                                     const GrD3DDescriptorHeap::CPUHandle& colorRenderTargetView,
                                     const GrD3DDescriptorHeap::CPUHandle& resolveRenderTargetView,
                                     std::string_view label)
        : GrSurface(gpu, dimensions, info.fProtected, label)
        , GrD3DTextureResource(info, std::move(state))
        // for the moment we only support 1:1 color to stencil
        , GrRenderTarget(gpu, dimensions, msaaInfo.fSampleCount, info.fProtected, label)
        , fMSAATextureResource(new GrD3DTextureResource(msaaInfo, std::move(msaaState)))
        , fColorRenderTargetView(colorRenderTargetView)
        , fResolveRenderTargetView(resolveRenderTargetView) {
    SkASSERT(info.fProtected == msaaInfo.fProtected);
    SkASSERT(msaaInfo.fSampleCount > 1);
}

// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
                                     SkISize dimensions,
                                     const GrD3DTextureResourceInfo& info,
                                     sk_sp<GrD3DResourceState> state,
                                     const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
                                     Wrapped,
                                     std::string_view label)
        : GrSurface(gpu, dimensions, info.fProtected, label)
        , GrD3DTextureResource(info, std::move(state))
        , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected, label)
        , fMSAATextureResource(nullptr)
        , fColorRenderTargetView(renderTargetView) {
    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
}

// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrD3DRenderTarget::GrD3DRenderTarget(GrD3DGpu* gpu,
                                     SkISize dimensions,
                                     const GrD3DTextureResourceInfo& info,
                                     sk_sp<GrD3DResourceState> state,
                                     const GrD3DDescriptorHeap::CPUHandle& renderTargetView,
                                     std::string_view label)
        : GrSurface(gpu, dimensions, info.fProtected, label)
        , GrD3DTextureResource(info, std::move(state))
        , GrRenderTarget(gpu, dimensions, info.fSampleCount, info.fProtected, label)
        , fMSAATextureResource(nullptr)
        , fColorRenderTargetView(renderTargetView) {}

sk_sp<GrD3DRenderTarget> GrD3DRenderTarget::MakeWrappedRenderTarget(
            GrD3DGpu* gpu, SkISize dimensions, int sampleCnt, const GrD3DTextureResourceInfo& info,
            sk_sp<GrD3DResourceState> state) {
    SkASSERT(info.fResource.get());
    SkASSERT(info.fLevelCount == 1);
    SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1);

    int wrappedTextureSampleCnt = static_cast<int>(info.fSampleCount);
    if (sampleCnt != wrappedTextureSampleCnt && wrappedTextureSampleCnt != 1) {
        return nullptr;
    }

    GrD3DDescriptorHeap::CPUHandle renderTargetView =
            gpu->resourceProvider().createRenderTargetView(info.fResource.get());

    // create msaa surface if necessary
    GrD3DRenderTarget* d3dRT;
    if (sampleCnt != wrappedTextureSampleCnt) {
        GrD3DTextureResourceInfo msInfo;
        sk_sp<GrD3DResourceState> msState;
        // for wrapped MSAA surface we assume clear to white
        SkColor4f clearColor = { 1, 1, 1, 1 };
        std::tie(msInfo, msState) =
                GrD3DTextureResource::CreateMSAA(gpu, dimensions, sampleCnt, info, clearColor);

        GrD3DDescriptorHeap::CPUHandle msaaRenderTargetView =
                gpu->resourceProvider().createRenderTargetView(msInfo.fResource.get());

        d3dRT = new GrD3DRenderTarget(gpu, dimensions, info, std::move(state), msInfo,
                                      std::move(msState), msaaRenderTargetView, renderTargetView,
                                      kWrapped,
                                      /*label=*/"MakeWrappedRenderTargetWithMSAASurface");
    } else {
        d3dRT = new GrD3DRenderTarget(
                gpu, dimensions, info, std::move(state), renderTargetView, kWrapped,
                /*label=*/"MakeWrappedRenderTarget");
    }

    return sk_sp<GrD3DRenderTarget>(d3dRT);
}

GrD3DRenderTarget::~GrD3DRenderTarget() {
    // either release or abandon should have been called by the owner of this object.
    SkASSERT(!fMSAATextureResource);
}

const GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() const {
    if (this->numSamples() == 1) {
        SkASSERT(!fMSAATextureResource);
        return nullptr;
    }
    if (fMSAATextureResource) {
        return fMSAATextureResource.get();
    }
    SkASSERT(!fMSAATextureResource);
    return this;
}

GrD3DTextureResource* GrD3DRenderTarget::msaaTextureResource() {
    auto* constThis = const_cast<const GrD3DRenderTarget*>(this);
    return const_cast<GrD3DTextureResource*>(constThis->msaaTextureResource());
}

void GrD3DRenderTarget::releaseInternalObjects() {
    GrD3DGpu* gpu = this->getD3DGpu();

    if (fMSAATextureResource) {
        fMSAATextureResource->releaseResource(gpu);
        fMSAATextureResource.reset();
        gpu->resourceProvider().recycleRenderTargetView(fResolveRenderTargetView);
    }

    gpu->resourceProvider().recycleRenderTargetView(fColorRenderTargetView);
}

void GrD3DRenderTarget::onRelease() {
    this->releaseInternalObjects();
    this->releaseResource(this->getD3DGpu());
    GrRenderTarget::onRelease();
}

void GrD3DRenderTarget::onAbandon() {
    this->releaseInternalObjects();
    this->releaseResource(this->getD3DGpu());
    GrRenderTarget::onAbandon();
}

GrBackendRenderTarget GrD3DRenderTarget::getBackendRenderTarget() const {
    return GrBackendRenderTarget(this->width(), this->height(), fInfo, this->grD3DResourceState());
}

GrD3DGpu* GrD3DRenderTarget::getD3DGpu() const {
    SkASSERT(!this->wasDestroyed());
    return static_cast<GrD3DGpu*>(this->getGpu());
}

DXGI_FORMAT GrD3DRenderTarget::stencilDxgiFormat() const {
    if (auto stencil = this->getStencilAttachment()) {
        auto d3dStencil = static_cast<GrD3DAttachment*>(stencil);
        return d3dStencil->dxgiFormat();
    }
    return DXGI_FORMAT_UNKNOWN;
}

void GrD3DRenderTarget::genKey(skgpu::KeyBuilder* b) const {
    b->add32(this->dxgiFormat());
    b->add32(this->numSamples());
    b->add32(this->stencilDxgiFormat());
#ifdef SK_DEBUG
    if (const GrAttachment* stencil = this->getStencilAttachment()) {
        SkASSERT(stencil->numSamples() == this->numSamples());
    }
#endif
    b->add32(this->sampleQualityPattern());
}

void GrD3DRenderTarget::onSetLabel() {
    SkASSERT(this->d3dResource());
    if (!this->getLabel().empty()) {
        if (fMSAATextureResource) {
            SkASSERT(fMSAATextureResource->d3dResource());
            const std::wstring suffix = GrD3DMultiByteToWide(this->getLabel());
            const std::wstring msaaLabel = L"_Skia_MSAA_" + suffix;
            fMSAATextureResource->d3dResource()->SetName(msaaLabel.c_str());
            const std::wstring resolveLabel = L"_Skia_Resolve_" + suffix;
            this->d3dResource()->SetName(resolveLabel.c_str());
        } else {
            const std::wstring label = L"_Skia_" + GrD3DMultiByteToWide(this->getLabel());
            this->d3dResource()->SetName(label.c_str());
        }
    }
}
