/*
 * 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/TextureUtils.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/private/SkAttributes.h"
#include "include/private/SkTArray.h"
#include "src/core/SkBlurEngine.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkDevice.h"
#include "src/core/SkImageFilterCache.h"
#include "src/core/SkImageFilterTypes.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkSamplingPriv.h"
#include "src/core/SkTraceEvent.h"
#include "src/image/SkImage_Base.h"

#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/GraphiteTypes.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/ImageProvider.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "include/private/SkLog.h"
#include "src/gpu/BlurUtils.h"
#include "src/gpu/RefCntedCallback.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/graphite/Buffer.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/Device.h"
#include "src/gpu/graphite/DrawContext.h"
#include "src/gpu/graphite/Image_Base_Graphite.h"
#include "src/gpu/graphite/Image_Graphite.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/SpecialImage_Graphite.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "src/gpu/graphite/task/CopyTask.h"
#include "src/gpu/graphite/task/SynchronizeToCpuTask.h"
#include "src/gpu/graphite/task/UploadTask.h"

#include <array>


using SkImages::GraphitePromiseTextureFulfillProc;
using SkImages::GraphitePromiseTextureFulfillContext;
using SkImages::GraphitePromiseTextureReleaseProc;

namespace skgpu::graphite {

namespace {

// We choose a fallback color type that will map to the same texture format as `dstCT` but will be
// considered renderable (assuming the format is supported). This allows the content to be
// rendered and then we "cast" back to the original requested color type for the image view of the
// scratch surface.
//
// This function takes in the `srcCT` as well because it can enable some fallbacks that are not
// otherwise possible (e.g. gray -> red -> gray).
SkColorType renderable_colortype(SkColorType srcCT, SkColorType dstCT) {
    // This mapping only includes color types that are often deemed non-renderable because of
    // semantics (e.g. can't blend into an alpha channel that is meant to be masked during sampling,
    // or can't render gray from an arbitrary RGB source).
    //
    // We intentionally don't support falling back from one color type to another if it changes
    // the underlying data type. It is better to fail the operation to signal to the client that
    // the action isn't possible and let them choose what sort of fallback should happen.
    switch (dstCT) {
        // For these types we can always render with the alpha channel and not worry about
        // blending because every draw operation uses kSrc and we're filling all pixels. The
        // image view will then still use an rgb1 swizzle to hide any bad alpha data from the
        // original image.
        case kRGB_101010x_SkColorType:    return kRGBA_1010102_SkColorType;
        case kBGR_101010x_SkColorType:    return kBGRA_1010102_SkColorType;
        case kRGB_F16F16F16x_SkColorType: return kRGBA_F16_SkColorType;
        case kRGBA_F16Norm_SkColorType:   return kRGBA_F16_SkColorType;

        // While it is the case that a BGRA format can be used with a kRGB_888x colortype, we
        // don't look at srcCT to guess the format and switch to kBGRA_8888. In the event that
        // this copied image will be read back to the CPU, it's best to match the color type's
        // channel ordering.
        case kRGB_888x_SkColorType:       return kRGBA_8888_SkColorType;

        // Normally kGray is never renderable from arbitrary RGB color data because calculating the
        // luminance/gray level is a dot product. However, if the source color type is also gray,
        // then the only channel we care about is R, which is renderable. After rendering to R,
        // the image view's swizzle can splat that out to produce grayscale.
        case kGray_8_SkColorType:
            if (srcCT == kGray_8_SkColorType) {
                return kR8_unorm_SkColorType;
            } else {
                return kUnknown_SkColorType;
            }

        default:
            // If this color type isn't renderable or doesn't map to a supported format, then there
            // isn't any other fallback that can happen.
            return dstCT;
    }
}

SkAlphaType renderable_alphatype(SkAlphaType srcAT, SkAlphaType dstAT) {
    switch (srcAT) {
        case kUnknown_SkAlphaType:
            // The src image will be forced opaque as part of sampling, so the output pixels will
            // be guaranteed opaque (can upgrade requested kPremul or kUnpremul to kOpaque since the
            // RGB values are unchanged).
            return kOpaque_SkAlphaType;
        case kOpaque_SkAlphaType:
            // The src image claims to be opaque, so the output pixels should be opaque.
            return kOpaque_SkAlphaType;
        case kPremul_SkAlphaType:
            if (dstAT == kUnpremul_SkAlphaType) {
                // If the requested dst AT is kUnpremul, allow rendering directly to a kUnpremul
                // scratch surface using kSrc blending.
                return kUnpremul_SkAlphaType;
            }
            // Always render to kPremul, regardless of the requested dst AT. If the dst AT was
            // kPremul this is a no-op. If it was kOpaque, SkColorSpaceXformSteps treats it as the
            // src AT, so it's also a no-op. If it was kUnknown, the image view will presumably be
            // sampled with a masked opaque alpha channel, so producing premul RGB values emulates
            // having blended with solid black.
            return kPremul_SkAlphaType;
        case kUnpremul_SkAlphaType:
            // If the requested dst AT is kPremul, then keep that so the premultiply is performed
            // during the copy conversion. In all other cases, switch to kOpaque so that we are
            // deemed renderable and color conversion in SkColorSpaceXformSteps produces a no-op.
            // Since the only actual rendering to this surface will be pixel-filling with kSrc
            // blending, this alpha type manipulation is valid.
            return dstAT == kPremul_SkAlphaType ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
    }
    SkUNREACHABLE;
}

SkAlphaType final_alphatype(SkAlphaType srcAT, SkAlphaType renderedAT) {
    // Assuming `renderedAT` was the result of calling `renderable_alphatype` for `srcAT` and some
    // `dstAT`, the final AT to use for the image view is almost always `renderedAT` because it is
    // either more accurate (propogates src opaque-ness into the copy's alpha type), a no-op (it
    // was premul), or unpremul output was requested for premul input and that's not supported so
    // we need to reflect the copy as premul still in its image info.
    //
    // The only exception is for when both srcAT and dstAT were unpremul, in which case
    // `renderedAT` is manipulated to be kOpaque for rendering but in actuality the output remains
    // unpremul and that should be reflected in the final image info as well.
    return (srcAT == kUnpremul_SkAlphaType && renderedAT == kOpaque_SkAlphaType) ?
            kUnpremul_SkAlphaType : renderedAT;
}

SkColorInfo make_renderable(const SkColorInfo& srcInfo, const SkColorInfo& dstInfo) {
    return dstInfo.makeColorType(renderable_colortype(srcInfo.colorType(), dstInfo.colorType()))
                  .makeAlphaType(renderable_alphatype(srcInfo.alphaType(), dstInfo.alphaType()));
}

bool valid_client_provided_image(const SkImage* clientProvided,
                                 const SkImage* original,
                                 SkImage::RequiredProperties requiredProps) {
    if (!clientProvided ||
        !as_IB(clientProvided)->isGraphiteBacked() ||
        original->dimensions() != clientProvided->dimensions() ||
        original->alphaType() != clientProvided->alphaType()) {
        return false;
    }

    uint32_t origChannels = SkColorTypeChannelFlags(original->colorType());
    uint32_t clientChannels = SkColorTypeChannelFlags(clientProvided->colorType());
    if ((origChannels & clientChannels) != origChannels) {
        return false;
    }

    // We require provided images to have a TopLeft origin
    auto graphiteImage = static_cast<const Image*>(clientProvided);
    if (graphiteImage->textureProxyView().origin() != Origin::kTopLeft) {
        SKIA_LOG_E("Client provided image must have a TopLeft origin.");
        return false;
    }

    return true;
}

// This class is the lazy instantiation callback for promise images. It manages calling the
// client's Fulfill, ImageRelease, and TextureRelease procs.
class PromiseLazyInstantiateCallback {
public:
    PromiseLazyInstantiateCallback(sk_sp<RefCntedCallback> releaseHelper,
                                   GraphitePromiseTextureFulfillProc fulfillProc,
                                   GraphitePromiseTextureFulfillContext fulfillContext,
                                   GraphitePromiseTextureReleaseProc textureReleaseProc,
                                   std::string_view label)
            : fReleaseHelper(std::move(releaseHelper))
            , fFulfillProc(fulfillProc)
            , fFulfillContext(fulfillContext)
            , fTextureReleaseProc(textureReleaseProc)
            , fLabel(label) {
    }
    PromiseLazyInstantiateCallback(PromiseLazyInstantiateCallback&&) = default;
    PromiseLazyInstantiateCallback(const PromiseLazyInstantiateCallback&) {
        // Because we get wrapped in std::function we must be copyable. But we should never
        // be copied.
        SkASSERT(false);
    }
    PromiseLazyInstantiateCallback& operator=(PromiseLazyInstantiateCallback&&) = default;
    PromiseLazyInstantiateCallback& operator=(const PromiseLazyInstantiateCallback&) {
        SkASSERT(false);
        return *this;
    }

    sk_sp<Texture> operator()(ResourceProvider* resourceProvider) {
        // Invoke the fulfill proc to get the promised backend texture.
        auto [ backendTexture, textureReleaseCtx ] = fFulfillProc(fFulfillContext);
        if (!backendTexture.isValid()) {
            SKIA_LOG_W("FulfillProc returned an invalid backend texture");
            return nullptr;
        }

        sk_sp<RefCntedCallback> textureReleaseCB = RefCntedCallback::Make(fTextureReleaseProc,
                                                                          textureReleaseCtx);

        sk_sp<Texture> texture = resourceProvider->createWrappedTexture(backendTexture,
                                                                        std::move(fLabel));
        if (!texture) {
            SKIA_LOG_W("Failed to wrap BackendTexture returned by fulfill proc");
            return nullptr;
        }
        texture->setReleaseCallback(std::move(textureReleaseCB));
        return texture;
    }

private:
    sk_sp<RefCntedCallback> fReleaseHelper;
    GraphitePromiseTextureFulfillProc fFulfillProc;
    GraphitePromiseTextureFulfillContext fFulfillContext;
    GraphitePromiseTextureReleaseProc fTextureReleaseProc;
    std::string fLabel;
};

} // anonymous namespace

TextureProxyView MakeBitmapProxyView(Recorder* recorder,
                                     const SkBitmap& bitmap,
                                     sk_sp<SkMipmap> mipmapsIn,
                                     Mipmapped mipmapped,
                                     Budgeted budgeted,
                                     std::string_view label) {
    // Adjust params based on input and Caps
    const Caps* caps = recorder->priv().caps();
    const SkColorType ct = bitmap.info().colorType();

    if (bitmap.dimensions().area() <= 1) {
        mipmapped = Mipmapped::kNo;
    }

    Protected isProtected = recorder->priv().isProtected();
    auto textureInfo = caps->getDefaultSampledTextureInfo(ct, mipmapped, isProtected,
                                                          Renderable::kNo);
    if (!textureInfo.isValid()) {
        return {};
    }
    if (!SkImageInfoIsValid(bitmap.info())) {
        return {};
    }

    int mipLevelCount = (mipmapped == Mipmapped::kYes) ?
            SkMipmap::ComputeLevelCount(bitmap.width(), bitmap.height()) + 1 : 1;

    // setup MipLevels
    sk_sp<SkMipmap> mipmaps = mipmapsIn;
    skia_private::STArray<16, MipLevel> levels(mipLevelCount);
    levels.push_back({bitmap.getPixels(), bitmap.rowBytes()}); // base level is always included
    if (mipLevelCount > 1) {
        if (!mipmaps && !(mipmaps = sk_sp<SkMipmap>(SkMipmap::Build(bitmap.pixmap(), nullptr)))) {
            SKIA_LOG_E("Generating mipmaps failed");
            return {};
        }
        SkASSERT(mipLevelCount == mipmaps->countLevels() + 1);
        for (int i = 1; i < mipLevelCount; ++i) {
            SkMipmap::Level mipLevel;
            SkAssertResult(mipmaps->getLevel(i - 1, &mipLevel));
            levels.push_back({mipLevel.fPixmap.addr(), mipLevel.fPixmap.rowBytes()});
        }
    }

    // Create proxy
    sk_sp<TextureProxy> proxy = TextureProxy::Make(caps,
                                                   recorder->priv().resourceProvider(),
                                                   bitmap.dimensions(),
                                                   textureInfo,
                                                   budgeted,
                                                   label);
    if (!proxy) {
        return {};
    }

    const TextureFormat format = proxy->format();
    SkASSERT(AreColorTypeAndFormatCompatible(ct, format));
    SkASSERT(mipmapped == Mipmapped::kNo || proxy->mipmapped() == Mipmapped::kYes);

    const Swizzle swizzle = ReadSwizzleForColorType(ct, format);
    TextureProxyView view{std::move(proxy), swizzle};

    // Src and dst colorInfo are the same
    const SkColorInfo& colorInfo = bitmap.info().colorInfo();
    // Add upload to the root upload list. These bitmaps are uploaded to unique textures so there is
    // no need to coordinate resource sharing. It is better to then group them into a single task
    // at the start of the Recording.
    const SkIRect dimensions = SkIRect::MakeSize(bitmap.dimensions());
    // Move the view into `uploadSource` so that it is the unique holder of the proxy
    UploadSource uploadSource = UploadSource::Make(
            recorder->priv().caps(), std::move(view), colorInfo, colorInfo, levels, dimensions);
    if (!uploadSource.isValid()) {
        SKIA_LOG_E("MakeBitmapProxyView: Could not create UploadSource");
        return {};
    }

    if (uploadSource.attemptUploadOnhost()) {
        return uploadSource.view();
    }
    // else it failed or was unavailable, so use a task on the root upload list

    if (!recorder->priv().rootUploadList()->recordUpload(recorder,
                                                         uploadSource,
                                                         std::make_unique<ImageUploadContext>())) {
        SKIA_LOG_E("MakeBitmapProxyView: Could not create UploadInstance");
        return {};
    }

    return uploadSource.view();
}

sk_sp<TextureProxy> MakePromiseImageLazyProxy(
        const Caps* caps,
        SkISize dimensions,
        TextureInfo textureInfo,
        Volatile isVolatile,
        sk_sp<RefCntedCallback> releaseHelper,
        GraphitePromiseTextureFulfillProc fulfillProc,
        GraphitePromiseTextureFulfillContext fulfillContext,
        GraphitePromiseTextureReleaseProc textureReleaseProc,
        std::string_view label) {
    SkASSERT(!dimensions.isEmpty());
    SkASSERT(releaseHelper);

    if (!fulfillProc) {
        return nullptr;
    }

    PromiseLazyInstantiateCallback callback{std::move(releaseHelper), fulfillProc,
                                            fulfillContext, textureReleaseProc, label};
    // Proxies for promise images are assumed to always be destined for a client's SkImage so
    // are never considered budgeted.
    return TextureProxy::MakeLazy(caps, dimensions, textureInfo, Budgeted::kNo, isVolatile,
                                  std::move(callback));
}

size_t ComputeSize(SkISize dimensions, const TextureInfo& info) {
    TextureFormat format = TextureInfoPriv::ViewFormat(info);
    SkTextureCompressionType compression = TextureFormatCompressionType(format);

    size_t colorSize = 0;

    if (compression != SkTextureCompressionType::kNone) {
        colorSize =  SkCompressedFormatDataSize(compression,
                                                dimensions,
                                                info.mipmapped() == Mipmapped::kYes);
    } else {
        // TODO(b/401016699): Add logic to handle multiplanar formats
        int bytesPerPixel = TextureFormatBytesPerBlock(format);

        colorSize = (size_t)dimensions.width() * dimensions.height() * bytesPerPixel;
    }

    size_t finalSize = colorSize * (uint8_t) info.sampleCount();

    if (info.mipmapped() == Mipmapped::kYes) {
        finalSize += colorSize/3;
    }
    return finalSize;
}

sk_sp<Image> CopyAsDraw(Recorder* recorder,
                        DrawContext* drawContext,
                        const SkImage* image,
                        const SkIRect& subset,
                        const SkColorInfo& dstColorInfo,
                        Budgeted budgeted,
                        Mipmapped mipmapped,
                        SkBackingFit backingFit,
                        std::string_view label) {
    // NOTE: This info may not exactly match `dstColorInfo` but will be castable back to
    // `dstColorInfo` when we create the Image view.
    SkImageInfo dstInfo = SkImageInfo::Make(
            subset.size(), make_renderable(image->imageInfo().colorInfo(), dstColorInfo));

    // The surface goes out of scope when we return, so it can be scratch, but it may or may
    // not be budgeted depending on how the copied image is used (or returned to the client).
    sk_sp<Surface> surface =
            Surface::MakeScratch(recorder, dstInfo, label, budgeted, mipmapped, backingFit,
                                 /*allowUnpremul=*/true);
    if (!surface) {
        return nullptr;
    }

    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);
    surface->getCanvas()->drawImage(image, -subset.left(), -subset.top(),
                                    SkFilterMode::kNearest, &paint);
    surface->flushToDrawContext(drawContext);
    // Get the image with the actual requested color type and the final alpha type.
    return surface->asImage(dstColorInfo.colorType(),
                            final_alphatype(image->alphaType(), dstInfo.alphaType()));
}

