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

#include "src/image/SkImage_Gpu.h"

#include "include/core/SkCanvas.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/gpu/GrYUVABackendTextures.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkBitmapCache.h"
#include "src/core/SkImageInfoPriv.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkScopeExit.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/ganesh/GrAHardwareBufferImageGenerator.h"
#include "src/gpu/ganesh/GrAHardwareBufferUtils_impl.h"
#include "src/gpu/ganesh/GrBackendTextureImageGenerator.h"
#include "src/gpu/ganesh/GrBackendUtils.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrImageContextPriv.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSemaphore.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/GrTextureProxyPriv.h"
#include "src/gpu/ganesh/GrYUVATextureProxies.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"

#include <cstddef>
#include <cstring>
#include <type_traits>

inline SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy)
        : fStableProxy(std::move(stableProxy)) {
    SkASSERT(fStableProxy);
}

inline SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy,
                                               sk_sp<GrSurfaceProxy> volatileProxy,
                                               sk_sp<GrRenderTask> copyTask,
                                               int volatileProxyTargetCount)
        : fStableProxy(std::move(stableProxy))
        , fVolatileProxy(std::move(volatileProxy))
        , fVolatileToStableCopyTask(std::move(copyTask))
        , fVolatileProxyTargetCount(volatileProxyTargetCount) {
    SkASSERT(fStableProxy);
    SkASSERT(fVolatileProxy);
    SkASSERT(fVolatileToStableCopyTask);
}

inline SkImage_Gpu::ProxyChooser::~ProxyChooser() {
    // The image is being destroyed. If there is a stable copy proxy but we've been able to use
    // the volatile proxy for all requests then we can skip the copy.
    if (fVolatileToStableCopyTask) {
        fVolatileToStableCopyTask->makeSkippable();
    }
}

inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::chooseProxy(GrRecordingContext* context) {
    SkAutoSpinlock hold(fLock);
    if (fVolatileProxy) {
        SkASSERT(fVolatileProxyTargetCount <= fVolatileProxy->getTaskTargetCount());
        // If this image is used off the direct context it originated on, i.e. on a recording-only
        // context, we don't know how the recording context's actions are ordered WRT direct context
        // actions until the recording context's DAG is imported into the direct context.
        if (context->asDirectContext() &&
            fVolatileProxyTargetCount == fVolatileProxy->getTaskTargetCount()) {
            return fVolatileProxy;
        }
        fVolatileProxy.reset();
        fVolatileToStableCopyTask.reset();
        return fStableProxy;
    }
    return fStableProxy;
}

inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::switchToStableProxy() {
    SkAutoSpinlock hold(fLock);
    fVolatileProxy.reset();
    fVolatileToStableCopyTask.reset();
    return fStableProxy;
}

inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::makeVolatileProxyStable() {
    SkAutoSpinlock hold(fLock);
    if (fVolatileProxy) {
        fStableProxy = std::move(fVolatileProxy);
        fVolatileToStableCopyTask->makeSkippable();
        fVolatileToStableCopyTask.reset();
    }
    return fStableProxy;
}

inline bool SkImage_Gpu::ProxyChooser::surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const {
    SkAutoSpinlock hold(fLock);
    return surfaceProxy->underlyingUniqueID() == fStableProxy->underlyingUniqueID();
}

inline size_t SkImage_Gpu::ProxyChooser::gpuMemorySize() const {
    SkAutoSpinlock hold(fLock);
    size_t size = fStableProxy->gpuMemorySize();
    if (fVolatileProxy) {
        SkASSERT(fVolatileProxy->gpuMemorySize() == size);
    }
    return size;
}

inline GrMipmapped SkImage_Gpu::ProxyChooser::mipmapped() const {
    SkAutoSpinlock hold(fLock);
    GrMipmapped mipmapped = fStableProxy->asTextureProxy()->mipmapped();
    if (fVolatileProxy) {
        SkASSERT(fVolatileProxy->asTextureProxy()->mipmapped() == mipmapped);
    }
    return mipmapped;
}

