/*
 * 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/dawn/DawnTexture.h"

#include "include/core/SkTraceMemoryDump.h"
#include "include/gpu/MutableTextureState.h"
#include "include/private/SkLog.h"
#include "src/core/SkMipmap.h"
#include "src/gpu/graphite/Sampler.h"
#include "src/gpu/graphite/TextureUtils.h"
#include "src/gpu/graphite/dawn/DawnCaps.h"
#include "src/gpu/graphite/dawn/DawnGraphiteUtils.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"

namespace skgpu::graphite {

wgpu::Texture DawnTexture::MakeDawnTexture(const DawnSharedContext* sharedContext,
                                           SkISize dimensions,
                                           const TextureInfo& info) {
    const auto* caps = sharedContext->dawnCaps();
    if (dimensions.width() > caps->maxTextureSize() ||
        dimensions.height() > caps->maxTextureSize()) {
        SKIA_LOG_E("Texture creation failure: dimensions %d x %d too large.",
                    dimensions.width(), dimensions.height());
        return {};
    }

    const auto& dawnInfo = TextureInfoPriv::Get<DawnTextureInfo>(info);

    if (dawnInfo.fUsage & wgpu::TextureUsage::TextureBinding &&
        !caps->isTexturable(info, /*allowMSAA=*/true) &&
        !caps->isReadable(info, /*allowMSAA=*/true)) {
        return {};
    }

    if (dawnInfo.fUsage & wgpu::TextureUsage::RenderAttachment && !caps->isRenderable(info)) {
        return {};
    }

    if (dawnInfo.fUsage & wgpu::TextureUsage::StorageBinding && !caps->isStorage(info)) {
        return {};
    }

#if !defined(__EMSCRIPTEN__)
    // If a non-default YCbCr descriptor is provided, either the vkFormat or the externalFormat must
    // be defined.
    if (DawnDescriptorIsValid(dawnInfo.fYcbcrVkDescriptor) &&
    dawnInfo.fYcbcrVkDescriptor.vkFormat == 0 &&
    dawnInfo.fYcbcrVkDescriptor.externalFormat == 0) {
        return {};
    }
#endif

    int numMipLevels = 1;
    if (info.mipmapped() == Mipmapped::kYes) {
        numMipLevels = SkMipmap::ComputeLevelCount(dimensions) + 1;
    }

    wgpu::TextureDescriptor desc;
    desc.usage                   = dawnInfo.fUsage;
    desc.dimension               = wgpu::TextureDimension::e2D;
    desc.size.width              = dimensions.width();
    desc.size.height             = dimensions.height();
    desc.size.depthOrArrayLayers = 1;
    desc.format                  = dawnInfo.fFormat;
    desc.mipLevelCount           = numMipLevels;
    desc.sampleCount             = (uint8_t) info.sampleCount();
    desc.viewFormatCount         = 0;
    desc.viewFormats             = nullptr;

    auto texture = sharedContext->device().CreateTexture(&desc);
    if (!texture) {
        return {};
    }

    return texture;
}

static bool has_transient_usage(const TextureInfo& info) {
#if !defined(__EMSCRIPTEN__)
    const auto& dawnInfo = TextureInfoPriv::Get<DawnTextureInfo>(info);
    return dawnInfo.fUsage & wgpu::TextureUsage::TransientAttachment;
#else
    return false;
#endif
}

DawnTexture::DawnTexture(const DawnSharedContext* sharedContext,
                         SkISize dimensions,
                         const TextureInfo& info,
                         wgpu::Texture texture,
                         wgpu::TextureView sampleTextureView,
                         wgpu::TextureView renderTextureView,
                         Ownership ownership,
                         std::string_view label)
        : Texture(sharedContext,
                  dimensions,
                  info,
                  /*isTransient=*/has_transient_usage(info),
                  /*mutableState=*/nullptr,
                  ownership,
                  label)
        , fTexture(std::move(texture))
        , fSampleTextureView(std::move(sampleTextureView))
        , fRenderTextureView(std::move(renderTextureView)) {
    // Update the newly-created underlying GPU object's label to match the Resource's
    this->synchronizeBackendLabel();
}

