Coverage Report

Created: 2024-09-14 07:19

/src/skia/include/gpu/graphite/Image.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 skgpu_graphite_Image_DEFINED
9
#define skgpu_graphite_Image_DEFINED
10
11
#include "include/core/SkColorSpace.h"
12
#include "include/core/SkImage.h"
13
#include "include/core/SkRefCnt.h"
14
#include "include/core/SkSpan.h"
15
#include "include/gpu/GpuTypes.h"
16
17
#include <string_view>
18
19
class SkYUVAInfo;
20
class SkYUVAPixmaps;
21
struct SkIRect;
22
23
namespace skgpu::graphite {
24
    class BackendTexture;
25
    class Recorder;
26
    class TextureInfo;
27
    class YUVABackendTextureInfo;
28
    class YUVABackendTextures;
29
    enum class Volatile : bool;
30
}
31
32
namespace SkImages {
33
enum class GenerateMipmapsFromBase : bool { kNo, kYes };
34
35
using TextureReleaseProc = void (*)(ReleaseContext);
36
37
// Passed to imageRelease
38
using GraphitePromiseImageContext = void*;
39
// Passed to fulfill; for non-YUVA promise images, the image context is used as the fulfill context,
40
// while YUVA promise images have a per-plane fulfill context.
41
using GraphitePromiseTextureFulfillContext = void*;
42
// Returned from fulfill and passed into textureRelease
43
using GraphitePromiseTextureReleaseContext = void*;
44
45
using GraphitePromiseTextureFulfillProc =
46
        std::tuple<skgpu::graphite::BackendTexture, GraphitePromiseTextureReleaseContext> (*)(
47
                GraphitePromiseTextureFulfillContext);
48
using GraphitePromiseImageReleaseProc = void (*)(GraphitePromiseImageContext);
49
using GraphitePromiseTextureReleaseProc = void (*)(GraphitePromiseTextureReleaseContext);
50
51
/** Creates an SkImage from a GPU texture associated with the recorder. The client is still
52
    responsible for managing the backend texture's lifetime.
53
54
    SkImage is returned if the format of backendTexture is recognized and supported.
55
    Recognized formats vary by GPU back-end.
56
57
    @param recorder                The recorder
58
    @param backendTexture          texture residing on GPU
59
    @param colorSpace              This describes the color space of this image's contents, as
60
                                   seen after sampling. In general, if the format of the backend
61
                                   texture is SRGB, some linear colorSpace should be supplied
62
                                   (e.g., SkColorSpace::MakeSRGBLinear()). If the format of the
63
                                   backend texture is linear, then the colorSpace should include
64
                                   a description of the transfer function as
65
                                   well (e.g., SkColorSpace::MakeSRGB()).
66
    @param origin                  Whether the Texture logically treats the origin as TopLeft or
67
                                   BottomLeft
68
    @param generateMipmapsFromBase If kYes then the pixel contents of the textures upper mipmap
69
                                   levels are generated by successive downsampling of the base
70
                                   level. If the texture is not mipmapped or isn't renderable then
71
                                   image creation will fail. If kNo and the texture is mipmapped
72
                                   then the contents of upper levels are assumed to already be
73
                                   valid.
74
    @return                        created SkImage, or nullptr
75
*/
76
SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*,
77
                                  const skgpu::graphite::BackendTexture&,
78
                                  SkColorType colorType,
79
                                  SkAlphaType alphaType,
80
                                  sk_sp<SkColorSpace> colorSpace,
81
                                  skgpu::Origin origin,
82
                                  GenerateMipmapsFromBase generateMipmapsFromBase,
83
                                  TextureReleaseProc = nullptr,
84
                                  ReleaseContext = nullptr,
85
                                  std::string_view label = {});
86
87
SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*,
88
                                  const skgpu::graphite::BackendTexture&,
89
                                  SkColorType colorType,
90
                                  SkAlphaType alphaType,
91
                                  sk_sp<SkColorSpace> colorSpace,
92
                                  skgpu::Origin origin,
93
                                  TextureReleaseProc = nullptr,
94
                                  ReleaseContext = nullptr,
95
                                  std::string_view label = {});
96
97
SK_API sk_sp<SkImage> WrapTexture(skgpu::graphite::Recorder*,
98
                                  const skgpu::graphite::BackendTexture&,
99
                                  SkColorType colorType,
100
                                  SkAlphaType alphaType,
101
                                  sk_sp<SkColorSpace> colorSpace,
102
                                  TextureReleaseProc = nullptr,
103
                                  ReleaseContext = nullptr,
104
                                  std::string_view label = {});
