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/SkImageInfo.h" 13 #include "include/core/SkPixmap.h" 14 #include "include/core/SkRefCnt.h" 15 #include "include/core/SkSamplingOptions.h" 16 #include "include/core/SkScalar.h" 17 #include "include/core/SkSurfaceProps.h" 18 #include "include/core/SkTypes.h" 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <memory> 23 24 class GrBackendSemaphore; 25 class GrBackendTexture; 26 class GrRecordingContext; 27 class GrSurfaceCharacterization; 28 enum GrSurfaceOrigin : int; 29 class SkBitmap; 30 class SkCanvas; 31 class SkCapabilities; 32 class SkColorSpace; 33 class SkPaint; 34 class SkSurface; 35 struct SkIRect; 36 struct SkISize; 37 38 namespace skgpu::graphite { 39 class Recorder; 40 } 41 42 namespace SkSurfaces { 43 44 enum class BackendSurfaceAccess { 45 kNoAccess, //!< back-end surface will not be used by client 46 kPresent, //!< back-end surface will be used for presenting to screen 47 }; 48 49 /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface 50 has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr. 51 52 @param width one or greater 53 @param height one or greater 54 @return SkSurface if width and height are positive; otherwise, nullptr 55 56 example: https://fiddle.skia.org/c/@Surface_MakeNull 57 */ 58 SK_API sk_sp<SkSurface> Null(int width, int height); 59 60 /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into those allocated 61 pixels, which are zeroed before use. Pixel memory size is imageInfo.height() times 62 imageInfo.minRowBytes() or rowBytes, if provided and non-zero. 63 64 Pixel memory is deleted when SkSurface is deleted. 65 66 Validity constraints include: 67 - info dimensions are greater than zero; 68 - info contains SkColorType and SkAlphaType supported by raster surface. 69 70 @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, 71 of raster surface; width and height must be greater than zero 72 @param rowBytes interval from one SkSurface row to the next. 73 @param props LCD striping orientation and setting for device independent fonts; 74 may be nullptr 75 @return SkSurface if parameters are valid and memory was allocated, else nullptr. 76 */ 77 SK_API sk_sp<SkSurface> Raster(const SkImageInfo& imageInfo, 78 size_t rowBytes, 79 const SkSurfaceProps* surfaceProps); 80 inline sk_sp<SkSurface> Raster(const SkImageInfo& imageInfo, 81 const SkSurfaceProps* props = nullptr) { 82 return Raster(imageInfo, 0, props); 83 } 84 85 /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into the 86 provided pixels. 87 88 SkSurface is returned if all parameters are valid. 89 Valid parameters include: 90 info dimensions are greater than zero; 91 info contains SkColorType and SkAlphaType supported by raster surface; 92 pixels is not nullptr; 93 rowBytes is large enough to contain info width pixels of SkColorType. 94 95 Pixel buffer size should be info height times computed rowBytes. 96 Pixels are not initialized. 97 To access pixels after drawing, peekPixels() or readPixels(). 98 99 @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, 100 of raster surface; width and height must be greater than zero 101 @param pixels pointer to destination pixels buffer 102 @param rowBytes interval from one SkSurface row to the next 103 @param surfaceProps LCD striping orientation and setting for device independent fonts; 104 may be nullptr 105 @return SkSurface if all parameters are valid; otherwise, nullptr 106 */ 107 108 SK_API sk_sp<SkSurface> WrapPixels(const SkImageInfo& imageInfo, 109 void* pixels, 110 size_t rowBytes, 111 const SkSurfaceProps* surfaceProps = nullptr); 112 inline sk_sp<SkSurface> WrapPixels(const SkPixmap& pm, const SkSurfaceProps* props = nullptr) { 113 return WrapPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), props); 114 } 115 116 using PixelsReleaseProc = void(void* pixels, void* context); 117 118 /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into the provided 119 pixels. releaseProc is called with pixels and context when SkSurface is deleted. 120 121 SkSurface is returned if all parameters are valid. 122 Valid parameters include: 123 info dimensions are greater than zero; 124 info contains SkColorType and SkAlphaType supported by raster surface; 125 pixels is not nullptr; 126 rowBytes is large enough to contain info width pixels of SkColorType. 127 128 Pixel buffer size should be info height times computed rowBytes. 129 Pixels are not initialized. 130 To access pixels after drawing, call flush() or peekPixels(). 131 132 @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, 133 of raster surface; width and height must be greater than zero 134 @param pixels pointer to destination pixels buffer 135 @param rowBytes interval from one SkSurface row to the next 136 @param releaseProc called when SkSurface is deleted; may be nullptr 137 @param context passed to releaseProc; may be nullptr 138 @param surfaceProps LCD striping orientation and setting for device independent fonts; 139 may be nullptr 140 @return SkSurface if all parameters are valid; otherwise, nullptr 141 */ 142 SK_API sk_sp<SkSurface> WrapPixels(const SkImageInfo& imageInfo, 143 void* pixels, 144 size_t rowBytes, 145 PixelsReleaseProc, 146 void* context, 147 const SkSurfaceProps* surfaceProps = nullptr); 148 } // namespace SkSurfaces 149 150 /** \class SkSurface 151 SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be 152 allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface). 153 SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call 154 surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface). 155 SkSurface always has non-zero dimensions. If there is a request for a new surface, and either 156 of the requested dimensions are zero, then nullptr will be returned. 157 158 Clients should *not* subclass SkSurface as there is a lot of internal machinery that is 159 not publicly accessible. 160 */ 161 class SK_API SkSurface : public SkRefCnt { 162 public: 163 /** Is this surface compatible with the provided characterization? 164 165 This method can be used to determine if an existing SkSurface is a viable destination 166 for an GrDeferredDisplayList. 167 168 @param characterization The characterization for which a compatibility check is desired 169 @return true if this surface is compatible with the characterization; 170 false otherwise 171 */ 172 bool isCompatible(const GrSurfaceCharacterization& characterization) const; 173 174 /** Returns pixel count in each row; may be zero or greater. 175 176 @return number of pixel columns 177 */ width()178 int width() const { return fWidth; } 179 180 /** Returns pixel row count; may be zero or greater. 181 182 @return number of pixel rows 183 */ height()184 int height() const { return fHeight; } 185 186 /** Returns an ImageInfo describing the surface. 187 */ imageInfo()188 virtual SkImageInfo imageInfo() const { return SkImageInfo::MakeUnknown(fWidth, fHeight); } 189 190 /** Returns unique value identifying the content of SkSurface. Returned value changes 191 each time the content changes. Content is changed by drawing, or by calling 192 notifyContentWillChange(). 193 194 @return unique content identifier 195 196 example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange 197 */ 198 uint32_t generationID(); 199 200 /** \enum SkSurface::ContentChangeMode 201 ContentChangeMode members are parameters to notifyContentWillChange(). 202 */ 203 enum ContentChangeMode { 204 kDiscard_ContentChangeMode, //!< discards surface on change 205 kRetain_ContentChangeMode, //!< preserves surface on change 206 }; 207 208 /** Notifies that SkSurface contents will be changed by code outside of Skia. 209 Subsequent calls to generationID() return a different value. 210 211 TODO: Can kRetain_ContentChangeMode be deprecated? 212 213 example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange 214 */ 215 void notifyContentWillChange(ContentChangeMode mode); 216 217 /** Returns the recording context being used by the SkSurface. 218 219 @return the recording context, if available; nullptr otherwise 220 */ 221 GrRecordingContext* recordingContext() const; 222 223 /** Returns the recorder being used by the SkSurface. 224 225 @return the recorder, if available; nullptr otherwise 226 */ 227 skgpu::graphite::Recorder* recorder() const; 228 229 enum class BackendHandleAccess { 230 kFlushRead, //!< back-end object is readable 231 kFlushWrite, //!< back-end object is writable 232 kDiscardWrite, //!< back-end object must be overwritten 233 234 // Legacy names, remove when clients are migrated 235 kFlushRead_BackendHandleAccess = kFlushRead, 236 kFlushWrite_BackendHandleAccess = kFlushWrite, 237 kDiscardWrite_BackendHandleAccess = kDiscardWrite, 238 }; 239 240 // Legacy names, remove when clients are migrated 241 static constexpr BackendHandleAccess kFlushRead_BackendHandleAccess = 242 BackendHandleAccess::kFlushRead; 243 static constexpr BackendHandleAccess kFlushWrite_BackendHandleAccess = 244 BackendHandleAccess::kFlushWrite; 245 static constexpr BackendHandleAccess kDiscardWrite_BackendHandleAccess = 246 BackendHandleAccess::kDiscardWrite; 247 248 /** Caller data passed to TextureReleaseProc; may be nullptr. */ 249 using ReleaseContext = void*; 250 /** User function called when supplied texture may be deleted. */ 251 using TextureReleaseProc = void (*)(ReleaseContext); 252 253 /** If the surface was made via MakeFromBackendTexture then it's backing texture may be 254 substituted with a different texture. The contents of the previous backing texture are 255 copied into the new texture. SkCanvas state is preserved. The original sample count is 256 used. The GrBackendFormat and dimensions of replacement texture must match that of 257 the original. 258 259 Upon success textureReleaseProc is called when it is safe to delete the texture in the 260 backend API (accounting only for use of the texture by this surface). If SkSurface creation 261 fails textureReleaseProc is called before this function returns. 262 263 @param backendTexture the new backing texture for the surface 264 @param mode Retain or discard current Content 265 @param TextureReleaseProc function called when texture can be released 266 @param ReleaseContext state passed to textureReleaseProc 267 */ 268 virtual bool replaceBackendTexture(const GrBackendTexture& backendTexture, 269 GrSurfaceOrigin origin, 270 ContentChangeMode mode = kRetain_ContentChangeMode, 271 TextureReleaseProc = nullptr, 272 ReleaseContext = nullptr) = 0; 273 274 /** Returns SkCanvas that draws into SkSurface. Subsequent calls return the same SkCanvas. 275 SkCanvas returned is managed and owned by SkSurface, and is deleted when SkSurface 276 is deleted. 277 278 @return drawing SkCanvas for SkSurface 279 280 example: https://fiddle.skia.org/c/@Surface_getCanvas 281 */ 282 SkCanvas* getCanvas(); 283 284 /** Returns SkCapabilities that describes the capabilities of the SkSurface's device. 285 286 @return SkCapabilities of SkSurface's device. 287 */ 288 sk_sp<const SkCapabilities> capabilities(); 289 290 /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains 291 the same raster, GPU, or null properties as the original. Returned SkSurface 292 does not share the same pixels. 293 294 Returns nullptr if imageInfo width or height are zero, or if imageInfo 295 is incompatible with SkSurface. 296 297 @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, 298 of SkSurface; width and height must be greater than zero 299 @return compatible SkSurface or nullptr 300 301 example: https://fiddle.skia.org/c/@Surface_makeSurface 302 */ 303 sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo); 304 305 /** Calls makeSurface(ImageInfo) with the same ImageInfo as this surface, but with the 306 * specified width and height. 307 */ 308 sk_sp<SkSurface> makeSurface(int width, int height); 309 310 /** Returns SkImage capturing SkSurface contents. Subsequent drawing to SkSurface contents 311 are not captured. SkImage allocation is accounted for if SkSurface was created with 312 skgpu::Budgeted::kYes. 313 314 @return SkImage initialized with SkSurface contents 315 316 example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot 317 */ 318 sk_sp<SkImage> makeImageSnapshot(); 319 320 /** 321 * Like the no-parameter version, this returns an image of the current surface contents. 322 * This variant takes a rectangle specifying the subset of the surface that is of interest. 323 * These bounds will be sanitized before being used. 324 * - If bounds extends beyond the surface, it will be trimmed to just the intersection of 325 * it and the surface. 326 * - If bounds does not intersect the surface, then this returns nullptr. 327 * - If bounds == the surface, then this is the same as calling the no-parameter variant. 328 329 example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot_2 330 */ 331 sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds); 332 333 /** Draws SkSurface contents to canvas, with its top-left corner at (x, y). 334 335 If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter, and SkBlendMode. 336 337 @param canvas SkCanvas drawn into 338 @param x horizontal offset in SkCanvas 339 @param y vertical offset in SkCanvas 340 @param sampling what technique to use when sampling the surface pixels 341 @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter, 342 and so on; or nullptr 343 344 example: https://fiddle.skia.org/c/@Surface_draw 345 */ 346 void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling, 347 const SkPaint* paint); 348 349 void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint = nullptr) { 350 this->draw(canvas, x, y, SkSamplingOptions(), paint); 351 } 352 353 /** Copies SkSurface pixel address, row bytes, and SkImageInfo to SkPixmap, if address 354 is available, and returns true. If pixel address is not available, return 355 false and leave SkPixmap unchanged. 356 357 pixmap contents become invalid on any future change to SkSurface. 358 359 @param pixmap storage for pixel state if pixels are readable; otherwise, ignored 360 @return true if SkSurface has direct access to pixels 361 362 example: https://fiddle.skia.org/c/@Surface_peekPixels 363 */ 364 bool peekPixels(SkPixmap* pixmap); 365 366 /** Copies SkRect of pixels to dst. 367 368 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 369 Destination SkRect corners are (0, 0) and (dst.width(), dst.height()). 370 Copies each readable pixel intersecting both rectangles, without scaling, 371 converting to dst.colorType() and dst.alphaType() if required. 372 373 Pixels are readable when SkSurface is raster, or backed by a GPU. 374 375 The destination pixel storage must be allocated by the caller. 376 377 Pixel values are converted only if SkColorType and SkAlphaType 378 do not match. Only pixels within both source and destination rectangles 379 are copied. dst contents outside SkRect intersection are unchanged. 380 381 Pass negative values for srcX or srcY to offset pixels across or down destination. 382 383 Does not copy, and returns false if: 384 - Source and destination rectangles do not intersect. 385 - SkPixmap pixels could not be allocated. 386 - dst.rowBytes() is too small to contain one row of pixels. 387 388 @param dst storage for pixels copied from SkSurface 389 @param srcX offset into readable pixels on x-axis; may be negative 390 @param srcY offset into readable pixels on y-axis; may be negative 391 @return true if pixels were copied 392 393 example: https://fiddle.skia.org/c/@Surface_readPixels 394 */ 395 bool readPixels(const SkPixmap& dst, int srcX, int srcY); 396 397 /** Copies SkRect of pixels from SkCanvas into dstPixels. 398 399 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 400 Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()). 401 Copies each readable pixel intersecting both rectangles, without scaling, 402 converting to dstInfo.colorType() and dstInfo.alphaType() if required. 403 404 Pixels are readable when SkSurface is raster, or backed by a GPU. 405 406 The destination pixel storage must be allocated by the caller. 407 408 Pixel values are converted only if SkColorType and SkAlphaType 409 do not match. Only pixels within both source and destination rectangles 410 are copied. dstPixels contents outside SkRect intersection are unchanged. 411 412 Pass negative values for srcX or srcY to offset pixels across or down destination. 413 414 Does not copy, and returns false if: 415 - Source and destination rectangles do not intersect. 416 - SkSurface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). 417 - dstRowBytes is too small to contain one row of pixels. 418 419 @param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels 420 @param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger 421 @param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger 422 @param srcX offset into readable pixels on x-axis; may be negative 423 @param srcY offset into readable pixels on y-axis; may be negative 424 @return true if pixels were copied 425 */ 426 bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 427 int srcX, int srcY); 428 429 /** Copies SkRect of pixels from SkSurface into bitmap. 430 431 Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). 432 Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()). 433 Copies each readable pixel intersecting both rectangles, without scaling, 434 converting to bitmap.colorType() and bitmap.alphaType() if required. 435 436 Pixels are readable when SkSurface is raster, or backed by a GPU. 437 438 The destination pixel storage must be allocated by the caller. 439 440 Pixel values are converted only if SkColorType and SkAlphaType 441 do not match. Only pixels within both source and destination rectangles 442 are copied. dst contents outside SkRect intersection are unchanged. 443 444 Pass negative values for srcX or srcY to offset pixels across or down destination. 445 446 Does not copy, and returns false if: 447 - Source and destination rectangles do not intersect. 448 - SkSurface pixels could not be converted to dst.colorType() or dst.alphaType(). 449 - dst pixels could not be allocated. 450 - dst.rowBytes() is too small to contain one row of pixels. 451 452 @param dst storage for pixels copied from SkSurface 453 @param srcX offset into readable pixels on x-axis; may be negative 454 @param srcY offset into readable pixels on y-axis; may be negative 455 @return true if pixels were copied 456 457 example: https://fiddle.skia.org/c/@Surface_readPixels_3 458 */ 459 bool readPixels(const SkBitmap& dst, int srcX, int srcY); 460 461 using AsyncReadResult = SkImage::AsyncReadResult; 462 463 /** Client-provided context that is passed to client-provided ReadPixelsContext. */ 464 using ReadPixelsContext = void*; 465 466 /** Client-provided callback to asyncRescaleAndReadPixels() or 467 asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure. 468 */ 469 using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>); 470 471 /** Controls the gamma that rescaling occurs in for asyncRescaleAndReadPixels() and 472 asyncRescaleAndReadPixelsYUV420(). 473 */ 474 using RescaleGamma = SkImage::RescaleGamma; 475 using RescaleMode = SkImage::RescaleMode; 476 477 /** Makes surface pixel data available to caller, possibly asynchronously. It can also rescale 478 the surface pixels. 479 480 Currently asynchronous reads are only supported on the GPU backend and only when the 481 underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all 482 other cases this operates synchronously. 483 484 Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is 485 rescaled to the size indicated by 'info', is then converted to the color space, color type, 486 and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the surface 487 causes failure. 488 489 When the pixel data is ready the caller's ReadPixelsCallback is called with a 490 AsyncReadResult containing pixel data in the requested color type, alpha type, and color 491 space. The AsyncReadResult will have count() == 1. Upon failure the callback is called 492 with nullptr for AsyncReadResult. For a GPU surface this flushes work but a submit must 493 occur to guarantee a finite time before the callback is called. 494 495 The data is valid for the lifetime of AsyncReadResult with the exception that if the 496 SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned 497 or destroyed. 498 499 @param info info of the requested pixels 500 @param srcRect subrectangle of surface to read 501 @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether 502 the source data is transformed to a linear gamma before rescaling. 503 @param rescaleMode controls the technique of the rescaling 504 @param callback function to call with result of the read 505 @param context passed to callback 506 */ 507 void asyncRescaleAndReadPixels(const SkImageInfo& info, 508 const SkIRect& srcRect, 509 RescaleGamma rescaleGamma, 510 RescaleMode rescaleMode, 511 ReadPixelsCallback callback, 512 ReadPixelsContext context); 513 514 /** 515 Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The 516 RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three 517 planes ordered y, u, v. The u and v planes are half the width and height of the resized 518 rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize' 519 width and height are not even. A 'srcRect' that is not contained by the bounds of the 520 surface causes failure. 521 522 When the pixel data is ready the caller's ReadPixelsCallback is called with a 523 AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3. 524 Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU surface this 525 flushes work but a submit must occur to guarantee a finite time before the callback is 526 called. 527 528 The data is valid for the lifetime of AsyncReadResult with the exception that if the 529 SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned 530 or destroyed. 531 532 @param yuvColorSpace The transformation from RGB to YUV. Applied to the resized image 533 after it is converted to dstColorSpace. 534 @param dstColorSpace The color space to convert the resized image to, after rescaling. 535 @param srcRect The portion of the surface to rescale and convert to YUV planes. 536 @param dstSize The size to rescale srcRect to 537 @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether 538 the source data is transformed to a linear gamma before rescaling. 539 @param rescaleMode controls the sampling technique of the rescaling 540 @param callback function to call with the planar read result 541 @param context passed to callback 542 */ 543 void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, 544 sk_sp<SkColorSpace> dstColorSpace, 545 const SkIRect& srcRect, 546 const SkISize& dstSize, 547 RescaleGamma rescaleGamma, 548 RescaleMode rescaleMode, 549 ReadPixelsCallback callback, 550 ReadPixelsContext context); 551 552 /** 553 * Identical to asyncRescaleAndReadPixelsYUV420 but a fourth plane is returned in the 554 * AsyncReadResult passed to 'callback'. The fourth plane contains the alpha chanel at the 555 * same full resolution as the Y plane. 556 */ 557 void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace, 558 sk_sp<SkColorSpace> dstColorSpace, 559 const SkIRect& srcRect, 560 const SkISize& dstSize, 561 RescaleGamma rescaleGamma, 562 RescaleMode rescaleMode, 563 ReadPixelsCallback callback, 564 ReadPixelsContext context); 565 566 /** Copies SkRect of pixels from the src SkPixmap to the SkSurface. 567 568 Source SkRect corners are (0, 0) and (src.width(), src.height()). 569 Destination SkRect corners are (dstX, dstY) and 570 (dstX + Surface width(), dstY + Surface height()). 571 572 Copies each readable pixel intersecting both rectangles, without scaling, 573 converting to SkSurface colorType() and SkSurface alphaType() if required. 574 575 @param src storage for pixels to copy to SkSurface 576 @param dstX x-axis position relative to SkSurface to begin copy; may be negative 577 @param dstY y-axis position relative to SkSurface to begin copy; may be negative 578 579 example: https://fiddle.skia.org/c/@Surface_writePixels 580 */ 581 void writePixels(const SkPixmap& src, int dstX, int dstY); 582 583 /** Copies SkRect of pixels from the src SkBitmap to the SkSurface. 584 585 Source SkRect corners are (0, 0) and (src.width(), src.height()). 586 Destination SkRect corners are (dstX, dstY) and 587 (dstX + Surface width(), dstY + Surface height()). 588 589 Copies each readable pixel intersecting both rectangles, without scaling, 590 converting to SkSurface colorType() and SkSurface alphaType() if required. 591 592 @param src storage for pixels to copy to SkSurface 593 @param dstX x-axis position relative to SkSurface to begin copy; may be negative 594 @param dstY y-axis position relative to SkSurface to begin copy; may be negative 595 596 example: https://fiddle.skia.org/c/@Surface_writePixels_2 597 */ 598 void writePixels(const SkBitmap& src, int dstX, int dstY); 599 600 /** Returns SkSurfaceProps for surface. 601 602 @return LCD striping orientation and setting for device independent fonts 603 */ props()604 const SkSurfaceProps& props() const { return fProps; } 605 606 /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before 607 executing any more commands on the GPU for this surface. We only guarantee blocking 608 transfer and fragment shader work, but may block earlier stages as well depending on the 609 backend. 610 If this call returns false, then the GPU back-end will not wait on any passed in 611 semaphores, and the client will still own the semaphores, regardless of the value of 612 deleteSemaphoresAfterWait. 613 614 If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case 615 it is the client's responsibility to not destroy or attempt to reuse the semaphores until it 616 knows that Skia has finished waiting on them. This can be done by using finishedProcs 617 on flush calls. 618 619 @param numSemaphores size of waitSemaphores array 620 @param waitSemaphores array of semaphore containers 621 @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores 622 @return true if GPU is waiting on semaphores 623 */ 624 bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, 625 bool deleteSemaphoresAfterWait = true); 626 627 /** Initializes GrSurfaceCharacterization that can be used to perform GPU back-end 628 processing in a separate thread. Typically this is used to divide drawing 629 into multiple tiles. GrDeferredDisplayListRecorder records the drawing commands 630 for each tile. 631 632 Return true if SkSurface supports characterization. raster surface returns false. 633 634 @param characterization properties for parallel drawing 635 @return true if supported 636 637 example: https://fiddle.skia.org/c/@Surface_characterize 638 */ 639 bool characterize(GrSurfaceCharacterization* characterization) const; 640 641 protected: 642 SkSurface(int width, int height, const SkSurfaceProps* surfaceProps); 643 SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps); 644 645 // called by subclass if their contents have changed dirtyGenerationID()646 void dirtyGenerationID() { 647 fGenerationID = 0; 648 } 649 650 private: 651 const SkSurfaceProps fProps; 652 const int fWidth; 653 const int fHeight; 654 uint32_t fGenerationID; 655 656 using INHERITED = SkRefCnt; 657 }; 658 659 #endif 660