/*
 * 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/gpu/graphite/dawn/DawnTypes.h"
#include "include/private/gpu/graphite/DawnTypesPriv.h"
#include "src/core/SkMipmap.h"
#include "src/gpu/MutableTextureStateRef.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/dawn/DawnCaps.h"
#include "src/gpu/graphite/dawn/DawnGraphiteUtilsPriv.h"
#include "src/gpu/graphite/dawn/DawnSharedContext.h"

namespace skgpu::graphite {
namespace {

const char* texture_info_to_label(const TextureInfo& info,
                                  const DawnTextureSpec& dawnSpec) {
#ifdef SK_DEBUG
    if (dawnSpec.fUsage & wgpu::TextureUsage::RenderAttachment) {
        if (DawnFormatIsDepthOrStencil(dawnSpec.fFormat)) {
            return "DepthStencil";
        } else {
            if (info.numSamples() > 1) {
                if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding) {
                    return "MSAA SampledTexture-ColorAttachment";
                } else {
                    return "MSAA ColorAttachment";
                }
            } else {
                if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding) {
                    return "SampledTexture-ColorAttachment";
                } else {
                    return "ColorAttachment";
                }
            }
        }
    } else {
        SkASSERT(dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding);
        return "SampledTexture";
    }
#else
    return nullptr;
#endif
}

}

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

    const DawnTextureSpec& dawnSpec = info.dawnTextureSpec();

    if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding && !caps->isTexturable(info)) {
        return {};
    }

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

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

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

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

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

    return texture;
}

DawnTexture::DawnTexture(const DawnSharedContext* sharedContext,
                         SkISize dimensions,
                         const TextureInfo& info,
                         wgpu::Texture texture,
                         wgpu::TextureView textureView,
                         Ownership ownership,
                         skgpu::Budgeted budgeted)
        : Texture(sharedContext, dimensions, info, /*mutableState=*/nullptr, ownership, budgeted)
        , fTexture(std::move(texture))
        , fTextureView(std::move(textureView)) {}

sk_sp<Texture> DawnTexture::Make(const DawnSharedContext* sharedContext,
                                 SkISize dimensions,
                                 const TextureInfo& info,
                                 skgpu::Budgeted budgeted) {
    auto texture = MakeDawnTexture(sharedContext, dimensions, info);
    if (!texture) {
        return {};
    }
    auto textureView = texture.CreateView();
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          std::move(texture),
                                          std::move(textureView),
                                          Ownership::kOwned,
                                          budgeted));
}

sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
                                        SkISize dimensions,
                                        const TextureInfo& info,
                                        wgpu::Texture texture) {
    if (!texture) {
        SKGPU_LOG_E("No valid texture passed into MakeWrapped\n");
        return {};
    }
    auto textureView = texture.CreateView();
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          std::move(texture),
                                          std::move(textureView),
                                          Ownership::kWrapped,
                                          skgpu::Budgeted::kNo));
}

sk_sp<Texture> DawnTexture::MakeWrapped(const DawnSharedContext* sharedContext,
                                        SkISize dimensions,
                                        const TextureInfo& info,
                                        wgpu::TextureView textureView) {
    if (!textureView) {
        SKGPU_LOG_E("No valid texture passed into MakeWrapped\n");
        return {};
    }
    return sk_sp<Texture>(new DawnTexture(sharedContext,
                                          dimensions,
                                          info,
                                          nullptr,
                                          std::move(textureView),
                                          Ownership::kWrapped,
                                          skgpu::Budgeted::kNo));
}

void DawnTexture::freeGpuData() {
    fTexture = nullptr;
    fTextureView = nullptr;
}

} // namespace skgpu::graphite