105
106
/** Create a new SkImage that is very similar to an SkImage created by WrapTexture. The difference
107
    is that the caller need not have created the backend texture nor populated it with data when
108
    creating the image. Instead of passing a BackendTexture to the factory the client supplies a
109
    description of the texture consisting of dimensions, TextureInfo, SkColorInfo and Volatility.
110
111
    In general, 'fulfill' must return a BackendTexture that matches the properties provided at
112
    SkImage creation time. The BackendTexture must refer to a valid existing texture in the backend
113
    API context/device, and already be populated with data. The texture cannot be deleted until
114
    'textureRelease' is called. 'textureRelease' will be called with the textureReleaseContext
115
    returned by 'fulfill'.
116
117
    Wrt when and how often the fulfill, imageRelease, and textureRelease callbacks will be called:
118
119
    For non-volatile promise images, 'fulfill' will be called at Context::insertRecording time.
120
    Regardless of whether 'fulfill' succeeded or failed, 'imageRelease' will always be called only
121
    once - when Skia will no longer try calling 'fulfill' to get a backend texture. If 'fulfill'
122
    failed (i.e., it didn't return a valid backend texture) then 'textureRelease' will never be
123
    called. If 'fulfill' was successful then 'textureRelease' will be called only once when the GPU
124
    is done with the contents of the promise image. This will usually occur during a Context::submit
125
    call but it could occur earlier due to error conditions. 'fulfill' can be called multiple times
126
    if the promise image is used in multiple recordings. If 'fulfill' fails, the insertRecording
127
    itself will fail. Subsequent insertRecording calls (with Recordings that use the promise image)
128
    will keep calling 'fulfill' until it succeeds.
129
130
    For volatile promise images, 'fulfill' will be called each time the Recording is inserted into a
131
    Context. Regardless of whether 'fulfill' succeeded or failed, 'imageRelease' will always be
132
    called only once just like the non-volatile case. If 'fulfill' fails at insertRecording-time,
133
    'textureRelease' will never be called. If 'fulfill' was successful then a 'textureRelease'
134
    matching that 'fulfill' will be called when the GPU is done with the contents of the promise
135
    image. This will usually occur during a Context::submit call but it could occur earlier due to
136
    error conditions.
137
138
    @param recorder       the recorder that will capture the commands creating the image
139
    @param dimensions     width & height of promised gpu texture
140
    @param textureInfo    structural information for the promised gpu texture
141
    @param colorInfo      color type, alpha type and colorSpace information for the image
142
    @param origin         Whether the Texture logically treats the origin as TopLeft or BottomLeft
143
    @param isVolatile     volatility of the promise image
144
    @param fulfill        function called to get the actual backend texture,
145
                          and the instance for the GraphitePromiseTextureReleaseProc
146
    @param imageRelease   function called when any image-centric data can be deleted
147
    @param textureRelease function called when the backend texture can be deleted
148
    @param imageContext   state passed to fulfill and imageRelease
149
    @return               created SkImage, or nullptr
150
*/
151
SK_API sk_sp<SkImage> PromiseTextureFrom(skgpu::graphite::Recorder*,
152
                                         SkISize dimensions,
153
                                         const skgpu::graphite::TextureInfo&,
154
                                         const SkColorInfo&,
155
                                         skgpu::Origin origin,
156
                                         skgpu::graphite::Volatile,
157
                                         GraphitePromiseTextureFulfillProc,
158
                                         GraphitePromiseImageReleaseProc,
159
                                         GraphitePromiseTextureReleaseProc,
160
                                         GraphitePromiseImageContext,
161
                                         std::string_view label = {});
162
163
SK_API sk_sp<SkImage> PromiseTextureFrom(skgpu::graphite::Recorder*,
164
                                         SkISize dimensions,
165
                                         const skgpu::graphite::TextureInfo&,
166
                                         const SkColorInfo&,
167
                                         skgpu::graphite::Volatile,
168
                                         GraphitePromiseTextureFulfillProc,
169
                                         GraphitePromiseImageReleaseProc,
170
                                         GraphitePromiseTextureReleaseProc,
171
                                         GraphitePromiseImageContext);
