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

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/core/SkYUVAInfo.h"
#include "include/core/SkYUVAPixmaps.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Surface.h"
#include "include/gpu/graphite/YUVABackendTextures.h"
#include "include/private/SkAttributes.h"
#include "include/private/SkLog.h"
#include "src/core/SkImageFilterTypes.h"
#include "src/core/SkImageFilter_Base.h"
#include "src/gpu/RefCntedCallback.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/Image_Base_Graphite.h"
#include "src/gpu/graphite/Image_Graphite.h"
#include "src/gpu/graphite/Image_YUVA_Graphite.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "src/gpu/graphite/TextureProxy.h"
#include "src/gpu/graphite/TextureProxyView.h"
#include "src/gpu/graphite/TextureUtils.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>

namespace SkImages {

using namespace skgpu::graphite;

namespace {

bool validate_backend_texture(const Caps* caps,
                                     const BackendTexture& texture,
                                     const SkColorInfo& info) {
    if (!texture.isValid() || texture.dimensions().width() <= 0 ||
        texture.dimensions().height() <= 0) {
        return false;
    }

    if (!SkColorInfoIsValid(info)) {
        return false;
    }

    if (!caps->isTexturable(texture.info())) {
        return false;
    }

    return AreColorTypeAndFormatCompatible(info.colorType(),
                                           TextureInfoPriv::ViewFormat(texture.info()));
}

} // anonymous namespace

sk_sp<SkImage> WrapTexture(Recorder* recorder,
                           const BackendTexture& backendTex,
                           SkColorType ct,
                           SkAlphaType at,
                           sk_sp<SkColorSpace> cs,
                           skgpu::Origin origin,
                           GenerateMipmapsFromBase genMipmaps,
                           TextureReleaseProc releaseP,
                           ReleaseContext releaseC,
                           std::string_view label) {
    auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);

    if (!recorder) {
        return nullptr;
    }

    const Caps* caps = recorder->priv().caps();

    SkColorInfo info(ct, at, std::move(cs));

    if (!validate_backend_texture(caps, backendTex, info)) {
        return nullptr;
    }

    if (label.empty()) {
        label = "WrappedImage";
    }

    sk_sp<Texture> texture =
            recorder->priv().resourceProvider()->createWrappedTexture(backendTex, label);
    if (!texture) {
        SKIA_LOG_W("Texture creation failed");
        return nullptr;
    }
    texture->setReleaseCallback(std::move(releaseHelper));

    sk_sp<TextureProxy> proxy = TextureProxy::Wrap(std::move(texture));
    SkASSERT(proxy);

    skgpu::Swizzle swizzle = ReadSwizzleForColorType(ct, proxy->format());
    TextureProxyView view(std::move(proxy), swizzle, origin);

    if (genMipmaps == GenerateMipmapsFromBase::kYes) {
        if (view.proxy()->mipmapped() == skgpu::Mipmapped::kNo) {
            SKIA_LOG_W("Failed SkImage:::WrapTexture because asked to generate mipmaps for "
                        "nonmipmapped texture");
            return nullptr;
        }
        if (!GenerateMipmaps(recorder, /*drawContext=*/nullptr, view.refProxy())) {
            SKIA_LOG_W("Failed SkImage::WrapTexture. Could not generate mipmaps.");
            return nullptr;
        }
    }

    return sk_make_sp<Image>(view, info);
}

