• 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/SkRefCnt.h"
13 #include "include/core/SkSurfaceProps.h"
14 
15 #include "include/gpu/GrTypes.h"
16 
17 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
18 #include <android/hardware_buffer.h>
19 #endif
20 
21 class SkCanvas;
22 class SkDeferredDisplayList;
23 class SkPaint;
24 class SkSurfaceCharacterization;
25 class GrBackendRenderTarget;
26 class GrBackendSemaphore;
27 class GrBackendTexture;
28 class GrContext;
29 class GrRecordingContext;
30 class GrRenderTarget;
31 
32 /** \class SkSurface
33     SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be
34     allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface).
35     SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
36     surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface).
37     SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
38     of the requested dimensions are zero, then nullptr will be returned.
39 */
40 class SK_API SkSurface : public SkRefCnt {
41 public:
42 
43     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
44 
45         SkSurface is returned if all parameters are valid.
46         Valid parameters include:
47         info dimensions are greater than zero;
48         info contains SkColorType and SkAlphaType supported by raster surface;
49         pixels is not nullptr;
50         rowBytes is large enough to contain info width pixels of SkColorType.
51 
52         Pixel buffer size should be info height times computed rowBytes.
53         Pixels are not initialized.
54         To access pixels after drawing, call flush() or peekPixels().
55 
56         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
57                              of raster surface; width and height must be greater than zero
58         @param pixels        pointer to destination pixels buffer
59         @param rowBytes      interval from one SkSurface row to the next
60         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
61                              may be nullptr
62         @return              SkSurface if all parameters are valid; otherwise, nullptr
63     */
64     static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
65                                              size_t rowBytes,
66                                              const SkSurfaceProps* surfaceProps = nullptr);
67 
68     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
69         releaseProc is called with pixels and context when SkSurface is deleted.
70 
71         SkSurface is returned if all parameters are valid.
72         Valid parameters include:
73         info dimensions are greater than zero;
74         info contains SkColorType and SkAlphaType supported by raster surface;
75         pixels is not nullptr;
76         rowBytes is large enough to contain info width pixels of SkColorType.
77 
78         Pixel buffer size should be info height times computed rowBytes.
79         Pixels are not initialized.
80         To access pixels after drawing, call flush() or peekPixels().
81 
82         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
83                              of raster surface; width and height must be greater than zero
84         @param pixels        pointer to destination pixels buffer
85         @param rowBytes      interval from one SkSurface row to the next
86         @param releaseProc   called when SkSurface is deleted; may be nullptr
87         @param context       passed to releaseProc; may be nullptr
88         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
89                              may be nullptr
90         @return              SkSurface if all parameters are valid; otherwise, nullptr
91     */
92     static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
93                                     size_t rowBytes,
94                                     void (*releaseProc)(void* pixels, void* context),
95                                     void* context, const SkSurfaceProps* surfaceProps = nullptr);
96 
97     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
98         Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
99         rowBytes, or times imageInfo.minRowBytes() if rowBytes is zero.
100         Pixel memory is deleted when SkSurface is deleted.
101 
102         SkSurface is returned if all parameters are valid.
103         Valid parameters include:
104         info dimensions are greater than zero;
105         info contains SkColorType and SkAlphaType supported by raster surface;
106         rowBytes is large enough to contain info width pixels of SkColorType, or is zero.
107 
108         If rowBytes is not zero, subsequent images returned by makeImageSnapshot()
109         have the same rowBytes.
110 
111         @param imageInfo     width, height, SkColorType, SkAlphaType, SkColorSpace,
112                              of raster surface; width and height must be greater than zero
113         @param rowBytes      interval from one SkSurface row to the next; may be zero
114         @param surfaceProps  LCD striping orientation and setting for device independent fonts;
115                              may be nullptr
116         @return              SkSurface if all parameters are valid; otherwise, nullptr
117     */
118     static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
119                                        const SkSurfaceProps* surfaceProps);
120 
121     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
122         Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
123         imageInfo.minRowBytes().
124         Pixel memory is deleted when SkSurface is deleted.
125 
126         SkSurface is returned if all parameters are valid.
127         Valid parameters include:
128         info dimensions are greater than zero;
129         info contains SkColorType and SkAlphaType supported by raster surface.
130 
131         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
132                           of raster surface; width and height must be greater than zero
133         @param props      LCD striping orientation and setting for device independent fonts;
134                           may be nullptr
135         @return           SkSurface if all parameters are valid; otherwise, nullptr
136     */
137     static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
138                                        const SkSurfaceProps* props = nullptr) {
139         return MakeRaster(imageInfo, 0, props);
140     }
141 
142     /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into pixels.
143         Allocates and zeroes pixel memory. Pixel memory size is height times width times
144         four. Pixel memory is deleted when SkSurface is deleted.
145 
146         Internally, sets SkImageInfo to width, height, native color type, and
147         kPremul_SkAlphaType.
148 
149         SkSurface is returned if width and height are greater than zero.
150 
151         Use to create SkSurface that matches SkPMColor, the native pixel arrangement on
152         the platform. SkSurface drawn to output device skips converting its pixel format.
153 
154         @param width         pixel column count; must be greater than zero
155         @param height        pixel row count; must be greater than zero
156         @param surfaceProps  LCD striping orientation and setting for device independent
157                              fonts; may be nullptr
158         @return              SkSurface if all parameters are valid; otherwise, nullptr
159     */
160     static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
161                                                 const SkSurfaceProps* surfaceProps = nullptr);
162 
163     /** Caller data passed to RenderTarget/TextureReleaseProc; may be nullptr. */
164     typedef void* ReleaseContext;
165 
166     /** User function called when supplied render target may be deleted. */
167     typedef void (*RenderTargetReleaseProc)(ReleaseContext releaseContext);
168 
169     /** User function called when supplied texture may be deleted. */
170     typedef void (*TextureReleaseProc)(ReleaseContext releaseContext);
171 
172     /** Wraps a GPU-backed texture into SkSurface. Caller must ensure the texture is
173         valid for the lifetime of returned SkSurface. If sampleCnt greater than zero,
174         creates an intermediate MSAA SkSurface which is used for drawing backendTexture.
175 
176         SkSurface is returned if all parameters are valid. backendTexture is valid if
177         its pixel configuration agrees with colorSpace and context; for instance, if
178         backendTexture has an sRGB configuration, then context must support sRGB,
179         and colorSpace must be present. Further, backendTexture width and height must
180         not exceed context capabilities, and the context must be able to support
181         back-end textures.
182 
183         If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
184 
185         @param context             GPU context
186         @param backendTexture      texture residing on GPU
187         @param origin              one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
188         @param sampleCnt           samples per pixel, or 0 to disable full scene anti-aliasing
189         @param colorType           one of:
190                                    kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
191                                    kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
192                                    kRGB_888x_SkColorType, kBGRA_8888_SkColorType,
193                                    kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
194                                    kGray_8_SkColorType, kRGBA_F16_SkColorType
195         @param colorSpace          range of colors; may be nullptr
196         @param surfaceProps        LCD striping orientation and setting for device independent
197                                    fonts; may be nullptr
198         @param textureReleaseProc  function called when texture can be released
199         @param releaseContext      state passed to textureReleaseProc
200         @return                    SkSurface if all parameters are valid; otherwise, nullptr
201     */
202     static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
203                                                    const GrBackendTexture& backendTexture,
204                                                    GrSurfaceOrigin origin, int sampleCnt,
205                                                    SkColorType colorType,
206                                                    sk_sp<SkColorSpace> colorSpace,
207                                                    const SkSurfaceProps* surfaceProps,
208                                                    TextureReleaseProc textureReleaseProc = nullptr,
209                                                    ReleaseContext releaseContext = nullptr);
210 
211     /** Wraps a GPU-backed buffer into SkSurface. Caller must ensure backendRenderTarget
212         is valid for the lifetime of returned SkSurface.
213 
214         SkSurface is returned if all parameters are valid. backendRenderTarget is valid if
215         its pixel configuration agrees with colorSpace and context; for instance, if
216         backendRenderTarget has an sRGB configuration, then context must support sRGB,
217         and colorSpace must be present. Further, backendRenderTarget width and height must
218         not exceed context capabilities, and the context must be able to support
219         back-end render targets.
220 
221         If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
222 
223         @param context                  GPU context
224         @param backendRenderTarget      GPU intermediate memory buffer
225         @param origin                   one of:
226                                         kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
227         @param colorType                one of:
228                                         kUnknown_SkColorType, kAlpha_8_SkColorType,
229                                         kRGB_565_SkColorType,
230                                         kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
231                                         kRGB_888x_SkColorType, kBGRA_8888_SkColorType,
232                                         kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
233                                         kGray_8_SkColorType, kRGBA_F16_SkColorType
234         @param colorSpace               range of colors
235         @param surfaceProps             LCD striping orientation and setting for device independent
236                                         fonts; may be nullptr
237         @param releaseProc              function called when texture can be released
238         @param releaseContext           state passed to textureReleaseProc
239         @return                         SkSurface if all parameters are valid; otherwise, nullptr
240     */
241     static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
242                                                 const GrBackendRenderTarget& backendRenderTarget,
243                                                 GrSurfaceOrigin origin,
244                                                 SkColorType colorType,
245                                                 sk_sp<SkColorSpace> colorSpace,
246                                                 const SkSurfaceProps* surfaceProps,
247                                                 RenderTargetReleaseProc releaseProc = nullptr,
248                                                 ReleaseContext releaseContext = nullptr);
249 
250     /** Wraps a GPU-backed texture into SkSurface. Caller must ensure backendTexture is
251         valid for the lifetime of returned SkSurface. If sampleCnt greater than zero,
252         creates an intermediate MSAA SkSurface which is used for drawing backendTexture.
253 
254         SkSurface is returned if all parameters are valid. backendTexture is valid if
255         its pixel configuration agrees with colorSpace and context; for instance, if
256         backendTexture has an sRGB configuration, then context must support sRGB,
257         and colorSpace must be present. Further, backendTexture width and height must
258         not exceed context capabilities.
259 
260         Returned SkSurface is available only for drawing into, and cannot generate an
261         SkImage.
262 
263         If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
264 
265         @param context         GPU context
266         @param backendTexture  texture residing on GPU
267         @param origin          one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
268         @param sampleCnt       samples per pixel, or 0 to disable full scene anti-aliasing
269         @param colorType       one of:
270                                kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
271                                kARGB_4444_SkColorType, kRGBA_8888_SkColorType,
272                                kRGB_888x_SkColorType, kBGRA_8888_SkColorType,
273                                kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
274                                kGray_8_SkColorType, kRGBA_F16_SkColorType
275         @param colorSpace      range of colors; may be nullptr
276         @param surfaceProps    LCD striping orientation and setting for device independent
277                                fonts; may be nullptr
278         @return                SkSurface if all parameters are valid; otherwise, nullptr
279     */
280     static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
281                                                             const GrBackendTexture& backendTexture,
282                                                             GrSurfaceOrigin origin,
283                                                             int sampleCnt,
284                                                             SkColorType colorType,
285                                                             sk_sp<SkColorSpace> colorSpace,
286                                                             const SkSurfaceProps* surfaceProps);
287 
288 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
289     /** Private.
290         Creates SkSurface from Android hardware buffer.
291         Returned SkSurface takes a reference on the buffer. The ref on the buffer will be released
292         when the SkSurface is destroyed and there is no pending work on the GPU involving the
293         buffer.
294 
295         Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
296 
297         Currently this is only supported for buffers that can be textured as well as rendered to.
298         In other workds that must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
299         AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE usage bits.
300 
301         @param context         GPU context
302         @param hardwareBuffer  AHardwareBuffer Android hardware buffer
303         @param origin          one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
304         @param colorSpace      range of colors; may be nullptr
305         @param surfaceProps    LCD striping orientation and setting for device independent
306                                fonts; may be nullptr
307         @return                created SkSurface, or nullptr
308     */
309     static sk_sp<SkSurface> MakeFromAHardwareBuffer(GrContext* context,
310                                                     AHardwareBuffer* hardwareBuffer,
311                                                     GrSurfaceOrigin origin,
312                                                     sk_sp<SkColorSpace> colorSpace,
313                                                     const SkSurfaceProps* surfaceProps);
314 #endif
315 
316     /** Returns SkSurface on GPU indicated by context. Allocates memory for
317         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
318         selects whether allocation for pixels is tracked by context. imageInfo
319         describes the pixel format in SkColorType, and transparency in
320         SkAlphaType, and color matching in SkColorSpace.
321 
322         sampleCount requests the number of samples per pixel.
323         Pass zero to disable multi-sample anti-aliasing.  The request is rounded
324         up to the next supported count, or rounded down if it is larger than the
325         maximum supported count.
326 
327         surfaceOrigin pins either the top-left or the bottom-left corner to the origin.
328 
329         shouldCreateWithMips hints that SkImage returned by makeImageSnapshot() is mip map.
330 
331         If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
332 
333         @param context               GPU context
334         @param budgeted              one of: SkBudgeted::kNo, SkBudgeted::kYes
335         @param imageInfo             width, height, SkColorType, SkAlphaType, SkColorSpace;
336                                      width, or height, or both, may be zero
337         @param sampleCount           samples per pixel, or 0 to disable full scene anti-aliasing
338         @param surfaceOrigin         one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
339         @param surfaceProps          LCD striping orientation and setting for device independent
340                                      fonts; may be nullptr
341         @param shouldCreateWithMips  hint that SkSurface will host mip map images
342         @return                      SkSurface if all parameters are valid; otherwise, nullptr
343     */
344     static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
345                                              const SkImageInfo& imageInfo,
346                                              int sampleCount, GrSurfaceOrigin surfaceOrigin,
347                                              const SkSurfaceProps* surfaceProps,
348                                              bool shouldCreateWithMips = false);
349 
350     /** Returns SkSurface on GPU indicated by context. Allocates memory for
351         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
352         selects whether allocation for pixels is tracked by context. imageInfo
353         describes the pixel format in SkColorType, and transparency in
354         SkAlphaType, and color matching in SkColorSpace.
355 
356         sampleCount requests the number of samples per pixel.
357         Pass zero to disable multi-sample anti-aliasing.  The request is rounded
358         up to the next supported count, or rounded down if it is larger than the
359         maximum supported count.
360 
361         SkSurface bottom-left corner is pinned to the origin.
362 
363         @param context      GPU context
364         @param budgeted     one of: SkBudgeted::kNo, SkBudgeted::kYes
365         @param imageInfo    width, height, SkColorType, SkAlphaType, SkColorSpace,
366                             of raster surface; width, or height, or both, may be zero
367         @param sampleCount  samples per pixel, or 0 to disable multi-sample anti-aliasing
368         @param surfaceProps LCD striping orientation and setting for device independent
369                             fonts; may be nullptr
370         @return             SkSurface if all parameters are valid; otherwise, nullptr
371     */
MakeRenderTarget(GrContext * context,SkBudgeted budgeted,const SkImageInfo & imageInfo,int sampleCount,const SkSurfaceProps * surfaceProps)372     static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
373                                              const SkImageInfo& imageInfo, int sampleCount,
374                                              const SkSurfaceProps* surfaceProps) {
375         return MakeRenderTarget(context, budgeted, imageInfo, sampleCount,
376                                 kBottomLeft_GrSurfaceOrigin, surfaceProps);
377     }
378 
379     /** Returns SkSurface on GPU indicated by context. Allocates memory for
380         pixels, based on the width, height, and SkColorType in SkImageInfo.  budgeted
381         selects whether allocation for pixels is tracked by context. imageInfo
382         describes the pixel format in SkColorType, and transparency in
383         SkAlphaType, and color matching in SkColorSpace.
384 
385         SkSurface bottom-left corner is pinned to the origin.
386 
387         @param context    GPU context
388         @param budgeted   one of: SkBudgeted::kNo, SkBudgeted::kYes
389         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
390                           of raster surface; width, or height, or both, may be zero
391         @return           SkSurface if all parameters are valid; otherwise, nullptr
392     */
MakeRenderTarget(GrContext * context,SkBudgeted budgeted,const SkImageInfo & imageInfo)393     static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
394                                              const SkImageInfo& imageInfo) {
395         if (!imageInfo.width() || !imageInfo.height()) {
396             return nullptr;
397         }
398         return MakeRenderTarget(context, budgeted, imageInfo, 0, kBottomLeft_GrSurfaceOrigin,
399                                 nullptr);
400     }
401 
402     /** Returns SkSurface on GPU indicated by context that is compatible with the provided
403         characterization. budgeted selects whether allocation for pixels is tracked by context.
404 
405         @param context           GPU context
406         @param characterization  description of the desired SkSurface
407         @param budgeted          one of: SkBudgeted::kNo, SkBudgeted::kYes
408         @return                  SkSurface if all parameters are valid; otherwise, nullptr
409     */
410     static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
411                                              const SkSurfaceCharacterization& characterization,
412                                              SkBudgeted budgeted);
413 
414     /** Wraps a backend texture in an SkSurface - setting up the surface to match the provided
415         characterization. The caller must ensure the texture is valid for the lifetime of
416         returned SkSurface.
417 
418         If the backend texture and surface characterization are incompatible then null will
419         be returned.
420 
421         Usually, the GrContext::createBackendTexture variant that takes a surface characterization
422         should be used to create the backend texture. If not,
423         SkSurfaceCharacterization::isCompatible can be used to determine if a given backend texture
424         is compatible with a specific surface characterization.
425 
426         @param context             GPU context
427         @param characterization    characterization of the desired surface
428         @param backendTexture      texture residing on GPU
429         @param textureReleaseProc  function called when texture can be released
430         @param releaseContext      state passed to textureReleaseProc
431         @return                    SkSurface if all parameters are compatible; otherwise, nullptr
432     */
433     static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
434                                                    const SkSurfaceCharacterization& characterzation,
435                                                    const GrBackendTexture& backendTexture,
436                                                    TextureReleaseProc textureReleaseProc = nullptr,
437                                                    ReleaseContext releaseContext = nullptr);
438 
439     /** Is this surface compatible with the provided characterization?
440 
441         This method can be used to determine if an existing SkSurface is a viable destination
442         for an SkDeferredDisplayList.
443 
444         @param characterization  The characterization for which a compatibility check is desired
445         @return                  true if this surface is compatible with the characterization;
446                                  false otherwise
447     */
448     bool isCompatible(const SkSurfaceCharacterization& characterization) const;
449 
450     /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface
451         has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr.
452 
453         @param width   one or greater
454         @param height  one or greater
455         @return        SkSurface if width and height are positive; otherwise, nullptr
456     */
457     static sk_sp<SkSurface> MakeNull(int width, int height);
458 
459     /** Returns pixel count in each row; may be zero or greater.
460 
461         @return  number of pixel columns
462     */
width()463     int width() const { return fWidth; }
464 
465     /** Returns pixel row count; may be zero or greater.
466 
467         @return  number of pixel rows
468     */
height()469     int height() const { return fHeight; }
470 
471     /** Returns an ImageInfo describing the surface.
472      */
473     SkImageInfo imageInfo();
474 
475     /** Returns unique value identifying the content of SkSurface. Returned value changes
476         each time the content changes. Content is changed by drawing, or by calling
477         notifyContentWillChange().
478 
479         @return  unique content identifier
480     */
481     uint32_t generationID();
482 
483     /** \enum SkSurface::ContentChangeMode
484         ContentChangeMode members are parameters to notifyContentWillChange().
485     */
486     enum ContentChangeMode {
487         kDiscard_ContentChangeMode, //!< discards surface on change
488         kRetain_ContentChangeMode,  //!< preserves surface on change
489     };
490 
491     /** Notifies that SkSurface contents will be changed by code outside of Skia.
492         Subsequent calls to generationID() return a different value.
493 
494         TODO: Can kRetain_ContentChangeMode be deprecated?
495 
496         @param mode  one of: kDiscard_ContentChangeMode, kRetain_ContentChangeMode
497     */
498     void notifyContentWillChange(ContentChangeMode mode);
499 
500     enum BackendHandleAccess {
501         kFlushRead_BackendHandleAccess,    //!< back-end object is readable
502         kFlushWrite_BackendHandleAccess,   //!< back-end object is writable
503         kDiscardWrite_BackendHandleAccess, //!< back-end object must be overwritten
504     };
505 
506     /** Deprecated.
507     */
508     static const BackendHandleAccess kFlushRead_TextureHandleAccess =
509             kFlushRead_BackendHandleAccess;
510 
511     /** Deprecated.
512     */
513     static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
514             kFlushWrite_BackendHandleAccess;
515 
516     /** Deprecated.
517     */
518     static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
519             kDiscardWrite_BackendHandleAccess;
520 
521     /** Retrieves the back-end texture. If SkSurface has no back-end texture, an invalid
522         object is returned. Call GrBackendTexture::isValid to determine if the result
523         is valid.
524 
525         The returned GrBackendTexture should be discarded if the SkSurface is drawn to or deleted.
526 
527         @param backendHandleAccess  one of:  kFlushRead_BackendHandleAccess,
528                                     kFlushWrite_BackendHandleAccess,
529                                     kDiscardWrite_BackendHandleAccess
530         @return                     GPU texture reference; invalid on failure
531     */
532     GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess);
533 
534     /** Retrieves the back-end render target. If SkSurface has no back-end render target, an invalid
535         object is returned. Call GrBackendRenderTarget::isValid to determine if the result
536         is valid.
537 
538         The returned GrBackendRenderTarget should be discarded if the SkSurface is drawn to
539         or deleted.
540 
541         @param backendHandleAccess  one of:  kFlushRead_BackendHandleAccess,
542                                     kFlushWrite_BackendHandleAccess,
543                                     kDiscardWrite_BackendHandleAccess
544         @return                     GPU render target reference; invalid on failure
545     */
546     GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess);
547 
548     /** If the surface was made via MakeFromBackendTexture then it's backing texture may be
549         substituted with a different texture. The contents of the previous backing texture are
550         copied into the new texture. SkCanvas state is preserved. The original sample count is
551         used. The GrBackendFormat and dimensions of replacement texture must match that of
552         the original.
553 
554         @param backendTexture      the new backing texture for the surface.
555         @param origin              one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
556         @param textureReleaseProc  function called when texture can be released
557         @param releaseContext      state passed to textureReleaseProc
558      */
559     bool replaceBackendTexture(const GrBackendTexture& backendTexture,
560                                GrSurfaceOrigin origin,
561                                TextureReleaseProc textureReleaseProc = nullptr,
562                                ReleaseContext releaseContext = nullptr);
563 
564     /** Returns SkCanvas that draws into SkSurface. Subsequent calls return the same SkCanvas.
565         SkCanvas returned is managed and owned by SkSurface, and is deleted when SkSurface
566         is deleted.
567 
568         @return  drawing SkCanvas for SkSurface
569     */
570     SkCanvas* getCanvas();
571 
572     /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains
573         the same raster, GPU, or null properties as the original. Returned SkSurface
574         does not share the same pixels.
575 
576         Returns nullptr if imageInfo width or height are zero, or if imageInfo
577         is incompatible with SkSurface.
578 
579         @param imageInfo  width, height, SkColorType, SkAlphaType, SkColorSpace,
580                           of SkSurface; width and height must be greater than zero
581         @return           compatible SkSurface or nullptr
582     */
583     sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo);
584 
585     /** Calls makeSurface(ImageInfo) with the same ImageInfo as this surface, but with the
586      *  specified width and height.
587      */
588     sk_sp<SkSurface> makeSurface(int width, int height);
589 
590     /** Returns SkImage capturing SkSurface contents. Subsequent drawing to SkSurface contents
591         are not captured. SkImage allocation is accounted for if SkSurface was created with
592         SkBudgeted::kYes.
593 
594         @return  SkImage initialized with SkSurface contents
595     */
596     sk_sp<SkImage> makeImageSnapshot();
597 
598     /**
599      *  Like the no-parameter version, this returns an image of the current surface contents.
600      *  This variant takes a rectangle specifying the subset of the surface that is of interest.
601      *  These bounds will be sanitized before being used.
602      *  - If bounds extends beyond the surface, it will be trimmed to just the intersection of
603      *    it and the surface.
604      *  - If bounds does not intersect the surface, then this returns nullptr.
605      *  - If bounds == the surface, then this is the same as calling the no-parameter variant.
606      */
607     sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds);
608 
609     /** Draws SkSurface contents to canvas, with its top-left corner at (x, y).
610 
611         If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter,
612         SkBlendMode, and SkDrawLooper.
613 
614         @param canvas  SkCanvas drawn into
615         @param x       horizontal offset in SkCanvas
616         @param y       vertical offset in SkCanvas
617         @param paint   SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter,
618                        and so on; or nullptr
619     */
620     void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint);
621 
622     /** Copies SkSurface pixel address, row bytes, and SkImageInfo to SkPixmap, if address
623         is available, and returns true. If pixel address is not available, return
624         false and leave SkPixmap unchanged.
625 
626         pixmap contents become invalid on any future change to SkSurface.
627 
628         @param pixmap  storage for pixel state if pixels are readable; otherwise, ignored
629         @return        true if SkSurface has direct access to pixels
630     */
631     bool peekPixels(SkPixmap* pixmap);
632 
633     /** Copies SkRect of pixels to dst.
634 
635         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
636         Destination SkRect corners are (0, 0) and (dst.width(), dst.height()).
637         Copies each readable pixel intersecting both rectangles, without scaling,
638         converting to dst.colorType() and dst.alphaType() if required.
639 
640         Pixels are readable when SkSurface is raster, or backed by a GPU.
641 
642         The destination pixel storage must be allocated by the caller.
643 
644         Pixel values are converted only if SkColorType and SkAlphaType
645         do not match. Only pixels within both source and destination rectangles
646         are copied. dst contents outside SkRect intersection are unchanged.
647 
648         Pass negative values for srcX or srcY to offset pixels across or down destination.
649 
650         Does not copy, and returns false if:
651         - Source and destination rectangles do not intersect.
652         - SkPixmap pixels could not be allocated.
653         - dst.rowBytes() is too small to contain one row of pixels.
654 
655         @param dst   storage for pixels copied from SkSurface
656         @param srcX  offset into readable pixels on x-axis; may be negative
657         @param srcY  offset into readable pixels on y-axis; may be negative
658         @return      true if pixels were copied
659     */
660     bool readPixels(const SkPixmap& dst, int srcX, int srcY);
661 
662     /** Copies SkRect of pixels from SkCanvas into dstPixels.
663 
664         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
665         Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
666         Copies each readable pixel intersecting both rectangles, without scaling,
667         converting to dstInfo.colorType() and dstInfo.alphaType() if required.
668 
669         Pixels are readable when SkSurface is raster, or backed by a GPU.
670 
671         The destination pixel storage must be allocated by the caller.
672 
673         Pixel values are converted only if SkColorType and SkAlphaType
674         do not match. Only pixels within both source and destination rectangles
675         are copied. dstPixels contents outside SkRect intersection are unchanged.
676 
677         Pass negative values for srcX or srcY to offset pixels across or down destination.
678 
679         Does not copy, and returns false if:
680         - Source and destination rectangles do not intersect.
681         - SkSurface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType().
682         - dstRowBytes is too small to contain one row of pixels.
683 
684         @param dstInfo      width, height, SkColorType, and SkAlphaType of dstPixels
685         @param dstPixels    storage for pixels; dstInfo.height() times dstRowBytes, or larger
686         @param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger
687         @param srcX         offset into readable pixels on x-axis; may be negative
688         @param srcY         offset into readable pixels on y-axis; may be negative
689         @return             true if pixels were copied
690     */
691     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
692                     int srcX, int srcY);
693 
694     /** Copies SkRect of pixels from SkSurface into bitmap.
695 
696         Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()).
697         Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()).
698         Copies each readable pixel intersecting both rectangles, without scaling,
699         converting to bitmap.colorType() and bitmap.alphaType() if required.
700 
701         Pixels are readable when SkSurface is raster, or backed by a GPU.
702 
703         The destination pixel storage must be allocated by the caller.
704 
705         Pixel values are converted only if SkColorType and SkAlphaType
706         do not match. Only pixels within both source and destination rectangles
707         are copied. dst contents outside SkRect intersection are unchanged.
708 
709         Pass negative values for srcX or srcY to offset pixels across or down destination.
710 
711         Does not copy, and returns false if:
712         - Source and destination rectangles do not intersect.
713         - SkSurface pixels could not be converted to dst.colorType() or dst.alphaType().
714         - dst pixels could not be allocated.
715         - dst.rowBytes() is too small to contain one row of pixels.
716 
717         @param dst   storage for pixels copied from SkSurface
718         @param srcX  offset into readable pixels on x-axis; may be negative
719         @param srcY  offset into readable pixels on y-axis; may be negative
720         @return      true if pixels were copied
721     */
722     bool readPixels(const SkBitmap& dst, int srcX, int srcY);
723 
724     /** Makes pixel data available to caller, possibly asynchronously. Can perform rescaling.
725 
726         Currently asynchronous reads are only supported on the GPU backend and only when the
727         underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
728         other cases this operates synchronously.
729 
730         Data is read from the source rectangle, is optionally converted to a linear gamma, is
731         rescaled to the size indicated by 'info', is then converted to the color space, color type,
732         and alpha type of 'info'.
733 
734         When the pixel data is ready the caller's ReadPixelsCallback is called with a pointer to
735         the data in the requested color type, alpha type, and color space. The data pointer is
736         only valid for the duration of the callback.
737 
738         Upon failure the the callback is called with nullptr as the data pointer.
739 
740         If the src rectangle is not contained by the bounds of the surface then failure occurs.
741 
742         Failure is indicated by calling callback with a nullptr for 'data'.
743 
744         @param info             info of the requested pixels
745         @param srcRect          subrectangle of surface to read
746         @param rescaleGamma     controls whether rescaling is done in the surface's gamma or whether
747                                 the source data is transformed to a linear gamma before rescaling.
748         @param rescaleQuality   controls the quality (and cost) of the rescaling
749         @param callback         function to call with result of the read
750         @param context          passed to callback
751      */
752     using ReadPixelsContext = void*;
753     using ReadPixelsCallback = void(ReadPixelsContext, const void* data, size_t rowBytes);
754     enum RescaleGamma : bool { kSrc, kLinear };
755     void asyncRescaleAndReadPixels(const SkImageInfo& info, const SkIRect& srcRect,
756                                    RescaleGamma rescaleGamma, SkFilterQuality rescaleQuality,
757                                    ReadPixelsCallback callback, ReadPixelsContext context);
758 
759     /**
760         Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
761         RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
762         planes ordered y, u, v. The u and v planes are half the width and height of the resized
763         rectangle. Currently this fails if dstW or dstH are not even.
764 
765         On failure the callback is called with a null data pointer array. Fails if srcRect is not
766         contained in the surface bounds.
767 
768         @param yuvColorSpace  The transformation from RGB to YUV. Applied to the resized image
769                               after it is converted to dstColorSpace.
770         @param dstColorSpace  The color space to convert the resized image to, after rescaling.
771         @param srcRect        The portion of the surface to rescale and convert to YUV planes.
772         @param dstW           The width to rescale srcRect to
773         @param dstH           The height to rescale srcRect to
774         @param rescaleGamma     controls whether rescaling is done in the surface's gamma or whether
775                                 the source data is transformed to a linear gamma before rescaling.
776         @param rescaleQuality   controls the quality (and cost) of the rescaling
777         @param callback         function to call with the planar read result
778         @param context          passed to callback
779      */
780     using ReadPixelsCallbackYUV420 = void(ReadPixelsContext, const void* data[3],
781                                           size_t rowBytes[3]);
782     void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
783                                          sk_sp<SkColorSpace> dstColorSpace, const SkIRect& srcRect,
784                                          int dstW, int dstH, RescaleGamma rescaleGamma,
785                                          SkFilterQuality rescaleQuality,
786                                          ReadPixelsCallbackYUV420 callback, ReadPixelsContext);
787 
788     /** Copies SkRect of pixels from the src SkPixmap to the SkSurface.
789 
790         Source SkRect corners are (0, 0) and (src.width(), src.height()).
791         Destination SkRect corners are (dstX, dstY) and
792         (dstX + Surface width(), dstY + Surface height()).
793 
794         Copies each readable pixel intersecting both rectangles, without scaling,
795         converting to SkSurface colorType() and SkSurface alphaType() if required.
796 
797         @param src   storage for pixels to copy to SkSurface
798         @param dstX  x-axis position relative to SkSurface to begin copy; may be negative
799         @param dstY  y-axis position relative to SkSurface to begin copy; may be negative
800     */
801     void writePixels(const SkPixmap& src, int dstX, int dstY);
802 
803     /** Copies SkRect of pixels from the src SkBitmap to the SkSurface.
804 
805         Source SkRect corners are (0, 0) and (src.width(), src.height()).
806         Destination SkRect corners are (dstX, dstY) and
807         (dstX + Surface width(), dstY + Surface height()).
808 
809         Copies each readable pixel intersecting both rectangles, without scaling,
810         converting to SkSurface colorType() and SkSurface alphaType() if required.
811 
812         @param src   storage for pixels to copy to SkSurface
813         @param dstX  x-axis position relative to SkSurface to begin copy; may be negative
814         @param dstY  y-axis position relative to SkSurface to begin copy; may be negative
815     */
816     void writePixels(const SkBitmap& src, int dstX, int dstY);
817 
818     /** Returns SkSurfaceProps for surface.
819 
820         @return  LCD striping orientation and setting for device independent fonts
821     */
props()822     const SkSurfaceProps& props() const { return fProps; }
823 
824     /** Issues pending SkSurface commands to the GPU-backed API and resolves any SkSurface MSAA.
825 
826         Skia flushes as needed, so it is not necessary to call this if Skia manages
827         drawing and object lifetime. Call when interleaving Skia calls with native
828         GPU calls.
829     */
830     void flush();
831 
832     enum class BackendSurfaceAccess {
833         kNoAccess,  //!< back-end object will not be used by client
834         kPresent,   //!< back-end surface will be used for presenting to screen
835     };
836 
837     /** Issues pending SkSurface commands to the GPU-backed API and resolves any SkSurface MSAA.
838         The work that is submitted to the GPU will be dependent on the BackendSurfaceAccess that is
839         passed in.
840 
841         If BackendSurfaceAccess::kNoAccess is passed in all commands will be issued to the GPU.
842 
843         If BackendSurfaceAccess::kPresent is passed in and the backend API is not Vulkan, it is
844         treated the same as kNoAccess. If the backend API is Vulkan, the VkImage that backs the
845         SkSurface will be transferred back to its original queue. If the SkSurface was created by
846         wrapping a VkImage, the queue will be set to the queue which was originally passed in on
847         the GrVkImageInfo. Additionally, if the original queue was not external or foreign the
848         layout of the VkImage will be set to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.
849 
850         The GrFlushInfo describes additional options to flush. Please see documentation at
851         GrFlushInfo for more info.
852 
853         If GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not create or
854         add any semaphores to signal on the GPU; the caller should not instruct the GPU
855         to wait on any of the semaphores passed in the GrFlushInfo.
856 
857         Pending surface commands are flushed regardless of the return result.
858 
859         @param access  type of access the call will do on the backend object after flush
860         @param info    flush options
861         @return        one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo
862     */
863     GrSemaphoresSubmitted flush(BackendSurfaceAccess access, const GrFlushInfo& info);
864 
865     /** Deprecated
866      */
867     GrSemaphoresSubmitted flush(BackendSurfaceAccess access, GrFlushFlags flags,
868                                 int numSemaphores, GrBackendSemaphore signalSemaphores[],
869                                 GrGpuFinishedProc finishedProc = nullptr,
870                                 GrGpuFinishedContext finishedContext = nullptr);
871 
872     /** The below enum and flush call are deprecated
873      */
874     enum FlushFlags {
875         kNone_FlushFlags = 0,
876         // flush will wait till all submitted GPU work is finished before returning.
877         kSyncCpu_FlushFlag = 0x1,
878     };
879     GrSemaphoresSubmitted flush(BackendSurfaceAccess access, FlushFlags flags,
880                                 int numSemaphores, GrBackendSemaphore signalSemaphores[]);
881 
882     /** Deprecated.
883     */
884     GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
885                                                    GrBackendSemaphore signalSemaphores[]);
886 
887     /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
888         executing any more commands on the GPU for this surface. Skia will take ownership of the
889         underlying semaphores and delete them once they have been signaled and waited on.
890         If this call returns false, then the GPU back-end will not wait on any passed in semaphores,
891         and the client will still own the semaphores.
892 
893         @param numSemaphores   size of waitSemaphores array
894         @param waitSemaphores  array of semaphore containers
895         @return                true if GPU is waiting on semaphores
896     */
897     bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores);
898 
899     /** Initializes SkSurfaceCharacterization that can be used to perform GPU back-end
900         processing in a separate thread. Typically this is used to divide drawing
901         into multiple tiles. SkDeferredDisplayListRecorder records the drawing commands
902         for each tile.
903 
904         Return true if SkSurface supports characterization. raster surface returns false.
905 
906         @param characterization  properties for parallel drawing
907         @return                  true if supported
908     */
909     bool characterize(SkSurfaceCharacterization* characterization) const;
910 
911     /** Draws deferred display list created using SkDeferredDisplayListRecorder.
912         Has no effect and returns false if SkSurfaceCharacterization stored in
913         deferredDisplayList is not compatible with SkSurface.
914 
915         raster surface returns false.
916 
917         @param deferredDisplayList  drawing commands
918         @return                     false if deferredDisplayList is not compatible
919     */
920     bool draw(SkDeferredDisplayList* deferredDisplayList);
921 
922 protected:
923     SkSurface(int width, int height, const SkSurfaceProps* surfaceProps);
924     SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps);
925 
926     // called by subclass if their contents have changed
dirtyGenerationID()927     void dirtyGenerationID() {
928         fGenerationID = 0;
929     }
930 
931 private:
932     const SkSurfaceProps fProps;
933     const int            fWidth;
934     const int            fHeight;
935     uint32_t             fGenerationID;
936 
937     typedef SkRefCnt INHERITED;
938 };
939 
940 #endif
941