/src/skia/include/gpu/ganesh/SkImageGanesh.h
Line | Count | Source (jump to first uncovered line) |
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/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 | | |
185 | | /** Returns SkImage backed by GPU texture associated with context. Returned SkImage is |
186 | | compatible with SkSurface created with dstColorSpace. The returned SkImage respects |
187 | | mipmapped setting; if mipmapped equals skgpu::Mipmapped::kYes, the backing texture |
188 | | allocates mip map levels. |
189 | | The mipmapped parameter is effectively treated as kNo if MIP maps are not supported by the |
190 | | GPU. |
191 | | Returns original SkImage if the image is already texture-backed, the context matches, and |
192 | | mipmapped is compatible with the backing GPU texture. skgpu::Budgeted is ignored in this |
193 | | case. |
194 | | Returns nullptr if context is nullptr, or if SkImage was created with another |
195 | | GrDirectContext. |
196 | | @param GrDirectContext the GrDirectContext in play, if it exists |
197 | | @param SkImage a non-null pointer to an SkImage. |
198 | | @param skgpu::Mipmapped Whether created SkImage texture must allocate mip map levels. |
199 | | Defaults to no. |
200 | | @param skgpu::Budgeted Whether to count a newly created texture for the returned image |
201 | | counts against the context's budget. Defaults to yes. |
202 | | @return created SkImage, or nullptr |
203 | | */ |
204 | | SK_API sk_sp<SkImage> TextureFromImage(GrDirectContext*, |
205 | | const SkImage*, |
206 | | skgpu::Mipmapped = skgpu::Mipmapped::kNo, |
207 | | skgpu::Budgeted = skgpu::Budgeted::kYes); |
208 | | inline sk_sp<SkImage> TextureFromImage(GrDirectContext* ctx, |
209 | | const sk_sp<const SkImage>& img, |
210 | | skgpu::Mipmapped m = skgpu::Mipmapped::kNo, |
211 | 0 | skgpu::Budgeted b = skgpu::Budgeted::kYes) { |
212 | 0 | return TextureFromImage(ctx, img.get(), m, b); |
213 | 0 | } |
214 | | |
215 | | /** Creates a GPU-backed SkImage from SkYUVAPixmaps. |
216 | | The image will remain planar with each plane converted to a texture using the passed |
217 | | GrRecordingContext. |
218 | | SkYUVAPixmaps has a SkYUVAInfo which specifies the transformation from YUV to RGB. |
219 | | The SkColorSpace of the resulting RGB values is specified by imageColorSpace. This will |
220 | | be the SkColorSpace reported by the image and when drawn the RGB values will be converted |
221 | | from this space into the destination space (if the destination is tagged). |
222 | | Currently, this is only supported using the GPU backend and will fail if context is nullptr. |
223 | | SkYUVAPixmaps does not need to remain valid after this returns. |
224 | | @param context GPU context |
225 | | @param pixmaps The planes as pixmaps with supported SkYUVAInfo that |
226 | | specifies conversion to RGB. |
227 | | @param buildMips create internal YUVA textures as mip map if kYes. This is |
228 | | silently ignored if the context does not support mip maps. |
229 | | @param limitToMaxTextureSize downscale image to GPU maximum texture size, if necessary |
230 | | @param imageColorSpace range of colors of the resulting image; may be nullptr |
231 | | @return created SkImage, or nullptr |
232 | | */ |
233 | | SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context, |
234 | | const SkYUVAPixmaps& pixmaps, |
235 | | skgpu::Mipmapped buildMips, |
236 | | bool limitToMaxTextureSize, |
237 | | sk_sp<SkColorSpace> imageColorSpace); |
238 | | SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(GrRecordingContext* context, |
239 | | const SkYUVAPixmaps& pixmaps, |
240 | | skgpu::Mipmapped buildMips = skgpu::Mipmapped::kNo, |
241 | | bool limitToMaxTextureSize = false); |
242 | | |
243 | | /** Creates a GPU-backed SkImage from YUV[A] planar textures. This requires that the textures |
244 | | * stay valid for the lifetime of the image. The ReleaseContext can be used to know when it is |
245 | | * safe to either delete or overwrite the textures. If ReleaseProc is provided it is also called |
246 | | * before return on failure. |
247 | | @param context GPU context |
248 | | @param yuvaTextures A set of textures containing YUVA data and a description of the |
249 | | data and transformation to RGBA. |
250 | | @param imageColorSpace range of colors of the resulting image after conversion to RGB; |
251 | | may be nullptr |
252 | | @param textureReleaseProc called when the backend textures can be released |
253 | | @param releaseContext state passed to textureReleaseProc |
254 | | @return created SkImage, or nullptr |
255 | | */ |
256 | | SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context, |
257 | | const GrYUVABackendTextures& yuvaTextures, |
258 | | sk_sp<SkColorSpace> imageColorSpace, |
259 | | TextureReleaseProc textureReleaseProc = nullptr, |
260 | | ReleaseContext releaseContext = nullptr); |
261 | | SK_API sk_sp<SkImage> TextureFromYUVATextures(GrRecordingContext* context, |
262 | | const GrYUVABackendTextures& yuvaTextures); |
263 | | |
264 | | /** Retrieves the existing backend texture. If SkImage is not a Ganesh-backend texture image |
265 | | or otherwise does not have such a texture, false is returned. Otherwise, outTexture will |
266 | | be set to the image's texture. |
267 | | |
268 | | If flushPendingGrContextIO is true, completes deferred I/O operations. |
269 | | If origin in not nullptr, copies location of content drawn into SkImage. |
270 | | @param outTexture Will be set to the underlying texture of the image if non-null. |
271 | | @param flushPendingGrContextIO flag to flush outstanding requests |
272 | | @param origin Will be set to the origin orientation of the image if non-null. |
273 | | @return false if a Ganesh backend texture cannot be retrieved. |
274 | | */ |
275 | | SK_API bool GetBackendTextureFromImage(const SkImage* img, |
276 | | GrBackendTexture* outTexture, |
277 | | bool flushPendingGrContextIO, |
278 | | GrSurfaceOrigin* origin = nullptr); |
279 | | inline bool GetBackendTextureFromImage(const sk_sp<const SkImage>& img, |
280 | | GrBackendTexture* outTexture, |
281 | | bool flushPendingGrContextIO, |
282 | 0 | GrSurfaceOrigin* origin = nullptr) { |
283 | 0 | return GetBackendTextureFromImage(img.get(), outTexture, flushPendingGrContextIO, origin); |
284 | 0 | } |
285 | | |
286 | | /** Extracts the backendTexture from an existing SkImage. |
287 | | If the image is not already GPU-backed, the raster data will be uploaded as a texture |
288 | | and returned. |
289 | | If this is the only reference to the image, the old image's texture will be |
290 | | moved out of the passed in image. |
291 | | If the image is shared (has a refcount > 1), the texture will be copied and then returned. |
292 | | @param context GPU context |
293 | | @param image image, either CPU-backed or GPU-backed |
294 | | @param backendTexture Will be set to the underlying texture of the image. |
295 | | @param backendTextureReleaseProc Called when the texture is released |
296 | | @return false if image cannot be uploaded. |
297 | | */ |
298 | | SK_API bool MakeBackendTextureFromImage(GrDirectContext* context, |
299 | | sk_sp<SkImage> image, |
300 | | GrBackendTexture* backendTexture, |
301 | | BackendTextureReleaseProc* backendTextureReleaseProc); |
302 | | // Legacy name |
303 | | inline bool GetBackendTextureFromImage(GrDirectContext* context, |
304 | | sk_sp<SkImage> image, |
305 | | GrBackendTexture* backendTexture, |
306 | 0 | BackendTextureReleaseProc* backendTextureReleaseProc) { |
307 | 0 | return MakeBackendTextureFromImage(context, std::move(image), backendTexture, |
308 | 0 | backendTextureReleaseProc); |
309 | 0 | } |
310 | | |
311 | | /** Returns subset of this image as a texture-backed image. |
312 | | |
313 | | Returns nullptr if any of the following are true: |
314 | | - Subset is empty |
315 | | - Subset is not contained inside the image's bounds |
316 | | - Pixels in the source image could not be read or copied |
317 | | - The source image is texture-backed and context does not match the source image's context. |
318 | | |
319 | | @param context the non-null GrDirectContext to which the subset should be uploaded. |
320 | | @param subset bounds of returned SkImage |
321 | | @return the subsetted image, uploaded as a texture, or nullptr |
322 | | */ |
323 | | SK_API sk_sp<SkImage> SubsetTextureFrom(GrDirectContext* context, |
324 | | const SkImage* img, |
325 | | const SkIRect& subset); |
326 | | |
327 | | /** Creates a filtered SkImage on the GPU. filter processes the src image, potentially changing |
328 | | color, position, and size. subset is the bounds of src that are processed |
329 | | by filter. clipBounds is the expected bounds of the filtered SkImage. outSubset |
330 | | is required storage for the actual bounds of the filtered SkImage. offset is |
331 | | required storage for translation of returned SkImage. |
332 | | |
333 | | Returns nullptr if SkImage could not be created or if the recording context provided doesn't |
334 | | match the GPU context in which the image was created. If nullptr is returned, outSubset |
335 | | and offset are undefined. |
336 | | |
337 | | Useful for animation of SkImageFilter that varies size from frame to frame. |
338 | | Returned SkImage is created larger than required by filter so that GPU texture |
339 | | can be reused with different sized effects. outSubset describes the valid bounds |
340 | | of GPU texture returned. offset translates the returned SkImage to keep subsequent |
341 | | animation frames aligned with respect to each other. |
342 | | |
343 | | @param context the GrRecordingContext in play - if it exists |
344 | | @param filter how SkImage is sampled when transformed |
345 | | @param subset bounds of SkImage processed by filter |
346 | | @param clipBounds expected bounds of filtered SkImage |
347 | | @param outSubset storage for returned SkImage bounds |
348 | | @param offset storage for returned SkImage translation |
349 | | @return filtered SkImage, or nullptr |
350 | | */ |
351 | | SK_API sk_sp<SkImage> MakeWithFilter(GrRecordingContext* context, |
352 | | sk_sp<SkImage> src, |
353 | | const SkImageFilter* filter, |
354 | | const SkIRect& subset, |
355 | | const SkIRect& clipBounds, |
356 | | SkIRect* outSubset, |
357 | | SkIPoint* offset); |
358 | | |
359 | | } // namespace SkImages |
360 | | |
361 | | #endif |