• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Google Inc.
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 SkSurface_DEFINED
9 #define SkSurface_DEFINED
10 
11 #include "include/core/SkImage.h"
12 #include "include/core/SkImageInfo.h"
13 #include "include/core/SkPixmap.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkSamplingOptions.h"
16 #include "include/core/SkScalar.h"
17 #include "include/core/SkSurfaceProps.h"
18 #include "include/core/SkTypes.h"
19 
20 #if defined(SK_GANESH)
21 #include "include/gpu/GrTypes.h"
22 #else
23 enum GrSurfaceOrigin: int;
24 #endif
25 
26 #if defined(SK_GRAPHITE)
27 #include "include/gpu/GpuTypes.h"
28 #include "include/gpu/GrTypes.h"
29 #endif
30 
31 #if defined(SK_GRAPHITE)
32 #include "include/gpu/GpuTypes.h"
33 namespace skgpu::graphite {
34 class BackendTexture;
35 }
36 #endif
37 
38 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
39 #include <android/hardware_buffer.h>
40 class GrDirectContext;
41 #endif
42 
43 #if defined(SK_GANESH) && defined(SK_METAL)
44 #include "include/gpu/mtl/GrMtlTypes.h"
45 #endif
46 
47 #include <cstddef>
48 #include <cstdint>
49 #include <memory>
50 
51 class GrBackendRenderTarget;
52 class GrBackendSemaphore;
53 class GrBackendTexture;
54 class GrRecordingContext;
55 class SkBitmap;
56 class SkCanvas;
57 class SkCapabilities;
58 class SkColorSpace;
59 class SkDeferredDisplayList;
60 class SkPaint;
61 class SkSurfaceCharacterization;
62 enum SkColorType : int;
63 struct SkIRect;
64 struct SkISize;
65 
66 namespace skgpu {
67 class MutableTextureState;
68 enum class Budgeted : bool;
69 }
70 
71 namespace skgpu::graphite {
72 class Recorder;
73 }
74 
75 /** \class SkSurface
76     SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be
77     allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface).
78     SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
79     surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface).
80     SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
81     of the requested dimensions are zero, then nullptr will be returned.
82 */
83 class SK_API SkSurface : public SkRefCnt {
84 public:
85 
86     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
87 
88         SkSurface is returned if all parameters are valid.
89         Valid parameters include:
90         info dimensions are greater than zero;
91         info contains SkColorType and SkAlphaType supported by raster surface;
92         pixels is not nullptr;
93         rowBytes is large enough to contain info width pixels of SkColorType.
94 
95         Pixel buffer size should be info height times computed rowBytes.
96         Pixels are not initialized.
97         To access pixels after drawing, peekPixels() or readPixels().
98 
99         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
100                              of raster surface; width and height must be greater than zero
101         @param pixels        pointer to destination pixels buffer
102         @param rowBytes      interval from one SkSurface row to the next
103         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
104                              may be nullptr
105         @return              SkSurface if all parameters are valid; otherwise, nullptr
106     */
107     static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
108                                              size_t rowBytes,
109                                              const SkSurfaceProps* surfaceProps = nullptr);
110 
111     static sk_sp<SkSurface> MakeRasterDirect(const SkPixmap& pm,
112                                              const SkSurfaceProps* props = nullptr) {
113         return MakeRasterDirect(pm.info(), pm.writable_addr(), pm.rowBytes(), props);
114     }
115 
116     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
117         releaseProc is called with pixels and context when SkSurface is deleted.
118 
119         SkSurface is returned if all parameters are valid.
120         Valid parameters include:
121         info dimensions are greater than zero;
122         info contains SkColorType and SkAlphaType supported by raster surface;
123         pixels is not nullptr;
124         rowBytes is large enough to contain info width pixels of SkColorType.
125 
126         Pixel buffer size should be info height times computed rowBytes.
127         Pixels are not initialized.
128         To access pixels after drawing, call flush() or peekPixels().
129 
130         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
131                              of raster surface; width and height must be greater than zero
132         @param pixels        pointer to destination pixels buffer
133         @param rowBytes      interval from one SkSurface row to the next
134         @param releaseProc   called when SkSurface is deleted; may be nullptr
135         @param context       passed to releaseProc; may be nullptr
136         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
137                              may be nullptr
138         @return              SkSurface if all parameters are valid; otherwise, nullptr
139     */
140     static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
141                                     size_t rowBytes,
142                                     void (*releaseProc)(void* pixels, void* context),
143                                     void* context, const SkSurfaceProps* surfaceProps = nullptr);
144 
145     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
146         Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
147         rowBytes, or times imageInfo.minRowBytes() if rowBytes is zero.
148         Pixel memory is deleted when SkSurface is deleted.
149 
150         SkSurface is returned if all parameters are valid.
151         Valid parameters include:
152         info dimensions are greater than zero;
153         info contains SkColorType and SkAlphaType supported by raster surface;
154         rowBytes is large enough to contain info width pixels of SkColorType, or is zero.
155 
156         If rowBytes is zero, a suitable value will be chosen internally.
157 
158         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
159                              of raster surface; width and height must be greater than zero
160         @param rowBytes      interval from one SkSurface row to the next; may be zero
161         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
162                              may be nullptr
163         @return              SkSurface if all parameters are valid; otherwise, nullptr
164     */
165     static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
166                                        const SkSurfaceProps* surfaceProps);
167 
168     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
169         Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
170         imageInfo.minRowBytes().
171         Pixel memory is deleted when SkSurface is deleted.
172 
173         SkSurface is returned if all parameters are valid.
174         Valid parameters include:
175         info dimensions are greater than zero;
176         info contains SkColorType and SkAlphaType supported by raster surface.
177 
178         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
179                           of raster surface; width and height must be greater than zero
180         @param props      LCD striping orientation and setting for device independent fonts;
181                           may be nullptr
182         @return           SkSurface if all parameters are valid; otherwise, nullptr
183     */
184     static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
185                                        const SkSurfaceProps* props = nullptr) {
186         return MakeRaster(imageInfo, 0, props);
187     }
188 
189     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
190         Allocates and zeroes pixel memory. Pixel memory size is height times width times
191         four. Pixel memory is deleted when SkSurface is deleted.
192 
193         Internally, sets SkImageInfo to width, height, native color type, and
194         kPremul_SkAlphaType.
195 
196         SkSurface is returned if width and height are greater than zero.
197 
198         Use to create SkSurface that matches SkPMColor, the native pixel arrangement on
199         the platform. SkSurface drawn to output device skips converting its pixel format.
200 
201         @param width         pixel column count; must be greater than zero
202         @param height        pixel row count; must be greater than zero
203         @param surfaceProps  LCD striping orientation and setting for device independent
204                              fonts; may be nullptr
205         @return              SkSurface if all parameters are valid; otherwise, nullptr
206     */
207     static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
208                                                 const SkSurfaceProps* surfaceProps = nullptr);
209 
210     /** Caller data passed to RenderTarget/TextureReleaseProc; may be nullptr. */
211     typedef void* ReleaseContext;
212 
213     /** User function called when supplied render target may be deleted. */
214     typedef void (*RenderTargetReleaseProc)(ReleaseContext releaseContext);
215 
216     /** User function called when supplied texture may be deleted. */
217     typedef void (*TextureReleaseProc)(ReleaseContext releaseContext);
218 
219     /** Wraps a GPU-backed texture into SkSurface. Caller must ensure the texture is
220         valid for the lifetime of returned SkSurface. If sampleCnt greater than zero,
221         creates an intermediate MSAA SkSurface which is used for drawing backendTexture.
222 
223         SkSurface is returned if all parameters are valid. backendTexture is valid if
224         its pixel configuration agrees with colorSpace and context; for instance, if
225         backendTexture has an sRGB configuration, then context must support sRGB,
226         and colorSpace must be present. Further, backendTexture width and height must
227         not exceed context capabilities, and the context must be able to support
228         back-end textures.
229 
230         Upon success textureReleaseProc is called when it is safe to delete the texture in the
231         backend API (accounting only for use of the texture by this surface). If SkSurface creation
232         fails textureReleaseProc is called before this function returns.
233 
234         If defined(SK_GANESH) is defined as zero, has no effect and returns nullptr.
235 
236         @param context             GPU context
237         @param backendTexture      texture residing on GPU
238         @param sampleCnt           samples per pixel, or 0 to disable full scene anti-aliasing
239         @param colorSpace          range of colors; may be nullptr
240         @param surfaceProps        LCD striping orientation and setting for device independent
241                                    fonts; may be nullptr
242         @param textureReleaseProc  function called when texture can be released
243         @param releaseContext      state passed to textureReleaseProc
244         @return                    SkSurface if all parameters are valid; otherwise, nullptr
245     */
246     static sk_sp<SkSurface> MakeFromBackendTexture(GrRecordingContext* context,
247                                                    const GrBackendTexture& backendTexture,
248                                                    GrSurfaceOrigin origin, int sampleCnt,
249                                                    SkColorType colorType,
250                                                    sk_sp<SkColorSpace> colorSpace,
251                                                    const SkSurfaceProps* surfaceProps,
252                                                    TextureReleaseProc textureReleaseProc = nullptr,
253                                                    ReleaseContext releaseContext = nullptr);
254 
255     /** Wraps a GPU-backed buffer into SkSurface. Caller must ensure backendRenderTarget
256         is valid for the lifetime of returned SkSurface.
257 
258         SkSurface is returned if all parameters are valid. backendRenderTarget is valid if
259         its pixel configuration agrees with colorSpace and context; for instance, if
260         backendRenderTarget has an sRGB configuration, then context must support sRGB,
261         and colorSpace must be present. Further, backendRenderTarget width and height must
262         not exceed context capabilities, and the context must be able to support
263         back-end render targets.
264 
265         Upon success releaseProc is called when it is safe to delete the render target in the
266         backend API (accounting only for use of the render target by this surface). If SkSurface
267         creation fails releaseProc is called before this function returns.
268 
269         If defined(SK_GANESH) is defined as zero, has no effect and returns nullptr.
270 
271         @param context                  GPU context
272         @param backendRenderTarget      GPU intermediate memory buffer
273         @param colorSpace               range of colors
274         @param surfaceProps             LCD striping orientation and setting for device independent
275                                         fonts; may be nullptr
276         @param releaseProc              function called when backendRenderTarget can be released
277         @param releaseContext           state passed to releaseProc
278         @return                         SkSurface if all parameters are valid; otherwise, nullptr
279     */
280     static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrRecordingContext* context,
281                                                 const GrBackendRenderTarget& backendRenderTarget,
282                                                 GrSurfaceOrigin origin,
283                                                 SkColorType colorType,
284                                                 sk_sp<SkColorSpace> colorSpace,
285                                                 const SkSurfaceProps* surfaceProps,
286                                                 RenderTargetReleaseProc releaseProc = nullptr,
287                                                 ReleaseContext releaseContext = nullptr);
288 
289     /** Returns SkSurface on GPU indicated by context. Allocates memory for
290         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
291         selects whether allocation for pixels is tracked by context. imageInfo
292         describes the pixel format in SkColorType, and transparency in
293         SkAlphaType, and color matching in SkColorSpace.
294 
295         sampleCount requests the number of samples per pixel.
296         Pass zero to disable multi-sample anti-aliasing.  The request is rounded
297         up to the next supported count, or rounded down if it is larger than the
298         maximum supported count.
299 
300         surfaceOrigin pins either the top-left or the bottom-left corner to the origin.
301 
302         shouldCreateWithMips hints that SkImage returned by makeImageSnapshot() is mip map.
303 
304         If defined(SK_GANESH) is defined as zero, has no effect and returns nullptr.
305 
306         @param context               GPU context
307         @param imageInfo             width, height, SkColorType, SkAlphaType, SkColorSpace;
308                                      width, or height, or both, may be zero
309         @param sampleCount           samples per pixel, or 0 to disable full scene anti-aliasing
310         @param surfaceProps          LCD striping orientation and setting for device independent
311                                      fonts; may be nullptr
312         @param shouldCreateWithMips  hint that SkSurface will host mip map images
313         @return                      SkSurface if all parameters are valid; otherwise, nullptr
314     */
315     static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
316                                              skgpu::Budgeted budgeted,
317                                              const SkImageInfo& imageInfo,
318                                              int sampleCount,
319                                              GrSurfaceOrigin surfaceOrigin,
320                                              const SkSurfaceProps* surfaceProps,
321                                              bool shouldCreateWithMips = false);
322 
323     /** Returns SkSurface on GPU indicated by context. Allocates memory for
324         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
325         selects whether allocation for pixels is tracked by context. imageInfo
326         describes the pixel format in SkColorType, and transparency in
327         SkAlphaType, and color matching in SkColorSpace.
328 
329         sampleCount requests the number of samples per pixel.
330         Pass zero to disable multi-sample anti-aliasing.  The request is rounded
331         up to the next supported count, or rounded down if it is larger than the
332         maximum supported count.
333 
334         SkSurface bottom-left corner is pinned to the origin.
335 
336         @param context      GPU context
337         @param imageInfo    width, height, SkColorType, SkAlphaType, SkColorSpace,
338                             of raster surface; width, or height, or both, may be zero
339         @param sampleCount  samples per pixel, or 0 to disable multi-sample anti-aliasing
340         @param surfaceProps LCD striping orientation and setting for device independent
341                             fonts; may be nullptr
342         @return             SkSurface if all parameters are valid; otherwise, nullptr
343     */
MakeRenderTarget(GrRecordingContext * context,skgpu::Budgeted budgeted,const SkImageInfo & imageInfo,int sampleCount,const SkSurfaceProps * surfaceProps)344     static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
345                                              skgpu::Budgeted budgeted,
346                                              const SkImageInfo& imageInfo,
347                                              int sampleCount,
348                                              const SkSurfaceProps* surfaceProps) {
349 #if defined(SK_GANESH)
350         return MakeRenderTarget(context, budgeted, imageInfo, sampleCount,
351                                 kBottomLeft_GrSurfaceOrigin, surfaceProps);
352 #else
353         // TODO(kjlubick, scroggo) Remove this once Android is updated.
354         return nullptr;
355 #endif
356     }
357 
358     /** Returns SkSurface on GPU indicated by context. Allocates memory for
359         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
360         selects whether allocation for pixels is tracked by context. imageInfo
361         describes the pixel format in SkColorType, and transparency in
362         SkAlphaType, and color matching in SkColorSpace.
363 
364         SkSurface bottom-left corner is pinned to the origin.
365 
366         @param context    GPU context
367         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
368                           of raster surface; width, or height, or both, may be zero
369         @return           SkSurface if all parameters are valid; otherwise, nullptr
370     */
MakeRenderTarget(GrRecordingContext * context,skgpu::Budgeted budgeted,const SkImageInfo & imageInfo)371     static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
372                                              skgpu::Budgeted budgeted,
373                                              const SkImageInfo& imageInfo) {
374 #if defined(SK_GANESH)
375         if (!imageInfo.width() || !imageInfo.height()) {
376             return nullptr;
377         }
378         return MakeRenderTarget(context, budgeted, imageInfo, 0, kBottomLeft_GrSurfaceOrigin,
379                                 nullptr);
380 #else
381         // TODO(kjlubick, scroggo) Remove this once Android is updated.
382         return nullptr;
383 #endif
384     }
385 
386     /** Returns SkSurface on GPU indicated by context that is compatible with the provided
387         characterization. budgeted selects whether allocation for pixels is tracked by context.
388 
389         @param context           GPU context
390         @param characterization  description of the desired SkSurface
391         @return                  SkSurface if all parameters are valid; otherwise, nullptr
392     */
393     static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
394                                              const SkSurfaceCharacterization& characterization,
395                                              skgpu::Budgeted budgeted);
396 
397 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
398     /** Private.
399         Creates SkSurface from Android hardware buffer.
400         Returned SkSurface takes a reference on the buffer. The ref on the buffer will be released
401         when the SkSurface is destroyed and there is no pending work on the GPU involving the
402         buffer.
403 
404         Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
405 
406         Currently this is only supported for buffers that can be textured as well as rendered to.
407         In other words that must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
408         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE usage bits.
409 
410         @param context         GPU context
411         @param hardwareBuffer  AHardwareBuffer Android hardware buffer
412         @param colorSpace      range of colors; may be nullptr
413         @param surfaceProps    LCD striping orientation and setting for device independent
414                                fonts; may be nullptr
415         @param fromWindow      Whether or not the AHardwareBuffer is part of an Android Window.
416                                Currently only used with Vulkan backend.
417         @return                created SkSurface, or nullptr
418     */
419     static sk_sp<SkSurface> MakeFromAHardwareBuffer(GrDirectContext* context,
420                                                     AHardwareBuffer* hardwareBuffer,
421                                                     GrSurfaceOrigin origin,
422                                                     sk_sp<SkColorSpace> colorSpace,
423                                                     const SkSurfaceProps* surfaceProps
424 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
425                                                     , bool fromWindow = false
426 #endif  // SK_BUILD_FOR_ANDROID_FRAMEWORK
427                                                     );
428 #endif
429 
430 #if defined(SK_GRAPHITE)
431     /**
432      * In Graphite, while clients hold a ref on an SkSurface, the backing gpu object does _not_
433      * count against the budget. Once an SkSurface is freed, the backing gpu object may or may
434      * not become a scratch (i.e., reusable) resource but, if it does, it will be counted against
435      * the budget.
436      */
437     static sk_sp<SkSurface> MakeGraphite(
438             skgpu::graphite::Recorder*,
439             const SkImageInfo& imageInfo,
440             skgpu::Mipmapped = skgpu::Mipmapped::kNo,
441             const SkSurfaceProps* surfaceProps = nullptr);
442 
443     /**
444      * Wraps a GPU-backed texture in an SkSurface. Depending on the backend gpu API, the caller may
445      * be required to ensure the texture is valid for the lifetime of the returned SkSurface. The
446      * required lifetimes for the specific apis are:
447      *     Metal: Skia will call retain on the underlying MTLTexture so the caller can drop it once
448      *            this call returns.
449      *
450      * SkSurface is returned if all the parameters are valid. The backendTexture is valid if its
451      * format agrees with colorSpace and recorder; for instance, if backendTexture has an sRGB
452      * configuration, then the recorder must support sRGB, and colorSpace must be present. Further,
453      * backendTexture's width and height must not exceed the recorder's capabilities, and the
454      * recorder must be able to support the back-end texture.
455      */
456     static sk_sp<SkSurface> MakeGraphiteFromBackendTexture(skgpu::graphite::Recorder*,
457                                                            const skgpu::graphite::BackendTexture&,
458                                                            SkColorType colorType,
459                                                            sk_sp<SkColorSpace> colorSpace,
460                                                            const SkSurfaceProps* props);
461 
462 #endif // SK_GRAPHITE
463 
464 #if defined(SK_GANESH) && defined(SK_METAL)
465     /** Creates SkSurface from CAMetalLayer.
466         Returned SkSurface takes a reference on the CAMetalLayer. The ref on the layer will be
467         released when the SkSurface is destroyed.
468 
469         Only available when Metal API is enabled.
470 
471         Will grab the current drawable from the layer and use its texture as a backendRT to
472         create a renderable surface.
473 
474         @param context         GPU context
475         @param layer           GrMTLHandle (expected to be a CAMetalLayer*)
476         @param sampleCnt       samples per pixel, or 0 to disable full scene anti-aliasing
477         @param colorSpace      range of colors; may be nullptr
478         @param surfaceProps    LCD striping orientation and setting for device independent
479                                fonts; may be nullptr
480         @param drawable        Pointer to drawable to be filled in when this surface is
481                                instantiated; may not be nullptr
482         @return                created SkSurface, or nullptr
483      */
484     static sk_sp<SkSurface> MakeFromCAMetalLayer(GrRecordingContext* context,
485                                                  GrMTLHandle layer,
486                                                  GrSurfaceOrigin origin,
487                                                  int sampleCnt,
488                                                  SkColorType colorType,
489                                                  sk_sp<SkColorSpace> colorSpace,
490                                                  const SkSurfaceProps* surfaceProps,
491                                                  GrMTLHandle* drawable)
492                                                  SK_API_AVAILABLE_CA_METAL_LAYER;
493 
494     /** Creates SkSurface from MTKView.
495         Returned SkSurface takes a reference on the MTKView. The ref on the layer will be
496         released when the SkSurface is destroyed.
497 
498         Only available when Metal API is enabled.
499 
500         Will grab the current drawable from the layer and use its texture as a backendRT to
501         create a renderable surface.
502 
503         @param context         GPU context
504         @param layer           GrMTLHandle (expected to be a MTKView*)
505         @param sampleCnt       samples per pixel, or 0 to disable full scene anti-aliasing
506         @param colorSpace      range of colors; may be nullptr
507         @param surfaceProps    LCD striping orientation and setting for device independent
508                                fonts; may be nullptr
509         @return                created SkSurface, or nullptr
510      */
511     static sk_sp<SkSurface> MakeFromMTKView(GrRecordingContext* context,
512                                             GrMTLHandle mtkView,
513                                             GrSurfaceOrigin origin,
514                                             int sampleCnt,
515                                             SkColorType colorType,
516                                             sk_sp<SkColorSpace> colorSpace,
517                                             const SkSurfaceProps* surfaceProps)
518                                             SK_API_AVAILABLE(macos(10.11), ios(9.0));
519 #endif
520 
521     /** Is this surface compatible with the provided characterization?
522 
523         This method can be used to determine if an existing SkSurface is a viable destination
524         for an SkDeferredDisplayList.
525 
526         @param characterization  The characterization for which a compatibility check is desired
527         @return                  true if this surface is compatible with the characterization;
528                                  false otherwise
529     */
530     bool isCompatible(const SkSurfaceCharacterization& characterization) const;
531 
532     /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface
533         has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr.
534 
535         @param width   one or greater
536         @param height  one or greater
537         @return        SkSurface if width and height are positive; otherwise, nullptr
538 
539         example: https://fiddle.skia.org/c/@Surface_MakeNull
540     */
541     static sk_sp<SkSurface> MakeNull(int width, int height);
542 
543     /** Returns pixel count in each row; may be zero or greater.
544 
545         @return  number of pixel columns
546     */
width()547     int width() const { return fWidth; }
548 
549     /** Returns pixel row count; may be zero or greater.
550 
551         @return  number of pixel rows
552     */
height()553     int height() const { return fHeight; }
554 
555     /** Returns an ImageInfo describing the surface.
556      */
imageInfo()557     virtual SkImageInfo imageInfo() const { return SkImageInfo::MakeUnknown(fWidth, fHeight); }
558 
559     /** Returns unique value identifying the content of SkSurface. Returned value changes
560         each time the content changes. Content is changed by drawing, or by calling
561         notifyContentWillChange().
562 
563         @return  unique content identifier
564 
565         example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange
566     */
567     uint32_t generationID();
568 
569     /** \enum SkSurface::ContentChangeMode
570         ContentChangeMode members are parameters to notifyContentWillChange().
571     */
572     enum ContentChangeMode {
573         kDiscard_ContentChangeMode, //!< discards surface on change
574         kRetain_ContentChangeMode,  //!< preserves surface on change
575     };
576 
577     /** Notifies that SkSurface contents will be changed by code outside of Skia.
578         Subsequent calls to generationID() return a different value.
579 
580         TODO: Can kRetain_ContentChangeMode be deprecated?
581 
582         example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange
583     */
584     void notifyContentWillChange(ContentChangeMode mode);
585 
586     /** Returns the recording context being used by the SkSurface.
587 
588         @return the recording context, if available; nullptr otherwise
589      */
590     GrRecordingContext* recordingContext();
591 
592     /** Returns the recorder being used by the SkSurface.
593 
594         @return the recorder, if available; nullptr otherwise
595      */
596     skgpu::graphite::Recorder* recorder();
597 
598 #if defined(SK_GANESH)
599     enum BackendHandleAccess {
600         kFlushRead_BackendHandleAccess,    //!< back-end object is readable
601         kFlushWrite_BackendHandleAccess,   //!< back-end object is writable
602         kDiscardWrite_BackendHandleAccess, //!< back-end object must be overwritten
603     };
604 
605     /** Deprecated.
606     */
607     static const BackendHandleAccess kFlushRead_TextureHandleAccess =
608             kFlushRead_BackendHandleAccess;
609 
610     /** Deprecated.
611     */
612     static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
613             kFlushWrite_BackendHandleAccess;
614 
615     /** Deprecated.
616     */
617     static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
618             kDiscardWrite_BackendHandleAccess;
619 
620     /** Retrieves the back-end texture. If SkSurface has no back-end texture, an invalid
621         object is returned. Call GrBackendTexture::isValid to determine if the result
622         is valid.
623 
624         The returned GrBackendTexture should be discarded if the SkSurface is drawn to or deleted.
625 
626         @return                     GPU texture reference; invalid on failure
627     */
628     GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess);
629 
630     /** Retrieves the back-end render target. If SkSurface has no back-end render target, an invalid
631         object is returned. Call GrBackendRenderTarget::isValid to determine if the result
632         is valid.
633 
634         The returned GrBackendRenderTarget should be discarded if the SkSurface is drawn to
635         or deleted.
636 
637         @return                     GPU render target reference; invalid on failure
638     */
639     GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess);
640 
641     /** If the surface was made via MakeFromBackendTexture then it's backing texture may be
642         substituted with a different texture. The contents of the previous backing texture are
643         copied into the new texture. SkCanvas state is preserved. The original sample count is
644         used. The GrBackendFormat and dimensions of replacement texture must match that of
645         the original.
646 
647         Upon success textureReleaseProc is called when it is safe to delete the texture in the
648         backend API (accounting only for use of the texture by this surface). If SkSurface creation
649         fails textureReleaseProc is called before this function returns.
650 
651         @param backendTexture      the new backing texture for the surface
652         @param mode                Retain or discard current Content
653         @param textureReleaseProc  function called when texture can be released
654         @param releaseContext      state passed to textureReleaseProc
655      */
656     bool replaceBackendTexture(const GrBackendTexture& backendTexture,
657                                GrSurfaceOrigin origin,
658                                ContentChangeMode mode = kRetain_ContentChangeMode,
659                                TextureReleaseProc textureReleaseProc = nullptr,
660                                ReleaseContext releaseContext = nullptr);
661 #endif
662 
663     /** Returns SkCanvas that draws into SkSurface. Subsequent calls return the same SkCanvas.
664         SkCanvas returned is managed and owned by SkSurface, and is deleted when SkSurface
665         is deleted.
666 
667         @return  drawing SkCanvas for SkSurface
668 
669         example: https://fiddle.skia.org/c/@Surface_getCanvas
670     */
671     SkCanvas* getCanvas();
672 
673     /** Returns SkCapabilities that describes the capabilities of the SkSurface's device.
674 
675         @return  SkCapabilities of SkSurface's device.
676     */
677     sk_sp<const SkCapabilities> capabilities();
678 
679     /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains
680         the same raster, GPU, or null properties as the original. Returned SkSurface
681         does not share the same pixels.
682 
683         Returns nullptr if imageInfo width or height are zero, or if imageInfo
684         is incompatible with SkSurface.
685 
686         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
687                           of SkSurface; width and height must be greater than zero
688         @return           compatible SkSurface or nullptr
689 
690         example: https://fiddle.skia.org/c/@Surface_makeSurface
691     */
692     sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo);
693 
694     /** Calls makeSurface(ImageInfo) with the same ImageInfo as this surface, but with the
695      *  specified width and height.
696      */
697     sk_sp<SkSurface> makeSurface(int width, int height);
698 
699     /** Returns SkImage capturing SkSurface contents. Subsequent drawing to SkSurface contents
700         are not captured. SkImage allocation is accounted for if SkSurface was created with
701         skgpu::Budgeted::kYes.
702 
703         @return  SkImage initialized with SkSurface contents
704 
705         example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot
706     */
707     sk_sp<SkImage> makeImageSnapshot();
708 
709     /**
710      *  Like the no-parameter version, this returns an image of the current surface contents.
711      *  This variant takes a rectangle specifying the subset of the surface that is of interest.
712      *  These bounds will be sanitized before being used.
713      *  - If bounds extends beyond the surface, it will be trimmed to just the intersection of
714      *    it and the surface.
715      *  - If bounds does not intersect the surface, then this returns nullptr.
716      *  - If bounds == the surface, then this is the same as calling the no-parameter variant.
717 
718         example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot_2
719      */
720     sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds);
721 
722 #if defined(SK_GRAPHITE)
723     /**
724      * The 'asImage' and 'makeImageCopy' API/entry points are currently only available for
725      * Graphite.
726      *
727      * In this API, SkSurface no longer supports copy-on-write behavior. Instead, when creating
728      * an image for a surface, the client must explicitly indicate if a copy should be made.
729      * In both of the below calls the resource backing the surface will never change.
730      *
731      * The 'asImage' entry point has some major ramifications for the mutability of the
732      * returned SkImage. Since the originating surface and the returned image share the
733      * same backing, care must be taken by the client to ensure that the contents of the image
734      * reflect the desired contents when it is consumed by the gpu.
735      * Note: if the backing GPU buffer isn't textureable this method will return null. Graphite
736      * will not attempt to make a copy.
737      * Note: For 'asImage', the mipmapping of the image will match that of the source surface.
738      *
739      * The 'makeImageCopy' entry point allows subsetting and the addition of mipmaps (since
740      * a copy is already being made).
741      *
742      * In Graphite, the legacy API call (i.e., makeImageSnapshot) will just always make a copy.
743      */
744     sk_sp<SkImage> asImage();
745 
746     sk_sp<SkImage> makeImageCopy(const SkIRect* subset = nullptr,
747                                  skgpu::Mipmapped mipmapped = skgpu::Mipmapped::kNo);
748 #endif
749 
750     /** Draws SkSurface contents to canvas, with its top-left corner at (x, y).
751 
752         If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter, and SkBlendMode.
753 
754         @param canvas  SkCanvas drawn into
755         @param x       horizontal offset in SkCanvas
756         @param y       vertical offset in SkCanvas
757         @param sampling what technique to use when sampling the surface pixels
758         @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
759                        and so on; or nullptr
760 
761         example: https://fiddle.skia.org/c/@Surface_draw
762     */
763     void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling,
764               const SkPaint* paint);
765 
766     void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint = nullptr) {
767         this->draw(canvas, x, y, SkSamplingOptions(), paint);
768     }
769 
770     /** Copies SkSurface pixel address, row bytes, and SkImageInfo to SkPixmap, if address
771         is available, and returns true. If pixel address is not available, return
772         false and leave SkPixmap unchanged.
773 
774         pixmap contents become invalid on any future change to SkSurface.
775 
776         @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
777         @return        true if SkSurface has direct access to pixels
778 
779         example: https://fiddle.skia.org/c/@Surface_peekPixels
780     */
781     bool peekPixels(SkPixmap* pixmap);
782 
783     /** Copies SkRect of pixels to dst.
784 
785         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
786         Destination SkRect corners are (0, 0) and (dst.width(), dst.height()).
787         Copies each readable pixel intersecting both rectangles, without scaling,
788         converting to dst.colorType() and dst.alphaType() if required.
789 
790         Pixels are readable when SkSurface is raster, or backed by a GPU.
791 
792         The destination pixel storage must be allocated by the caller.
793 
794         Pixel values are converted only if SkColorType and SkAlphaType
795         do not match. Only pixels within both source and destination rectangles
796         are copied. dst contents outside SkRect intersection are unchanged.
797 
798         Pass negative values for srcX or srcY to offset pixels across or down destination.
799 
800         Does not copy, and returns false if:
801         - Source and destination rectangles do not intersect.
802         - SkPixmap pixels could not be allocated.
803         - dst.rowBytes() is too small to contain one row of pixels.
804 
805         @param dst   storage for pixels copied from SkSurface
806         @param srcX  offset into readable pixels on x-axis; may be negative
807         @param srcY  offset into readable pixels on y-axis; may be negative
808         @return      true if pixels were copied
809 
810         example: https://fiddle.skia.org/c/@Surface_readPixels
811     */
812     bool readPixels(const SkPixmap& dst, int srcX, int srcY);
813 
814     /** Copies SkRect of pixels from SkCanvas into dstPixels.
815 
816         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
817         Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
818         Copies each readable pixel intersecting both rectangles, without scaling,
819         converting to dstInfo.colorType() and dstInfo.alphaType() if required.
820 
821         Pixels are readable when SkSurface is raster, or backed by a GPU.
822 
823         The destination pixel storage must be allocated by the caller.
824 
825         Pixel values are converted only if SkColorType and SkAlphaType
826         do not match. Only pixels within both source and destination rectangles
827         are copied. dstPixels contents outside SkRect intersection are unchanged.
828 
829         Pass negative values for srcX or srcY to offset pixels across or down destination.
830 
831         Does not copy, and returns false if:
832         - Source and destination rectangles do not intersect.
833         - SkSurface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
834         - dstRowBytes is too small to contain one row of pixels.
835 
836         @param dstInfo      width, height, SkColorType, and SkAlphaType of dstPixels
837         @param dstPixels    storage for pixels; dstInfo.height() times dstRowBytes, or larger
838         @param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger
839         @param srcX         offset into readable pixels on x-axis; may be negative
840         @param srcY         offset into readable pixels on y-axis; may be negative
841         @return             true if pixels were copied
842     */
843     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
844                     int srcX, int srcY);
845 
846     /** Copies SkRect of pixels from SkSurface into bitmap.
847 
848         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
849         Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
850         Copies each readable pixel intersecting both rectangles, without scaling,
851         converting to bitmap.colorType() and bitmap.alphaType() if required.
852 
853         Pixels are readable when SkSurface is raster, or backed by a GPU.
854 
855         The destination pixel storage must be allocated by the caller.
856 
857         Pixel values are converted only if SkColorType and SkAlphaType
858         do not match. Only pixels within both source and destination rectangles
859         are copied. dst contents outside SkRect intersection are unchanged.
860 
861         Pass negative values for srcX or srcY to offset pixels across or down destination.
862 
863         Does not copy, and returns false if:
864         - Source and destination rectangles do not intersect.
865         - SkSurface pixels could not be converted to dst.colorType() or dst.alphaType().
866         - dst pixels could not be allocated.
867         - dst.rowBytes() is too small to contain one row of pixels.
868 
869         @param dst   storage for pixels copied from SkSurface
870         @param srcX  offset into readable pixels on x-axis; may be negative
871         @param srcY  offset into readable pixels on y-axis; may be negative
872         @return      true if pixels were copied
873 
874         example: https://fiddle.skia.org/c/@Surface_readPixels_3
875     */
876     bool readPixels(const SkBitmap& dst, int srcX, int srcY);
877 
878     using AsyncReadResult = SkImage::AsyncReadResult;
879 
880     /** Client-provided context that is passed to client-provided ReadPixelsContext. */
881     using ReadPixelsContext = void*;
882 
883     /**  Client-provided callback to asyncRescaleAndReadPixels() or
884          asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure.
885      */
886     using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>);
887 
888     /** Controls the gamma that rescaling occurs in for asyncRescaleAndReadPixels() and
889         asyncRescaleAndReadPixelsYUV420().
890      */
891     using RescaleGamma = SkImage::RescaleGamma;
892     using RescaleMode  = SkImage::RescaleMode;
893 
894     /** Makes surface pixel data available to caller, possibly asynchronously. It can also rescale
895         the surface pixels.
896 
897         Currently asynchronous reads are only supported on the GPU backend and only when the
898         underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
899         other cases this operates synchronously.
900 
901         Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is
902         rescaled to the size indicated by 'info', is then converted to the color space, color type,
903         and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the surface
904         causes failure.
905 
906         When the pixel data is ready the caller's ReadPixelsCallback is called with a
907         AsyncReadResult containing pixel data in the requested color type, alpha type, and color
908         space. The AsyncReadResult will have count() == 1. Upon failure the callback is called
909         with nullptr for AsyncReadResult. For a GPU surface this flushes work but a submit must
910         occur to guarantee a finite time before the callback is called.
911 
912         The data is valid for the lifetime of AsyncReadResult with the exception that if the
913         SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned
914         or destroyed.
915 
916         @param info            info of the requested pixels
917         @param srcRect         subrectangle of surface to read
918         @param rescaleGamma    controls whether rescaling is done in the surface's gamma or whether
919                                the source data is transformed to a linear gamma before rescaling.
920         @param rescaleMode     controls the technique of the rescaling
921         @param callback        function to call with result of the read
922         @param context         passed to callback
923      */
924     void asyncRescaleAndReadPixels(const SkImageInfo& info,
925                                    const SkIRect& srcRect,
926                                    RescaleGamma rescaleGamma,
927                                    RescaleMode rescaleMode,
928                                    ReadPixelsCallback callback,
929                                    ReadPixelsContext context);
930 
931     /**
932         Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
933         RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
934         planes ordered y, u, v. The u and v planes are half the width and height of the resized
935         rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize'
936         width and height are not even. A 'srcRect' that is not contained by the bounds of the
937         surface causes failure.
938 
939         When the pixel data is ready the caller's ReadPixelsCallback is called with a
940         AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3.
941         Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU surface this
942         flushes work but a submit must occur to guarantee a finite time before the callback is
943         called.
944 
945         The data is valid for the lifetime of AsyncReadResult with the exception that if the
946         SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned
947         or destroyed.
948 
949         @param yuvColorSpace  The transformation from RGB to YUV. Applied to the resized image
950                               after it is converted to dstColorSpace.
951         @param dstColorSpace  The color space to convert the resized image to, after rescaling.
952         @param srcRect        The portion of the surface to rescale and convert to YUV planes.
953         @param dstSize        The size to rescale srcRect to
954         @param rescaleGamma   controls whether rescaling is done in the surface's gamma or whether
955                               the source data is transformed to a linear gamma before rescaling.
956         @param rescaleMode    controls the sampling technique of the rescaling
957         @param callback       function to call with the planar read result
958         @param context        passed to callback
959      */
960     void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
961                                          sk_sp<SkColorSpace> dstColorSpace,
962                                          const SkIRect& srcRect,
963                                          const SkISize& dstSize,
964                                          RescaleGamma rescaleGamma,
965                                          RescaleMode rescaleMode,
966                                          ReadPixelsCallback callback,
967                                          ReadPixelsContext context);
968 
969     /** Copies SkRect of pixels from the src SkPixmap to the SkSurface.
970 
971         Source SkRect corners are (0, 0) and (src.width(), src.height()).
972         Destination SkRect corners are (dstX, dstY) and
973         (dstX + Surface width(), dstY + Surface height()).
974 
975         Copies each readable pixel intersecting both rectangles, without scaling,
976         converting to SkSurface colorType() and SkSurface alphaType() if required.
977 
978         @param src   storage for pixels to copy to SkSurface
979         @param dstX  x-axis position relative to SkSurface to begin copy; may be negative
980         @param dstY  y-axis position relative to SkSurface to begin copy; may be negative
981 
982         example: https://fiddle.skia.org/c/@Surface_writePixels
983     */
984     void writePixels(const SkPixmap& src, int dstX, int dstY);
985 
986     /** Copies SkRect of pixels from the src SkBitmap to the SkSurface.
987 
988         Source SkRect corners are (0, 0) and (src.width(), src.height()).
989         Destination SkRect corners are (dstX, dstY) and
990         (dstX + Surface width(), dstY + Surface height()).
991 
992         Copies each readable pixel intersecting both rectangles, without scaling,
993         converting to SkSurface colorType() and SkSurface alphaType() if required.
994 
995         @param src   storage for pixels to copy to SkSurface
996         @param dstX  x-axis position relative to SkSurface to begin copy; may be negative
997         @param dstY  y-axis position relative to SkSurface to begin copy; may be negative
998 
999         example: https://fiddle.skia.org/c/@Surface_writePixels_2
1000     */
1001     void writePixels(const SkBitmap& src, int dstX, int dstY);
1002 
1003     /** Returns SkSurfaceProps for surface.
1004 
1005         @return  LCD striping orientation and setting for device independent fonts
1006     */
props()1007     const SkSurfaceProps& props() const { return fProps; }
1008 
1009     /** Call to ensure all reads/writes of the surface have been issued to the underlying 3D API.
1010         Skia will correctly order its own draws and pixel operations. This must to be used to ensure
1011         correct ordering when the surface backing store is accessed outside Skia (e.g. direct use of
1012         the 3D API or a windowing system). GrDirectContext has additional flush and submit methods
1013         that apply to all surfaces and images created from a GrDirectContext. This is equivalent to
1014         calling SkSurface::flush with a default GrFlushInfo followed by
1015         GrDirectContext::submit(syncCpu).
1016     */
1017     void flushAndSubmit(bool syncCpu = false);
1018 
1019     enum class BackendSurfaceAccess {
1020         kNoAccess,  //!< back-end object will not be used by client
1021         kPresent,   //!< back-end surface will be used for presenting to screen
1022     };
1023 
1024 #if defined(SK_GANESH)
1025     /** If a surface is GPU texture backed, is being drawn with MSAA, and there is a resolve
1026         texture, this call will insert a resolve command into the stream of gpu commands. In order
1027         for the resolve to actually have an effect, the work still needs to be flushed and submitted
1028         to the GPU after recording the resolve command. If a resolve is not supported or the
1029         SkSurface has no dirty work to resolve, then this call is a no-op.
1030 
1031         This call is most useful when the SkSurface is created by wrapping a single sampled gpu
1032         texture, but asking Skia to render with MSAA. If the client wants to use the wrapped texture
1033         outside of Skia, the only way to trigger a resolve is either to call this command or use
1034         SkSurface::flush.
1035      */
1036     void resolveMSAA();
1037 
1038     /** Issues pending SkSurface commands to the GPU-backed API objects and resolves any SkSurface
1039         MSAA. A call to GrDirectContext::submit is always required to ensure work is actually sent
1040         to the gpu. Some specific API details:
1041             GL: Commands are actually sent to the driver, but glFlush is never called. Thus some
1042                 sync objects from the flush will not be valid until a submission occurs.
1043 
1044             Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command
1045                 buffer or encoder objects. However, these objects are not sent to the gpu until a
1046                 submission occurs.
1047 
1048         The work that is submitted to the GPU will be dependent on the BackendSurfaceAccess that is
1049         passed in.
1050 
1051         If BackendSurfaceAccess::kNoAccess is passed in all commands will be issued to the GPU.
1052 
1053         If BackendSurfaceAccess::kPresent is passed in and the backend API is not Vulkan, it is
1054         treated the same as kNoAccess. If the backend API is Vulkan, the VkImage that backs the
1055         SkSurface will be transferred back to its original queue. If the SkSurface was created by
1056         wrapping a VkImage, the queue will be set to the queue which was originally passed in on
1057         the GrVkImageInfo. Additionally, if the original queue was not external or foreign the
1058         layout of the VkImage will be set to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
1059 
1060         The GrFlushInfo describes additional options to flush. Please see documentation at
1061         GrFlushInfo for more info.
1062 
1063         If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be
1064         submitted to the gpu during the next submit call (it is possible Skia failed to create a
1065         subset of the semaphores). The client should not wait on these semaphores until after submit
1066         has been called, but must keep them alive until then. If a submit flag was passed in with
1067         the flush these valid semaphores can we waited on immediately. If this call returns
1068         GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on
1069         the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in
1070         with the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the
1071         client is still responsible for deleting any initialized semaphores.
1072         Regardless of semaphore submission the context will still be flushed. It should be
1073         emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
1074         happen. It simply means there were no semaphores submitted to the GPU. A caller should only
1075         take this as a failure if they passed in semaphores to be submitted.
1076 
1077         Pending surface commands are flushed regardless of the return result.
1078 
1079         @param access  type of access the call will do on the backend object after flush
1080         @param info    flush options
1081     */
1082     GrSemaphoresSubmitted flush(BackendSurfaceAccess access, const GrFlushInfo& info);
1083 
1084     /** Issues pending SkSurface commands to the GPU-backed API objects and resolves any SkSurface
1085         MSAA. A call to GrDirectContext::submit is always required to ensure work is actually sent
1086         to the gpu. Some specific API details:
1087             GL: Commands are actually sent to the driver, but glFlush is never called. Thus some
1088                 sync objects from the flush will not be valid until a submission occurs.
1089 
1090             Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command
1091                 buffer or encoder objects. However, these objects are not sent to the gpu until a
1092                 submission occurs.
1093 
1094         The GrFlushInfo describes additional options to flush. Please see documentation at
1095         GrFlushInfo for more info.
1096 
1097         If a skgpu::MutableTextureState is passed in, at the end of the flush we will transition
1098         the surface to be in the state requested by the skgpu::MutableTextureState. If the surface
1099         (or SkImage or GrBackendSurface wrapping the same backend object) is used again after this
1100         flush the state may be changed and no longer match what is requested here. This is often
1101         used if the surface will be used for presenting or external use and the client wants backend
1102         object to be prepped for that use. A finishedProc or semaphore on the GrFlushInfo will also
1103         include the work for any requested state change.
1104 
1105         If the backend API is Vulkan, the caller can set the skgpu::MutableTextureState's
1106         VkImageLayout to VK_IMAGE_LAYOUT_UNDEFINED or queueFamilyIndex to VK_QUEUE_FAMILY_IGNORED to
1107         tell Skia to not change those respective states.
1108 
1109         If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be
1110         submitted to the gpu during the next submit call (it is possible Skia failed to create a
1111         subset of the semaphores). The client should not wait on these semaphores until after submit
1112         has been called, but must keep them alive until then. If a submit flag was passed in with
1113         the flush these valid semaphores can we waited on immediately. If this call returns
1114         GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on
1115         the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in
1116         with the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the
1117         client is still responsible for deleting any initialized semaphores.
1118         Regardleess of semaphore submission the context will still be flushed. It should be
1119         emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
1120         happen. It simply means there were no semaphores submitted to the GPU. A caller should only
1121         take this as a failure if they passed in semaphores to be submitted.
1122 
1123         Pending surface commands are flushed regardless of the return result.
1124 
1125         @param info    flush options
1126         @param access  optional state change request after flush
1127     */
1128     GrSemaphoresSubmitted flush(const GrFlushInfo& info,
1129                                 const skgpu::MutableTextureState* newState = nullptr);
1130 #endif // defined(SK_GANESH)
1131 
1132     void flush();
1133 
1134     /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
1135         executing any more commands on the GPU for this surface. If this call returns false, then
1136         the GPU back-end will not wait on any passed in semaphores, and the client will still own
1137         the semaphores, regardless of the value of deleteSemaphoresAfterWait.
1138 
1139         If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case
1140         it is the client's responsibility to not destroy or attempt to reuse the semaphores until it
1141         knows that Skia has finished waiting on them. This can be done by using finishedProcs
1142         on flush calls.
1143 
1144         @param numSemaphores               size of waitSemaphores array
1145         @param waitSemaphores              array of semaphore containers
1146         @paramm deleteSemaphoresAfterWait  who owns and should delete the semaphores
1147         @return                            true if GPU is waiting on semaphores
1148     */
1149     bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
1150               bool deleteSemaphoresAfterWait = true);
1151 
1152     /** Initializes SkSurfaceCharacterization that can be used to perform GPU back-end
1153         processing in a separate thread. Typically this is used to divide drawing
1154         into multiple tiles. SkDeferredDisplayListRecorder records the drawing commands
1155         for each tile.
1156 
1157         Return true if SkSurface supports characterization. raster surface returns false.
1158 
1159         @param characterization  properties for parallel drawing
1160         @return                  true if supported
1161 
1162         example: https://fiddle.skia.org/c/@Surface_characterize
1163     */
1164     bool characterize(SkSurfaceCharacterization* characterization) const;
1165 
1166     /** Draws the deferred display list created via a SkDeferredDisplayListRecorder.
1167         If the deferred display list is not compatible with this SkSurface, the draw is skipped
1168         and false is return.
1169 
1170         The xOffset and yOffset parameters are experimental and, if not both zero, will cause
1171         the draw to be ignored.
1172         When implemented, if xOffset or yOffset are non-zero, the DDL will be drawn offset by that
1173         amount into the surface.
1174 
1175         @param deferredDisplayList  drawing commands
1176         @param xOffset              x-offset at which to draw the DDL
1177         @param yOffset              y-offset at which to draw the DDL
1178         @return                     false if deferredDisplayList is not compatible
1179 
1180         example: https://fiddle.skia.org/c/@Surface_draw_2
1181     */
1182     bool draw(sk_sp<const SkDeferredDisplayList> deferredDisplayList,
1183               int xOffset = 0,
1184               int yOffset = 0);
1185 
1186 protected:
1187     SkSurface(int width, int height, const SkSurfaceProps* surfaceProps);
1188     SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps);
1189 
1190     // called by subclass if their contents have changed
dirtyGenerationID()1191     void dirtyGenerationID() {
1192         fGenerationID = 0;
1193     }
1194 
1195 private:
1196     const SkSurfaceProps fProps;
1197     const int            fWidth;
1198     const int            fHeight;
1199     uint32_t             fGenerationID;
1200 
1201     using INHERITED = SkRefCnt;
1202 };
1203 
1204 #endif
1205