• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkImageGanesh_DEFINED
9 #define SkImageGanesh_DEFINED
10 
11 #include "include/core/SkImage.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/gpu/GpuTypes.h"
14 #include "include/gpu/ganesh/GrTypes.h"
15 #include "include/private/base/SkAPI.h"
16 
17 #include <functional>
18 #include <utility>
19 
20 class GrBackendTexture;
21 class GrDirectContext;
22 class GrRecordingContext;
23 class GrYUVABackendTextures;
24 class SkColorSpace;
25 class SkData;
26 class SkImageFilter;
27 struct SkIPoint;
28 class SkPixmap;
29 class SkYUVAPixmaps;
30 enum SkAlphaType : int;
31 enum SkColorType : int;
32 enum class SkTextureCompressionType;
33 struct SkIRect;
34 
35 /**
36  * All factories in this file refer to the Ganesh GPU backend when they say GPU.
37  */
38 
39 namespace SkImages {
40 /** Defines a callback function, taking one parameter of type GrBackendTexture with
41     no return value. Function is called when backend texture is to be released.
42 */
43 using BackendTextureReleaseProc = std::function<void(GrBackendTexture)>;
44 /** User function called when supplied texture may be deleted. */
45 using TextureReleaseProc = void (*)(ReleaseContext);
46 
47 /** Creates GPU-backed SkImage from backendTexture associated with context.
48     Skia will assume ownership of the resource and will release it when no longer needed.
49     A non-null SkImage is returned if format of backendTexture is recognized and supported.
50     Recognized formats vary by GPU backend.
51     @param context         GPU context
52     @param backendTexture  texture residing on GPU
53     @param textureOrigin   origin of backendTexture
54     @param colorType       color type of the resulting image
55     @param alphaType       alpha type of the resulting image
56     @param colorSpace      range of colors; may be nullptr
57     @return                created SkImage, or nullptr
58 */
59 SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
60                                        const GrBackendTexture& backendTexture,
61                                        GrSurfaceOrigin textureOrigin,
62                                        SkColorType colorType);
63 SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
64                                        const GrBackendTexture& backendTexture,
65                                        GrSurfaceOrigin textureOrigin,
66                                        SkColorType colorType,
67                                        SkAlphaType alphaType);
68 SK_API sk_sp<SkImage> AdoptTextureFrom(GrRecordingContext* context,
69                                        const GrBackendTexture& backendTexture,
70                                        GrSurfaceOrigin textureOrigin,
71                                        SkColorType colorType,
72                                        SkAlphaType alphaType,
73                                        sk_sp<SkColorSpace> colorSpace);
74 
75 /** Creates GPU-backed SkImage from the provided GPU texture associated with context.
76     GPU texture must stay valid and unchanged until textureReleaseProc is called by Skia.
77     Skia will call textureReleaseProc with the passed-in releaseContext when SkImage
78     is deleted or no longer refers to the texture.
79     A non-null SkImage is returned if format of backendTexture is recognized and supported.
80     Recognized formats vary by GPU backend.
81     @note When using a DDL recording context, textureReleaseProc will be called on the
82     GPU thread after the DDL is played back on the direct context.
83     @param context             GPU context
84     @param backendTexture      texture residing on GPU
85     @param colorSpace          This describes the color space of this image's contents, as
86                                seen after sampling. In general, if the format of the backend
87                                texture is SRGB, some linear colorSpace should be supplied
88                                (e.g., SkColorSpace::MakeSRGBLinear()). If the format of the
89                                backend texture is linear, then the colorSpace should include
90                                a description of the transfer function as
91                                well (e.g., SkColorSpace::MakeSRGB()).
92     @param textureReleaseProc  function called when texture can be released
93     @param releaseContext      state passed to textureReleaseProc
94     @return                    created SkImage, or nullptr
95 */
96 SK_API sk_sp<SkImage> BorrowTextureFrom(GrRecordingContext* context,
97                                         const GrBackendTexture& backendTexture,
98                                         GrSurfaceOrigin origin,
99                                         SkColorType colorType,
100                                         SkAlphaType alphaType,
101                                         sk_sp<SkColorSpace> colorSpace,
102                                         TextureReleaseProc textureReleaseProc = nullptr,
103                                         ReleaseContext releaseContext = nullptr);
104 
105 /** Creates a GPU-backed SkImage from pixmap. It is uploaded to GPU backend using context.
106     Created SkImage is available to other GPU contexts, and is available across thread
107     boundaries. All contexts must be in the same GPU share group, or otherwise
108     share resources.
109     When SkImage is no longer referenced, context releases texture memory
110     asynchronously.
111     SkColorSpace of SkImage is determined by pixmap.colorSpace().
112     SkImage is returned referring to GPU backend if context is not nullptr,
113     format of data is recognized and supported, and if context supports moving
114     resources between contexts. Otherwise, pixmap pixel data is copied and SkImage
115     as returned in raster format if possible; nullptr may be returned.
116     Recognized GPU formats vary by platform and GPU backend.
117     @param context                GPU context
118     @param pixmap                 SkImageInfo, pixel address, and row bytes
119     @param buildMips              create SkImage as mip map if true
120     @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
121     @return                       created SkImage, or nullptr
122 */
123 SK_API sk_sp<SkImage> CrossContextTextureFromPixmap(GrDirectContext* context,
124                                                     const SkPixmap& pixmap,
125                                                     bool buildMips,
126                                                     bool limitToMaxTextureSize = false);
127 
128 /** Creates a GPU-backed SkImage from a GPU backend texture. The backend texture must stay
129     valid and unchanged until textureReleaseProc is called. The textureReleaseProc is
130     called when the SkImage is deleted or no longer refers to the texture and will be
131     passed the releaseContext.
132     An SkImage is returned if the format of backendTexture is recognized and supported.
133     Recognized formats vary by GPU backend.
134     @note When using a DDL recording context, textureReleaseProc will be called on the
135     GPU thread after the DDL is played back on the direct context.
136     @param context             the GPU context
137     @param backendTexture      a texture already allocated by the GPU
138     @param alphaType           This characterizes the nature of the alpha values in the
139                                backend texture. For opaque compressed formats (e.g., ETC1)
140                                this should usually be set to kOpaq
141                                ue_SkAlphaType.
142     @param colorSpace          This describes the color space of this image's contents, as
143                                seen after sampling. In general, if the format of the backend
144                                texture is SRGB, some linear colorSpace should be supplied
145                                (e.g., SkColorSpace::MakeSRGBLinear()). If the format of the
146                                backend texture is linear, then the colorSpace should include
147                                a description of the transfer function as
148                                well (e.g., SkColorSpace::MakeSRGB()).
149     @param textureReleaseProc  function called when the backend texture can be released
150     @param releaseContext      state passed to textureReleaseProc
151     @return                    created SkImage, or nullptr
152 */
153 SK_API sk_sp<SkImage> TextureFromCompressedTexture(GrRecordingContext* context,
154                                                    const GrBackendTexture& backendTexture,
155                                                    GrSurfaceOrigin origin,
156                                                    SkAlphaType alphaType,
157                                                    sk_sp<SkColorSpace> colorSpace,
158                                                    TextureReleaseProc textureReleaseProc = nullptr,
159                                                    ReleaseContext releaseContext = nullptr);
160 
161 /** Creates a GPU-backed SkImage from compressed data.
162     This method will return an SkImage representing the compressed data.
163     If the GPU doesn't support the specified compression method, the data
164     will be decompressed and then wrapped in a GPU-backed image.
165     Note: one can query the supported compression formats via
166     GrRecordingContext::compressedBackendFormat.
167     @param context     GPU context
168     @param data        compressed data to store in SkImage
169     @param width       width of full SkImage
170     @param height      height of full SkImage
171     @param type        type of compression used
172     @param mipmapped   does 'data' contain data for all the mipmap levels?
173     @param isProtected do the contents of 'data' require DRM protection (on Vulkan)?
174     @return            created SkImage, or nullptr
175 */
176 SK_API sk_sp<SkImage> TextureFromCompressedTextureData(
177         GrDirectContext* direct,
178         sk_sp<SkData> data,
179         int width,
180         int height,
181         SkTextureCompressionType type,
182         skgpu::Mipmapped mipmapped = skgpu::Mipmapped::kNo,
183         GrProtected isProtected = GrProtected::kNo,
184         sk_sp<SkColorSpace> colorSpace = nullptr);
185 
186 /** Returns SkImage backed by GPU texture associated with context. Returned SkImage is
187     compatible with SkSurface created with dstColorSpace. The returned SkImage respects
188     mipmapped setting; if mipmapped equals skgpu::Mipmapped::kYes, the backing texture
189     allocates mip map levels.
190     The mipmapped parameter is effectively treated as kNo if MIP maps are not supported by the
191     GPU.
192     Returns original SkImage if the image is already texture-backed, the context matches, and
193     mipmapped is compatible with the backing GPU texture. skgpu::Budgeted is ignored in this
194    case.
195     Returns nullptr if context is nullptr, or if SkImage was created with another
196     GrDirectContext.
197     @param GrDirectContext  the GrDirectContext in play, if it exists
198     @param SkImage          a non-null pointer to an SkImage.
199     @param skgpu::Mipmapped Whether created SkImage texture must allocate mip map levels.
200                             Defaults to no.
201     @param skgpu::Budgeted  Whether to count a newly created texture for the returned image
202                             counts against the context's budget. Defaults to yes.
203     @return                 created SkImage, or nullptr
204 */
205 SK_API sk_sp<SkImage> TextureFromImage(GrDirectContext*,
206                                        const SkImage*,
207                                        skgpu::Mipmapped = skgpu::Mipmapped::kNo,
208                                        skgpu::Budgeted = skgpu::Budgeted::kYes);
209 inline sk_sp<SkImage> TextureFromImage(GrDirectContext* ctx,
210                                        const sk_sp<const SkImage>& img,
211                                        skgpu::Mipmapped m = skgpu::Mipmapped::kNo,
212                                        skgpu::Budgeted b = skgpu::Budgeted::kYes) {
213     return TextureFromImage(ctx, img.get(), m, b);
214 }
215 
216 /** Creates a GPU-backed SkImage from SkYUVAPixmaps.
217     The image will remain planar with each plane converted to a texture using the passed
218     GrRecordingContext.
219     SkYUVAPixmaps has a SkYUVAInfo which specifies the transformation from YUV to RGB.
220     The SkColorSpace of the resulting RGB values is specified by imageColorSpace. This will
221     be the SkColorSpace reported by the image and when drawn the RGB values will be converted
222     from this space into the destination space (if the destination is tagged).
223     Currently, this is only supported using the GPU backend and will fail if context is nullptr.
224     SkYUVAPixmaps does not need to remain valid after this returns.
225     @param context                GPU context
226     @param pixmaps                The planes as pixmaps with supported SkYUVAInfo that
227                                   specifies conversion to RGB.
228     @param buildMips              create internal YUVA textures as mip map if kYes. This is
229                                   silently ignored if the context does not support mip maps.
230     @param limitToMaxTextureSize  downscale image to GPU maximum texture size, if necessary
231     @param imageColorSpace        range of colors of the resulting image; may be nullptr
232     @return                       created SkImage, or nullptr
233 */
234 SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context,
235                                              const SkYUVAPixmaps& pixmaps,
236                                              skgpu::Mipmapped buildMips,
237                                              bool limitToMaxTextureSize,
238                                              sk_sp<SkColorSpace> imageColorSpace);
239 SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context,
240                                              const SkYUVAPixmaps& pixmaps,
241                                              skgpu::Mipmapped buildMips = skgpu::Mipmapped::kNo,
242                                              bool limitToMaxTextureSize = false);
243 
244 /** Creates a GPU-backed SkImage from YUV[A] planar textures. This requires that the textures
245  *  stay valid for the lifetime of the image. The ReleaseContext can be used to know when it is
246  *  safe to either delete or overwrite the textures. If ReleaseProc is provided it is also called
247  *  before return on failure.
248     @param context            GPU context
249     @param yuvaTextures       A set of textures containing YUVA data and a description of the
250                               data and transformation to RGBA.
251     @param imageColorSpace    range of colors of the resulting image after conversion to RGB;
252                               may be nullptr
253     @param textureReleaseProc called when the backend textures can be released
254     @param releaseContext     state passed to textureReleaseProc
255     @return                   created SkImage, or nullptr
256 */
257 SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context,
258                                               const GrYUVABackendTextures& yuvaTextures,
259                                               sk_sp<SkColorSpace> imageColorSpace,
260                                               TextureReleaseProc textureReleaseProc = nullptr,
261                                               ReleaseContext releaseContext = nullptr);
262 SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context,
263                                               const GrYUVABackendTextures& yuvaTextures);
264 
265 /** Retrieves the existing backend texture. If SkImage is not a Ganesh-backend texture image
266     or otherwise does not have such a texture, false is returned. Otherwise, outTexture will
267     be set to the image's texture.
268 
269     If flushPendingGrContextIO is true, completes deferred I/O operations.
270     If origin in not nullptr, copies location of content drawn into SkImage.
271     @param outTexture               Will be set to the underlying texture of the image if non-null.
272     @param flushPendingGrContextIO  flag to flush outstanding requests
273     @param origin                   Will be set to the origin orientation of the image if non-null.
274     @return                         false if a Ganesh backend texture cannot be retrieved.
275 */
276 SK_API bool GetBackendTextureFromImage(const SkImage* img,
277                                        GrBackendTexture* outTexture,
278                                        bool flushPendingGrContextIO,
279                                        GrSurfaceOrigin* origin = nullptr);
280 inline bool GetBackendTextureFromImage(const sk_sp<const SkImage>& img,
281                                        GrBackendTexture* outTexture,
282                                        bool flushPendingGrContextIO,
283                                        GrSurfaceOrigin* origin = nullptr) {
284     return GetBackendTextureFromImage(img.get(), outTexture, flushPendingGrContextIO, origin);
285 }
286 
287 /** Extracts the backendTexture from an existing SkImage.
288     If the image is not already GPU-backed, the raster data will be uploaded as a texture
289     and returned.
290     If this is the only reference to the image, the old image's texture will be
291     moved out of the passed in image.
292     If the image is shared (has a refcount > 1), the texture will be copied and then returned.
293     @param context                    GPU context
294     @param image                      image, either CPU-backed or GPU-backed
295     @param backendTexture             Will be set to the underlying texture of the image.
296     @param backendTextureReleaseProc  Called when the texture is released
297     @return                           false if image cannot be uploaded.
298 */
299 SK_API bool MakeBackendTextureFromImage(GrDirectContext* context,
300                                         sk_sp<SkImage> image,
301                                         GrBackendTexture* backendTexture,
302                                         BackendTextureReleaseProc* backendTextureReleaseProc);
303 // Legacy name
GetBackendTextureFromImage(GrDirectContext * context,sk_sp<SkImage> image,GrBackendTexture * backendTexture,BackendTextureReleaseProc * backendTextureReleaseProc)304 inline bool GetBackendTextureFromImage(GrDirectContext* context,
305                                        sk_sp<SkImage> image,
306                                        GrBackendTexture* backendTexture,
307                                        BackendTextureReleaseProc* backendTextureReleaseProc) {
308     return MakeBackendTextureFromImage(context, std::move(image), backendTexture,
309                                        backendTextureReleaseProc);
310 }
311 
312 /** Returns subset of this image as a texture-backed image.
313 
314     Returns nullptr if any of the following are true:
315       - Subset is empty
316       - Subset is not contained inside the image's bounds
317       - Pixels in the source image could not be read or copied
318       - The source image is texture-backed and context does not match the source image's context.
319 
320     @param context the non-null GrDirectContext to which the subset should be uploaded.
321     @param subset  bounds of returned SkImage
322     @return        the subsetted image, uploaded as a texture, or nullptr
323 */
324 SK_API sk_sp<SkImage> SubsetTextureFrom(GrDirectContext* context,
325                                         const SkImage* img,
326                                         const SkIRect& subset);
327 
328 /** Creates a filtered SkImage on the GPU. filter processes the src image, potentially changing
329     color, position, and size. subset is the bounds of src that are processed
330     by filter. clipBounds is the expected bounds of the filtered SkImage. outSubset
331     is required storage for the actual bounds of the filtered SkImage. offset is
332     required storage for translation of returned SkImage.
333 
334     Returns nullptr if SkImage could not be created or if the recording context provided doesn't
335     match the GPU context in which the image was created. If nullptr is returned, outSubset
336     and offset are undefined.
337 
338     Useful for animation of SkImageFilter that varies size from frame to frame.
339     Returned SkImage is created larger than required by filter so that GPU texture
340     can be reused with different sized effects. outSubset describes the valid bounds
341     of GPU texture returned. offset translates the returned SkImage to keep subsequent
342     animation frames aligned with respect to each other.
343 
344     @param context     the GrRecordingContext in play - if it exists
345     @param filter      how SkImage is sampled when transformed
346     @param subset      bounds of SkImage processed by filter
347     @param clipBounds  expected bounds of filtered SkImage
348     @param outSubset   storage for returned SkImage bounds
349     @param offset      storage for returned SkImage translation
350     @return            filtered SkImage, or nullptr
351 */
352 SK_API sk_sp<SkImage> MakeWithFilter(GrRecordingContext* context,
353                                      sk_sp<SkImage> src,
354                                      const SkImageFilter* filter,
355                                      const SkIRect& subset,
356                                      const SkIRect& clipBounds,
357                                      SkIRect* outSubset,
358                                      SkIPoint* offset);
359 
360 }  // namespace SkImages
361 
362 #endif
363