/*
 * 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 "src/gpu/ganesh/image/GrImageUtils.h"

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrContextOptions.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkIDChangeListener.h"
#include "include/private/SkMutex.h"
#include "include/private/gpu/ganesh/GrImageContext.h"
#include "include/private/gpu/ganesh/GrTextureGenerator.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkBlurEngine.h"
#include "src/core/SkCachedData.h"
#include "src/core/SkImageFilterCache.h"
#include "src/core/SkImageFilterTypes.h"
#include "src/core/SkSamplingPriv.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/Device.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/GrThreadSafeCache.h"
#include "src/gpu/ganesh/GrYUVATextureProxies.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/effects/GrBicubicEffect.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "src/gpu/ganesh/effects/GrYUVtoRGBEffect.h"
#include "src/gpu/ganesh/image/GrMippedBitmap.h"
#include "src/gpu/ganesh/image/SkImage_Ganesh.h"
#include "src/gpu/ganesh/image/SkImage_GaneshBase.h"
#include "src/gpu/ganesh/image/SkImage_RasterPinnable.h"
#include "src/gpu/ganesh/image/SkSpecialImage_Ganesh.h"
#include "src/image/SkImage_Base.h"
#include "src/image/SkImage_Lazy.h"
#include "src/image/SkImage_Picture.h"
#include "src/image/SkImage_Raster.h"

#include <string_view>
#include <utility>

class SkDevice;
class SkMatrix;
class SkSurfaceProps;
enum SkColorType : int;

class SkSpecialImage;

namespace skgpu::ganesh {

GrSurfaceProxyView CopyView(GrRecordingContext* context,
                            GrSurfaceProxyView src,
                            skgpu::Mipmapped mipmapped,
                            GrImageTexGenPolicy policy,
                            std::string_view label) {
    skgpu::Budgeted budgeted = policy == GrImageTexGenPolicy::kNew_Uncached_Budgeted
                                       ? skgpu::Budgeted::kYes
                                       : skgpu::Budgeted::kNo;
    return GrSurfaceProxyView::Copy(context,
                                    std::move(src),
                                    mipmapped,
                                    SkBackingFit::kExact,
                                    budgeted,
                                    /*label=*/label);
}

std::tuple<GrSurfaceProxyView, GrColorType> RasterAsView(GrRecordingContext* rContext,
                                                         const SkImage_Raster* raster,
                                                         skgpu::Mipmapped mipmapped,
                                                         GrImageTexGenPolicy policy) {
    if (policy == GrImageTexGenPolicy::kDraw) {
        // If the draw doesn't require mipmaps but this SkImage has them go ahead and make a
        // mipmapped texture. There are three reasons for this:
        // 1) Avoiding another texture creation if a later draw requires mipmaps.
        // 2) Ensuring we upload the bitmap's levels instead of generating on the GPU from the base.
        if (raster->hasMipmaps()) {
            mipmapped = skgpu::Mipmapped::kYes;
        }
        return GrMakeCachedBitmapProxyView(rContext,
                                           GrMippedBitmap(raster->bitmap(), raster->refMips()),
                                           /*label=*/"TextureForImageRasterWithPolicyEqualKDraw",
                                           mipmapped);
    }
    auto budgeted = (policy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted)
                            ? skgpu::Budgeted::kNo
                            : skgpu::Budgeted::kYes;
    return GrMakeUncachedBitmapProxyView(rContext,
                                         GrMippedBitmap(raster->bitmap(), raster->refMips()),
                                         mipmapped,
                                         SkBackingFit::kExact,
                                         budgeted);
}

// Returns the GrColorType to use with the GrTextureProxy returned from lockTextureProxy. This
// may be different from the color type on the image in the case where we need up upload CPU
// data to a texture but the GPU doesn't support the format of CPU data. In this case we convert
// the data to RGBA_8888 unorm on the CPU then upload that.
GrColorType ColorTypeOfLockTextureProxy(const GrCaps* caps, SkColorType sct) {
    GrColorType ct = SkColorTypeToGrColorType(sct);
    GrBackendFormat format = caps->getDefaultBackendFormat(ct, GrRenderable::kNo);
    if (!format.isValid()) {
        ct = GrColorType::kRGBA_8888;
    }
    return ct;
}