sk_sp<SkImage> WrapTexture(Recorder* recorder,
                           const BackendTexture& backendTex,
                           SkAlphaType at,
                           sk_sp<SkColorSpace> cs,
                           skgpu::Origin origin,
                           GenerateMipmapsFromBase genMipmaps,
                           TextureReleaseProc releaseP,
                           ReleaseContext releaseC,
                           std::string_view label) {
    auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);

    if (!recorder) {
        return nullptr;
    }

    const Caps* caps = recorder->priv().caps();

    TextureFormat format = TextureInfoPriv::ViewFormat(backendTex.info());
    auto [ct, _] = TextureFormatColorTypeInfo(format);
    // TODO(michaelludwig): Generalize this function for promise images and wrapped surfaces.
    // The ambiguity for single-channel textures (R) being interpreted at a high-level in Skia as
    // alpha-only (which impacts effect generation) or just as red data is resolved by looking at
    // the requested alpha type. If the alpha type is premul/unpremul we assume the texture should
    // be interpreted as an alpha texture; if it's opaque then it'll be red.
    if (at == kPremul_SkAlphaType || at == kUnpremul_SkAlphaType) {
        switch (ct) {
            case kR8_unorm_SkColorType: ct = kAlpha_8_SkColorType; break;
            case kR16_unorm_SkColorType: ct = kA16_unorm_SkColorType; break;
            case kR16_float_SkColorType: ct = kA16_float_SkColorType; break;
            default: break; // no adjustment
        }
    }

    skgpu::Swizzle swizzle = ReadSwizzleForColorType(ct, format);
    // An unknown alpha type needs to be forced to opaque by a swizzle if the texture format won't
    // do it for us automatically. Once we force it to opaque, we can report kOpaque for the
    // higher-level SkImage's alpha type so Skia's logic can benefit from our swizzling.
    if (at == kUnknown_SkAlphaType) {
        at = kOpaque_SkAlphaType;
        if (SkToBool(TextureFormatChannelMask(format) & kAlpha_SkColorChannelFlag) &&
            swizzle[3] != '1') {
            swizzle = skgpu::Swizzle::Concat(swizzle, skgpu::Swizzle::RGB1());
            // Patch `ct` if possible:
            switch (ct) {
                case kRGBA_8888_SkColorType:    ct = kRGB_888x_SkColorType; break;
                case kRGBA_1010102_SkColorType: ct = kRGB_101010x_SkColorType; break;
                case kBGRA_1010102_SkColorType: ct = kBGR_101010x_SkColorType; break;
                case kRGBA_F16_SkColorType:     ct = kRGB_F16F16F16x_SkColorType; break;
                default: break; // no further adjustment
            }
        }
    }

    SkColorInfo info(ct, at, std::move(cs));
    if (!validate_backend_texture(caps, backendTex, info)) {
        return nullptr;
    }

    if (label.empty()) {
        label = "WrappedImage";
    }

    sk_sp<Texture> texture =
            recorder->priv().resourceProvider()->createWrappedTexture(backendTex, label);
    if (!texture) {
        SKIA_LOG_W("Texture creation failed");
        return nullptr;
    }
    texture->setReleaseCallback(std::move(releaseHelper));

    TextureProxyView view(TextureProxy::Wrap(std::move(texture)), swizzle, origin);
    if (genMipmaps == GenerateMipmapsFromBase::kYes) {
        if (view.proxy()->mipmapped() == skgpu::Mipmapped::kNo) {
            SKIA_LOG_W("Failed SkImage:::WrapTexture because asked to generate mipmaps for "
                        "nonmipmapped texture");
            return nullptr;
        }
        if (!GenerateMipmaps(recorder, /*drawContext=*/nullptr, view.refProxy())) {
            SKIA_LOG_W("Failed SkImage::WrapTexture. Could not generate mipmaps.");
            return nullptr;
        }
    }

    return sk_make_sp<skgpu::graphite::Image>(view, info);
}

sk_sp<SkImage> WrapTexture(Recorder* recorder,
                           const BackendTexture& backendTex,
                           SkColorType ct,
                           SkAlphaType at,
                           sk_sp<SkColorSpace> cs,
                           skgpu::Origin origin,
                           TextureReleaseProc releaseP,
                           ReleaseContext releaseC,
                           std::string_view label) {
    return WrapTexture(recorder,
                       backendTex,
                       ct,
                       at,
                       std::move(cs),
                       origin,
                       SkImages::GenerateMipmapsFromBase::kNo,
                       releaseP,
                       releaseC,
                       label);
}