sk_sp<Image> RescaleImage(Recorder* recorder,
                          const Image_Base* srcImage,
                          SkIRect srcIRect,
                          const SkImageInfo& dstInfo,
                          SkImage::RescaleGamma rescaleGamma,
                          SkImage::RescaleMode rescaleMode) {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);
    TRACE_EVENT_INSTANT2("skia.gpu", "RescaleImage Src", TRACE_EVENT_SCOPE_THREAD,
                         "width", srcIRect.width(), "height", srcIRect.height());
    TRACE_EVENT_INSTANT2("skia.gpu", "RescaleImage Dst", TRACE_EVENT_SCOPE_THREAD,
                         "width", dstInfo.width(), "height", dstInfo.height());

    // Other than the final step, rescaling will be performed in the source color type and color
    // space, possibly with a linear gamma adjustment (although changing the SkColorSpace can be
    // applied to the result of make_renderable).
    SkColorInfo stepInfo = make_renderable(srcImage->imageInfo().colorInfo(),
                                           srcImage->imageInfo().colorInfo());

    // Make a Surface *exactly* (barring renderable adjustments) matching dstInfo for the final
    // scaling step.
    SkColorInfo renderableDstInfo =
            make_renderable(srcImage->imageInfo().colorInfo(), dstInfo.colorInfo());
    sk_sp<Surface> dst = Surface::MakeScratch(
            recorder,
            SkImageInfo::Make(dstInfo.dimensions(), renderableDstInfo),
            "RescaleDstTexture",
            Budgeted::kYes,
            Mipmapped::kNo,
            SkBackingFit::kExact,
            /*allowUnpremul=*/true);
    if (!dst) {
        return nullptr;
    }

    SkRect srcRect = SkRect::Make(srcIRect);
    SkRect dstRect = SkRect::Make(dstInfo.dimensions());

    SkISize finalSize = SkISize::Make(dstRect.width(), dstRect.height());
    if (finalSize == srcIRect.size()) {
        rescaleGamma = Image::RescaleGamma::kSrc;
        rescaleMode = Image::RescaleMode::kNearest;
    }

    // Within a rescaling pass tempInput is read from and tempOutput is written to.
    // At the end of the pass tempOutput's texture is wrapped and assigned to tempInput.
    sk_sp<Image_Base> tempInput = sk_ref_sp(srcImage);
    sk_sp<Surface> tempOutput;

    // Assume we should ignore the rescale linear request if the surface has no color space since
    // it's unclear how we'd linearize from an unknown color space.
    if (rescaleGamma == Image::RescaleGamma::kLinear &&
        stepInfo.colorSpace() &&
        !stepInfo.colorSpace()->gammaIsLinear()) {
        // Draw the src image into a new surface with linear gamma, and make that the new tempInput
        sk_sp<SkColorSpace> linearGamma = stepInfo.colorSpace()->makeLinearGamma();
        SkImageInfo gammaDstInfo = SkImageInfo::Make(srcIRect.size(),
                                                     stepInfo.makeColorSpace(linearGamma));
        tempOutput = Surface::MakeScratch(recorder,
                                          gammaDstInfo,
                                          "RescaleLinearGammaTexture");

        if (!tempOutput) {
            return nullptr;
        }
        SkCanvas* gammaDst = tempOutput->getCanvas();
        SkRect gammaDstRect = SkRect::Make(srcIRect.size());

        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kSrc);
        gammaDst->drawImageRect(tempInput, srcRect, gammaDstRect,
                                SkSamplingOptions(SkFilterMode::kNearest), &paint,
                                SkCanvas::kStrict_SrcRectConstraint);
        tempInput = tempOutput->asImage();
        srcRect = gammaDstRect;
        stepInfo = gammaDstInfo.colorInfo(); // remaining steps output linear gamma too
    }

    do {
        SkISize nextDims = finalSize;
        if (rescaleMode != Image::RescaleMode::kNearest &&
            rescaleMode != Image::RescaleMode::kLinear) {
            if (srcRect.width() > finalSize.width()) {
                nextDims.fWidth = std::max((srcRect.width() + 1)/2, (float)finalSize.width());
            } else if (srcRect.width() < finalSize.width()) {
                nextDims.fWidth = std::min(srcRect.width()*2, (float)finalSize.width());
            }
            if (srcRect.height() > finalSize.height()) {
                nextDims.fHeight = std::max((srcRect.height() + 1)/2, (float)finalSize.height());
            } else if (srcRect.height() < finalSize.height()) {
                nextDims.fHeight = std::min(srcRect.height()*2, (float)finalSize.height());
            }
        }

        SkRect stepDstRect;
        if (nextDims == finalSize) {
            // The final surface's color info is `renderableDstInfo`
            tempOutput = dst;
            stepDstRect = dstRect;
        } else {
            tempOutput = Surface::MakeScratch(recorder,
                                              SkImageInfo::Make(nextDims, stepInfo),
                                              "RescaleImageTempTexture");
            if (!tempOutput) {
                return nullptr;
            }
            stepDstRect = SkRect::Make(tempOutput->imageInfo().dimensions());
        }

        SkSamplingOptions samplingOptions;
        if (rescaleMode == Image::RescaleMode::kRepeatedCubic) {
            samplingOptions = SkSamplingOptions(SkCubicResampler::CatmullRom());
        } else {
            samplingOptions = (rescaleMode == Image::RescaleMode::kNearest) ?
                               SkSamplingOptions(SkFilterMode::kNearest) :
                               SkSamplingOptions(SkFilterMode::kLinear);
        }
        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kSrc);
        tempOutput->getCanvas()->drawImageRect(tempInput, srcRect, stepDstRect, samplingOptions,
                                               &paint, SkCanvas::kStrict_SrcRectConstraint);

        tempInput = tempOutput->asImage();
        srcRect = SkRect::Make(nextDims);
    } while (srcRect.width() != finalSize.width() || srcRect.height() != finalSize.height());

    // Cast back to the requested color type and final alpha type now that rendering is finished.
    return dst->asImage(dstInfo.colorType(),
                        final_alphatype(srcImage->alphaType(), renderableDstInfo.alphaType()));
}