static GrSurfaceOrigin get_origin(const SkImage_Lazy* img) {
    SkASSERT(img->generator());
    if (!img->generator()->isTextureGenerator()) {
        return kTopLeft_GrSurfaceOrigin;
    }
    // origin should be thread safe
    return static_cast<const GrTextureGenerator*>(img->generator()->fGenerator.get())->origin();
}


static GrSurfaceProxyView texture_proxy_view_from_planes(GrRecordingContext* ctx,
                                                         const SkImage_Lazy* img,
                                                         skgpu::Budgeted budgeted) {
    auto supportedDataTypes = SupportedTextureFormats(*ctx);
    SkYUVAPixmaps yuvaPixmaps;
    sk_sp<SkCachedData> dataStorage = img->getPlanes(supportedDataTypes, &yuvaPixmaps);
    if (!dataStorage) {
        return {};
    }

    GrSurfaceProxyView views[SkYUVAInfo::kMaxPlanes];
    GrColorType pixmapColorTypes[SkYUVAInfo::kMaxPlanes];
    for (int i = 0; i < yuvaPixmaps.numPlanes(); ++i) {
        // If the sizes of the components are not all the same we choose to create exact-match
        // textures for the smaller ones rather than add a texture domain to the draw.
        // TODO: revisit this decision to improve texture reuse?
        SkBackingFit fit = yuvaPixmaps.plane(i).dimensions() == img->dimensions()
                                   ? SkBackingFit::kApprox
                                   : SkBackingFit::kExact;

        // We grab a ref to cached yuv data. When the SkBitmap we create below goes away it will
        // call releaseProc which will release this ref.
        // DDL TODO: Currently we end up creating a lazy proxy that will hold onto a ref to the
        // SkImage in its lambda. This means that we'll keep the ref on the YUV data around for the
        // life time of the proxy and not just upload. For non-DDL draws we should look into
        // releasing this SkImage after uploads (by deleting the lambda after instantiation).
        auto releaseProc = [](void*, void* data) {
            auto cachedData = static_cast<SkCachedData*>(data);
            SkASSERT(cachedData);
            cachedData->unref();
        };
        std::optional<GrMippedBitmap> bitmap =
                GrMippedBitmap::Make(yuvaPixmaps.plane(i).info(),
                                     yuvaPixmaps.plane(i).writable_addr(),
                                     yuvaPixmaps.plane(i).rowBytes(),
                                     releaseProc,
                                     SkRef(dataStorage.get()));
        if (!bitmap) {
            return {};
        }
        pixmapColorTypes[i] = SkColorTypeToGrColorType(bitmap->colorType());
        std::tie(views[i], std::ignore) =
                GrMakeUncachedBitmapProxyView(ctx, bitmap.value(), skgpu::Mipmapped::kNo, fit);
        if (!views[i]) {
            return {};
        }
    }

    // TODO: investigate preallocating mip maps here
    GrImageInfo info(SkColorTypeToGrColorType(img->colorType()),
                     kPremul_SkAlphaType,
                     /*color space*/ nullptr,
                     img->dimensions());

    auto sfc = ctx->priv().makeSFC(info,
                                   "ImageLazy_TextureProxyViewFromPlanes",
                                   SkBackingFit::kExact,
                                   1,
                                   skgpu::Mipmapped::kNo,
                                   GrProtected::kNo,
                                   kTopLeft_GrSurfaceOrigin,
                                   budgeted);
    if (!sfc) {
        return {};
    }

    GrYUVATextureProxies yuvaProxies(yuvaPixmaps.yuvaInfo(), views, pixmapColorTypes);
    SkAssertResult(yuvaProxies.isValid());

    std::unique_ptr<GrFragmentProcessor> fp = GrYUVtoRGBEffect::Make(
            yuvaProxies,
            GrSamplerState::Filter::kNearest,
            *ctx->priv().caps());

    // The pixels after yuv->rgb will be in the generator's color space.
    // If onMakeColorTypeAndColorSpace has been called then this will not match this image's
    // color space. To correct this, apply a color space conversion from the generator's color
    // space to this image's color space.
    SkColorSpace* srcColorSpace = img->generator()->getInfo().colorSpace();
    SkColorSpace* dstColorSpace = img->colorSpace();

    // If the caller expects the pixels in a different color space than the one from the image,
    // apply a color conversion to do this.
    fp = GrColorSpaceXformEffect::Make(std::move(fp),
                                       srcColorSpace, kOpaque_SkAlphaType,
                                       dstColorSpace, kOpaque_SkAlphaType);
    sfc->fillWithFP(std::move(fp));

    return sfc->readSurfaceView();
}