sk_sp<SkImage> WrapTexture(Recorder* recorder,
                           const BackendTexture& backendTex,
                           SkColorType ct,
                           SkAlphaType at,
                           sk_sp<SkColorSpace> cs,
                           TextureReleaseProc releaseP,
                           ReleaseContext releaseC,
                           std::string_view label) {
    return WrapTexture(recorder,
                       backendTex,
                       ct,
                       at,
                       std::move(cs),
                       skgpu::Origin::kTopLeft,
                       SkImages::GenerateMipmapsFromBase::kNo,
                       releaseP,
                       releaseC,
                       label);
}

sk_sp<SkImage> PromiseTextureFrom(Recorder* recorder,
                                  SkISize dimensions,
                                  const TextureInfo& textureInfo,
                                  const SkColorInfo& colorInfo,
                                  skgpu::Origin origin,
                                  Volatile isVolatile,
                                  GraphitePromiseTextureFulfillProc fulfillProc,
                                  GraphitePromiseImageReleaseProc imageReleaseProc,
                                  GraphitePromiseTextureReleaseProc textureReleaseProc,
                                  GraphitePromiseImageContext imageContext,
                                  std::string_view label) {
    // Our contract is that we will always call the _image_ release proc even on failure.
    // We use the helper to convey the imageContext, so we need to ensure Make doesn't fail.
    imageReleaseProc = imageReleaseProc ? imageReleaseProc : [](void*) {};
    auto releaseHelper = skgpu::RefCntedCallback::Make(imageReleaseProc, imageContext);

    if (!recorder) {
        SKIA_LOG_W("Null Recorder");
        return nullptr;
    }

    const Caps* caps = recorder->priv().caps();

    SkImageInfo info = SkImageInfo::Make(dimensions, colorInfo);
    if (!SkImageInfoIsValid(info)) {
        SKIA_LOG_W("Invalid SkImageInfo");
        return nullptr;
    }

    const TextureFormat format = TextureInfoPriv::ViewFormat(textureInfo);
    if (!AreColorTypeAndFormatCompatible(colorInfo.colorType(), format)) {
        SKIA_LOG_W("Incompatible SkColorType and TextureInfo");
        return nullptr;
    }

    // Non-YUVA promise images use the 'imageContext' for both the release proc and fulfill proc.
    sk_sp<TextureProxy> proxy = MakePromiseImageLazyProxy(caps,
                                                          dimensions,
                                                          textureInfo,
                                                          isVolatile,
                                                          std::move(releaseHelper),
                                                          fulfillProc,
                                                          imageContext,
                                                          textureReleaseProc,
                                                          label);
    if (!proxy) {
        return nullptr;
    }

    skgpu::Swizzle swizzle = ReadSwizzleForColorType(colorInfo.colorType(), format);
    TextureProxyView view(std::move(proxy), swizzle, origin);
    return sk_make_sp<Image>(view, colorInfo);
}

sk_sp<SkImage> PromiseTextureFrom(Recorder* recorder,
                                  SkISize dimensions,
                                  const TextureInfo& textureInfo,
                                  const SkColorInfo& colorInfo,
                                  Volatile isVolatile,
                                  GraphitePromiseTextureFulfillProc fulfillProc,
                                  GraphitePromiseImageReleaseProc imageReleaseProc,
                                  GraphitePromiseTextureReleaseProc textureReleaseProc,
                                  GraphitePromiseImageContext imageContext) {
    return PromiseTextureFrom(recorder,
                              dimensions,
                              textureInfo,
                              colorInfo,
                              skgpu::Origin::kTopLeft,
                              isVolatile,
                              fulfillProc,
                              imageReleaseProc,
                              textureReleaseProc,
                              imageContext);
}

