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

#include "include/core/SkImageGenerator.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrExternalTextureGenerator.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/private/base/SkAssert.h"
#include "include/private/gpu/ganesh/GrTextureGenerator.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/gpu/RefCntedCallback.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include <cstdint>
#include <memory>
#include <utility>

enum class GrImageTexGenPolicy : int;

namespace skgpu {
enum class Mipmapped : bool;
}

static void dispose_external_texture(void *context) {
    // Reify the unique_ptr so that we delete the `GrExternalTexture` at the end of scope.
    auto texture = std::unique_ptr<GrExternalTexture>(reinterpret_cast<GrExternalTexture *>(context));
    texture->dispose();
}

GrTextureGenerator::GrTextureGenerator(const SkImageInfo& info, uint32_t uniqueID)
        : SkImageGenerator(info, uniqueID) {}

GrSurfaceProxyView GrTextureGenerator::generateTexture(GrRecordingContext* ctx,
                                                       const SkImageInfo& info,
                                                       skgpu::Mipmapped mipmapped,
                                                       GrImageTexGenPolicy texGenPolicy) {
    SkASSERT_RELEASE(fInfo.dimensions() == info.dimensions());

    if (!ctx || ctx->abandoned()) {
        return {};
    }

    return this->onGenerateTexture(ctx, info, mipmapped, texGenPolicy);
}

GrExternalTextureGenerator::GrExternalTextureGenerator(const SkImageInfo& info) : GrTextureGenerator(info) {}

GrSurfaceProxyView GrExternalTextureGenerator::onGenerateTexture(GrRecordingContext* ctx,
                                                                 const SkImageInfo& info,
                                                                 skgpu::Mipmapped mipmapped,
                                                                 GrImageTexGenPolicy texGenPolicy) {
    std::unique_ptr<GrExternalTexture> externalTexture = generateExternalTexture(ctx, mipmapped);
    GrBackendTexture backendTexture = externalTexture->getBackendTexture();
    const GrBackendFormat& format = backendTexture.getBackendFormat();
    const GrColorType colorType = SkColorTypeToGrColorType(info.colorType());
    if (!ctx->priv().caps()->areColorTypeAndFormatCompatible(colorType, format)) {
        return {};
    }

    auto cleanupCallback = skgpu::RefCntedCallback::Make(dispose_external_texture, externalTexture.release());
    sk_sp<GrSurfaceProxy> proxy = ctx->priv().proxyProvider()->wrapBackendTexture(
            backendTexture,
            kBorrow_GrWrapOwnership,
            GrWrapCacheable::kYes,
            kRead_GrIOType,
            std::move(cleanupCallback));
    if (!proxy) {
        return {};
    }
    static constexpr auto kOrigin = kTopLeft_GrSurfaceOrigin;
    skgpu::Swizzle swizzle = ctx->priv().caps()->getReadSwizzle(format, colorType);
    return GrSurfaceProxyView(std::move(proxy), kOrigin, swizzle);
}