static GrSurfaceProxyView generate_picture_texture(GrRecordingContext* ctx,
                                                   const SkImage_Picture* img,
                                                   skgpu::Mipmapped mipmapped,
                                                   GrImageTexGenPolicy texGenPolicy) {
    SkASSERT(ctx);
    SkASSERT(img);

    skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
                                       ? skgpu::Budgeted::kNo
                                       : skgpu::Budgeted::kYes;
    auto surface = SkSurfaces::RenderTarget(ctx,
                                            budgeted,
                                            img->imageInfo(),
                                            0,
                                            kTopLeft_GrSurfaceOrigin,
                                            img->props(),
                                            mipmapped == skgpu::Mipmapped::kYes);
    if (!surface) {
        return {};
    }

    img->replay(surface->getCanvas());

    sk_sp<SkImage> image(surface->makeImageSnapshot());
    if (!image) {
        return {};
    }

    // The surface the image was created from is only local to this function so there will not be a
    // need for a copy when getting the view of the image for a future draw.
    auto [view, ct] = AsView(ctx, image, mipmapped, /*targetSurface=*/nullptr);
    SkASSERT(view);
    SkASSERT(mipmapped == skgpu::Mipmapped::kNo ||
             view.asTextureProxy()->mipmapped() == skgpu::Mipmapped::kYes);
    return view;
}

