| /* | |
| * 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" | |
| 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 { | |
| using TextureReleaseProc = void (*)(ReleaseContext); | |
| // Passed to both non-YUVA fulfill and imageRelease | |
| using GraphitePromiseImageContext = void*; | |
| // Passed to YUVA fulfill | |
| using GraphitePromiseTextureContext = void*; | |
| // Returned from fulfill and passed into textureRelease | |
| using GraphitePromiseTextureReleaseContext = void*; | |
| using GraphitePromiseImageFulfillProc = | |
| std::tuple<skgpu::graphite::BackendTexture, GraphitePromiseTextureReleaseContext> (*)( | |
| GraphitePromiseImageContext); | |
| using GraphitePromiseImageYUVAFulfillProc = | |
| std::tuple<skgpu::graphite::BackendTexture, GraphitePromiseTextureReleaseContext> (*)( | |
| GraphitePromiseTextureContext); | |
| 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 | |
| @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, | |
| TextureReleaseProc = nullptr, | |
| ReleaseContext = nullptr); | |
| 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); | |
| #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, | |
| GraphitePromiseImageFulfillProc, | |
| GraphitePromiseImageReleaseProc, | |
| GraphitePromiseTextureReleaseProc, | |
| GraphitePromiseImageContext); | |
| SK_API sk_sp<SkImage> PromiseTextureFrom(skgpu::graphite::Recorder*, | |
| SkISize dimensions, | |
| const skgpu::graphite::TextureInfo&, | |
| const SkColorInfo&, | |
| skgpu::graphite::Volatile, | |
| GraphitePromiseImageFulfillProc, | |
| 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 GraphitePromiseTextureContext. The GraphitePromiseImageReleaseProc will be made even on | |
| failure. 'textureContexts' 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 textureContexts states passed to fulfill and textureRelease | |
| @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, | |
| GraphitePromiseImageYUVAFulfillProc, | |
| GraphitePromiseImageReleaseProc, | |
| GraphitePromiseTextureReleaseProc, | |
| GraphitePromiseImageContext imageContext, | |
| GraphitePromiseTextureContext textureContexts[]); | |
| /** 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); | |
| /** 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); | |
| /** 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 |