// static
std::pair<wgpu::TextureView, wgpu::TextureView> DawnTexture::CreateTextureViews(
        const wgpu::Texture& texture, const TextureInfo& info) {
    const auto& dawnInfo = TextureInfoPriv::Get<DawnTextureInfo>(info);
    const auto aspect = dawnInfo.fAspect;
    if (aspect == wgpu::TextureAspect::All) {
        wgpu::TextureViewDescriptor viewDesc = {};
        viewDesc.dimension = wgpu::TextureViewDimension::e2D;
        viewDesc.baseArrayLayer = dawnInfo.fSlice;
        viewDesc.arrayLayerCount = 1;
#if !defined(__EMSCRIPTEN__)
        // Ensure that the TextureView is configured to use YCbCr sampling if the Texture is
        // doing so.
        const wgpu::YCbCrVkDescriptor& ycbcrDesc = dawnInfo.fYcbcrVkDescriptor;
        if (DawnDescriptorIsValid(ycbcrDesc)) {
            viewDesc.nextInChain = &ycbcrDesc;
        }
#endif
        wgpu::TextureView sampleTextureView = texture.CreateView(&viewDesc);
        wgpu::TextureView renderTextureView;
        if (info.mipmapped() == Mipmapped::kYes) {
            viewDesc.baseMipLevel = 0;
            viewDesc.mipLevelCount = 1;
            renderTextureView = texture.CreateView(&viewDesc);
        } else {
            renderTextureView = sampleTextureView;
        }
        return {sampleTextureView, renderTextureView};
    }

#if defined(__EMSCRIPTEN__)
    SkASSERT(false);
    return {};
#else
    SkASSERT(aspect == wgpu::TextureAspect::Plane0Only ||
             aspect == wgpu::TextureAspect::Plane1Only ||
             aspect == wgpu::TextureAspect::Plane2Only);
    wgpu::TextureView planeTextureView;
    wgpu::TextureViewDescriptor planeViewDesc = {};

    planeViewDesc.format = dawnInfo.fViewFormat;
    planeViewDesc.dimension = wgpu::TextureViewDimension::e2D;
    planeViewDesc.aspect = aspect;
    planeViewDesc.baseArrayLayer = dawnInfo.fSlice;
    planeViewDesc.arrayLayerCount = 1;
    planeTextureView = texture.CreateView(&planeViewDesc);
    return {planeTextureView, planeTextureView};
#endif
}

sk_sp<Texture> DawnTexture::Make(const DawnSharedContext* sharedContext,
                                 SkISize dimensions,
                                 const TextureInfo& info,
                                 std::string_view label) {
    auto texture = MakeDawnTexture(sharedContext, dimensions, info);
    if (!texture) {
        return {};
    }
    auto [sampleTextureView, renderTextureView] = CreateTextureViews(texture, info);
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          std::move(texture),
                                          std::move(sampleTextureView),
                                          std::move(renderTextureView),
                                          Ownership::kOwned,
                                          label));
}

sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
                                        SkISize dimensions,
                                        const TextureInfo& info,
                                        wgpu::Texture texture,
                                        std::string_view label) {
    if (!texture) {
        SKIA_LOG_E("No valid texture passed into MakeWrapped\n");
        return {};
    }

    auto [sampleTextureView, renderTextureView] = CreateTextureViews(texture, info);
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          std::move(texture),
                                          std::move(sampleTextureView),
                                          std::move(renderTextureView),
                                          Ownership::kWrapped,
                                          label));
}

sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
                                        SkISize dimensions,
                                        const TextureInfo& info,
                                        const wgpu::TextureView& textureView,
                                        std::string_view label) {
    if (!textureView) {
        SKIA_LOG_E("No valid texture view passed into MakeWrapped\n");
        return {};
    }
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          /*texture=*/nullptr,
                                          /*sampleTextureView=*/textureView,
                                          /*renderTextureView=*/textureView,
                                          Ownership::kWrapped,
                                          label));
}

void DawnTexture::freeGpuData() {
    if (this->ownership() != Ownership::kWrapped && fTexture) {
        // Destroy the texture even if it is still referenced by other BindGroup or views.
        // Graphite should already guarantee that all command buffers using this texture (indirectly
        // via BindGroup or views) are already completed.
        fTexture.Destroy();
    }
    fTexture = nullptr;
    fSampleTextureView = nullptr;
    fRenderTextureView = nullptr;
}

void DawnTexture::setBackendLabel(char const* label) {
    if (!sharedContext()->caps()->setBackendLabels()) {
        return;
    }
    SkASSERT(label);
    // Wrapped texture views won't have an associated texture here.
    if (fTexture) {
        fTexture.SetLabel(label);
    }
    // But we always have the texture views available.
    SkASSERT(fSampleTextureView);
    SkASSERT(fRenderTextureView);
    if (fSampleTextureView.Get() == fRenderTextureView.Get()) {
        fSampleTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_TextureView").c_str());
    } else {
        fSampleTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_SampleTextureView").c_str());
        fRenderTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_RenderTextureView").c_str());
    }
}

const wgpu::BindGroup* DawnTexture::getCachedSingleTextureBindGroup(const Sampler* sampler) const {
    SkASSERT(sampler);
    for (auto& cachedGroup : fCachedSingleTextureBindGroups) {
        if (cachedGroup.first->uniqueID() == sampler->uniqueID()) {
            return &cachedGroup.second;
        }
    }
    return nullptr;
}

void DawnTexture::addCachedSingleTextureBindGroup(wgpu::BindGroup bindGroup,
                                                  const Sampler* sampler) const {
    SkASSERT(sampler);
    fCachedSingleTextureBindGroups.push_back({sampler, bindGroup});
}

} // namespace skgpu::graphite