#ifdef SK_DEBUG
inline GrBackendFormat SkImage_Gpu::ProxyChooser::backendFormat() {
    SkAutoSpinlock hold(fLock);
    if (fVolatileProxy) {
        SkASSERT(fVolatileProxy->backendFormat() == fStableProxy->backendFormat());
    }
    return fStableProxy->backendFormat();
}
#endif

//////////////////////////////////////////////////////////////////////////////

SkImage_Gpu::SkImage_Gpu(sk_sp<GrImageContext> context,
                         uint32_t uniqueID,
                         GrSurfaceProxyView view,
                         SkColorInfo info)
        : INHERITED(std::move(context),
                    SkImageInfo::Make(view.proxy()->backingStoreDimensions(), std::move(info)),
                    uniqueID)
        , fChooser(view.detachProxy())
        , fSwizzle(view.swizzle())
        , fOrigin(view.origin()) {
#ifdef SK_DEBUG
    const GrBackendFormat& format = fChooser.backendFormat();
    const GrCaps* caps = this->context()->priv().caps();
    GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
    SkASSERT(caps->isFormatCompressed(format) ||
             caps->areColorTypeAndFormatCompatible(grCT, format));
#endif
}

SkImage_Gpu::SkImage_Gpu(sk_sp<GrDirectContext> dContext,
                         GrSurfaceProxyView volatileSrc,
                         sk_sp<GrSurfaceProxy> stableCopy,
                         sk_sp<GrRenderTask> copyTask,
                         int volatileSrcTargetCount,
                         SkColorInfo info)
        : INHERITED(std::move(dContext),
                    SkImageInfo::Make(volatileSrc.proxy()->backingStoreDimensions(),
                                      std::move(info)),
                    kNeedNewImageUniqueID)
        , fChooser(std::move(stableCopy),
                   volatileSrc.detachProxy(),
                   std::move(copyTask),
                   volatileSrcTargetCount)
        , fSwizzle(volatileSrc.swizzle())
        , fOrigin(volatileSrc.origin()) {
#ifdef SK_DEBUG
    const GrBackendFormat& format = fChooser.backendFormat();
    const GrCaps* caps = this->context()->priv().caps();
    GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
    SkASSERT(caps->isFormatCompressed(format) ||
             caps->areColorTypeAndFormatCompatible(grCT, format));
#endif
}

sk_sp<SkImage> SkImage_Gpu::MakeWithVolatileSrc(sk_sp<GrRecordingContext> rContext,
                                                GrSurfaceProxyView volatileSrc,
                                                SkColorInfo colorInfo) {
    SkASSERT(rContext);
    SkASSERT(volatileSrc);
    SkASSERT(volatileSrc.proxy()->asTextureProxy());
    GrMipmapped mm = volatileSrc.proxy()->asTextureProxy()->mipmapped();
    sk_sp<GrRenderTask> copyTask;
    auto copy = GrSurfaceProxy::Copy(rContext.get(),
                                     volatileSrc.refProxy(),
                                     volatileSrc.origin(),
                                     mm,
                                     SkBackingFit::kExact,
                                     skgpu::Budgeted::kYes,
                                     /*label=*/"ImageGpu_MakeWithVolatileSrc",
                                     &copyTask);
    if (!copy) {
        return nullptr;
    }
    // We only attempt to make a dual-proxy image on a direct context. This optimziation requires
    // knowing how things are ordered and recording-only contexts are not well ordered WRT other
    // recording contexts.
    if (auto direct = sk_ref_sp(rContext->asDirectContext())) {
        int targetCount = volatileSrc.proxy()->getTaskTargetCount();
        return sk_sp<SkImage>(new SkImage_Gpu(std::move(direct),
                                              std::move(volatileSrc),
                                              std::move(copy),
                                              std::move(copyTask),
                                              targetCount,
                                              std::move(colorInfo)));
    }
    GrSurfaceProxyView copyView(std::move(copy), volatileSrc.origin(), volatileSrc.swizzle());
    return sk_make_sp<SkImage_Gpu>(std::move(rContext),
                                   kNeedNewImageUniqueID,
                                   std::move(copyView),
                                   std::move(colorInfo));
}

SkImage_Gpu::~SkImage_Gpu() = default;

bool SkImage_Gpu::surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const {
    return fChooser.surfaceMustCopyOnWrite(surfaceProxy);
}

