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

#ifndef SkImageGanesh_DEFINED
#define SkImageGanesh_DEFINED

#include "include/core/SkImage.h"
#include "include/core/SkRefCnt.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrTypes.h"
#include "include/private/base/SkAPI.h"

#include <functional>

class GrBackendFormat;
class GrBackendTexture;
class GrContextThreadSafeProxy;
class GrDirectContext;
class GrRecordingContext;
class GrYUVABackendTextureInfo;
class GrYUVABackendTextures;
class SkColorSpace;
class SkData;
class SkPixmap;
class SkPromiseImageTexture;
class SkYUVAPixmaps;
enum SkAlphaType : int;
enum SkColorType : int;
enum class SkTextureCompressionType;
struct SkISize;

/**
 * All factories in this file refer to the Ganesh GPU backend when they say GPU.
 */

namespace SkImages {
/** Defines a callback function, taking one parameter of type GrBackendTexture with
    no return value. Function is called when backend texture is to be released.
*/
using BackendTextureReleaseProc = std::function<void(GrBackendTexture)>;
/** User function called when supplied texture may be deleted. */
using TextureReleaseProc = void (*)(ReleaseContext);

/** Creates GPU-backed SkImage from backendTexture associated with context.
    Skia will assume ownership of the resource and will release it when no longer needed.
    A non-null SkImage is returned if format of backendTexture is recognized and supported.
    Recognized formats vary by GPU backend.
    @param context         GPU context
    @param backendTexture  texture residing on GPU
    @param textureOrigin   origin of backendTexture
    @param colorType       color type of the resulting image
    @param alphaType       alpha type of the resulting image
    @param colorSpace      range of colors; may be nullptr
    @return                created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
                                       const GrBackendTexture& backendTexture,
                                       GrSurfaceOrigin textureOrigin,
                                       SkColorType colorType);
SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
                                       const GrBackendTexture& backendTexture,
                                       GrSurfaceOrigin textureOrigin,
                                       SkColorType colorType,
                                       SkAlphaType alphaType);
SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
                                       const GrBackendTexture& backendTexture,
                                       GrSurfaceOrigin textureOrigin,
                                       SkColorType colorType,
                                       SkAlphaType alphaType,
                                       sk_sp<SkColorSpace> colorSpace);

/** Creates GPU-backed SkImage from the provided GPU texture associated with context.
    GPU texture must stay valid and unchanged until textureReleaseProc is called by Skia.
    Skia will call textureReleaseProc with the passed-in releaseContext when SkImage
    is deleted or no longer refers to the texture.
    A non-null SkImage is returned if format of backendTexture is recognized and supported.
    Recognized formats vary by GPU backend.
    @note When using a DDL recording context, textureReleaseProc will be called on the
    GPU thread after the DDL is played back on the direct context.
    @param context             GPU context
    @param backendTexture      texture residing on GPU
    @param colorSpace          This describes the color space of this image's contents, as
                               seen after sampling. In general, if the format of the backend
                               texture is SRGB, some linear colorSpace should be supplied
                               (e.g., SkColorSpace::MakeSRGBLinear()). If the format of the
                               backend texture is linear, then the colorSpace should include
                               a description of the transfer function as
                               well (e.g., SkColorSpace::MakeSRGB()).
    @param textureReleaseProc  function called when texture can be released
    @param releaseContext      state passed to textureReleaseProc
    @return                    created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> BorrowTextureFrom(GrRecordingContext* context,
                                        const GrBackendTexture& backendTexture,
                                        GrSurfaceOrigin origin,
                                        SkColorType colorType,
                                        SkAlphaType alphaType,
                                        sk_sp<SkColorSpace> colorSpace,
                                        TextureReleaseProc textureReleaseProc = nullptr,
                                        ReleaseContext releaseContext = nullptr);

/** Creates a GPU-backed SkImage from pixmap. It is uploaded to GPU backend using context.
    Created SkImage is available to other GPU contexts, and is available across thread
    boundaries. All contexts must be in the same GPU share group, or otherwise
    share resources.
    When SkImage is no longer referenced, context releases texture memory
    asynchronously.
    SkColorSpace of SkImage is determined by pixmap.colorSpace().
    SkImage is returned referring to GPU backend if context is not nullptr,
    format of data is recognized and supported, and if context supports moving
    resources between contexts. Otherwise, pixmap pixel data is copied and SkImage
    as returned in raster format if possible; nullptr may be returned.
    Recognized GPU formats vary by platform and GPU backend.
    @param context                GPU context
    @param pixmap                 SkImageInfo, pixel address, and row bytes
    @param buildMips              create SkImage as mip map if true
    @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
    @return                       created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> CrossContextTextureFromPixmap(GrDirectContext* context,
                                                    const SkPixmap& pixmap,
                                                    bool buildMips,
                                                    bool limitToMaxTextureSize = false);

/** Creates a GPU-backed SkImage from a GPU backend texture. The backend texture must stay
    valid and unchanged until textureReleaseProc is called. The textureReleaseProc is
    called when the SkImage is deleted or no longer refers to the texture and will be
    passed the releaseContext.
    An SkImage is returned if the format of backendTexture is recognized and supported.
    Recognized formats vary by GPU backend.
    @note When using a DDL recording context, textureReleaseProc will be called on the
    GPU thread after the DDL is played back on the direct context.
    @param context             the GPU context
    @param backendTexture      a texture already allocated by the GPU
    @param alphaType           This characterizes the nature of the alpha values in the
                               backend texture. For opaque compressed formats (e.g., ETC1)
                               this should usually be set to kOpaq
                               ue_SkAlphaType.
    @param colorSpace          This describes the color space of this image's contents, as
                               seen after sampling. In general, if the format of the backend
                               texture is SRGB, some linear colorSpace should be supplied
                               (e.g., SkColorSpace::MakeSRGBLinear()). If the format of the
                               backend texture is linear, then the colorSpace should include
                               a description of the transfer function as
                               well (e.g., SkColorSpace::MakeSRGB()).
    @param textureReleaseProc  function called when the backend texture can be released
    @param releaseContext      state passed to textureReleaseProc
    @return                    created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> TextureFromCompressedTexture(GrRecordingContext* context,
                                                   const GrBackendTexture& backendTexture,
                                                   GrSurfaceOrigin origin,
                                                   SkAlphaType alphaType,
                                                   sk_sp<SkColorSpace> colorSpace,
                                                   TextureReleaseProc textureReleaseProc = nullptr,
                                                   ReleaseContext releaseContext = nullptr);

/** Creates a GPU-backed SkImage from compressed data.
    This method will return an SkImage representing the compressed data.
    If the GPU doesn't support the specified compression method, the data
    will be decompressed and then wrapped in a GPU-backed image.
    Note: one can query the supported compression formats via
    GrRecordingContext::compressedBackendFormat.
    @param context     GPU context
    @param data        compressed data to store in SkImage
    @param width       width of full SkImage
    @param height      height of full SkImage
    @param type        type of compression used
    @param mipmapped   does 'data' contain data for all the mipmap levels?
    @param isProtected do the contents of 'data' require DRM protection (on Vulkan)?
    @return            created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> TextureFromCompressedTextureData(GrDirectContext* direct,
                                                       sk_sp<SkData> data,
                                                       int width,
                                                       int height,
                                                       SkTextureCompressionType type,
                                                       GrMipmapped mipmapped = GrMipmapped::kNo,
                                                       GrProtected isProtected = GrProtected::kNo);

/** Returns SkImage backed by GPU texture associated with context. Returned SkImage is
    compatible with SkSurface created with dstColorSpace. The returned SkImage respects
    mipmapped setting; if mipmapped equals skgpu::Mipmapped::kYes, the backing texture
    allocates mip map levels.
    The mipmapped parameter is effectively treated as kNo if MIP maps are not supported by the
    GPU.
    Returns original SkImage if the image is already texture-backed, the context matches, and
    mipmapped is compatible with the backing GPU texture. skgpu::Budgeted is ignored in this
   case.
    Returns nullptr if context is nullptr, or if SkImage was created with another
    GrDirectContext.
    @param GrDirectContext  the GrDirectContext in play, if it exists
    @param SkImage          a non-null pointer to an SkImage.
    @param skgpu::Mipmapped Whether created SkImage texture must allocate mip map levels.
                            Defaults to no.
    @param skgpu::Budgeted  Whether to count a newly created texture for the returned image
                            counts against the context's budget. Defaults to yes.
    @return                 created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> TextureFromImage(GrDirectContext*,
                                       const SkImage*,
                                       skgpu::Mipmapped = skgpu::Mipmapped::kNo,
                                       skgpu::Budgeted = skgpu::Budgeted::kYes);
inline sk_sp<SkImage> TextureFromImage(GrDirectContext* ctx,
                                       sk_sp<const SkImage> img,
                                       skgpu::Mipmapped m = skgpu::Mipmapped::kNo,
                                       skgpu::Budgeted b = skgpu::Budgeted::kYes) {
    return TextureFromImage(ctx, img.get(), m, b);
}

/** Creates a GPU-backed SkImage from SkYUVAPixmaps.
    The image will remain planar with each plane converted to a texture using the passed
    GrRecordingContext.
    SkYUVAPixmaps has a SkYUVAInfo which specifies the transformation from YUV to RGB.
    The SkColorSpace of the resulting RGB values is specified by imageColorSpace. This will
    be the SkColorSpace reported by the image and when drawn the RGB values will be converted
    from this space into the destination space (if the destination is tagged).
    Currently, this is only supported using the GPU backend and will fail if context is nullptr.
    SkYUVAPixmaps does not need to remain valid after this returns.
    @param context                GPU context
    @param pixmaps                The planes as pixmaps with supported SkYUVAInfo that
                                  specifies conversion to RGB.
    @param buildMips              create internal YUVA textures as mip map if kYes. This is
                                  silently ignored if the context does not support mip maps.
    @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
    @param imageColorSpace        range of colors of the resulting image; may be nullptr
    @return                       created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context,
                                             const SkYUVAPixmaps& pixmaps,
                                             GrMipmapped buildMips,
                                             bool limitToMaxTextureSize,
                                             sk_sp<SkColorSpace> imageColorSpace);
SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context,
                                             const SkYUVAPixmaps& pixmaps,
                                             GrMipmapped buildMips = GrMipmapped::kNo,
                                             bool limitToMaxTextureSize = false);

/** Creates a GPU-backed SkImage from YUV[A] planar textures. This requires that the textures
 *  stay valid for the lifetime of the image. The ReleaseContext can be used to know when it is
 *  safe to either delete or overwrite the textures. If ReleaseProc is provided it is also called
 *  before return on failure.
    @param context            GPU context
    @param yuvaTextures       A set of textures containing YUVA data and a description of the
                              data and transformation to RGBA.
    @param imageColorSpace    range of colors of the resulting image after conversion to RGB;
                              may be nullptr
    @param textureReleaseProc called when the backend textures can be released
    @param releaseContext     state passed to textureReleaseProc
    @return                   created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context,
                                              const GrYUVABackendTextures& yuvaTextures,
                                              sk_sp<SkColorSpace> imageColorSpace,
                                              TextureReleaseProc textureReleaseProc = nullptr,
                                              ReleaseContext releaseContext = nullptr);
SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context,
                                              const GrYUVABackendTextures& yuvaTextures);

using PromiseImageTextureContext = void*;
using PromiseImageTextureFulfillProc = sk_sp<SkPromiseImageTexture> (*)(PromiseImageTextureContext);
using PromiseImageTextureReleaseProc = void (*)(PromiseImageTextureContext);

/** Create a new GPU-backed SkImage that is very similar to an SkImage created by BorrowTextureFrom.
    The difference is that the caller need not have created the texture nor populated it with the
    image pixel data. Moreover, the SkImage may be created on a thread as the creation of the
    image does not require access to the backend API or GrDirectContext. Instead of passing a
    GrBackendTexture the client supplies a description of the texture consisting of
    GrBackendFormat, width, height, and GrMipmapped state. The resulting SkImage can be drawn
    to a SkDeferredDisplayListRecorder or directly to a GPU-backed SkSurface.
    When the actual texture is required to perform a backend API draw, textureFulfillProc will
    be called to receive a GrBackendTexture. The properties of the GrBackendTexture must match
    those set during the SkImage creation, and it must refer to a valid existing texture in the
    backend API context/device, and be populated with the image pixel data. The texture cannot
    be deleted until textureReleaseProc is called.
    There is at most one call to each of textureFulfillProc and textureReleaseProc.
    textureReleaseProc is always called even if image creation fails or if the
    image is never fulfilled (e.g. it is never drawn or all draws are clipped out)
    @param gpuContextProxy     the thread-safe proxy of the gpu context. required.
    @param backendFormat       format of promised gpu texture
    @param dimensions          width & height of promised gpu texture
    @param mipmapped           mip mapped state of promised gpu texture
    @param origin              surface origin of promised gpu texture
    @param colorType           color type of promised gpu texture
    @param alphaType           alpha type of promised gpu texture
    @param colorSpace          range of colors; may be nullptr
    @param textureFulfillProc  function called to get actual gpu texture
    @param textureReleaseProc  function called when texture can be deleted
    @param textureContext      state passed to textureFulfillProc and textureReleaseProc
    @return                    created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> PromiseTextureFrom(sk_sp<GrContextThreadSafeProxy> gpuContextProxy,
                                         const GrBackendFormat& backendFormat,
                                         SkISize dimensions,
                                         GrMipmapped mipmapped,
                                         GrSurfaceOrigin origin,
                                         SkColorType colorType,
                                         SkAlphaType alphaType,
                                         sk_sp<SkColorSpace> colorSpace,
                                         PromiseImageTextureFulfillProc textureFulfillProc,
                                         PromiseImageTextureReleaseProc textureReleaseProc,
                                         PromiseImageTextureContext textureContext);

/** This is similar to 'PromiseTextureFrom' but it creates a GPU-backed SkImage from YUV[A] data.
    The source data may be planar (i.e. spread across multiple textures). In
    the extreme Y, U, V, and A are all in different planes and thus the image is specified by
    four textures. 'backendTextureInfo' describes the planar arrangement, texture formats,
    conversion to RGB, and origin of the textures. Separate 'textureFulfillProc' and
    'textureReleaseProc' calls are made for each texture. Each texture has its own
    PromiseImageTextureContext. If 'backendTextureInfo' is not valid then no release proc
    calls are made. Otherwise, the calls will be made even on failure. 'textureContexts' has one
    entry for each of the up to four textures, as indicated by 'backendTextureInfo'.
    Currently the mip mapped property of 'backendTextureInfo' is ignored. However, in the
    near future it will be required that if it is kYes then textureFulfillProc must return
    a mip mapped texture for each plane in order to successfully draw the image.
    @param gpuContextProxy     the thread-safe proxy of the gpu context. required.
    @param backendTextureInfo  info about the promised yuva gpu texture
    @param imageColorSpace     range of colors; may be nullptr
    @param textureFulfillProc  function called to get actual gpu texture
    @param textureReleaseProc  function called when texture can be deleted
    @param textureContexts     state passed to textureFulfillProc and textureReleaseProc
    @return                    created SkImage, or nullptr
*/
SK_API sk_sp<SkImage> PromiseTextureFromYUVA(sk_sp<GrContextThreadSafeProxy> gpuContextProxy,
                                             const GrYUVABackendTextureInfo& backendTextureInfo,
                                             sk_sp<SkColorSpace> imageColorSpace,
                                             PromiseImageTextureFulfillProc textureFulfillProc,
                                             PromiseImageTextureReleaseProc textureReleaseProc,
                                             PromiseImageTextureContext textureContexts[]);

/** Retrieves the existing backend texture. If SkImage is not a Ganesh-backend texture image
    or otherwise does not have such a texture, false is returned. Otherwise, outTexture will
    be set to the image's texture.

    If flushPendingGrContextIO is true, completes deferred I/O operations.
    If origin in not nullptr, copies location of content drawn into SkImage.
    @param outTexture               Will be set to the underlying texture of the image.
    @param flushPendingGrContextIO  flag to flush outstanding requests
    @return                         back-end API texture handle; invalid on failure
*/
SK_API bool GetBackendTextureFromImage(sk_sp<const SkImage> img,
                                       GrBackendTexture* outTexture,
                                       bool flushPendingGrContextIO,
                                       GrSurfaceOrigin* origin = nullptr);

/** Extracts the backendTexture from an existing SkImage.
    If the image is not already GPU-backed, the raster data will be uploaded as a texture
    and returned.
    If this is the only reference to the image, the old image's texture will be
    moved out of the passed in image.
    If the image is shared (has a refcount > 1), the texture will be copied and then returned.
    @param context                    GPU context
    @param image                      image, either CPU-backed or GPU-backed
    @param backendTexture             Will be set to the underlying texture of the image.
    @param backendTextureReleaseProc  Called when the texture is released
*/
SK_API bool MakeBackendTextureFromImage(GrDirectContext* context,
                                        sk_sp<SkImage> image,
                                        GrBackendTexture* backendTexture,
                                        BackendTextureReleaseProc* backendTextureReleaseProc);
// Legacy name
inline bool GetBackendTextureFromImage(GrDirectContext* context,
                                       sk_sp<SkImage> image,
                                       GrBackendTexture* backendTexture,
                                       BackendTextureReleaseProc* backendTextureReleaseProc) {
    return MakeBackendTextureFromImage(context, image, backendTexture, backendTextureReleaseProc);
}

}  // namespace SkImages

#endif