bool GenerateMipmaps(Recorder* recorder, DrawContext* drawContext, sk_sp<TextureProxy> texture) {
    SkASSERT(texture->mipmapped() == Mipmapped::kYes);

    // GenerateMipmaps uses Surface and Image to generate mipmaps by drawing each level at 1/2
    // scale compared to the last level and then copying from the scratch surface into `texture`.
    // Surface and Image require SkColorInfo but it does not matter what is chosen so long as the
    // final color management results in the identity function (including read/write swizzles).
    // This ensures that whatever the original color handling of `texture` is, the regenerated
    // levels will match. To do this, we use these settings for both surface and images
    //   - the default color type for the texture's format
    //   - kOpaque_SkAlphaType to disable all premul/unpremul conversions and remain renderable,
    //     (which is okay since all our drawing uses kSrc blending anyways)
    //   - provide no SkColorSpace
    //
    // NOTE: In the future, if we were generate mipmaps in linear gamma, we would need to know about
    // the original image's color space and alpha type.  We would also have to implement a custom
    // filtering shader that sampled the base level several times with nearest filtering, convert
    // each sample to linear+premul space, average them, and then convert that to the source color
    // space and alpha type.
    auto [colorType, _] = TextureFormatColorTypeInfo(texture->format());
    SkColorInfo colorInfo{colorType, kOpaque_SkAlphaType, /*cs=*/nullptr};
    // Since we are creating the color info from the default color type for the texture format,
    // it should match what we'd expect from make_renderable already.
    SkASSERT(make_renderable(colorInfo, colorInfo) == colorInfo);

    // Configure swizzle for the initial image to match what happens in Surface::asImage()
    auto imgSwizzle = ReadSwizzleForColorType(colorInfo.colorType(), texture->format());
    sk_sp<SkImage> scratchImg(new Image(TextureProxyView(texture, imgSwizzle), colorInfo));

    // Alternate between two scratch surfaces to avoid reading from and writing to a texture in the
    // same pass. The dimensions of the first usages of the two scratch textures will be 1/2 and 1/4
    // those of the original texture, respectively.
    SkISize srcSize = texture->dimensions();
    sk_sp<Surface> scratchSurfaces[2];
    for (int i = 0; i < 2; ++i) {
        SK_UNSAFE_TODO(scratchSurfaces[i]) = Surface::MakeScratch(
                recorder,
                SkImageInfo::Make(SkISize::Make(std::max(1, srcSize.width() >> (i + 1)),
                                                std::max(1, srcSize.height() >> (i + 1))),
                                  colorInfo),
                "GenerateMipmapsScratchTexture",
                Budgeted::kYes,
                Mipmapped::kNo,
                SkBackingFit::kApprox);
        if (SK_UNSAFE_TODO(!scratchSurfaces[i])) {
            return false;
        }
    }

    // Within a rescaling pass scratchImg is read from and a scratch surface is written to.
    // At the end of the pass the scratch surface's texture is wrapped and assigned to scratchImg.
    for (int mipLevel = 1; srcSize.width() > 1 || srcSize.height() > 1; ++mipLevel) {
        const SkISize dstSize = SkISize::Make(std::max(srcSize.width() >> 1, 1),
                                              std::max(srcSize.height() >> 1, 1));

        Surface* scratchSurface = scratchSurfaces[(mipLevel - 1) & 1].get();

        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kSrc);
        scratchSurface->getCanvas()->drawImageRect(scratchImg,
                                                   SkRect::Make(srcSize),
                                                   SkRect::Make(dstSize),
                                                   SkFilterMode::kLinear,
                                                   &paint,
                                                   SkCanvas::kStrict_SrcRectConstraint);

        // Make sure the rescaling draw finishes before copying the results.
        scratchSurface->flushToDrawContext(drawContext);

        sk_sp<CopyTextureToTextureTask> copyTask = CopyTextureToTextureTask::Make(
                static_cast<const Surface*>(scratchSurface)->target().refProxy(),
                SkIRect::MakeSize(dstSize),
                texture,
                {0, 0},
                mipLevel);
        if (!copyTask) {
            return false;
        }

        if (drawContext) {
            drawContext->recordDependency(std::move(copyTask));
        } else {
            recorder->priv().add(std::move(copyTask));
        }

        scratchImg = scratchSurface->asImage();
        srcSize = dstSize;
    }

    return true;
}

