/*
 * 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)) {
        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
