| /* |
| * 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 skgpu_graphite_Image_DEFINED |
| #define skgpu_graphite_Image_DEFINED |
| |
| #include "include/core/SkColorSpace.h" |
| #include "include/core/SkImage.h" |
| #include "include/core/SkRefCnt.h" |
| #include "include/core/SkSpan.h" |
| #include "include/gpu/GpuTypes.h" |
| |
| #include <string_view> |
| |
| class SkYUVAInfo; |
| class SkYUVAPixmaps; |
| struct SkIRect; |
| |
| namespace skgpu::graphite { |
| class BackendTexture; |
| class Recorder; |
| class TextureInfo; |
| class YUVABackendTextureInfo; |
| class YUVABackendTextures; |
| enum class Volatile : bool; |
| } |
| |
| namespace SkImages { |
| enum class GenerateMipmapsFromBase : bool { kNo, kYes }; |
| |
| using TextureReleaseProc = void (*)(ReleaseContext); |
| |
| // Passed to imageRelease |
| using GraphitePromiseImageContext = void*; |
| // Passed to fulfill; for non-YUVA promise images, the image context is used as the fulfill context, |
| // while YUVA promise images have a per-plane fulfill context. |
| using GraphitePromiseTextureFulfillContext = void*; |
| // Returned from fulfill and passed into textureRelease |
| using GraphitePromiseTextureReleaseContext = void*; |
| |
| using GraphitePromiseTextureFulfillProc = |
| std::tuple<skgpu::graphite::BackendTexture, GraphitePromiseTextureReleaseContext> (*)( |
| GraphitePromiseTextureFulfillContext); |
| using GraphitePromiseImageReleaseProc = void (*)(GraphitePromiseImageContext); |
| using GraphitePromiseTextureReleaseProc = void (*)(GraphitePromiseTextureReleaseContext); |
| |
| /** Creates an SkImage from a GPU texture associated with the recorder. The client is still |
| responsible for managing the backend texture's lifetime. |
| |
| SkImage is returned if the format of backendTexture is recognized and supported. |
| Recognized formats vary by GPU back-end. |
| |
| @param recorder The recorder |
| @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 origin Whether the Texture logically treats the origin as TopLeft or |
| BottomLeft |
| @param generateMipmapsFromBase If kYes then the pixel contents of the textures upper mipmap |
| levels are generated by successive downsampling of the base |
| level. If the texture is not mipmapped or isn't renderable then |
| image creation will fail. If kNo and the texture is mipmapped |
| then the contents of upper levels are assumed to already be |
| valid. |
| @return created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*, |
| const skgpu::graphite::BackendTexture&, |
| SkColorType colorType, |
| SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace, |
| skgpu::Origin origin, |
| GenerateMipmapsFromBase generateMipmapsFromBase, |
| TextureReleaseProc = nullptr, |
| ReleaseContext = nullptr, |
| std::string_view label = {}); |
| |
| SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*, |
| const skgpu::graphite::BackendTexture&, |
| SkColorType colorType, |
| SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace, |
| skgpu::Origin origin, |
| TextureReleaseProc = nullptr, |
| ReleaseContext = nullptr, |
| std::string_view label = {}); |
| |
| SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*, |
| const skgpu::graphite::BackendTexture&, |
| SkColorType colorType, |
| SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace, |
| TextureReleaseProc = nullptr, |
| ReleaseContext = nullptr, |
| std::string_view label = {}); |
| |
| #if !defined(SK_DISABLE_LEGACY_GRAPHITE_IMAGES) |
| inline sk_sp<SkImage> AdoptTextureFrom(skgpu::graphite::Recorder* recorder, |
| const skgpu::graphite::BackendTexture& tex, |
| SkColorType colorType, |
| SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace, |
| skgpu::Origin origin, |
| TextureReleaseProc trProc = nullptr, |
| ReleaseContext ctx = nullptr) { |
| return WrapTexture(recorder, tex, colorType, alphaType, colorSpace, origin, trProc, ctx); |
| } |
| |
| inline sk_sp<SkImage> AdoptTextureFrom(skgpu::graphite::Recorder* recorder, |
| const skgpu::graphite::BackendTexture& tex, |
| SkColorType colorType, |
| SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace, |
| TextureReleaseProc trProc = nullptr, |
| ReleaseContext ctx = nullptr) { |
| return WrapTexture(recorder, tex, colorType, alphaType, colorSpace, trProc, ctx); |
| } |
| #endif |
| |
| /** Create a new SkImage that is very similar to an SkImage created by WrapTexture. The difference |
| is that the caller need not have created the backend texture nor populated it with data when |
| creating the image. Instead of passing a BackendTexture to the factory the client supplies a |
| description of the texture consisting of dimensions, TextureInfo, SkColorInfo and Volatility. |
| |
| In general, 'fulfill' must return a BackendTexture that matches the properties provided at |
| SkImage creation time. The BackendTexture must refer to a valid existing texture in the backend |
| API context/device, and already be populated with data. The texture cannot be deleted until |
| 'textureRelease' is called. 'textureRelease' will be called with the textureReleaseContext |
| returned by 'fulfill'. |
| |
| Wrt when and how often the fulfill, imageRelease, and textureRelease callbacks will be called: |
| |
| For non-volatile promise images, 'fulfill' will be called at Context::insertRecording time. |
| Regardless of whether 'fulfill' succeeded or failed, 'imageRelease' will always be called only |
| once - when Skia will no longer try calling 'fulfill' to get a backend texture. If 'fulfill' |
| failed (i.e., it didn't return a valid backend texture) then 'textureRelease' will never be |
| called. If 'fulfill' was successful then 'textureRelease' will be called only once when the GPU |
| is done with the contents of the promise image. This will usually occur during a Context::submit |
| call but it could occur earlier due to error conditions. 'fulfill' can be called multiple times |
| if the promise image is used in multiple recordings. If 'fulfill' fails, the insertRecording |
| itself will fail. Subsequent insertRecording calls (with Recordings that use the promise image) |
| will keep calling 'fulfill' until it succeeds. |
| |
| For volatile promise images, 'fulfill' will be called each time the Recording is inserted into a |
| Context. Regardless of whether 'fulfill' succeeded or failed, 'imageRelease' will always be |
| called only once just like the non-volatile case. If 'fulfill' fails at insertRecording-time, |
| 'textureRelease' will never be called. If 'fulfill' was successful then a 'textureRelease' |
| matching that 'fulfill' will be called when the GPU is done with the contents of the promise |
| image. This will usually occur during a Context::submit call but it could occur earlier due to |
| error conditions. |
| |
| @param recorder the recorder that will capture the commands creating the image |
| @param dimensions width & height of promised gpu texture |
| @param textureInfo structural information for the promised gpu texture |
| @param colorInfo color type, alpha type and colorSpace information for the image |
| @param origin Whether the Texture logically treats the origin as TopLeft or BottomLeft |
| @param isVolatile volatility of the promise image |
| @param fulfill function called to get the actual backend texture, |
| and the instance for the GraphitePromiseTextureReleaseProc |
| @param imageRelease function called when any image-centric data can be deleted |
| @param textureRelease function called when the backend texture can be deleted |
| @param imageContext state passed to fulfill and imageRelease |
| @return created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> PromiseTextureFrom(skgpu::graphite::Recorder*, |
| SkISize dimensions, |
| const skgpu::graphite::TextureInfo&, |
| const SkColorInfo&, |
| skgpu::Origin origin, |
| skgpu::graphite::Volatile, |
| GraphitePromiseTextureFulfillProc, |
| GraphitePromiseImageReleaseProc, |
| GraphitePromiseTextureReleaseProc, |
| GraphitePromiseImageContext, |
| std::string_view label = {}); |
| |
| SK_API sk_sp<SkImage> PromiseTextureFrom(skgpu::graphite::Recorder*, |
| SkISize dimensions, |
| const skgpu::graphite::TextureInfo&, |
| const SkColorInfo&, |
| skgpu::graphite::Volatile, |
| GraphitePromiseTextureFulfillProc, |
| GraphitePromiseImageReleaseProc, |
| GraphitePromiseTextureReleaseProc, |
| GraphitePromiseImageContext); |
| |
| /** 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, and conversion to RGB. |
| Separate 'fulfill' and 'textureRelease' calls are made for each texture. Each texture has its |
| own GraphitePromiseFulfillContext. The GraphitePromiseImageReleaseProc will be made even on |
| failure. 'planeContexts' has one entry for each of the up to four textures, as indicated by |
| 'backendTextureInfo'. Currently the mipmapped property of 'backendTextureInfo' is ignored. |
| However, in the near future it will be required that if it is kYes then the fulfillProc must |
| return a mip mapped texture for each plane in order to successfully draw the image. |
| |
| @param recorder the recorder that will capture the commands creating the image |
| @param backendTextureInfo info about the promised yuva gpu texture(s) |
| @param imageColorSpace range of colors; may be nullptr |
| @param isVolatile volatility of the promise image |
| @param fulfill function called to get the actual backend texture for |
| a given GraphitePromiseTextureContext, and the instance |
| for the GraphitePromiseTextureReleaseProc |
| @param imageRelease function called when any image-centric data can be deleted |
| @param textureRelease function called when the backend texture can be deleted |
| @param imageContext state passed to imageRelease |
| @param planeContexts states passed to fulfill for each plane |
| @return created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> PromiseTextureFromYUVA(skgpu::graphite::Recorder*, |
| const skgpu::graphite::YUVABackendTextureInfo&, |
| sk_sp<SkColorSpace> imageColorSpace, |
| skgpu::graphite::Volatile, |
| GraphitePromiseTextureFulfillProc, |
| GraphitePromiseImageReleaseProc, |
| GraphitePromiseTextureReleaseProc, |
| GraphitePromiseImageContext imageContext, |
| GraphitePromiseTextureFulfillContext planeContexts[], |
| std::string_view label = {}); |
| |
| |
| /** Returns an SkImage backed by a Graphite texture, using the provided Recorder for creation and |
| uploads if necessary. The returned SkImage respects the required image properties' mipmap |
| setting for non-Graphite SkImages; i.e., if mipmapping is required, the backing Graphite texture |
| will have allocated mip map levels. |
| |
| It is assumed that MIP maps are always supported by the GPU. |
| |
| Returns original SkImage if the image is already Graphite-backed and the required mipmapping is |
| compatible with the backing Graphite texture. If the required mipmapping is not compatible, |
| nullptr will be returned. |
| |
| Returns nullptr if no Recorder is provided, or if SkImage was created with another Recorder and |
| work on that Recorder has not been submitted. |
| |
| @param Recorder the Recorder to use for storing commands |
| @param RequiredProperties properties the returned SkImage must possess (e.g. mipmaps) |
| @return created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> TextureFromImage(skgpu::graphite::Recorder*, |
| const SkImage*, |
| SkImage::RequiredProperties = {}); |
| |
| inline sk_sp<SkImage> TextureFromImage(skgpu::graphite::Recorder* r, |
| const sk_sp<const SkImage>& img, |
| SkImage::RequiredProperties props = {}) { |
| return TextureFromImage(r, img.get(), props); |
| } |
| |
| /** Creates SkImage from SkYUVAPixmaps. |
| |
| The image will remain planar with each plane converted to a texture using the passed Recorder. |
| |
| SkYUVAPixmaps has a SkYUVAInfo which specifies the transformation from YUV to RGB. The |
| SkColorSpace of the resulting RGB values is specified by imgColorSpace. 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). |
| |
| This is only supported using the GPU backend and will fail if recorder is nullptr. |
| |
| SkYUVAPixmaps does not need to remain valid after this returns. |
| |
| @param Recorder The Recorder to use for storing commands |
| @param pixmaps The planes as pixmaps with supported SkYUVAInfo that |
| specifies conversion to RGB. |
| @param RequiredProperties Properties the returned SkImage must possess (e.g. mipmaps) |
| @param limitToMaxTextureSize Downscale image to GPU maximum texture size, if necessary |
| @param imgColorSpace Range of colors of the resulting image; may be nullptr |
| @return Created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(skgpu::graphite::Recorder*, |
| const SkYUVAPixmaps& pixmaps, |
| SkImage::RequiredProperties = {}, |
| bool limitToMaxTextureSize = false, |
| sk_sp<SkColorSpace> imgColorSpace = nullptr, |
| std::string_view label = {}); |
| |
| /** Creates an SkImage from YUV[A] planar textures associated with the recorder. |
| @param recorder The recorder. |
| @param yuvaBackendTextures 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( |
| skgpu::graphite::Recorder* recorder, |
| const skgpu::graphite::YUVABackendTextures& yuvaBackendTextures, |
| sk_sp<SkColorSpace> imageColorSpace, |
| TextureReleaseProc = nullptr, |
| ReleaseContext = nullptr, |
| std::string_view label = {}); |
| |
| /** Creates an SkImage from YUV[A] planar SkImages associated with the recorder. |
| |
| The images should have kGraphite type, and the result will be nullptr if any are not. The |
| resulting SkImage will not take a ref on the given SkImages but will take a ref on the |
| underlying TextureProxies. The releaseProcs, if any, for those Textures will be the ones set |
| when the given SkImages were created. |
| |
| @param recorder The recorder. |
| @param yuvaInfo Structure describing the YUVA format |
| @param images A set of SkImages containing YUVA data |
| @param imageColorSpace Range of colors of the resulting image after conversion to RGB; |
| may be nullptr |
| @return created SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> TextureFromYUVAImages( |
| skgpu::graphite::Recorder* recorder, |
| const SkYUVAInfo& yuvaInfo, |
| SkSpan<const sk_sp<SkImage>> images, |
| sk_sp<SkColorSpace> imageColorSpace); |
| |
| /** Returns subset of this image as a texture-backed image. |
| |
| Returns nullptr if any of the following are true: |
| - Subset is empty |
| - Subset is not contained inside the image's bounds |
| - Pixels in the source image could not be read or copied |
| - The source image is texture-backed and context does not match the source image's context. |
| |
| @param recorder the non-null recorder in which to create the new image. |
| @param img Source image |
| @param subset bounds of returned SkImage |
| @param props properties the returned SkImage must possess (e.g. mipmaps) |
| @return the subsetted image, uploaded as a texture, or nullptr |
| */ |
| SK_API sk_sp<SkImage> SubsetTextureFrom(skgpu::graphite::Recorder* recorder, |
| const SkImage* img, |
| const SkIRect& subset, |
| SkImage::RequiredProperties props = {}); |
| |
| /** Creates a filtered SkImage on the GPU. filter processes the src image, potentially changing |
| color, position, and size. subset is the bounds of src that are processed by filter. clipBounds |
| is the expected bounds of the filtered SkImage. outSubset is required storage for the actual |
| bounds of the filtered SkImage. offset is required storage for translation of returned SkImage. |
| |
| Returns nullptr if SkImage could not be created. If nullptr is returned, outSubset and offset |
| are undefined. |
| |
| Useful for animation of SkImageFilter that varies size from frame to frame. Returned SkImage is |
| created larger than required by filter so that GPU texture can be reused with different sized |
| effects. outSubset describes the valid bounds of GPU texture returned. offset translates the |
| returned SkImage to keep subsequent animation frames aligned with respect to each other. |
| |
| @param recorder the recorder in which the filtering operation is to be performed |
| @param filter how SkImage is sampled when transformed |
| @param subset bounds of SkImage processed by filter |
| @param clipBounds expected bounds of filtered SkImage |
| @param outSubset storage for returned SkImage bounds |
| @param offset storage for returned SkImage translation |
| @return filtered SkImage, or nullptr |
| */ |
| SK_API sk_sp<SkImage> MakeWithFilter(skgpu::graphite::Recorder* recorder, |
| sk_sp<SkImage> src, |
| const SkImageFilter* filter, |
| const SkIRect& subset, |
| const SkIRect& clipBounds, |
| SkIRect* outSubset, |
| SkIPoint* offset); |
| |
| } // namespace SkImages |
| |
| |
| #endif // skgpu_graphite_Image_DEFINED |