bool SkImage_Gpu::onHasMipmaps() const { return fChooser.mipmapped() == GrMipmapped::kYes; }

GrSemaphoresSubmitted SkImage_Gpu::onFlush(GrDirectContext* dContext,
                                           const GrFlushInfo& info) const {
    if (!fContext->priv().matches(dContext) || dContext->abandoned()) {
        if (info.fSubmittedProc) {
            info.fSubmittedProc(info.fSubmittedContext, false);
        }
        if (info.fFinishedProc) {
            info.fFinishedProc(info.fFinishedContext);
        }
        return GrSemaphoresSubmitted::kNo;
    }

    sk_sp<GrSurfaceProxy> proxy = fChooser.chooseProxy(dContext);
    return dContext->priv().flushSurface(proxy.get(),
                                         SkSurface::BackendSurfaceAccess::kNoAccess,
                                         info);
}

GrBackendTexture SkImage_Gpu::onGetBackendTexture(bool flushPendingGrContextIO,
                                                  GrSurfaceOrigin* origin) const {
    auto direct = fContext->asDirectContext();
    if (!direct) {
        // This image was created with a DDL context and cannot be instantiated.
        return GrBackendTexture();  // invalid
    }
    if (direct->abandoned()) {
        return GrBackendTexture();  // invalid;
    }

    // We don't know how client's use of the texture will be ordered WRT Skia's. Ensure the
    // texture seen by the client won't be mutated by a SkSurface.
    sk_sp<GrSurfaceProxy> proxy = fChooser.switchToStableProxy();

    if (!proxy->isInstantiated()) {
        auto resourceProvider = direct->priv().resourceProvider();

        if (!proxy->instantiate(resourceProvider)) {
            return GrBackendTexture();  // invalid
        }
    }

    GrTexture* texture = proxy->peekTexture();
    if (texture) {
        if (flushPendingGrContextIO) {
            direct->priv().flushSurface(proxy.get());
        }
        if (origin) {
            *origin = fOrigin;
        }
        return texture->getBackendTexture();
    }
    return GrBackendTexture();  // invalid
}

size_t SkImage_Gpu::onTextureSize() const { return fChooser.gpuMemorySize(); }

sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(SkColorType targetCT,
                                                         sk_sp<SkColorSpace> targetCS,
                                                         GrDirectContext* dContext) const {
    SkColorInfo info(targetCT, this->alphaType(), std::move(targetCS));
    if (!fContext->priv().matches(dContext)) {
        return nullptr;
    }

    auto sfc = dContext->priv().makeSFCWithFallback(GrImageInfo(info, this->dimensions()),
                                                    SkBackingFit::kExact);
    if (!sfc) {
        return nullptr;
    }
    // We respecify info's CT because we called MakeWithFallback.
    auto ct = GrColorTypeToSkColorType(sfc->colorInfo().colorType());
    info = info.makeColorType(ct);

    // Draw this image's texture into the SFC.
    auto [view, _] = this->asView(dContext, GrMipmapped(this->hasMipmaps()));
    auto texFP = GrTextureEffect::Make(std::move(view), this->alphaType());
    auto colorFP = GrColorSpaceXformEffect::Make(std::move(texFP),
                                                 this->imageInfo().colorInfo(),
                                                 info);
    sfc->fillWithFP(std::move(colorFP));

    return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
                                   kNeedNewImageUniqueID,
                                   sfc->readSurfaceView(),
                                   std::move(info));
}

sk_sp<SkImage> SkImage_Gpu::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS) const {
    // It doesn't seem worth the complexity of trying to share the ProxyChooser among multiple
    // images. Just fall back to the stable copy.
    GrSurfaceProxyView view(fChooser.switchToStableProxy(), fOrigin, fSwizzle);
    return sk_make_sp<SkImage_Gpu>(fContext,
                                   kNeedNewImageUniqueID,
                                   std::move(view),
                                   this->imageInfo().colorInfo().makeColorSpace(std::move(newCS)));
}