std::pair<sk_sp<SkImage>, SkSamplingOptions> GetGraphiteBacked(Recorder* recorder,
                                                               const SkImage* imageIn,
                                                               SkSamplingOptions sampling) {
    Mipmapped mipmapped = (sampling.mipmap != SkMipmapMode::kNone)
                                     ? Mipmapped::kYes : Mipmapped::kNo;

    if (imageIn->dimensions().area() <= 1 && mipmapped == Mipmapped::kYes) {
        mipmapped = Mipmapped::kNo;
        sampling = SkSamplingOptions(SkFilterMode::kLinear);
    }

    sk_sp<SkImage> result;
    if (as_IB(imageIn)->isGraphiteBacked()) {
        result = sk_ref_sp(imageIn);

        // If the preexisting Graphite-backed image isn't texturable or doesn't have the required
        // mipmaps, we drop down the sampling
        const auto graphiteImage = static_cast<const Image_Base*>(result.get());
        bool isTexturable = true;
        for (const TextureProxyView& view : graphiteImage->textureProxyViews()) {
            if (view && !recorder->priv().caps()->isTexturable(view.proxy()->textureInfo())) {
                isTexturable = false;
                break;
            }
        }

        if (!isTexturable) {
            sampling = SkSamplingOptions(SkFilterMode::kNearest);
        } else if (mipmapped == Mipmapped::kYes && !result->hasMipmaps()) {
            sampling = SkSamplingOptions(SkFilterMode::kLinear);
        }
    } else {
        auto clientImageProvider = recorder->clientImageProvider();
        result = clientImageProvider->findOrCreate(
                recorder, imageIn, {mipmapped == Mipmapped::kYes});

        if (!valid_client_provided_image(
                    result.get(), imageIn, {mipmapped == Mipmapped::kYes})) {
            // The client did not fulfill the ImageProvider contract so drop the image.
            result = nullptr;
        }
    }

    if (sampling.isAniso() && result) {
        sampling = SkSamplingPriv::AnisoFallback(result->hasMipmaps());
    }

    return { result, sampling };
}