sk_sp<SkImage> PromiseTextureFromYUVA(Recorder* recorder,
                                      const YUVABackendTextureInfo& backendTextureInfo,
                                      sk_sp<SkColorSpace> imageColorSpace,
                                      Volatile isVolatile,
                                      GraphitePromiseTextureFulfillProc fulfillProc,
                                      GraphitePromiseImageReleaseProc imageReleaseProc,
                                      GraphitePromiseTextureReleaseProc textureReleaseProc,
                                      GraphitePromiseImageContext imageContext,
                                      GraphitePromiseTextureFulfillContext planeContexts[],
                                      std::string_view label) {
    // Our contract is that we will always call the _image_ release proc even on failure.
    // We use the helper to convey the imageContext, so we need to ensure Make doesn't fail.
    auto releaseHelper = skgpu::RefCntedCallback::Make(imageReleaseProc, imageContext);
    if (!recorder) {
        return nullptr;
    }
    // Precompute the dimensions for all promise texture planes
    SkISize planeDimensions[SkYUVAInfo::kMaxPlanes];
    if (!backendTextureInfo.yuvaInfo().planeDimensions(planeDimensions)) {
        return nullptr;
    }

    std::string labelStr(label);
    if (labelStr.empty()) {
        labelStr = "Wrapped_PromiseYUVPlane";
    } else {
        labelStr += "_PromiseYUVPlane";
    }

    TextureProxyView planes[SkYUVAInfo::kMaxPlanes];
    for (int i = 0; i < backendTextureInfo.numPlanes(); ++i) {
        sk_sp<TextureProxy> lazyProxy =
                MakePromiseImageLazyProxy(recorder->priv().caps(),
                                          SK_UNSAFE_TODO(planeDimensions[i]),
                                          backendTextureInfo.planeTextureInfo(i),
                                          isVolatile,
                                          releaseHelper,
                                          fulfillProc,
                                          SK_UNSAFE_TODO(planeContexts[i]),
                                          textureReleaseProc,
                                          labelStr);
        // Promise YUVA images assume the default rgba swizzle.
        SK_UNSAFE_TODO(planes[i]) = TextureProxyView(std::move(lazyProxy));
    }
    return Image_YUVA::Make(recorder->priv().caps(), backendTextureInfo.yuvaInfo(),
                            SkSpan(planes), std::move(imageColorSpace));
}

sk_sp<SkImage> SubsetTextureFrom(Recorder* recorder,
                                 const SkImage* img,
                                 const SkIRect& subset,
                                 SkImage::RequiredProperties props) {
    if (!recorder || !img) {
        return nullptr;
    }
    auto subsetImg = img->makeSubset(recorder, subset, props);
    return SkImages::TextureFromImage(recorder, subsetImg, props);
}

sk_sp<SkImage> MakeWithFilter(Recorder* recorder,
                              sk_sp<SkImage> src,
                              const SkImageFilter* filter,
                              const SkIRect& subset,
                              const SkIRect& clipBounds,
                              SkIRect* outSubset,
                              SkIPoint* offset) {
    if (!recorder || !src || !filter) {
        return nullptr;
    }

    sk_sp<skif::Backend> backend = skif::MakeGraphiteBackend(recorder, {}, src->colorType());
    sk_sp<SkImage> image = as_IFB(filter)->makeImageWithFilter(std::move(backend),
                                                               std::move(src),
                                                               subset,
                                                               clipBounds,
                                                               outSubset,
                                                               offset);
    // The skif backend creates budgeted, scratch textures. This is what we want most of the time,
    // but for the final result image returned from MakeWithFilter(), it needs to be a non-budgeted
    // non-shareable texture (i.e. matching what we return from the other factory methods).
    if (image) {
        SkASSERT(as_IB(image)->isGraphiteBacked());
        image = static_cast<Image_Base*>(image.get())->makeNonBudgeted(recorder);
    }
    return image;
}

static sk_sp<SkImage> generate_picture_texture(Recorder* recorder,
                                               const SkImage_Picture* img,
                                               const SkImageInfo& info,
                                               SkImage::RequiredProperties requiredProps) {
    auto mm = requiredProps.fMipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
    // Use a non-budgeted surface since the image wrapping the surface's texture will be owned by
    // the client.
    sk_sp<Surface> surface = Surface::Make(recorder,
                                           info,
                                           "LazySkImagePictureTexture",
                                           skgpu::Budgeted::kNo,
                                           mm,
                                           SkBackingFit::kExact,
                                           img->props());

    if (!surface) {
        SKIA_LOG_E("Failed to create Surface");
        return nullptr;
    }

    img->replay(surface->getCanvas());
    // If the surface was created with mipmaps, they will be automatically generated when flushing
    // the tasks when 'surface' goes out of scope.
    return surface->asImage();
}