// Returns the texture proxy. We will always cache the generated texture on success.
// We have 4 ways to try to return a texture (in sorted order)
//
// 1. Check the cache for a pre-existing one
// 2. Ask the generator to natively create one
// 3. Ask the generator to return YUV planes, which the GPU can convert
// 4. Ask the generator to return RGB(A) data, which the GPU can convert
GrSurfaceProxyView LockTextureProxyView(GrRecordingContext* rContext,
                                        const SkImage_Lazy* img,
                                        GrImageTexGenPolicy texGenPolicy,
                                        skgpu::Mipmapped mipmapped) {
    skgpu::UniqueKey key;
    if (texGenPolicy == GrImageTexGenPolicy::kDraw) {
        GrMakeKeyFromImageID(&key, img->uniqueID(), SkIRect::MakeSize(img->dimensions()));
    }

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

    auto installKey = [&](const GrSurfaceProxyView& view) {
        SkASSERT(view && view.asTextureProxy());
        if (key.isValid()) {
            auto listener = GrMakeUniqueKeyInvalidationListener(&key, rContext->priv().contextID());
            img->addUniqueIDListener(std::move(listener));
            proxyProvider->assignUniqueKeyToProxy(key, view.asTextureProxy());
        }
    };

    auto ct = ColorTypeOfLockTextureProxy(caps, img->colorType());

    // 1. Check the cache for a pre-existing one.
    if (key.isValid()) {
        auto proxy = proxyProvider->findOrCreateProxyByUniqueKey(key);
        if (proxy) {
            skgpu::Swizzle swizzle = caps->getReadSwizzle(proxy->backendFormat(), ct);
            GrSurfaceOrigin origin = get_origin(img);
            GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
            if (mipmapped == skgpu::Mipmapped::kNo ||
                view.asTextureProxy()->mipmapped() == skgpu::Mipmapped::kYes) {
                return view;
            } else {
                // We need a mipped proxy, but we found a cached proxy that wasn't mipped. Thus we
                // generate a new mipped surface and copy the original proxy into the base layer. We
                // will then let the gpu generate the rest of the mips.
                auto mippedView = GrCopyBaseMipMapToView(rContext, view);
                if (!mippedView) {
                    // We failed to make a mipped proxy with the base copied into it. This could
                    // have been from failure to make the proxy or failure to do the copy. Thus we
                    // will fall back to just using the non mipped proxy; See skbug.com/40038328.
                    return view;
                }
                proxyProvider->removeUniqueKeyFromProxy(view.asTextureProxy());
                installKey(mippedView);
                return mippedView;
            }
        }
    }

    // 2. Ask the generator to natively create one (if it knows how)
    {
        if (img->type() == SkImage_Base::Type::kLazyPicture) {
            if (auto view = generate_picture_texture(rContext,
                                                     static_cast<const SkImage_Picture*>(img),
                                                     mipmapped,
                                                     texGenPolicy)) {
                installKey(view);
                return view;
            }
            // The fallback for this would be to generate a bitmap, but some picture-backed
            // images can only be played back on the GPU.
            return {};
        } else if (img->generator()->isTextureGenerator()) {
            auto sharedGenerator = img->generator();
            SkAutoMutexExclusive mutex(sharedGenerator->fMutex);
            auto textureGen = static_cast<GrTextureGenerator*>(sharedGenerator->fGenerator.get());
            if (auto view = textureGen->generateTexture(rContext,
                                                        img->imageInfo(),
                                                        mipmapped,
                                                        texGenPolicy)) {
                installKey(view);
                return view;
            }
        }
    }

    // 3. Ask the generator to return YUV planes, which the GPU can convert. If we will be mipping
    //    the texture we skip this step so the CPU generate non-planar MIP maps for us.
    if (mipmapped == skgpu::Mipmapped::kNo &&
        !rContext->priv().options().fDisableGpuYUVConversion) {
        // TODO: Update to create the mipped surface in the textureProxyViewFromPlanes generator and
        //  draw the base layer directly into the mipped surface.
        skgpu::Budgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
                                           ? skgpu::Budgeted::kNo
                                           : skgpu::Budgeted::kYes;
        auto view = texture_proxy_view_from_planes(rContext, img, budgeted);
        if (view) {
            installKey(view);
            return view;
        }
    }

    // 4. Ask the generator to return a bitmap, which the GPU can convert.
    auto hint = texGenPolicy == GrImageTexGenPolicy::kDraw ? SkImage::CachingHint::kAllow_CachingHint
                                                           : SkImage::CachingHint::kDisallow_CachingHint;
    if (SkBitmap bitmap; img->getROPixels(nullptr, &bitmap, hint)) {
        // We always make an uncached bitmap here because we will cache it based on passed in policy
        // with *our* key, not a key derived from bitmap. We're just making the proxy here.
        auto budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
                                ? skgpu::Budgeted::kNo
                                : skgpu::Budgeted::kYes;

        auto view = std::get<0>(
                GrMakeUncachedBitmapProxyView(rContext,
                                              GrMippedBitmap(bitmap, as_IB(img)->refMips()),
                                              mipmapped,
                                              SkBackingFit::kExact,
                                              budgeted));
        if (view) {
            installKey(view);
            return view;
        }
    }

    return {};
}

static std::tuple<GrSurfaceProxyView, GrColorType> lazy_as_view(GrRecordingContext* context,
                                                                const SkImage_Lazy* img,
                                                                skgpu::Mipmapped mipmapped,
                                                                GrImageTexGenPolicy policy) {
    GrColorType ct = ColorTypeOfLockTextureProxy(context->priv().caps(), img->colorType());
    return {LockTextureProxyView(context, img, policy, mipmapped), ct};
}