TextureProxyView AsView(const SkImage* image) {
    if (!image) {
        return {};
    }
    if (!as_IB(image)->isGraphiteBacked()) {
        return {};
    }
    // A YUVA image (even if backed by graphite textures) is not a single texture
    if (as_IB(image)->isYUVA()) {
        return {};
    }

    auto gi = reinterpret_cast<const Image*>(image);
    return gi->textureProxyView();
}

SkColorType ComputeShaderCoverageMaskTargetFormat(const Caps* caps) {
    // GPU compute coverage mask renderers need to bind the mask texture as a storage binding, which
    // support a limited set of color formats. In general, we use RGBA8 if Alpha8 can't be
    // supported.
    if (caps->isStorage(caps->getDefaultStorageTextureInfo(kAlpha_8_SkColorType))) {
        return kAlpha_8_SkColorType;
    }
    return kRGBA_8888_SkColorType;
}

} // namespace skgpu::graphite

namespace skif {

namespace {

// TODO(michaelludwig): The skgpu::BlurUtils effects will be migrated to src/core to implement a
// shader BlurEngine that can be shared by rastr, Ganesh, and Graphite. This is blocked by having
// skif::FilterResult handle the resizing to the max supported sigma.
class GraphiteBackend :
        public Backend,
        private SkShaderBlurAlgorithm,
        private SkBlurEngine {
public:

    GraphiteBackend(skgpu::graphite::Recorder* recorder,
                    const SkSurfaceProps& surfaceProps,
                    SkColorType colorType)
            : Backend(SkImageFilterCache::Create(SkImageFilterCache::kDefaultTransientSize),
                      surfaceProps, colorType)
            , fRecorder(recorder) {}

    // 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 skgpu::graphite::Device::Make(fRecorder,
                                             imageInfo,
                                             skgpu::Budgeted::kYes,
                                             skgpu::Mipmapped::kNo,
                                             SkBackingFit::kApprox,
                                             props ? *props : this->surfaceProps(),
                                             skgpu::graphite::LoadOp::kDiscard,
                                             "ImageFilterResult");
    }

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

