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