std::tuple<GrSurfaceProxyView, GrColorType> AsView(GrRecordingContext* rContext,
                                                   const SkImage* img,
                                                   skgpu::Mipmapped mipmapped,
                                                   GrRenderTargetProxy* targetSurface,
                                                   GrImageTexGenPolicy policy) {
    SkASSERT(img);
    if (!rContext) {
        return {};
    }
    if (!rContext->priv().caps()->mipmapSupport() || img->dimensions().area() <= 1) {
        mipmapped = skgpu::Mipmapped::kNo;
    }

    auto ib = static_cast<const SkImage_Base*>(img);
    if (ib->type() == SkImage_Base::Type::kRaster) {
        return skgpu::ganesh::RasterAsView(
                    rContext, static_cast<const SkImage_Raster*>(ib), mipmapped, policy);
    } else if (ib->type() == SkImage_Base::Type::kRasterPinnable) {
        auto rp = static_cast<const SkImage_RasterPinnable*>(img);
        return rp->asView(rContext, mipmapped, policy);
    } else if (ib->isGaneshBacked()) {
        auto gb = static_cast<const SkImage_GaneshBase*>(img);
        return gb->asView(rContext, mipmapped, policy, targetSurface);
    } else if (ib->isLazyGenerated()) {
        return lazy_as_view(rContext, static_cast<const SkImage_Lazy*>(ib), mipmapped, policy);
    }

    SkDEBUGFAIL("Unsupported image type to make a View");
    return {};
}

static std::unique_ptr<GrFragmentProcessor> make_fp_from_view(GrRecordingContext* rContext,
                                                              GrSurfaceProxyView view,
                                                              SkAlphaType at,
                                                              SkSamplingOptions sampling,
                                                              const SkTileMode tileModes[2],
                                                              const SkMatrix& m,
                                                              const SkRect* subset,
                                                              const SkRect* domain) {
    if (!view) {
        return nullptr;
    }
    const GrCaps& caps = *rContext->priv().caps();
    auto wmx = SkTileModeToWrapMode(tileModes[0]);
    auto wmy = SkTileModeToWrapMode(tileModes[1]);
    if (sampling.useCubic) {
        if (subset) {
            if (domain) {
                return GrBicubicEffect::MakeSubset(std::move(view),
                                                   at,
                                                   m,
                                                   wmx,
                                                   wmy,
                                                   *subset,
                                                   *domain,
                                                   sampling.cubic,
                                                   GrBicubicEffect::Direction::kXY,
                                                   *rContext->priv().caps());
            }
            return GrBicubicEffect::MakeSubset(std::move(view),
                                               at,
                                               m,
                                               wmx,
                                               wmy,
                                               *subset,
                                               sampling.cubic,
                                               GrBicubicEffect::Direction::kXY,
                                               *rContext->priv().caps());
        }
        return GrBicubicEffect::Make(std::move(view),
                                     at,
                                     m,
                                     wmx,
                                     wmy,
                                     sampling.cubic,
                                     GrBicubicEffect::Direction::kXY,
                                     *rContext->priv().caps());
    }
    if (sampling.isAniso()) {
        if (!rContext->priv().caps()->anisoSupport()) {
            // Fallback to linear
            sampling = SkSamplingPriv::AnisoFallback(view.mipmapped() == skgpu::Mipmapped::kYes);
        }
    } else if (view.mipmapped() == skgpu::Mipmapped::kNo) {
        sampling = SkSamplingOptions(sampling.filter);
    }
    GrSamplerState sampler;
    if (sampling.isAniso()) {
        sampler = GrSamplerState::Aniso(wmx, wmy, sampling.maxAniso, view.mipmapped());
    } else {
        sampler = GrSamplerState(wmx, wmy, sampling.filter, sampling.mipmap);
    }
    if (subset) {
        if (domain) {
            return GrTextureEffect::MakeSubset(
                    std::move(view), at, m, sampler, *subset, *domain, caps);
        }
        return GrTextureEffect::MakeSubset(std::move(view), at, m, sampler, *subset, caps);
    } else {
        return GrTextureEffect::Make(std::move(view), at, m, sampler, caps);
    }
}

