blob: 81ca86ff1d34b2358012c803c48b85fa877e45bb [file] [log] [blame]
/*
* 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