void SkImage_Gpu::onAsyncRescaleAndReadPixels(const SkImageInfo& info,
                                              SkIRect srcRect,
                                              RescaleGamma rescaleGamma,
                                              RescaleMode rescaleMode,
                                              ReadPixelsCallback callback,
                                              ReadPixelsContext context) const {
    auto dContext = fContext->asDirectContext();
    if (!dContext) {
        // DDL TODO: buffer up the readback so it occurs when the DDL is drawn?
        callback(context, nullptr);
        return;
    }
    auto ctx = dContext->priv().makeSC(this->makeView(dContext), this->imageInfo().colorInfo());
    if (!ctx) {
        callback(context, nullptr);
        return;
    }
    ctx->asyncRescaleAndReadPixels(dContext, info, srcRect, rescaleGamma, rescaleMode,
                                   callback, context);
}

void SkImage_Gpu::onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
                                                    sk_sp<SkColorSpace> dstColorSpace,
                                                    SkIRect srcRect,
                                                    SkISize dstSize,
                                                    RescaleGamma rescaleGamma,
                                                    RescaleMode rescaleMode,
                                                    ReadPixelsCallback callback,
                                                    ReadPixelsContext context) const {
    auto dContext = fContext->asDirectContext();
    if (!dContext) {
        // DDL TODO: buffer up the readback so it occurs when the DDL is drawn?
        callback(context, nullptr);
        return;
    }
    auto ctx = dContext->priv().makeSC(this->makeView(dContext), this->imageInfo().colorInfo());
    if (!ctx) {
        callback(context, nullptr);
        return;
    }
    ctx->asyncRescaleAndReadPixelsYUV420(dContext,
                                         yuvColorSpace,
                                         std::move(dstColorSpace),
                                         srcRect,
                                         dstSize,
                                         rescaleGamma,
                                         rescaleMode,
                                         callback,
                                         context);
}

void SkImage_Gpu::generatingSurfaceIsDeleted() { fChooser.makeVolatileProxyStable(); }

///////////////////////////////////////////////////////////////////////////////////////////////////

static sk_sp<SkImage> new_wrapped_texture_common(GrRecordingContext* rContext,
                                                 const GrBackendTexture& backendTex,
                                                 GrColorType colorType,
                                                 GrSurfaceOrigin origin,
                                                 SkAlphaType at,
                                                 sk_sp<SkColorSpace> colorSpace,
                                                 GrWrapOwnership ownership,
                                                 sk_sp<skgpu::RefCntedCallback> releaseHelper) {
    if (!backendTex.isValid() || backendTex.width() <= 0 || backendTex.height() <= 0) {
        return nullptr;
    }

    GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
    sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
            backendTex, ownership, GrWrapCacheable::kNo, kRead_GrIOType, std::move(releaseHelper));
    if (!proxy) {
        return nullptr;
    }

    skgpu::Swizzle swizzle = rContext->priv().caps()->getReadSwizzle(proxy->backendFormat(),
                                                                     colorType);
    GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
    SkColorInfo info(GrColorTypeToSkColorType(colorType), at, std::move(colorSpace));
    return sk_make_sp<SkImage_Gpu>(sk_ref_sp(rContext),
                                   kNeedNewImageUniqueID,
                                   std::move(view),
                                   std::move(info));
}

sk_sp<SkImage> SkImage::MakeFromCompressedTexture(GrRecordingContext* rContext,
                                                  const GrBackendTexture& tex,
                                                  GrSurfaceOrigin origin,
                                                  SkAlphaType at,
                                                  sk_sp<SkColorSpace> cs,
                                                  TextureReleaseProc releaseP,
                                                  ReleaseContext releaseC) {
    auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);

    if (!rContext) {
        return nullptr;
    }

    const GrCaps* caps = rContext->priv().caps();

    if (!SkImage_GpuBase::ValidateCompressedBackendTexture(caps, tex, at)) {
        return nullptr;
    }

    GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
    sk_sp<GrTextureProxy> proxy = proxyProvider->wrapCompressedBackendTexture(
            tex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, std::move(releaseHelper));
    if (!proxy) {
        return nullptr;
    }

    CompressionType type = GrBackendFormatToCompressionType(tex.getBackendFormat());
    SkColorType ct = GrCompressionTypeToSkColorType(type);

    GrSurfaceProxyView view(std::move(proxy), origin, skgpu::Swizzle::RGBA());
    return sk_make_sp<SkImage_Gpu>(sk_ref_sp(rContext),
                                   kNeedNewImageUniqueID,
                                   std::move(view),
                                   SkColorInfo(ct, at, std::move(cs)));
}