172
173
/** This is similar to 'PromiseTextureFrom' but it creates a GPU-backed SkImage from YUV[A] data.
174
    The source data may be planar (i.e. spread across multiple textures). In the extreme Y, U, V,
175
    and A are all in different planes and thus the image is specified by four textures.
176
    'backendTextureInfo' describes the planar arrangement, texture formats, and conversion to RGB.
177
    Separate 'fulfill' and 'textureRelease' calls are made for each texture. Each texture has its
178
    own GraphitePromiseFulfillContext. The GraphitePromiseImageReleaseProc will be made even on
179
    failure. 'planeContexts' has one entry for each of the up to four textures, as indicated by
180
    'backendTextureInfo'. Currently the mipmapped property of 'backendTextureInfo' is ignored.
181
    However, in the near future it will be required that if it is kYes then the fulfillProc must
182
    return a mip mapped texture for each plane in order to successfully draw the image.
183
184
    @param recorder            the recorder that will capture the commands creating the image
185
    @param backendTextureInfo  info about the promised yuva gpu texture(s)
186
    @param imageColorSpace     range of colors; may be nullptr
187
    @param isVolatile          volatility of the promise image
188
    @param fulfill             function called to get the actual backend texture for
189
                               a given GraphitePromiseTextureContext, and the instance
190
                               for the GraphitePromiseTextureReleaseProc
191
    @param imageRelease        function called when any image-centric data can be deleted
192
    @param textureRelease      function called when the backend texture can be deleted
193
    @param imageContext        state passed to imageRelease
194
    @param planeContexts       states passed to fulfill for each plane
195
    @return                    created SkImage, or nullptr
196
*/
197
SK_API sk_sp<SkImage> PromiseTextureFromYUVA(skgpu::graphite::Recorder*,
198
                                             const skgpu::graphite::YUVABackendTextureInfo&,
199
                                             sk_sp<SkColorSpace> imageColorSpace,
200
                                             skgpu::graphite::Volatile,
201
                                             GraphitePromiseTextureFulfillProc,
202
                                             GraphitePromiseImageReleaseProc,
203
                                             GraphitePromiseTextureReleaseProc,
204
                                             GraphitePromiseImageContext imageContext,
205
                                             GraphitePromiseTextureFulfillContext planeContexts[],
206
                                             std::string_view label = {});
207
208
209
/** Returns an SkImage backed by a Graphite texture, using the provided Recorder for creation and
210
    uploads if necessary. The returned SkImage respects the required image properties' mipmap
211
    setting for non-Graphite SkImages; i.e., if mipmapping is required, the backing Graphite texture
212
    will have allocated mip map levels.
213
214
    It is assumed that MIP maps are always supported by the GPU.
215
216
    Returns original SkImage if the image is already Graphite-backed and the required mipmapping is
217
    compatible with the backing Graphite texture. If the required mipmapping is not compatible,
218
    nullptr will be returned.
219
220
    Returns nullptr if no Recorder is provided, or if SkImage was created with another Recorder and
221
    work on that Recorder has not been submitted.
222
223
    @param Recorder            the Recorder to use for storing commands
224
    @param RequiredProperties  properties the returned SkImage must possess (e.g. mipmaps)
225
    @return                    created SkImage, or nullptr
226
*/
227
SK_API sk_sp<SkImage> TextureFromImage(skgpu::graphite::Recorder*,
228
                                       const SkImage*,
229
                                       SkImage::RequiredProperties = {});
230
231
inline sk_sp<SkImage> TextureFromImage(skgpu::graphite::Recorder* r,
232
                                       const sk_sp<const SkImage>& img,
233
0
                                       SkImage::RequiredProperties props = {}) {
234
0
    return TextureFromImage(r, img.get(), props);
235
0
}
236
237
/** Creates SkImage from SkYUVAPixmaps.
238
239
    The image will remain planar with each plane converted to a texture using the passed Recorder.
240
241
    SkYUVAPixmaps has a SkYUVAInfo which specifies the transformation from YUV to RGB. The
242
    SkColorSpace of the resulting RGB values is specified by imgColorSpace. This will be the
243
    SkColorSpace reported by the image and when drawn the RGB values will be converted from this
244
    space into the destination space (if the destination is tagged).
245
246
    This is only supported using the GPU backend and will fail if recorder is nullptr.
247
248
    SkYUVAPixmaps does not need to remain valid after this returns.
249
250
    @param Recorder                 The Recorder to use for storing commands
251
    @param pixmaps                  The planes as pixmaps with supported SkYUVAInfo that
252
                                    specifies conversion to RGB.
253
    @param RequiredProperties       Properties the returned SkImage must possess (e.g. mipmaps)
254
    @param limitToMaxTextureSize    Downscale image to GPU maximum texture size, if necessary
255
    @param imgColorSpace            Range of colors of the resulting image; may be nullptr
256
    @return                         Created SkImage, or nullptr
257
*/
258
SK_API sk_sp<SkImage> TextureFromYUVAPixmaps(skgpu::graphite::Recorder*,
259
                                             const SkYUVAPixmaps& pixmaps,
260
                                             SkImage::RequiredProperties = {},
261
                                             bool limitToMaxTextureSize = false,
262
                                             sk_sp<SkColorSpace> imgColorSpace = nullptr,
263
                                             std::string_view label = {});
