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 @param fromWindow Whether or not the AHardwareBuffer is part of an Android Window. 378 Currently only used with Vulkan backend. 379 @return created SkSurface, or nullptr 380 */ 381 static sk_sp<SkSurface> MakeFromAHardwareBuffer(GrDirectContext* context, 382 AHardwareBuffer* hardwareBuffer, 383 GrSurfaceOrigin origin, 384 sk_sp<SkColorSpace> colorSpace, 385 const SkSurfaceProps* surfaceProps 386 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 387 , bool fromWindow = false 388 #endif // SK_BUILD_FOR_ANDROID_FRAMEWORK 389 ); 390 #endif 391 392 #ifdef SK_METAL 393 /** Creates SkSurface from CAMetalLayer. 394 Returned SkSurface takes a reference on the CAMetalLayer. The ref on the layer will be 395 released when the SkSurface is destroyed. 396 397 Only available when Metal API is enabled. 398 399 Will grab the current drawable from the layer and use its texture as a backendRT to 400 create a renderable surface. 401 402 @param context GPU context 403 @param layer GrMTLHandle (expected to be a CAMetalLayer*) 404 @param sampleCnt samples per pixel, or 0 to disable full scene anti-aliasing 405 @param colorSpace range of colors; may be nullptr 406 @param surfaceProps LCD striping orientation and setting for device independent 407 fonts; may be nullptr 408 @param drawable Pointer to drawable to be filled in when this surface is 409 instantiated; may not be nullptr 410 @return created SkSurface, or nullptr 411 */ 412 static sk_sp<SkSurface> MakeFromCAMetalLayer(GrRecordingContext* context, 413 GrMTLHandle layer, 414 GrSurfaceOrigin origin, 415 int sampleCnt, 416 SkColorType colorType, 417 sk_sp<SkColorSpace> colorSpace, 418 const SkSurfaceProps* surfaceProps, 419 GrMTLHandle* drawable) 420 SK_API_AVAILABLE_CA_METAL_LAYER; 421 422 /** Creates SkSurface from MTKView. 423 Returned SkSurface takes a reference on the MTKView. The ref on the layer will be 424 released when the SkSurface is destroyed. 425 426 Only available when Metal API is enabled. 427 428 Will grab the current drawable from the layer and use its texture as a backendRT to 429 create a renderable surface. 430 431 @param context GPU context 432 @param layer GrMTLHandle (expected to be a MTKView*) 433 @param sampleCnt samples per pixel, or 0 to disable full scene anti-aliasing 434 @param colorSpace range of colors; may be nullptr 435 @param surfaceProps LCD striping orientation and setting for device independent 436 fonts; may be nullptr 437 @return created SkSurface, or nullptr 438 */ 439 static sk_sp<SkSurface> MakeFromMTKView(GrRecordingContext* context, 440 GrMTLHandle mtkView, 441 GrSurfaceOrigin origin, 442 int sampleCnt, 443 SkColorType colorType, 444 sk_sp<SkColorSpace> colorSpace, 445 const SkSurfaceProps* surfaceProps) 446 SK_API_AVAILABLE(macos(10.11), ios(9.0)); 447 #endif 448 449 /** Is this surface compatible with the provided characterization? 450 451 This method can be used to determine if an existing SkSurface is a viable destination 452 for an SkDeferredDisplayList. 453 454 @param characterization The characterization for which a compatibility check is desired 455 @return true if this surface is compatible with the characterization; 456 false otherwise 457 */ 458 bool isCompatible(const SkSurfaceCharacterization& characterization) const; 459 460 /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface 461 has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr. 462 463 @param width one or greater 464 @param height one or greater 465 @return SkSurface if width and height are positive; otherwise, nullptr 466 467 example: https://fiddle.skia.org/c/@Surface_MakeNull 468 */ 469 static sk_sp<SkSurface> MakeNull(int width, int height); 470 471 /** Returns pixel count in each row; may be zero or greater. 472 473 @return number of pixel columns 474 */ width()475 int width() const { return fWidth; } 476 477 /** Returns pixel row count; may be zero or greater. 478 479 @return number of pixel rows 480 */ height()481 int height() const { return fHeight; } 482 483 /** Returns an ImageInfo describing the surface. 484 */ 485 SkImageInfo imageInfo(); 486 487 /** Returns unique value identifying the content of SkSurface. Returned value changes 488 each time the content changes. Content is changed by drawing, or by calling 489 notifyContentWillChange(). 490 491 @return unique content identifier 492 493 example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange 494 */ 495 uint32_t generationID(); 496 497 /** \enum SkSurface::ContentChangeMode 498 ContentChangeMode members are parameters to notifyContentWillChange(). 499 */ 500 enum ContentChangeMode { 501 kDiscard_ContentChangeMode, //!< discards surface on change 502 kRetain_ContentChangeMode, //!< preserves surface on change 503 }; 504 505 /** Notifies that SkSurface contents will be changed by code outside of Skia. 506 Subsequent calls to generationID() return a different value. 507 508 TODO: Can kRetain_ContentChangeMode be deprecated? 509 510 example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange 511 */ 512 void notifyContentWillChange(ContentChangeMode mode); 513 514 /** Returns the recording context being used by the SkSurface. 515 516 @return the recording context, if available; nullptr otherwise 517 */ 518 GrRecordingContext* recordingContext(); 519 520 #if SK_SUPPORT_GPU 521 enum BackendHandleAccess { 522 kFlushRead_BackendHandleAccess, //!< back-end object is readable 523 kFlushWrite_BackendHandleAccess, //!< back-end object is writable 524 kDiscardWrite_BackendHandleAccess, //!< back-end object must be overwritten 525 }; 526 527 /** Deprecated. 528 */ 529 static const BackendHandleAccess kFlushRead_TextureHandleAccess = 530 kFlushRead_BackendHandleAccess; 531 532 /** Deprecated. 533 */ 534 static const BackendHandleAccess kFlushWrite_TextureHandleAccess = 535 kFlushWrite_BackendHandleAccess; 536 537 /** Deprecated. 538 */ 539 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = 540 kDiscardWrite_BackendHandleAccess; 541 542 /** Retrieves the back-end texture. If SkSurface has no back-end texture, an invalid 543 object is returned. Call GrBackendTexture::isValid to determine if the result 544 is valid. 545 546 The returned GrBackendTexture should be discarded if the SkSurface is drawn to or deleted. 547 548 @return GPU texture reference; invalid on failure 549 */ 550 GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess); 551 552 /** Retrieves the back-end render target. If SkSurface has no back-end render target, an invalid 553 object is returned. Call GrBackendRenderTarget::isValid to determine if the result 554 is valid. 555 556 The returned GrBackendRenderTarget should be discarded if the SkSurface is drawn to 557 or deleted. 558 559 @return GPU render target reference; invalid on failure 560 */ 561 GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess); 562 563 /** If the surface was made via MakeFromBackendTexture then it's backing texture may be 564 substituted with a different texture. The contents of the previous backing texture are 565 copied into the new texture. SkCanvas state is preserved. The original sample count is 566 used. The GrBackendFormat and dimensions of replacement texture must match that of 567 the original. 568 569 Upon success textureReleaseProc is called when it is safe to delete the texture in the 570 backend API (accounting only for use of the texture by this surface). If SkSurface creation 571 fails textureReleaseProc is called before this function returns. 572 573 @param backendTexture the new backing texture for the surface 574 @param mode Retain or discard current Content 575 @param textureReleaseProc function called when texture can be released 576 @param releaseContext state passed to textureReleaseProc 577 */ 578 bool replaceBackendTexture(const GrBackendTexture& backendTexture, 579 GrSurfaceOrigin origin, 580 ContentChangeMode mode = kRetain_ContentChangeMode, 581 TextureReleaseProc textureReleaseProc = nullptr, 582 ReleaseContext releaseContext = nullptr); 583 #endif 584 585 /** Returns SkCanvas that draws into SkSurface. Subsequent calls return the same SkCanvas. 586 SkCanvas returned is managed and owned by SkSurface, and is deleted when SkSurface 587 is deleted. 588 589 @return drawing SkCanvas for SkSurface 590 591 example: https://fiddle.skia.org/c/@Surface_getCanvas 592 */ 593 SkCanvas* getCanvas(); 594 595 /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains 596 the same raster, GPU, or null properties as the original. Returned SkSurface 597 does not share the same pixels. 598 599 Returns nullptr if imageInfo width or height are zero, or if imageInfo 600 is incompatible with SkSurface. 601 602 @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, 603 of SkSurface; width and height must be greater than zero 604 @return compatible SkSurface or nullptr 605 606 example: https://fiddle.skia.org/c/@Surface_makeSurface 607 */ 608 sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo); 609 610 /** Calls makeSurface(ImageInfo) with the same ImageInfo as this surface, but with the 611 * specified width and height. 612 */ 613 sk_sp<SkSurface> makeSurface(int width, int height); 614 615 /** Returns SkImage capturing SkSurface contents. Subsequent drawing to SkSurface contents 616 are not captured. SkImage allocation is accounted for if SkSurface was created with 617 SkBudgeted::kYes. 618 619 @return SkImage initialized with SkSurface contents 620 621 example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot 622 */ 623 sk_sp<SkImage> makeImageSnapshot(); 624 625 /** 626 * Like the no-parameter version, this returns an image of the current surface contents. 627 * This variant takes a rectangle specifying the subset of the surface that is of interest. 628 * These bounds will be sanitized before being used. 629 * - If bounds extends beyond the surface, it will be trimmed to just the intersection of 630 * it and the surface. 631 * - If bounds does not intersect the surface, then this returns nullptr. 632 * - If bounds == the surface, then this is the same as calling the no-parameter variant. 633 634 example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot_2 635 */ 636 sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds); 637 638 /** Draws SkSurface contents to canvas, with its top-left corner at (x, y). 639 640 If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter, and SkBlendMode. 641 642 @param canvas SkCanvas drawn into 643 @param x horizontal offset in SkCanvas 644 @param y vertical offset in SkCanvas 645 @param sampling what technique to use when sampling the surface pixels 646 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter, 647 and so on; or nullptr 648 649 example: https://fiddle.skia.org/c/@Surface_draw 650 */ 651 void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling, 652 const SkPaint* paint); 653 654 void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint = nullptr) { 655 this->draw(canvas, x, y, SkSamplingOptions(), paint); 656 } 657 658 /** Copies SkSurface pixel address, row bytes, and SkImageInfo to SkPixmap, if address 659 is available, and returns true. If pixel address is not available, return 660 false and leave SkPixmap unchanged. 661 662 pixmap contents become invalid on any future change to SkSurface. 663 664 @param pixmap storage for pixel state if pixels are readable; otherwise, ignored 665 @return true if SkSurface has direct access to pixels 666 667 example: https://fiddle.skia.org/c/@Surface_peekPixels 668 */ 669 bool peekPixels(SkPixmap* pixmap); 670 671 /** Copies SkRect of pixels to dst. 672 673 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 674 Destination SkRect corners are (0, 0) and (dst.width(), dst.height()). 675 Copies each readable pixel intersecting both rectangles, without scaling, 676 converting to dst.colorType() and dst.alphaType() if required. 677 678 Pixels are readable when SkSurface is raster, or backed by a GPU. 679 680 The destination pixel storage must be allocated by the caller. 681 682 Pixel values are converted only if SkColorType and SkAlphaType 683 do not match. Only pixels within both source and destination rectangles 684 are copied. dst contents outside SkRect intersection are unchanged. 685 686 Pass negative values for srcX or srcY to offset pixels across or down destination. 687 688 Does not copy, and returns false if: 689 - Source and destination rectangles do not intersect. 690 - SkPixmap pixels could not be allocated. 691 - dst.rowBytes() is too small to contain one row of pixels. 692 693 @param dst storage for pixels copied from SkSurface 694 @param srcX offset into readable pixels on x-axis; may be negative 695 @param srcY offset into readable pixels on y-axis; may be negative 696 @return true if pixels were copied 697 698 example: https://fiddle.skia.org/c/@Surface_readPixels 699 */ 700 bool readPixels(const SkPixmap& dst, int srcX, int srcY); 701 702 /** Copies SkRect of pixels from SkCanvas into dstPixels. 703 704 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 705 Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()). 706 Copies each readable pixel intersecting both rectangles, without scaling, 707 converting to dstInfo.colorType() and dstInfo.alphaType() if required. 708 709 Pixels are readable when SkSurface is raster, or backed by a GPU. 710 711 The destination pixel storage must be allocated by the caller. 712 713 Pixel values are converted only if SkColorType and SkAlphaType 714 do not match. Only pixels within both source and destination rectangles 715 are copied. dstPixels contents outside SkRect intersection are unchanged. 716 717 Pass negative values for srcX or srcY to offset pixels across or down destination. 718 719 Does not copy, and returns false if: 720 - Source and destination rectangles do not intersect. 721 - SkSurface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). 722 - dstRowBytes is too small to contain one row of pixels. 723 724 @param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels 725 @param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger 726 @param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger 727 @param srcX offset into readable pixels on x-axis; may be negative 728 @param srcY offset into readable pixels on y-axis; may be negative 729 @return true if pixels were copied 730 */ 731 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 732 int srcX, int srcY); 733 734 /** Copies SkRect of pixels from SkSurface into bitmap. 735 736 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 737 Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()). 738 Copies each readable pixel intersecting both rectangles, without scaling, 739 converting to bitmap.colorType() and bitmap.alphaType() if required. 740 741 Pixels are readable when SkSurface is raster, or backed by a GPU. 742 743 The destination pixel storage must be allocated by the caller. 744 745 Pixel values are converted only if SkColorType and SkAlphaType 746 do not match. Only pixels within both source and destination rectangles 747 are copied. dst contents outside SkRect intersection are unchanged. 748 749 Pass negative values for srcX or srcY to offset pixels across or down destination. 750 751 Does not copy, and returns false if: 752 - Source and destination rectangles do not intersect. 753 - SkSurface pixels could not be converted to dst.colorType() or dst.alphaType(). 754 - dst pixels could not be allocated. 755 - dst.rowBytes() is too small to contain one row of pixels. 756 757 @param dst storage for pixels copied from SkSurface 758 @param srcX offset into readable pixels on x-axis; may be negative 759 @param srcY offset into readable pixels on y-axis; may be negative 760 @return true if pixels were copied 761 762 example: https://fiddle.skia.org/c/@Surface_readPixels_3 763 */ 764 bool readPixels(const SkBitmap& dst, int srcX, int srcY); 765 766 using AsyncReadResult = SkImage::AsyncReadResult; 767 768 /** Client-provided context that is passed to client-provided ReadPixelsContext. */ 769 using ReadPixelsContext = void*; 770 771 /** Client-provided callback to asyncRescaleAndReadPixels() or 772 asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure. 773 */ 774 using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>); 775 776 /** Controls the gamma that rescaling occurs in for asyncRescaleAndReadPixels() and 777 asyncRescaleAndReadPixelsYUV420(). 778 */ 779 using RescaleGamma = SkImage::RescaleGamma; 780 using RescaleMode = SkImage::RescaleMode; 781 782 /** Makes surface pixel data available to caller, possibly asynchronously. It can also rescale 783 the surface pixels. 784 785 Currently asynchronous reads are only supported on the GPU backend and only when the 786 underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all 787 other cases this operates synchronously. 788 789 Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is 790 rescaled to the size indicated by 'info', is then converted to the color space, color type, 791 and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the surface 792 causes failure. 793 794 When the pixel data is ready the caller's ReadPixelsCallback is called with a 795 AsyncReadResult containing pixel data in the requested color type, alpha type, and color 796 space. The AsyncReadResult will have count() == 1. Upon failure the callback is called 797 with nullptr for AsyncReadResult. For a GPU surface this flushes work but a submit must 798 occur to guarantee a finite time before the callback is called. 799 800 The data is valid for the lifetime of AsyncReadResult with the exception that if the 801 SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned 802 or destroyed. 803 804 @param info info of the requested pixels 805 @param srcRect subrectangle of surface to read 806 @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether 807 the source data is transformed to a linear gamma before rescaling. 808 @param rescaleMode controls the technique of the rescaling 809 @param callback function to call with result of the read 810 @param context passed to callback 811 */ 812 void asyncRescaleAndReadPixels(const SkImageInfo& info, 813 const SkIRect& srcRect, 814 RescaleGamma rescaleGamma, 815 RescaleMode rescaleMode, 816 ReadPixelsCallback callback, 817 ReadPixelsContext context); 818 819 /** 820 Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The 821 RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three 822 planes ordered y, u, v. The u and v planes are half the width and height of the resized 823 rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize' 824 width and height are not even. A 'srcRect' that is not contained by the bounds of the 825 surface causes failure. 826 827 When the pixel data is ready the caller's ReadPixelsCallback is called with a 828 AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3. 829 Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU surface this 830 flushes work but a submit must occur to guarantee a finite time before the callback is 831 called. 832 833 The data is valid for the lifetime of AsyncReadResult with the exception that if the 834 SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned 835 or destroyed. 836 837 @param yuvColorSpace The transformation from RGB to YUV. Applied to the resized image 838 after it is converted to dstColorSpace. 839 @param dstColorSpace The color space to convert the resized image to, after rescaling. 840 @param srcRect The portion of the surface to rescale and convert to YUV planes. 841 @param dstSize The size to rescale srcRect to 842 @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether 843 the source data is transformed to a linear gamma before rescaling. 844 @param rescaleMode controls the sampling technique of the rescaling 845 @param callback function to call with the planar read result 846 @param context passed to callback 847 */ 848 void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, 849 sk_sp<SkColorSpace> dstColorSpace, 850 const SkIRect& srcRect, 851 const SkISize& dstSize, 852 RescaleGamma rescaleGamma, 853 RescaleMode rescaleMode, 854 ReadPixelsCallback callback, 855 ReadPixelsContext context); 856 857 /** Copies SkRect of pixels from the src SkPixmap to the SkSurface. 858 859 Source SkRect corners are (0, 0) and (src.width(), src.height()). 860 Destination SkRect corners are (dstX, dstY) and 861 (dstX + Surface width(), dstY + Surface height()). 862 863 Copies each readable pixel intersecting both rectangles, without scaling, 864 converting to SkSurface colorType() and SkSurface alphaType() if required. 865 866 @param src storage for pixels to copy to SkSurface 867 @param dstX x-axis position relative to SkSurface to begin copy; may be negative 868 @param dstY y-axis position relative to SkSurface to begin copy; may be negative 869 870 example: https://fiddle.skia.org/c/@Surface_writePixels 871 */ 872 void writePixels(const SkPixmap& src, int dstX, int dstY); 873 874 /** Copies SkRect of pixels from the src SkBitmap to the SkSurface. 875 876 Source SkRect corners are (0, 0) and (src.width(), src.height()). 877 Destination SkRect corners are (dstX, dstY) and 878 (dstX + Surface width(), dstY + Surface height()). 879 880 Copies each readable pixel intersecting both rectangles, without scaling, 881 converting to SkSurface colorType() and SkSurface alphaType() if required. 882 883 @param src storage for pixels to copy to SkSurface 884 @param dstX x-axis position relative to SkSurface to begin copy; may be negative 885 @param dstY y-axis position relative to SkSurface to begin copy; may be negative 886 887 example: https://fiddle.skia.org/c/@Surface_writePixels_2 888 */ 889 void writePixels(const SkBitmap& src, int dstX, int dstY); 890 891 /** Returns SkSurfaceProps for surface. 892 893 @return LCD striping orientation and setting for device independent fonts 894 */ props()895 const SkSurfaceProps& props() const { return fProps; } 896 897 /** Call to ensure all reads/writes of the surface have been issued to the underlying 3D API. 898 Skia will correctly order its own draws and pixel operations. This must to be used to ensure 899 correct ordering when the surface backing store is accessed outside Skia (e.g. direct use of 900 the 3D API or a windowing system). GrDirectContext has additional flush and submit methods 901 that apply to all surfaces and images created from a GrDirectContext. This is equivalent to 902 calling SkSurface::flush with a default GrFlushInfo followed by 903 GrDirectContext::submit(syncCpu). 904 */ 905 void flushAndSubmit(bool syncCpu = false); 906 907 enum class BackendSurfaceAccess { 908 kNoAccess, //!< back-end object will not be used by client 909 kPresent, //!< back-end surface will be used for presenting to screen 910 }; 911 912 #if SK_SUPPORT_GPU 913 /** If a surface is GPU texture backed, is being drawn with MSAA, and there is a resolve 914 texture, this call will insert a resolve command into the stream of gpu commands. In order 915 for the resolve to actually have an effect, the work still needs to be flushed and submitted 916 to the GPU after recording the resolve command. If a resolve is not supported or the 917 SkSurface has no dirty work to resolve, then this call is a no-op. 918 919 This call is most useful when the SkSurface is created by wrapping a single sampled gpu 920 texture, but asking Skia to render with MSAA. If the client wants to use the wrapped texture 921 outside of Skia, the only way to trigger a resolve is either to call this command or use 922 SkSurface::flush. 923 */ 924 void resolveMSAA(); 925 926 /** Issues pending SkSurface commands to the GPU-backed API objects and resolves any SkSurface 927 MSAA. A call to GrDirectContext::submit is always required to ensure work is actually sent 928 to the gpu. Some specific API details: 929 GL: Commands are actually sent to the driver, but glFlush is never called. Thus some 930 sync objects from the flush will not be valid until a submission occurs. 931 932 Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command 933 buffer or encoder objects. However, these objects are not sent to the gpu until a 934 submission occurs. 935 936 The work that is submitted to the GPU will be dependent on the BackendSurfaceAccess that is 937 passed in. 938 939 If BackendSurfaceAccess::kNoAccess is passed in all commands will be issued to the GPU. 940 941 If BackendSurfaceAccess::kPresent is passed in and the backend API is not Vulkan, it is 942 treated the same as kNoAccess. If the backend API is Vulkan, the VkImage that backs the 943 SkSurface will be transferred back to its original queue. If the SkSurface was created by 944 wrapping a VkImage, the queue will be set to the queue which was originally passed in on 945 the GrVkImageInfo. Additionally, if the original queue was not external or foreign the 946 layout of the VkImage will be set to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR. 947 948 The GrFlushInfo describes additional options to flush. Please see documentation at 949 GrFlushInfo for more info. 950 951 If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be 952 submitted to the gpu during the next submit call (it is possible Skia failed to create a 953 subset of the semaphores). The client should not wait on these semaphores until after submit 954 has been called, but must keep them alive until then. If a submit flag was passed in with 955 the flush these valid semaphores can we waited on immediately. If this call returns 956 GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on 957 the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in 958 with the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the 959 client is still responsible for deleting any initialized semaphores. 960 Regardless of semaphore submission the context will still be flushed. It should be 961 emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not 962 happen. It simply means there were no semaphores submitted to the GPU. A caller should only 963 take this as a failure if they passed in semaphores to be submitted. 964 965 Pending surface commands are flushed regardless of the return result. 966 967 @param access type of access the call will do on the backend object after flush 968 @param info flush options 969 */ 970 GrSemaphoresSubmitted flush(BackendSurfaceAccess access, const GrFlushInfo& info); 971 972 /** Issues pending SkSurface commands to the GPU-backed API objects and resolves any SkSurface 973 MSAA. A call to GrDirectContext::submit is always required to ensure work is actually sent 974 to the gpu. Some specific API details: 975 GL: Commands are actually sent to the driver, but glFlush is never called. Thus some 976 sync objects from the flush will not be valid until a submission occurs. 977 978 Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command 979 buffer or encoder objects. However, these objects are not sent to the gpu until a 980 submission occurs. 981 982 The GrFlushInfo describes additional options to flush. Please see documentation at 983 GrFlushInfo for more info. 984 985 If a GrBackendSurfaceMutableState is passed in, at the end of the flush we will transition 986 the surface to be in the state requested by the GrBackendSurfaceMutableState. If the surface 987 (or SkImage or GrBackendSurface wrapping the same backend object) is used again after this 988 flush the state may be changed and no longer match what is requested here. This is often 989 used if the surface will be used for presenting or external use and the client wants backend 990 object to be prepped for that use. A finishedProc or semaphore on the GrFlushInfo will also 991 include the work for any requested state change. 992 993 If the backend API is Vulkan, the caller can set the GrBackendSurfaceMutableState's 994 VkImageLayout to VK_IMAGE_LAYOUT_UNDEFINED or queueFamilyIndex to VK_QUEUE_FAMILY_IGNORED to 995 tell Skia to not change those respective states. 996 997 If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be 998 submitted to the gpu during the next submit call (it is possible Skia failed to create a 999 subset of the semaphores). The client should not wait on these semaphores until after submit 1000 has been called, but must keep them alive until then. If a submit flag was passed in with 1001 the flush these valid semaphores can we waited on immediately. If this call returns 1002 GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on 1003 the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in 1004 with the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the 1005 client is still responsible for deleting any initialized semaphores. 1006 Regardleess of semaphore submission the context will still be flushed. It should be 1007 emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not 1008 happen. It simply means there were no semaphores submitted to the GPU. A caller should only 1009 take this as a failure if they passed in semaphores to be submitted. 1010 1011 Pending surface commands are flushed regardless of the return result. 1012 1013 @param info flush options 1014 @param access optional state change request after flush 1015 */ 1016 GrSemaphoresSubmitted flush(const GrFlushInfo& info, 1017 const GrBackendSurfaceMutableState* newState = nullptr); 1018 #endif // SK_SUPPORT_GPU 1019 1020 void flush(); 1021 1022 /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before 1023 executing any more commands on the GPU for this surface. If this call returns false, then 1024 the GPU back-end will not wait on any passed in semaphores, and the client will still own 1025 the semaphores, regardless of the value of deleteSemaphoresAfterWait. 1026 1027 If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case 1028 it is the client's responsibility to not destroy or attempt to reuse the semaphores until it 1029 knows that Skia has finished waiting on them. This can be done by using finishedProcs 1030 on flush calls. 1031 1032 @param numSemaphores size of waitSemaphores array 1033 @param waitSemaphores array of semaphore containers 1034 @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores 1035 @return true if GPU is waiting on semaphores 1036 */ 1037 bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, 1038 bool deleteSemaphoresAfterWait = true); 1039 1040 /** Initializes SkSurfaceCharacterization that can be used to perform GPU back-end 1041 processing in a separate thread. Typically this is used to divide drawing 1042 into multiple tiles. SkDeferredDisplayListRecorder records the drawing commands 1043 for each tile. 1044 1045 Return true if SkSurface supports characterization. raster surface returns false. 1046 1047 @param characterization properties for parallel drawing 1048 @return true if supported 1049 1050 example: https://fiddle.skia.org/c/@Surface_characterize 1051 */ 1052 bool characterize(SkSurfaceCharacterization* characterization) const; 1053 1054 /** Draws the deferred display list created via a SkDeferredDisplayListRecorder. 1055 If the deferred display list is not compatible with this SkSurface, the draw is skipped 1056 and false is return. 1057 1058 The xOffset and yOffset parameters are experimental and, if not both zero, will cause 1059 the draw to be ignored. 1060 When implemented, if xOffset or yOffset are non-zero, the DDL will be drawn offset by that 1061 amount into the surface. 1062 1063 @param deferredDisplayList drawing commands 1064 @param xOffset x-offset at which to draw the DDL 1065 @param yOffset y-offset at which to draw the DDL 1066 @return false if deferredDisplayList is not compatible 1067 1068 example: https://fiddle.skia.org/c/@Surface_draw_2 1069 */ 1070 bool draw(sk_sp<const SkDeferredDisplayList> deferredDisplayList, 1071 int xOffset = 0, 1072 int yOffset = 0); 1073 1074 protected: 1075 SkSurface(int width, int height, const SkSurfaceProps* surfaceProps); 1076 SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps); 1077 1078 // called by subclass if their contents have changed dirtyGenerationID()1079 void dirtyGenerationID() { 1080 fGenerationID = 0; 1081 } 1082 1083 private: 1084 const SkSurfaceProps fProps; 1085 const int fWidth; 1086 const int fHeight; 1087 uint32_t fGenerationID; 1088 1089 using INHERITED = SkRefCnt; 1090 }; 1091 1092 #endif 1093