    sk_sp<SkImage> getCachedBitmap(const SkBitmap& data) const override {
        auto proxy = skgpu::graphite::RecorderPriv::CreateCachedProxy(fRecorder, data,
                                                                      "ImageFilterCachedBitmap");
        if (!proxy) {
            return nullptr;
        }

        const SkColorInfo& colorInfo = data.info().colorInfo();
        skgpu::Swizzle swizzle = skgpu::graphite::ReadSwizzleForColorType(
                colorInfo.colorType(), proxy->format());
        return sk_make_sp<skgpu::graphite::Image>(
                skgpu::graphite::TextureProxyView(std::move(proxy), swizzle),
                colorInfo);
    }

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

    // SkBlurEngine
    const SkBlurEngine::Algorithm* findAlgorithm(SkSize sigma,
                                                 SkColorType colorType) const override {
        // The runtime effect blurs handle all tilemodes and color types
        return this;
    }

    // SkShaderBlurAlgorithm
    sk_sp<SkDevice> makeDevice(const SkImageInfo& imageInfo) const override {
        return skgpu::graphite::Device::Make(fRecorder,
                                             imageInfo,
                                             skgpu::Budgeted::kYes,
                                             skgpu::Mipmapped::kNo,
                                             SkBackingFit::kApprox,
                                             this->surfaceProps(),
                                             skgpu::graphite::LoadOp::kDiscard,
                                             "EvalBlurTexture");
    }

private:
    skgpu::graphite::Recorder* fRecorder;
};

} // anonymous namespace

sk_sp<Backend> MakeGraphiteBackend(skgpu::graphite::Recorder* recorder,
                                   const SkSurfaceProps& surfaceProps,
                                   SkColorType colorType) {
    SkASSERT(recorder);
    return sk_make_sp<GraphiteBackend>(recorder, surfaceProps, colorType);
}

}  // namespace skif