264
265
/** Creates an SkImage from YUV[A] planar textures associated with the recorder.
266
     @param recorder            The recorder.
267
     @param yuvaBackendTextures A set of textures containing YUVA data and a description of the
268
                                data and transformation to RGBA.
269
     @param imageColorSpace     range of colors of the resulting image after conversion to RGB;
270
                                may be nullptr
271
     @param TextureReleaseProc  called when the backend textures can be released
272
     @param ReleaseContext      state passed to TextureReleaseProc
273
     @return                    created SkImage, or nullptr
274
 */
275
SK_API sk_sp<SkImage> TextureFromYUVATextures(
276
        skgpu::graphite::Recorder* recorder,
277
        const skgpu::graphite::YUVABackendTextures& yuvaBackendTextures,
278
        sk_sp<SkColorSpace> imageColorSpace,
279
        TextureReleaseProc = nullptr,
280
        ReleaseContext = nullptr,
281
        std::string_view label = {});
282
283
/** Creates an SkImage from YUV[A] planar SkImages associated with the recorder.
284
285
    The images should have kGraphite type, and the result will be nullptr if any are not. The
286
    resulting SkImage will not take a ref on the given SkImages but will take a ref on the
287
    underlying TextureProxies. The releaseProcs, if any, for those Textures will be the ones set
288
    when the given SkImages were created.
289
290
     @param recorder            The recorder.
291
     @param yuvaInfo            Structure describing the YUVA format
292
     @param images              A set of SkImages containing YUVA data
293
     @param imageColorSpace     Range of colors of the resulting image after conversion to RGB;
294
                                may be nullptr
295
     @return                    created SkImage, or nullptr
296
 */
297
SK_API sk_sp<SkImage> TextureFromYUVAImages(
298
        skgpu::graphite::Recorder* recorder,
299
        const SkYUVAInfo& yuvaInfo,
300
        SkSpan<const sk_sp<SkImage>> images,
301
        sk_sp<SkColorSpace> imageColorSpace);
302
303
/** Returns subset of this image as a texture-backed image.
304
305
    Returns nullptr if any of the following are true:
306
      - Subset is empty
307
      - Subset is not contained inside the image's bounds
308
      - Pixels in the source image could not be read or copied
309
      - The source image is texture-backed and context does not match the source image's context.
310
311
    @param recorder the non-null recorder in which to create the new image.
312
    @param img     Source image
313
    @param subset  bounds of returned SkImage
314
    @param props   properties the returned SkImage must possess (e.g. mipmaps)
315
    @return        the subsetted image, uploaded as a texture, or nullptr
316
*/
317
SK_API sk_sp<SkImage> SubsetTextureFrom(skgpu::graphite::Recorder* recorder,
318
                                        const SkImage* img,
319
                                        const SkIRect& subset,
320
                                        SkImage::RequiredProperties props = {});
321
322
/** Creates a filtered SkImage on the GPU. filter processes the src image, potentially changing
323
    color, position, and size. subset is the bounds of src that are processed by filter. clipBounds
324
    is the expected bounds of the filtered SkImage. outSubset is required storage for the actual
325
    bounds of the filtered SkImage. offset is required storage for translation of returned SkImage.
326
327
    Returns nullptr if SkImage could not be created. If nullptr is returned, outSubset and offset
328
    are undefined.
329
330
    Useful for animation of SkImageFilter that varies size from frame to frame. Returned SkImage is
331
    created larger than required by filter so that GPU texture can be reused with different sized
332
    effects. outSubset describes the valid bounds of GPU texture returned. offset translates the
333
    returned SkImage to keep subsequent animation frames aligned with respect to each other.
334
335
    @param recorder    the recorder in which the filtering operation is to be performed
336
    @param filter      how SkImage is sampled when transformed
337
    @param subset      bounds of SkImage processed by filter
338
    @param clipBounds  expected bounds of filtered SkImage
339
    @param outSubset   storage for returned SkImage bounds
340
    @param offset      storage for returned SkImage translation
341
    @return            filtered SkImage, or nullptr
342
*/
343
SK_API sk_sp<SkImage> MakeWithFilter(skgpu::graphite::Recorder* recorder,
344
                                     sk_sp<SkImage> src,
345
                                     const SkImageFilter* filter,
346
                                     const SkIRect& subset,
347
                                     const SkIRect& clipBounds,
348
                                     SkIRect* outSubset,
349
                                     SkIPoint* offset);
350
351
} // namespace SkImages
352
353
354
#endif // skgpu_graphite_Image_DEFINED