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