std::unique_ptr<GrFragmentProcessor> raster_as_fp(GrRecordingContext* rContext,
                                                  const SkImage_Raster* img,
                                                  SkSamplingOptions sampling,
                                                  const SkTileMode tileModes[2],
                                                  const SkMatrix& m,
                                                  const SkRect* subset,
                                                  const SkRect* domain) {
    auto mm =
            sampling.mipmap == SkMipmapMode::kNone ? skgpu::Mipmapped::kNo : skgpu::Mipmapped::kYes;
    return make_fp_from_view(rContext,
                             std::get<0>(AsView(rContext, img, mm, /*targetSurface=*/nullptr)),
                             img->alphaType(),
                             sampling,
                             tileModes,
                             m,
                             subset,
                             domain);
}

std::unique_ptr<GrFragmentProcessor> AsFragmentProcessor(SurfaceDrawContext* sdc,
                                                         const SkImage* img,
                                                         SkSamplingOptions sampling,
                                                         const SkTileMode tileModes[2],
                                                         const SkMatrix& m,
                                                         const SkRect* subset,
                                                         const SkRect* domain) {
    if (!sdc) {
        return {};
    }
    GrRecordingContext* rContext = sdc->recordingContext();
    if (!rContext) {
        return {};
    }
    if (sampling.useCubic && !GrValidCubicResampler(sampling.cubic)) {
        return {};
    }
    if (sampling.mipmap != SkMipmapMode::kNone &&
        (!rContext->priv().caps()->mipmapSupport() || img->dimensions().area() <= 1)) {
        sampling = SkSamplingOptions(sampling.filter);
    }

    auto ib = static_cast<const SkImage_Base*>(img);
    if (ib->isRasterBacked()) {
        return raster_as_fp(rContext,
                            static_cast<const SkImage_Raster*>(ib),
                            sampling,
                            tileModes,
                            m,
                            subset,
                            domain);
    } else if (ib->isGaneshBacked()) {
        auto gb = static_cast<const SkImage_GaneshBase*>(img);
        return gb->asFragmentProcessor(sdc, sampling, tileModes, m, subset, domain);
    } else if (ib->isLazyGenerated()) {
        // TODO: If the CPU data is extracted as planes return a FP that reconstructs the image from
        // the planes.
        auto mm = sampling.mipmap == SkMipmapMode::kNone ? skgpu::Mipmapped::kNo
                                                         : skgpu::Mipmapped::kYes;
        auto rtp = sdc->asRenderTargetProxy();
        return MakeFragmentProcessorFromView(rContext,
                                             std::get<0>(AsView(rContext, img, mm, rtp)),
                                             img->alphaType(),
                                             sampling,
                                             tileModes,
                                             m,
                                             subset,
                                             domain);
    }

    SkDEBUGFAIL("Unsupported image type to make a FragmentProcessor");
    return {};
}