sk_sp<SkImage> SkImage::MakeFromTexture(GrRecordingContext* rContext,
                                        const GrBackendTexture& tex, GrSurfaceOrigin origin,
                                        SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
                                        TextureReleaseProc releaseP, ReleaseContext releaseC) {
    auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);

    if (!rContext) {
        return nullptr;
    }

    const GrCaps* caps = rContext->priv().caps();

    GrColorType grColorType = SkColorTypeToGrColorType(ct);
    if (GrColorType::kUnknown == grColorType) {
        return nullptr;
    }

    if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
        return nullptr;
    }

    return new_wrapped_texture_common(rContext, tex, grColorType, origin, at, std::move(cs),
                                      kBorrow_GrWrapOwnership, std::move(releaseHelper));
}

sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrRecordingContext* context,
                                               const GrBackendTexture& backendTexture,
                                               GrSurfaceOrigin textureOrigin,
                                               SkColorType colorType) {
    return SkImage::MakeFromAdoptedTexture(context, backendTexture, textureOrigin,
                                           colorType, kPremul_SkAlphaType, nullptr);
}
sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrRecordingContext* context,
                                               const GrBackendTexture& backendTexture,
                                               GrSurfaceOrigin textureOrigin,
                                               SkColorType colorType,
                                               SkAlphaType alphaType) {
    return SkImage::MakeFromAdoptedTexture(context, backendTexture, textureOrigin,
                                           colorType, alphaType, nullptr);
}

sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrRecordingContext* rContext,
                                               const GrBackendTexture& tex, GrSurfaceOrigin origin,
                                               SkColorType ct, SkAlphaType at,
                                               sk_sp<SkColorSpace> cs) {
    auto dContext = GrAsDirectContext(rContext);
    if (!dContext) {
        // We have a DDL context and we don't support adopted textures for them.
        return nullptr;
    }

    const GrCaps* caps = dContext->priv().caps();

    GrColorType grColorType = SkColorTypeToGrColorType(ct);
    if (GrColorType::kUnknown == grColorType) {
        return nullptr;
    }

    if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
        return nullptr;
    }

    return new_wrapped_texture_common(dContext, tex, grColorType, origin, at, std::move(cs),
                                      kAdopt_GrWrapOwnership, nullptr);
}

sk_sp<SkImage> SkImage::MakeTextureFromCompressed(GrDirectContext* direct, sk_sp<SkData> data,
                                                  int width, int height, CompressionType type,
                                                  GrMipmapped mipmapped,
                                                  GrProtected isProtected) {
    if (!direct || !data) {
        return nullptr;
    }

    GrBackendFormat beFormat = direct->compressedBackendFormat(type);
    if (!beFormat.isValid()) {
        sk_sp<SkImage> tmp = MakeRasterFromCompressed(std::move(data), width, height, type);
        if (!tmp) {
            return nullptr;
        }
        return tmp->makeTextureImage(direct, mipmapped);
    }

    GrProxyProvider* proxyProvider = direct->priv().proxyProvider();
    sk_sp<GrTextureProxy> proxy = proxyProvider->createCompressedTextureProxy(
            {width, height}, skgpu::Budgeted::kYes, mipmapped, isProtected, type, std::move(data));
    if (!proxy) {
        return nullptr;
    }
    GrSurfaceProxyView view(std::move(proxy));

    SkColorType colorType = GrCompressionTypeToSkColorType(type);

    return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct),
                                   kNeedNewImageUniqueID,
                                   std::move(view),
                                   SkColorInfo(colorType, kOpaque_SkAlphaType, nullptr));
}

