/*
 * 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/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);
}