std::unique_ptr<GrFragmentProcessor> MakeFragmentProcessorFromView(
        GrRecordingContext* rContext,
        GrSurfaceProxyView view,
        SkAlphaType at,
        SkSamplingOptions sampling,
        const SkTileMode tileModes[2],
        const SkMatrix& m,
        const SkRect* subset,
        const SkRect* domain) {
    if (!view) {
        return nullptr;
    }
    const GrCaps& caps = *rContext->priv().caps();
    auto wmx = SkTileModeToWrapMode(tileModes[0]);
    auto wmy = SkTileModeToWrapMode(tileModes[1]);
    if (sampling.useCubic) {
        if (subset) {
            if (domain) {
                return GrBicubicEffect::MakeSubset(std::move(view),
                                                   at,
                                                   m,
                                                   wmx,
                                                   wmy,
                                                   *subset,
                                                   *domain,
                                                   sampling.cubic,
                                                   GrBicubicEffect::Direction::kXY,
                                                   *rContext->priv().caps());
            }
            return GrBicubicEffect::MakeSubset(std::move(view),
                                               at,
                                               m,
                                               wmx,
                                               wmy,
                                               *subset,
                                               sampling.cubic,
                                               GrBicubicEffect::Direction::kXY,
                                               *rContext->priv().caps());
        }
        return GrBicubicEffect::Make(std::move(view),
                                     at,
                                     m,
                                     wmx,
                                     wmy,
                                     sampling.cubic,
                                     GrBicubicEffect::Direction::kXY,
                                     *rContext->priv().caps());
    }
    if (sampling.isAniso()) {
        if (!rContext->priv().caps()->anisoSupport()) {
            // Fallback to linear
            sampling = SkSamplingPriv::AnisoFallback(view.mipmapped() == skgpu::Mipmapped::kYes);
        }
    } else if (view.mipmapped() == skgpu::Mipmapped::kNo) {
        sampling = SkSamplingOptions(sampling.filter);
    }
    GrSamplerState sampler;
    if (sampling.isAniso()) {
        sampler = GrSamplerState::Aniso(wmx, wmy, sampling.maxAniso, view.mipmapped());
    } else {
        sampler = GrSamplerState(wmx, wmy, sampling.filter, sampling.mipmap);
    }
    if (subset) {
        if (domain) {
            return GrTextureEffect::MakeSubset(std::move(view),
                                               at,
                                               m,
                                               sampler,
                                               *subset,
                                               *domain,
                                               caps);
        }
        return GrTextureEffect::MakeSubset(std::move(view),
                                           at,
                                           m,
                                           sampler,
                                           *subset,
                                           caps);
    } else {
        return GrTextureEffect::Make(std::move(view), at, m, sampler, caps);
    }
}

GrSurfaceProxyView FindOrMakeCachedMipmappedView(GrRecordingContext* rContext,
                                                 GrSurfaceProxyView view,
                                                 uint32_t imageUniqueID) {
    SkASSERT(rContext);
    SkASSERT(imageUniqueID != SK_InvalidUniqueID);

    if (!view || view.proxy()->asTextureProxy()->mipmapped() == skgpu::Mipmapped::kYes) {
        return view;
    }
    GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();

    skgpu::UniqueKey baseKey;
    GrMakeKeyFromImageID(&baseKey, imageUniqueID, SkIRect::MakeSize(view.dimensions()));
    SkASSERT(baseKey.isValid());
    skgpu::UniqueKey mipmappedKey;
    static const skgpu::UniqueKey::Domain kMipmappedDomain = skgpu::UniqueKey::GenerateDomain();
    {  // No extra values beyond the domain are required. Must name the var to please clang-tidy.
        skgpu::UniqueKey::Builder b(&mipmappedKey, baseKey, kMipmappedDomain, 0);
    }
    SkASSERT(mipmappedKey.isValid());
    if (sk_sp<GrTextureProxy> cachedMippedView =
                proxyProvider->findOrCreateProxyByUniqueKey(mipmappedKey)) {
        return {std::move(cachedMippedView), view.origin(), view.swizzle()};
    }

    auto copy = GrCopyBaseMipMapToView(rContext, view);
    if (!copy) {
        return view;
    }
    // TODO: If we move listeners up from SkImage_Lazy to SkImage_Base then add one here.
    proxyProvider->assignUniqueKeyToProxy(mipmappedKey, copy.asTextureProxy());
    return copy;
}

using DataType = SkYUVAPixmapInfo::DataType;

SkYUVAPixmapInfo::SupportedDataTypes SupportedTextureFormats(const GrImageContext& context) {
    SkYUVAPixmapInfo::SupportedDataTypes dataTypes;
    const auto isValid = [&context](DataType dt, int n) {
        return context.defaultBackendFormat(SkYUVAPixmapInfo::DefaultColorTypeForDataType(dt, n),
                                            GrRenderable::kNo).isValid();
    };
     for (int n = 1; n <= 4; ++n) {
        if (isValid(DataType::kUnorm8, n)) {
            dataTypes.enableDataType(DataType::kUnorm8, n);
        }
        if (isValid(DataType::kUnorm16, n)) {
            dataTypes.enableDataType(DataType::kUnorm16, n);
        }
        if (isValid(DataType::kFloat16, n)) {
            dataTypes.enableDataType(DataType::kFloat16, n);
        }
        if (isValid(DataType::kUnorm10_Unorm2, n)) {
            dataTypes.enableDataType(DataType::kUnorm10_Unorm2, n);
        }
    }
     return dataTypes;
}

}  // namespace skgpu::ganesh