sk_sp<SkImage> make_from_bitmap(Recorder* recorder,
                                const SkColorInfo& colorInfo,
                                const SkBitmap& bitmap,
                                sk_sp<SkMipmap> mipmaps,
                                skgpu::Budgeted budgeted,
                                SkImage::RequiredProperties requiredProps,
                                std::string_view label) {
    auto mm = requiredProps.fMipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
    auto view = MakeBitmapProxyView(recorder, bitmap, std::move(mipmaps), mm, budgeted, label);
    if (!view) {
        return nullptr;
    }

    SkASSERT(!requiredProps.fMipmapped || view.proxy()->mipmapped() == skgpu::Mipmapped::kYes);
    return sk_make_sp<Image>(std::move(view), colorInfo);
}

/*
 *  We only have 2 ways to create a Graphite-backed image.
 *
 *  1. Ask the generator to natively create one
 *  2. Ask the generator to return RGB(A) data, which the GPU can convert
 */
static sk_sp<SkImage> make_texture_image_from_lazy(Recorder* recorder,
                                                   const SkImage_Lazy* img,
                                                   SkImage::RequiredProperties requiredProps) {
    // 1. Ask the generator to natively create one.
    {
        if (img->type() == SkImage_Base::Type::kLazyPicture) {
            sk_sp<SkImage> newImage =
                    generate_picture_texture(recorder,
                                             static_cast<const SkImage_Picture*>(img),
                                             img->imageInfo(),
                                             requiredProps);
            if (newImage) {
                SkASSERT(as_IB(newImage)->isGraphiteBacked());
                return newImage;
            }
            // The fallback for this would be to generate a bitmap, but some picture-backed
            // images can only be played back on the GPU.
            return nullptr;
        }
        // There is not an analog to GrTextureGenerator for Graphite yet, but if there was,
        // we would want to call it here.
    }

    // 2. Ask the generator to return a bitmap, which the GPU can convert.
    {
        SkBitmap bitmap;
        if (img->getROPixels(nullptr, &bitmap, SkImage_Lazy::CachingHint::kDisallow_CachingHint)) {
            return make_from_bitmap(recorder,
                                    img->imageInfo().colorInfo(),
                                    bitmap,
                                    nullptr,
                                    skgpu::Budgeted::kNo,
                                    requiredProps,
                                    "LazySkImageBitmapTexture");
        }
    }

    return nullptr;
}

sk_sp<SkImage> TextureFromImage(Recorder* recorder,
                                const SkImage* image,
                                SkImage::RequiredProperties requiredProps) {
    if (!recorder || !image) {
        return nullptr;
    }
    if (image->dimensions().area() <= 1) {
        requiredProps.fMipmapped = false;
    }

    auto ib = as_IB(image);
    SkASSERT(!ib->isGaneshBacked());

    if (ib->isRasterBacked()) {
        auto raster = static_cast<const SkImage_Raster*>(ib);
        return make_from_bitmap(recorder,
                                raster->imageInfo().colorInfo(),
                                raster->bitmap(),
                                raster->refMips(),
                                skgpu::Budgeted::kNo,
                                requiredProps,
                                "RasterBitmapTexture");
    }
    if (ib->isLazyGenerated()) {
        return make_texture_image_from_lazy(
                recorder, static_cast<const SkImage_Lazy*>(ib), requiredProps);
    }
    SkASSERT(ib->isGraphiteBacked());
    return ib->makeSubset(recorder, ib->bounds(), requiredProps);
}

