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