Coverage Report

Created: 2024-05-20 07:14

/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