sk_sp<SkImage> SkImage::makeTextureImage(GrDirectContext* dContext,
                                         GrMipmapped mipmapped,
                                         skgpu::Budgeted budgeted) const {
    if (!dContext) {
        return nullptr;
    }
    if (!dContext->priv().caps()->mipmapSupport() || this->dimensions().area() <= 1) {
        mipmapped = GrMipmapped::kNo;
    }

    if (as_IB(this)->isGaneshBacked()) {
        if (!as_IB(this)->context()->priv().matches(dContext)) {
            return nullptr;
        }

        if (mipmapped == GrMipmapped::kNo || this->hasMipmaps()) {
            return sk_ref_sp(const_cast<SkImage*>(this));
        }
    }
    GrImageTexGenPolicy policy = budgeted == skgpu::Budgeted::kYes
                                         ? GrImageTexGenPolicy::kNew_Uncached_Budgeted
                                         : GrImageTexGenPolicy::kNew_Uncached_Unbudgeted;
    // TODO: Don't flatten YUVA images here. Add mips to the planes instead.
    auto [view, ct] = as_IB(this)->asView(dContext, mipmapped, policy);
    if (!view) {
        return nullptr;
    }
    SkASSERT(view.asTextureProxy());
    SkASSERT(mipmapped == GrMipmapped::kNo ||
             view.asTextureProxy()->mipmapped() == GrMipmapped::kYes);
    SkColorInfo colorInfo(GrColorTypeToSkColorType(ct), this->alphaType(), this->refColorSpace());
    return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
                                   this->uniqueID(),
                                   std::move(view),
                                   std::move(colorInfo));
}

///////////////////////////////////////////////////////////////////////////////////////////////////

sk_sp<SkImage> SkImage::MakePromiseTexture(sk_sp<GrContextThreadSafeProxy> threadSafeProxy,
                                           const GrBackendFormat& backendFormat,
                                           SkISize dimensions,
                                           GrMipmapped mipmapped,
                                           GrSurfaceOrigin origin,
                                           SkColorType colorType,
                                           SkAlphaType alphaType,
                                           sk_sp<SkColorSpace> colorSpace,
                                           PromiseImageTextureFulfillProc textureFulfillProc,
                                           PromiseImageTextureReleaseProc textureReleaseProc,
                                           PromiseImageTextureContext textureContext) {
    // Our contract is that we will always call the release proc even on failure.
    // We use the helper to convey the context, so we need to ensure make doesn't fail.
    textureReleaseProc = textureReleaseProc ? textureReleaseProc : [](void*) {};
    auto releaseHelper = skgpu::RefCntedCallback::Make(textureReleaseProc, textureContext);
    SkImageInfo info = SkImageInfo::Make(dimensions, colorType, alphaType, colorSpace);
    if (!SkImageInfoIsValid(info)) {
        return nullptr;
    }

    if (!threadSafeProxy) {
        return nullptr;
    }

    if (dimensions.isEmpty()) {
        return nullptr;
    }

    GrColorType grColorType = SkColorTypeToGrColorType(colorType);
    if (GrColorType::kUnknown == grColorType) {
        return nullptr;
    }

    if (!threadSafeProxy->priv().caps()->areColorTypeAndFormatCompatible(grColorType,
                                                                         backendFormat)) {
        return nullptr;
    }

    auto proxy = SkImage_GpuBase::MakePromiseImageLazyProxy(threadSafeProxy.get(),
                                                            dimensions,
                                                            backendFormat,
                                                            mipmapped,
                                                            textureFulfillProc,
                                                            std::move(releaseHelper));
    if (!proxy) {
        return nullptr;
    }
    skgpu::Swizzle swizzle = threadSafeProxy->priv().caps()->getReadSwizzle(backendFormat,
                                                                            grColorType);
    GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
    sk_sp<GrImageContext> ctx(GrImageContextPriv::MakeForPromiseImage(std::move(threadSafeProxy)));
    return sk_make_sp<SkImage_Gpu>(std::move(ctx),
                                   kNeedNewImageUniqueID,
                                   std::move(view),
                                   SkColorInfo(colorType, alphaType, std::move(colorSpace)));
}

///////////////////////////////////////////////////////////////////////////////////////////////////

sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrDirectContext* dContext,
                                                   const SkPixmap& originalPixmap, bool buildMips,
                                                   bool limitToMaxTextureSize) {
    // Some backends or drivers don't support (safely) moving resources between contexts
    if (!dContext || !dContext->priv().caps()->crossContextTextureSupport()) {
        return SkImage::MakeRasterCopy(originalPixmap);
    }

    // If non-power-of-two mipmapping isn't supported, ignore the client's request
    if (!dContext->priv().caps()->mipmapSupport()) {
        buildMips = false;
    }

    const SkPixmap* pixmap = &originalPixmap;
    SkAutoPixmapStorage resized;
    int maxTextureSize = dContext->priv().caps()->maxTextureSize();
    int maxDim = std::max(originalPixmap.width(), originalPixmap.height());
    if (limitToMaxTextureSize && maxDim > maxTextureSize) {
        float scale = static_cast<float>(maxTextureSize) / maxDim;
        int newWidth = std::min(static_cast<int>(originalPixmap.width() * scale), maxTextureSize);
        int newHeight = std::min(static_cast<int>(originalPixmap.height() * scale), maxTextureSize);
        SkImageInfo info = originalPixmap.info().makeWH(newWidth, newHeight);
        SkSamplingOptions sampling(SkFilterMode::kLinear);
        if (!resized.tryAlloc(info) || !originalPixmap.scalePixels(resized, sampling)) {
            return nullptr;
        }
        pixmap = &resized;
    }
    // Turn the pixmap into a GrTextureProxy
    SkBitmap bmp;
    bmp.installPixels(*pixmap);
    GrMipmapped mipmapped = buildMips ? GrMipmapped::kYes : GrMipmapped::kNo;
    auto [view, ct] = GrMakeUncachedBitmapProxyView(dContext, bmp, mipmapped);
    if (!view) {
        return SkImage::MakeRasterCopy(*pixmap);
    }

    sk_sp<GrTexture> texture = sk_ref_sp(view.proxy()->peekTexture());

    // Flush any writes or uploads
    dContext->priv().flushSurface(view.proxy());
    GrGpu* gpu = dContext->priv().getGpu();

    std::unique_ptr<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());

    SkColorType skCT = GrColorTypeToSkColorType(ct);
    auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), view.origin(),
                                                    std::move(sema), skCT,
                                                    pixmap->alphaType(),
                                                    pixmap->info().refColorSpace());
    return SkImage::MakeFromGenerator(std::move(gen));
}

#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, SkAlphaType at,
                                                sk_sp<SkColorSpace> cs,
                                                GrSurfaceOrigin surfaceOrigin) {
    auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin);
    return SkImage::MakeFromGenerator(std::move(gen));
}

sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrDirectContext* dContext,
                                                        const SkPixmap& pixmap,
                                                        AHardwareBuffer* hardwareBuffer,
                                                        GrSurfaceOrigin surfaceOrigin) {
    AHardwareBuffer_Desc bufferDesc;
    AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);

    if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) {
        return nullptr;
    }


    GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(dContext,
                                                                             hardwareBuffer,
                                                                             bufferDesc.format,
                                                                             true);

    if (!backendFormat.isValid()) {
        return nullptr;
    }

    GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
    GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr;
    GrAHardwareBufferUtils::TexImageCtx deleteImageCtx = nullptr;

    const bool isRenderable = SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER);

    GrBackendTexture backendTexture =
            GrAHardwareBufferUtils::MakeBackendTexture(dContext, hardwareBuffer,
                                                       bufferDesc.width, bufferDesc.height,
                                                       &deleteImageProc, &updateImageProc,
                                                       &deleteImageCtx, false, backendFormat,
                                                       isRenderable);
    if (!backendTexture.isValid()) {
        return nullptr;
    }
    SkASSERT(deleteImageProc);

    auto releaseHelper = skgpu::RefCntedCallback::Make(deleteImageProc, deleteImageCtx);

    SkColorType colorType =
            GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);

    GrColorType grColorType = SkColorTypeToGrColorType(colorType);

    GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
    if (!proxyProvider) {
        return nullptr;
    }

    sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
            backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType,
            std::move(releaseHelper));
    if (!proxy) {
        return nullptr;
    }

    skgpu::Swizzle swizzle = dContext->priv().caps()->getReadSwizzle(backendFormat, grColorType);
    GrSurfaceProxyView framebufferView(std::move(proxy), surfaceOrigin, swizzle);
    SkColorInfo colorInfo = pixmap.info().colorInfo().makeColorType(colorType);
    sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext),
                                                   kNeedNewImageUniqueID,
                                                   framebufferView,
                                                   std::move(colorInfo));
    if (!image) {
        return nullptr;
    }

    GrDrawingManager* drawingManager = dContext->priv().drawingManager();
    if (!drawingManager) {
        return nullptr;
    }

    skgpu::v1::SurfaceContext surfaceContext(
            dContext, std::move(framebufferView),image->imageInfo().colorInfo());

    surfaceContext.writePixels(dContext, pixmap, {0, 0});

    GrSurfaceProxy* p[1] = {surfaceContext.asSurfaceProxy()};
    drawingManager->flush(p, SkSurface::BackendSurfaceAccess::kNoAccess, {}, nullptr);

    return image;
}
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////

bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct,
                                            sk_sp<SkImage> image,
                                            GrBackendTexture* backendTexture,
                                            BackendTextureReleaseProc* releaseProc) {
    if (!image || !backendTexture || !releaseProc) {
        return false;
    }

    auto [view, ct] = as_IB(image)->asView(direct, GrMipmapped::kNo);

    if (!view) {
        return false;
    }

    // Flush any pending IO on the texture.
    direct->priv().flushSurface(view.proxy());

    GrTexture* texture = view.asTextureProxy()->peekTexture();
    if (!texture) {
        return false;
    }
    // We must make a copy of the image if the image is not unique, if the GrTexture owned by the
    // image is not unique, or if the texture wraps an external object.
    if (!image->unique() || !texture->unique() ||
        texture->resourcePriv().refsWrappedObjects()) {
        // onMakeSubset will always copy the image.
        image = as_IB(image)->onMakeSubset(image->bounds(), direct);
        if (!image) {
            return false;
        }
        return MakeBackendTextureFromSkImage(direct, std::move(image), backendTexture, releaseProc);
    }

    SkASSERT(!texture->resourcePriv().refsWrappedObjects());
    SkASSERT(texture->unique());
    SkASSERT(image->unique());

    // Take a reference to the GrTexture and release the image.
    sk_sp<GrTexture> textureRef = sk_ref_sp(texture);
    view.reset();
    image = nullptr;
    SkASSERT(textureRef->unique());

    // Steal the backend texture from the GrTexture, releasing the GrTexture in the process.
    return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
}

std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Gpu::onAsView(
        GrRecordingContext* recordingContext,
        GrMipmapped mipmapped,
        GrImageTexGenPolicy policy) const {
    if (!fContext->priv().matches(recordingContext)) {
        return {};
    }
    if (policy != GrImageTexGenPolicy::kDraw) {
        return {CopyView(recordingContext,
                         this->makeView(recordingContext),
                         mipmapped,
                         policy,
                         /*label=*/"SkImageGpu_AsView"),
                SkColorTypeToGrColorType(this->colorType())};
    }
    GrSurfaceProxyView view = this->makeView(recordingContext);
    GrColorType ct = SkColorTypeToGrColorType(this->colorType());
    if (mipmapped == GrMipmapped::kYes) {
        view = FindOrMakeCachedMipmappedView(recordingContext, std::move(view), this->uniqueID());
    }
    return {std::move(view), ct};
}

std::unique_ptr<GrFragmentProcessor> SkImage_Gpu::onAsFragmentProcessor(
        GrRecordingContext* rContext,
        SkSamplingOptions sampling,
        const SkTileMode tileModes[2],
        const SkMatrix& m,
        const SkRect* subset,
        const SkRect* domain) const {
    if (!fContext->priv().matches(rContext)) {
        return {};
    }
    auto mm = sampling.mipmap == SkMipmapMode::kNone ? GrMipmapped::kNo : GrMipmapped::kYes;
    return MakeFragmentProcessorFromView(rContext,
                                         std::get<0>(this->asView(rContext, mm)),
                                         this->alphaType(),
                                         sampling,
                                         tileModes,
                                         m,
                                         subset,
                                         domain);
}

GrSurfaceProxyView SkImage_Gpu::makeView(GrRecordingContext* rContext) const {
    return {fChooser.chooseProxy(rContext), fOrigin, fSwizzle};
}