sk_sp<SkImage> TextureFromYUVAPixmaps(Recorder* recorder,
                                      const SkYUVAPixmaps& pixmaps,
                                      SkImage::RequiredProperties requiredProps,
                                      bool limitToMaxTextureSize,
                                      sk_sp<SkColorSpace> imageColorSpace,
                                      std::string_view label) {
    if (!recorder) {
        return nullptr;
    }

    // Determine if we have to resize the pixmaps
    const int maxTextureSize = recorder->priv().caps()->maxTextureSize();
    const int maxDim = std::max(pixmaps.yuvaInfo().width(), pixmaps.yuvaInfo().height());

    SkYUVAPixmapInfo finalInfo = pixmaps.pixmapsInfo();
    if (maxDim > maxTextureSize) {
        if (!limitToMaxTextureSize) {
            return nullptr;
        }
        float scale = static_cast<float>(maxTextureSize) / maxDim;
        SkISize newDimensions = {
                std::min(static_cast<int>(pixmaps.yuvaInfo().width() * scale), maxTextureSize),
                std::min(static_cast<int>(pixmaps.yuvaInfo().height() * scale), maxTextureSize)};
        finalInfo = SkYUVAPixmapInfo(pixmaps.yuvaInfo().makeDimensions(newDimensions),
                                     pixmaps.dataType(),
                                     /*rowBytes=*/nullptr);
    }

    std::string labelStr(label);
    if (labelStr.empty()) {
        labelStr = "YUVRasterBitmapPlane";
    } else {
        labelStr += "_YUVBitmapPlane";
    }

    auto mipmapped = requiredProps.fMipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
    TextureProxyView planes[SkYUVAInfo::kMaxPlanes];
    for (int i = 0; i < finalInfo.yuvaInfo().numPlanes(); ++i) {
        SkBitmap bmp;
        if (maxDim > maxTextureSize) {
            // Rescale the data before uploading
            if (!bmp.tryAllocPixels(finalInfo.planeInfo(i)) ||
                !pixmaps.plane(i).scalePixels(bmp.pixmap(), SkFilterMode::kLinear)) {
                return nullptr;
            }
        } else {
            // Use original data to upload
            if (!bmp.installPixels(pixmaps.plane(i))) {
                return nullptr;
            }
        }

        auto view = MakeBitmapProxyView(recorder, bmp, /*mipmapsIn=*/nullptr, mipmapped,
                                        skgpu::Budgeted::kNo, labelStr);
        SK_UNSAFE_TODO(planes[i]) = std::move(view);
    }
    return Image_YUVA::Make(recorder->priv().caps(), finalInfo.yuvaInfo(),
                            SkSpan(planes), std::move(imageColorSpace));
}

sk_sp<SkImage> TextureFromYUVATextures(Recorder* recorder,
                                       const YUVABackendTextures& yuvaTextures,
                                       sk_sp<SkColorSpace> imageColorSpace,
                                       TextureReleaseProc releaseP,
                                       ReleaseContext releaseC,
                                       std::string_view label) {
    auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);
    if (!recorder) {
        return nullptr;
    }

    std::string labelStr(label);
    if (labelStr.empty()) {
        labelStr = "Wrapped_YUVPlane";
    } else {
        labelStr += "_YUVPlane";
    }

    TextureProxyView planes[SkYUVAInfo::kMaxPlanes];
    for (int i = 0; i < yuvaTextures.yuvaInfo().numPlanes(); ++i) {
        sk_sp<Texture> texture = recorder->priv().resourceProvider()->createWrappedTexture(
                yuvaTextures.planeTexture(i), labelStr);
        if (!texture) {
            SKIA_LOG_W("Failed to wrap backend texture for YUVA plane %d", i);
            return nullptr;
        }
        texture->setReleaseCallback(releaseHelper);
        SK_UNSAFE_TODO(planes[i]) = TextureProxyView(TextureProxy::Wrap(std::move(texture)));
    }

    return Image_YUVA::Make(recorder->priv().caps(), yuvaTextures.yuvaInfo(),
                            SkSpan(planes), std::move(imageColorSpace));
}

sk_sp<SkImage> TextureFromYUVAImages(Recorder* recorder,
                                     const SkYUVAInfo& yuvaInfo,
                                     SkSpan<const sk_sp<SkImage>> images,
                                     sk_sp<SkColorSpace> imageColorSpace) {
    // This factory is just a view of the images, so does not actually trigger any work on the
    // recorder. It is just used to provide the Caps.
    return Image_YUVA::WrapImages(recorder->priv().caps(), yuvaInfo, images, imageColorSpace);
}

}  // namespace SkImages
