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 25 class SkCanvas; 26 class SkDeferredDisplayList; 27 class SkPaint; 28 class SkSurfaceCharacterization; 29 class GrBackendRenderTarget; 30 class GrBackendSemaphore; 31 class GrBackendTexture; 32 class GrContext; 33 class GrRecordingContext; 34 class 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 */ 44 class SK_API SkSurface : public SkRefCnt { 45 public: 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 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 */ MakeRenderTarget(GrContext * context,SkBudgeted budgeted,const SkImageInfo & imageInfo,int sampleCount,const SkSurfaceProps * surfaceProps)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 */ MakeRenderTarget(GrContext * context,SkBudgeted budgeted,const SkImageInfo & imageInfo)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 */ width()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 */ height()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 */ props()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 GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not create or 938 add any semaphores to signal on the GPU; the caller should not instruct the GPU 939 to wait on any of the semaphores passed in the GrFlushInfo. 940 941 Pending surface commands are flushed regardless of the return result. 942 943 @param access type of access the call will do on the backend object after flush 944 @param info flush options 945 */ 946 GrSemaphoresSubmitted flush(BackendSurfaceAccess access, const GrFlushInfo& info); 947 948 /** Deprecated 949 */ 950 GrSemaphoresSubmitted flush(BackendSurfaceAccess access, GrFlushFlags flags, 951 int numSemaphores, GrBackendSemaphore signalSemaphores[], 952 GrGpuFinishedProc finishedProc = nullptr, 953 GrGpuFinishedContext finishedContext = nullptr); 954 955 /** The below enum and flush call are deprecated 956 */ 957 enum FlushFlags { 958 kNone_FlushFlags = 0, 959 // flush will wait till all submitted GPU work is finished before returning. 960 kSyncCpu_FlushFlag = 0x1, 961 }; 962 GrSemaphoresSubmitted flush(BackendSurfaceAccess access, FlushFlags flags, 963 int numSemaphores, GrBackendSemaphore signalSemaphores[]); 964 965 /** Deprecated. 966 */ 967 GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, 968 GrBackendSemaphore signalSemaphores[]); 969 970 /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before 971 executing any more commands on the GPU for this surface. Skia will take ownership of the 972 underlying semaphores and delete them once they have been signaled and waited on. 973 If this call returns false, then the GPU back-end will not wait on any passed in semaphores, 974 and the client will still own the semaphores. 975 976 @param numSemaphores size of waitSemaphores array 977 @param waitSemaphores array of semaphore containers 978 @return true if GPU is waiting on semaphores 979 */ 980 bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores); 981 982 /** Initializes SkSurfaceCharacterization that can be used to perform GPU back-end 983 processing in a separate thread. Typically this is used to divide drawing 984 into multiple tiles. SkDeferredDisplayListRecorder records the drawing commands 985 for each tile. 986 987 Return true if SkSurface supports characterization. raster surface returns false. 988 989 @param characterization properties for parallel drawing 990 @return true if supported 991 992 example: https://fiddle.skia.org/c/@Surface_characterize 993 */ 994 bool characterize(SkSurfaceCharacterization* characterization) const; 995 996 /** Draws deferred display list created using SkDeferredDisplayListRecorder. 997 Has no effect and returns false if SkSurfaceCharacterization stored in 998 deferredDisplayList is not compatible with SkSurface. 999 1000 raster surface returns false. 1001 1002 @param deferredDisplayList drawing commands 1003 @return false if deferredDisplayList is not compatible 1004 1005 example: https://fiddle.skia.org/c/@Surface_draw_2 1006 */ 1007 bool draw(SkDeferredDisplayList* deferredDisplayList); 1008 1009 protected: 1010 SkSurface(int width, int height, const SkSurfaceProps* surfaceProps); 1011 SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps); 1012 1013 // called by subclass if their contents have changed dirtyGenerationID()1014 void dirtyGenerationID() { 1015 fGenerationID = 0; 1016 } 1017 1018 private: 1019 const SkSurfaceProps fProps; 1020 const int fWidth; 1021 const int fHeight; 1022 uint32_t fGenerationID; 1023 1024 typedef SkRefCnt INHERITED; 1025 }; 1026 1027 #endif 1028