namespace skif {

namespace {

class GaneshBackend :
        public Backend,
        private SkShaderBlurAlgorithm,
        private SkBlurEngine {
public:

    GaneshBackend(sk_sp<GrRecordingContext> context,
                  GrSurfaceOrigin origin,
                  const SkSurfaceProps& surfaceProps,
                  SkColorType colorType)
            : Backend(SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize),
                      surfaceProps, colorType)
            , fContext(std::move(context))
            , fOrigin(origin) {}

    // Backend
    sk_sp<SkDevice> makeDevice(SkISize size,
                               sk_sp<SkColorSpace> colorSpace,
                               const SkSurfaceProps* props) const override {
        SkImageInfo imageInfo = SkImageInfo::Make(size,
                                                  this->colorType(),
                                                  kPremul_SkAlphaType,
                                                  std::move(colorSpace));

        return fContext->priv().createDevice(skgpu::Budgeted::kYes,
                                             imageInfo,
                                             SkBackingFit::kApprox,
                                             1,
                                             skgpu::Mipmapped::kNo,
                                             GrProtected::kNo,
                                             fOrigin,
                                             props ? *props : this->surfaceProps(),
                                             skgpu::ganesh::Device::InitContents::kUninit);
    }

    sk_sp<SkSpecialImage> makeImage(const SkIRect& subset, sk_sp<SkImage> image) const override {
        return SkSpecialImages::MakeFromTextureImage(
                fContext.get(), subset, image, this->surfaceProps());
    }

    sk_sp<SkImage> getCachedBitmap(const SkBitmap& data) const override {
        // This uses the thread safe cache (instead of GrMakeCachedBitmapProxyView) so that image
        // filters can be evaluated on other threads with DDLs.
        auto threadSafeCache = fContext->priv().threadSafeCache();

        skgpu::UniqueKey key;
        SkIRect subset = SkIRect::MakePtSize(data.pixelRefOrigin(), data.dimensions());
        GrMakeKeyFromImageID(&key, data.getGenerationID(), subset);

        auto view = threadSafeCache->find(key);
        if (!view) {
            view = std::get<0>(GrMakeUncachedBitmapProxyView(
                    fContext.get(), GrMippedBitmap(data)));
            if (!view) {
                return nullptr;
            }
            threadSafeCache->add(key, view);
        }

        return sk_make_sp<SkImage_Ganesh>(fContext,
                                          data.getGenerationID(),
                                          std::move(view),
                                          data.info().colorInfo());
    }

    const SkBlurEngine* getBlurEngine() const override { return this; }

    // SkBlurEngine
    const SkBlurEngine::Algorithm* findAlgorithm(SkSize sigma,
                                                 SkColorType colorType) const override {
        // GrBlurUtils supports all tile modes and color types
        return this;
    }

    // SkShaderBlurAlgorithm
    sk_sp<SkDevice> makeDevice(const SkImageInfo& imageInfo) const override {
        return fContext->priv().createDevice(skgpu::Budgeted::kYes,
                                             imageInfo,
                                             SkBackingFit::kApprox,
                                             1,
                                             skgpu::Mipmapped::kNo,
                                             GrProtected::kNo,
                                             fOrigin,
                                             this->surfaceProps(),
                                             skgpu::ganesh::Device::InitContents::kUninit);
    }

private:
    sk_sp<GrRecordingContext> fContext;
    GrSurfaceOrigin fOrigin;
};

} // anonymous namespace

sk_sp<Backend> MakeGaneshBackend(sk_sp<GrRecordingContext> context,
                                 GrSurfaceOrigin origin,
                                 const SkSurfaceProps& surfaceProps,
                                 SkColorType colorType) {
    SkASSERT(context);
    return sk_make_sp<GaneshBackend>(std::move(context), origin, surfaceProps, colorType);
}

}  // namespace skif
