1 #Topic Surface 2 #Alias Surface_Reference ## 3 4 #Class SkSurface 5 6 #Code 7 #Populate 8 ## 9 10 SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be 11 allocated either in CPU memory, if a raster surface; or on the GPU, for a GrRenderTarget surface. 12 SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call 13 surface->getCanvas() to use that canvas. The caller should not delete the returned canvas; 14 it is owned by surface. 15 16 SkSurface always has non-zero dimensions. If there is a request for a new surface, and either 17 of the requested dimensions are zero, then nullptr will be returned. 18 19 # ------------------------------------------------------------------------------ 20 21 #Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels, 22 size_t rowBytes, 23 const SkSurfaceProps* surfaceProps = nullptr) 24 #In Constructors 25 #Line # creates Surface from SkImageInfo and Pixel_Storage ## 26 #Populate 27 28 #Example 29 void draw(SkCanvas* ) { 30 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); 31 const size_t size = info.computeMinByteSize(); 32 SkAutoTMalloc<SkPMColor> storage(size); 33 SkPMColor* pixels = storage.get(); 34 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes())); 35 SkCanvas* canvas = surface->getCanvas(); 36 canvas->clear(SK_ColorWHITE); 37 SkPMColor pmWhite = pixels[0]; 38 SkPaint paint; 39 canvas->drawPoint(1, 1, paint); 40 canvas->flush(); // ensure that point was drawn 41 for (int y = 0; y < info.height(); ++y) { 42 for (int x = 0; x < info.width(); ++x) { 43 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x'); 44 } 45 SkDebugf("\n"); 46 } 47 } 48 #StdOut 49 --- 50 -x- 51 --- 52 ## 53 ## 54 55 #SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect 56 57 #Method ## 58 59 # ------------------------------------------------------------------------------ 60 61 #Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels, 62 size_t rowBytes, 63 void (*releaseProc)(void* pixels, void* context), 64 void* context, const SkSurfaceProps* surfaceProps = nullptr) 65 #In Constructors 66 #Line # creates Surface from SkImageInfo and Pixel_Storage ## 67 #Populate 68 69 #Example 70 #Function 71 static void release_direct_surface_storage(void* pixels, void* context) { 72 if (pixels == context) { 73 SkDebugf("expected release context\n"); 74 } 75 sk_free(pixels); 76 } 77 78 ## 79 void draw(SkCanvas* ) { 80 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); 81 const size_t rowBytes = info.minRowBytes(); 82 void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes)); 83 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes, 84 release_direct_surface_storage, pixels)); 85 SkCanvas* canvas = surface->getCanvas(); 86 canvas->clear(SK_ColorWHITE); 87 SkPMColor* colorPtr = (SkPMColor*) pixels; 88 SkPMColor pmWhite = colorPtr[0]; 89 SkPaint paint; 90 canvas->drawPoint(1, 1, paint); 91 canvas->flush(); // ensure that point was drawn 92 for (int y = 0; y < info.height(); ++y) { 93 for (int x = 0; x < info.width(); ++x) { 94 SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x'); 95 } 96 SkDebugf("\n"); 97 } 98 } 99 #StdOut 100 --- 101 -x- 102 --- 103 expected release context 104 ## 105 ## 106 107 #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster 108 109 #Method ## 110 111 # ------------------------------------------------------------------------------ 112 113 #Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes, 114 const SkSurfaceProps* surfaceProps) 115 #In Constructors 116 #Line # creates Surface from SkImageInfo ## 117 #Populate 118 119 #Example 120 void draw(SkCanvas* ) { 121 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); 122 const size_t rowBytes = 64; 123 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr)); 124 SkCanvas* canvas = surface->getCanvas(); 125 canvas->clear(SK_ColorWHITE); 126 SkPixmap pixmap; 127 if (surface->peekPixels(&pixmap)) { 128 const uint32_t* colorPtr = pixmap.addr32(); 129 SkPMColor pmWhite = colorPtr[0]; 130 SkPaint paint; 131 canvas->drawPoint(1, 1, paint); 132 canvas->flush(); // ensure that point was drawn 133 for (int y = 0; y < info.height(); ++y) { 134 for (int x = 0; x < info.width(); ++x) { 135 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); 136 } 137 colorPtr += rowBytes / sizeof(colorPtr[0]); 138 SkDebugf("\n"); 139 } 140 } 141 } 142 #StdOut 143 --- 144 -x- 145 --- 146 ## 147 ## 148 149 #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc 150 151 #Method ## 152 153 # ------------------------------------------------------------------------------ 154 155 #Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, 156 const SkSurfaceProps* props = nullptr) 157 #Populate 158 159 #Example 160 void draw(SkCanvas* ) { 161 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); 162 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info)); 163 SkCanvas* canvas = surface->getCanvas(); 164 canvas->clear(SK_ColorWHITE); 165 SkPixmap pixmap; 166 if (surface->peekPixels(&pixmap)) { 167 const uint32_t* colorPtr = pixmap.addr32(); 168 SkPMColor pmWhite = colorPtr[0]; 169 SkPaint paint; 170 canvas->drawPoint(1, 1, paint); 171 canvas->flush(); // ensure that point was drawn 172 for (int y = 0; y < info.height(); ++y) { 173 for (int x = 0; x < info.width(); ++x) { 174 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); 175 } 176 colorPtr += info.width(); 177 SkDebugf("\n"); 178 } 179 } 180 } 181 ## 182 183 #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc 184 185 #Method ## 186 187 # ------------------------------------------------------------------------------ 188 189 #Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height, 190 const SkSurfaceProps* surfaceProps = nullptr) 191 #In Constructors 192 #Line # creates Surface from width, height matching output ## 193 #Populate 194 195 #Example 196 void draw(SkCanvas* ) { 197 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3)); 198 SkCanvas* canvas = surface->getCanvas(); 199 canvas->clear(SK_ColorWHITE); 200 SkPixmap pixmap; 201 if (surface->peekPixels(&pixmap)) { 202 const uint32_t* colorPtr = pixmap.addr32(); 203 SkPMColor pmWhite = colorPtr[0]; 204 SkPaint paint; 205 canvas->drawPoint(1, 1, paint); 206 canvas->flush(); // ensure that point was drawn 207 for (int y = 0; y < surface->height(); ++y) { 208 for (int x = 0; x < surface->width(); ++x) { 209 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); 210 } 211 colorPtr += surface->width(); 212 SkDebugf("\n"); 213 } 214 } 215 } 216 #StdOut 217 --- 218 -x- 219 --- 220 ## 221 ## 222 223 #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc 224 225 #Method ## 226 227 # ------------------------------------------------------------------------------ 228 229 #Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context, 230 const GrBackendTexture& backendTexture, 231 GrSurfaceOrigin origin, int sampleCnt, 232 SkColorType colorType, 233 sk_sp<SkColorSpace> colorSpace, 234 const SkSurfaceProps* surfaceProps) 235 #In Constructors 236 #Line # creates Surface from GPU texture ## 237 #Populate 238 239 #Example 240 #Platform gpu cpu 241 #Image 3 242 SkPaint paint; 243 paint.setTextSize(32); 244 GrContext* context = canvas->getGrContext(); 245 if (!context) { 246 canvas->drawString("GPU only!", 20, 40, paint); 247 return; 248 } 249 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context, 250 backEndTexture, kTopLeft_GrSurfaceOrigin, 0, 251 kRGBA_8888_SkColorType, nullptr, nullptr); 252 auto surfaceCanvas = gpuSurface->getCanvas(); 253 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); 254 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 255 canvas->drawImage(image, 0, 0); 256 ## 257 258 #SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget 259 260 #Method ## 261 262 # ------------------------------------------------------------------------------ 263 264 #Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context, 265 const GrBackendRenderTarget& backendRenderTarget, 266 GrSurfaceOrigin origin, 267 SkColorType colorType, 268 sk_sp<SkColorSpace> colorSpace, 269 const SkSurfaceProps* surfaceProps) 270 #In Constructors 271 #Line # creates Surface from GPU render target ## 272 #Populate 273 274 #Example 275 #ToDo remove !fiddle below once backEndTextureRenderTarget is available ## 276 #Platform !fiddle gpu 277 SkPaint paint; 278 paint.setTextSize(32); 279 GrContext* context = canvas->getGrContext(); 280 if (!context) { 281 canvas->drawString("GPU only!", 20, 40, paint); 282 return; 283 } 284 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context, 285 backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, 286 nullptr, nullptr); 287 auto surfaceCanvas = gpuSurface->getCanvas(); 288 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); 289 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 290 canvas->drawImage(image, 0, 0); 291 ## 292 293 #SeeAlso MakeFromBackendTexture MakeRenderTarget 294 295 #Method ## 296 297 # ------------------------------------------------------------------------------ 298 299 #Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context, 300 const GrBackendTexture& backendTexture, 301 GrSurfaceOrigin origin, 302 int sampleCnt, 303 SkColorType colorType, 304 sk_sp<SkColorSpace> colorSpace, 305 const SkSurfaceProps* surfaceProps) 306 #In Constructors 307 #Line # creates Surface from GPU back-end render target ## 308 #Populate 309 310 #Example 311 #ToDo example is bogus; gpuSurface should not make image ## 312 #Platform gpu 313 #Image 3 314 SkPaint paint; 315 paint.setTextSize(32); 316 GrContext* context = canvas->getGrContext(); 317 if (!context) { 318 canvas->drawString("GPU only!", 20, 40, paint); 319 return; 320 } 321 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget( 322 context, backEndTexture, kTopLeft_GrSurfaceOrigin, 0, 323 kRGBA_8888_SkColorType, nullptr, nullptr); 324 auto surfaceCanvas = gpuSurface->getCanvas(); 325 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); 326 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 327 canvas->drawImage(image, 0, 0); 328 ## 329 330 #SeeAlso MakeFromBackendRenderTarget MakeRenderTarget 331 332 #Method ## 333 334 # ------------------------------------------------------------------------------ 335 336 #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, 337 const SkImageInfo& imageInfo, 338 int sampleCount, GrSurfaceOrigin surfaceOrigin, 339 const SkSurfaceProps* surfaceProps, 340 bool shouldCreateWithMips = false) 341 #In Constructors 342 #Line # creates Surface pointing to new GPU memory buffer ## 343 #Populate 344 345 #Example 346 #Platform gpu 347 #Height 64 348 SkPaint paint; 349 paint.setTextSize(32); 350 GrContext* context = canvas->getGrContext(); 351 if (!context) { 352 canvas->drawString("GPU only!", 20, 40, paint); 353 return; 354 } 355 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType); 356 for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) { 357 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, 358 surfaceOrigin, nullptr)); 359 auto surfaceCanvas = gpuSurface->getCanvas(); 360 surfaceCanvas->clear(SK_ColorWHITE); 361 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); 362 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 363 canvas->drawImage(image, 0, 0); 364 canvas->translate(0, 128); 365 } 366 ## 367 368 #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget 369 370 #Method ## 371 372 # ------------------------------------------------------------------------------ 373 374 #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, 375 const SkImageInfo& imageInfo, int sampleCount, 376 const SkSurfaceProps* props) 377 #Populate 378 379 #Example 380 #Platform cpu gpu 381 #Description 382 LCD text takes advantage of raster striping to improve resolution. Only one of 383 the four combinations is correct, depending on whether monitor LCD striping is 384 horizontal or vertical, and whether the order of the stripes is red blue green 385 or red green blue. 386 ## 387 void draw(SkCanvas* canvas) { 388 auto test_draw = [](SkCanvas* surfaceCanvas) -> void { 389 SkPaint paint; 390 paint.setAntiAlias(true); 391 paint.setLCDRenderText(true); 392 paint.setColor(0xFFBBBBBB); 393 surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint); 394 paint.setColor(SK_ColorWHITE); 395 paint.setTextSize(32); 396 surfaceCanvas->drawString("Pest", 0, 25, paint); 397 }; 398 GrContext* context = canvas->getGrContext(); 399 SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType); 400 int y = 0; 401 for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry, 402 kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) { 403 SkSurfaceProps props(0, geometry); 404 sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget( 405 context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props); 406 test_draw(surface->getCanvas()); 407 surface->draw(canvas, 0, y, nullptr); 408 sk_sp<SkImage> image(surface->makeImageSnapshot()); 409 SkAutoCanvasRestore acr(canvas, true); 410 canvas->scale(8, 8); 411 canvas->drawImage(image, 12, y / 8); 412 y += 64; 413 } 414 } 415 ## 416 417 #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget 418 419 #Method ## 420 421 # ------------------------------------------------------------------------------ 422 423 #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, 424 const SkImageInfo& imageInfo) 425 #Populate 426 427 #Example 428 #Platform gpu 429 SkPaint paint; 430 paint.setTextSize(32); 431 GrContext* context = canvas->getGrContext(); 432 if (!context) { 433 canvas->drawString("GPU only!", 20, 40, paint); 434 return; 435 } 436 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType); 437 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info)); 438 auto surfaceCanvas = gpuSurface->getCanvas(); 439 surfaceCanvas->clear(SK_ColorWHITE); 440 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); 441 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 442 canvas->drawImage(image, 0, 0); 443 ## 444 445 #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget 446 447 #Method ## 448 449 # ------------------------------------------------------------------------------ 450 451 #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, 452 const SkSurfaceCharacterization& characterization, 453 SkBudgeted budgeted) 454 #Populate 455 456 #NoExample 457 ## 458 459 #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget 460 461 #Method ## 462 463 # ------------------------------------------------------------------------------ 464 465 #Method static sk_sp<SkSurface> MakeNull(int width, int height) 466 467 #In Constructors 468 #Line # creates Surface without backing pixels ## 469 #Populate 470 471 #Example 472 SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ? 473 '=' : '!'); 474 const int w = 37; 475 const int h = 1000; 476 auto surf = SkSurface::MakeNull(w, h); 477 auto nullCanvas = surf->getCanvas(); 478 nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws 479 SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ? 480 '=' : '!'); 481 #StdOut 482 SkSurface::MakeNull(0, 0) == nullptr 483 surf->makeImageSnapshot() == nullptr 484 ## 485 ## 486 487 #SeeAlso MakeRaster MakeRenderTarget 488 489 #Method ## 490 491 # ------------------------------------------------------------------------------ 492 #Subtopic Property 493 #Line # member values ## 494 ## 495 496 #Method int width() const 497 498 #In Property 499 #Line # returns pixel column count ## 500 #Populate 501 502 #Example 503 const int width = 37; 504 const int height = 1000; 505 auto surf = SkSurface::MakeNull(width, height); 506 auto nullCanvas = surf->getCanvas(); 507 SkDebugf("surface width=%d canvas width=%d\n", surf->width(), 508 nullCanvas->getBaseLayerSize().fWidth); 509 #StdOut 510 surface width=37 canvas width=37 511 ## 512 ## 513 514 #SeeAlso height() 515 516 #Method ## 517 518 # ------------------------------------------------------------------------------ 519 520 #Method int height() const 521 #In Property 522 #Line # returns pixel row count ## 523 #Populate 524 525 #Example 526 const int width = 37; 527 const int height = 1000; 528 auto surf = SkSurface::MakeNull(width, height); 529 auto nullCanvas = surf->getCanvas(); 530 SkDebugf("surface height=%d canvas height=%d\n", surf->height(), 531 nullCanvas->getBaseLayerSize().fHeight); 532 #StdOut 533 surface height=1000 canvas height=1000 534 ## 535 ## 536 537 #SeeAlso width() 538 539 #Method ## 540 541 # ------------------------------------------------------------------------------ 542 543 #Method uint32_t generationID() 544 #In Property 545 #Line # returns unique ID ## 546 #Populate 547 548 #Example 549 auto surface = SkSurface::MakeRasterN32Premul(1, 1); 550 for (int i = 0; i < 3; ++i) { 551 SkDebugf("surface generationID: %d\n", surface->generationID()); 552 if (0 == i) { 553 surface->getCanvas()->drawColor(SK_ColorBLACK); 554 } else { 555 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 556 } 557 } 558 #StdOut 559 surface generationID: 1 560 surface generationID: 2 561 surface generationID: 3 562 ## 563 ## 564 565 #SeeAlso notifyContentWillChange ContentChangeMode getCanvas 566 567 #Method ## 568 569 # ------------------------------------------------------------------------------ 570 571 #Enum ContentChangeMode 572 #Line # parameter options for notifyContentWillChange ## 573 #Code 574 enum ContentChangeMode { 575 kDiscard_ContentChangeMode, 576 kRetain_ContentChangeMode, 577 }; 578 ## 579 580 ContentChangeMode members are parameters to notifyContentWillChange. 581 582 #Const kDiscard_ContentChangeMode 583 #Line # discards surface on change ## 584 Pass to notifyContentWillChange to discard surface contents when 585 the surface is cleared or overwritten. 586 ## 587 #Const kRetain_ContentChangeMode 588 #Line # preserves surface on change ## 589 Pass to notifyContentWillChange when to preserve surface contents. 590 If a snapshot has been generated, this copies the Surface contents. 591 ## 592 593 #SeeAlso notifyContentWillChange generationID 594 595 #Enum ## 596 597 # ------------------------------------------------------------------------------ 598 599 #ToDo not crazy about misc catagory -- hopefully will become clear with time 600 ## 601 602 #Subtopic Miscellaneous 603 #Line # other functions ## 604 ## 605 606 #Method void notifyContentWillChange(ContentChangeMode mode) 607 #In Miscellaneous 608 #Line # notifies that contents will be changed outside of Skia ## 609 #Populate 610 611 #Example 612 auto surface = SkSurface::MakeRasterN32Premul(1, 1); 613 for (int i = 0; i < 3; ++i) { 614 SkDebugf("surface generationID: %d\n", surface->generationID()); 615 if (0 == i) { 616 surface->getCanvas()->drawColor(SK_ColorBLACK); 617 } else { 618 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); 619 } 620 } 621 ## 622 623 #SeeAlso ContentChangeMode generationID 624 625 #Method ## 626 627 # ------------------------------------------------------------------------------ 628 629 #Enum BackendHandleAccess 630 #Line # options to read and write back-end object ## 631 #Code 632 enum BackendHandleAccess { 633 kFlushRead_BackendHandleAccess, 634 kFlushWrite_BackendHandleAccess, 635 kDiscardWrite_BackendHandleAccess, 636 }; 637 638 static const BackendHandleAccess kFlushRead_TextureHandleAccess = 639 kFlushRead_BackendHandleAccess; 640 static const BackendHandleAccess kFlushWrite_TextureHandleAccess = 641 kFlushWrite_BackendHandleAccess; 642 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = 643 kDiscardWrite_BackendHandleAccess; 644 ## 645 646 #Const kFlushRead_BackendHandleAccess 0 647 #Line # back-end object is readable ## 648 Caller may read from the back-end object. 649 ## 650 #Const kFlushWrite_BackendHandleAccess 1 651 #Line # back-end object is writable ## 652 Caller may write to the back-end object. 653 ## 654 #Const kDiscardWrite_BackendHandleAccess 2 655 #Line # back-end object must be overwritten ## 656 Caller must overwrite the entire back-end object. 657 ## 658 659 #NoExample 660 // todo: need to update example to use GrBackendTexture instead of GrBackendObject 661 #Platform gpu 662 SkPaint paint; 663 paint.setTextSize(32); 664 GrContext* context = canvas->getGrContext(); 665 if (!context) { 666 canvas->drawString("GPU only!", 20, 40, paint); 667 return; 668 } 669 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget( 670 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10)); 671 int y = 20; 672 SkString str; 673 paint.setTextSize(16); 674 for (auto access : { SkSurface::kFlushRead_BackendHandleAccess, 675 SkSurface::kFlushWrite_BackendHandleAccess, 676 SkSurface::kDiscardWrite_BackendHandleAccess } ) { 677 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 678 str.printf("uniqueID=%d", image->uniqueID()); 679 canvas->drawString(str, 20, y += 20, paint); 680 GrBackendTexture backendTex = gpuSurface->getBackendTexture(access); 681 str.printf("backendTex is %svalid", backendTex.isValid() ? '' : 'not '); 682 canvas->drawString(str, 20, y += 20, paint); 683 } 684 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); 685 str.printf("final image uniqueID=%d", image->uniqueID()); 686 canvas->drawString(str, 20, y += 20, paint); 687 ## 688 689 #SeeAlso getBackendTexture getBackendRenderTarget 690 691 #Enum ## 692 693 # ------------------------------------------------------------------------------ 694 695 #Method GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess) 696 #In Property 697 #Line # returns the GPU reference to texture ## 698 #Populate 699 700 #NoExample 701 ## 702 703 #SeeAlso GrBackendTexture BackendHandleAccess getBackendRenderTarget 704 705 #Method ## 706 707 # ------------------------------------------------------------------------------ 708 709 #Method GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess) 710 #In Property 711 #Line # returns the GPU reference to render target ## 712 #Populate 713 714 #NoExample 715 ## 716 717 #SeeAlso GrBackendRenderTarget BackendHandleAccess getBackendTexture 718 719 #Method ## 720 721 # ------------------------------------------------------------------------------ 722 723 #Method SkCanvas* getCanvas() 724 #In Property 725 #Line # returns Canvas that draws into Surface ## 726 #Populate 727 728 #Example 729 #Height 64 730 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(64, 64)); 731 SkCanvas* surfaceCanvas = surface->getCanvas(); 732 surfaceCanvas->clear(SK_ColorBLUE); 733 SkPaint paint; 734 paint.setTextSize(40); 735 surfaceCanvas->drawString("\xF0\x9F\x98\x81", 12, 45, paint); 736 surface->draw(canvas, 0, 0, nullptr); 737 ## 738 739 #SeeAlso makeSurface makeImageSnapshot draw 740 741 #Method ## 742 743 # ------------------------------------------------------------------------------ 744 745 #Method sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo) 746 #In Constructors 747 #Line # creates a compatible Surface ## 748 #Populate 749 750 #Example 751 #Height 96 752 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); 753 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); 754 big->getCanvas()->clear(SK_ColorRED); 755 lil->getCanvas()->clear(SK_ColorBLACK); 756 SkPixmap pixmap; 757 if (big->peekPixels(&pixmap)) { 758 SkBitmap bigBits; 759 bigBits.installPixels(pixmap); 760 canvas->drawBitmap(bigBits, 0, 0); 761 } 762 if (lil->peekPixels(&pixmap)) { 763 SkBitmap lilBits; 764 lilBits.installPixels(pixmap); 765 canvas->drawBitmap(lilBits, 64, 64); 766 } 767 ## 768 769 #SeeAlso makeImageSnapshot getCanvas draw 770 771 #Method ## 772 773 # ------------------------------------------------------------------------------ 774 775 #Method sk_sp<SkImage> makeImageSnapshot() 776 #In Constructors 777 #Line # creates Image capturing Surface contents ## 778 #Populate 779 780 #Example 781 #Height 64 782 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); 783 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); 784 big->getCanvas()->clear(SK_ColorRED); 785 lil->getCanvas()->clear(SK_ColorBLACK); 786 sk_sp<SkImage> early(big->makeImageSnapshot()); 787 lil->draw(big->getCanvas(), 16, 16, nullptr); 788 sk_sp<SkImage> later(big->makeImageSnapshot()); 789 canvas->drawImage(early, 0, 0); 790 canvas->drawImage(later, 128, 0); 791 ## 792 793 #SeeAlso draw getCanvas 794 795 #Method ## 796 797 # ------------------------------------------------------------------------------ 798 799 #Method sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds) 800 #In Constructors 801 #Line # creates Image capturing subset of Surface contents ## 802 #Populate 803 804 #Example 805 #Height 64 806 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); 807 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); 808 big->getCanvas()->clear(SK_ColorRED); 809 lil->getCanvas()->clear(SK_ColorBLACK); 810 sk_sp<SkImage> early(big->makeImageSnapshot()); 811 lil->draw(big->getCanvas(), 16, 16, nullptr); 812 sk_sp<SkImage> later(big->makeImageSnapshot({0, 0, 16, 16})); 813 canvas->drawImage(early, 0, 0); 814 canvas->drawImage(later, 0, 0); 815 ## 816 817 #SeeAlso draw getCanvas 818 819 #Method ## 820 821 # ------------------------------------------------------------------------------ 822 #Subtopic Pixels 823 #Line # functions with pixel access ## 824 ## 825 826 #Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) 827 #In Pixels 828 #Line # draws Surface contents to canvas ## 829 #Populate 830 831 #Example 832 #Height 64 833 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); 834 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); 835 big->getCanvas()->clear(SK_ColorRED); 836 lil->getCanvas()->clear(SK_ColorBLACK); 837 lil->draw(big->getCanvas(), 16, 16, nullptr); 838 SkPixmap pixmap; 839 if (big->peekPixels(&pixmap)) { 840 SkBitmap bigBits; 841 bigBits.installPixels(pixmap); 842 canvas->drawBitmap(bigBits, 0, 0); 843 } 844 ## 845 846 #SeeAlso makeImageSnapshot getCanvas 847 848 #Method ## 849 850 # ------------------------------------------------------------------------------ 851 852 #Method bool peekPixels(SkPixmap* pixmap) 853 #In Pixels 854 #Line # copies Surface parameters to Pixmap ## 855 #Populate 856 857 #Example 858 #Height 64 859 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 860 auto surfCanvas = surf->getCanvas(); 861 surfCanvas->clear(SK_ColorRED); 862 SkPaint paint; 863 paint.setTextSize(40); 864 surfCanvas->drawString("&", 16, 48, paint); 865 SkPixmap pixmap; 866 if (surf->peekPixels(&pixmap)) { 867 SkBitmap surfBits; 868 surfBits.installPixels(pixmap); 869 canvas->drawBitmap(surfBits, 0, 0); 870 } 871 ## 872 873 #SeeAlso readPixels writePixels 874 875 #Method ## 876 877 # ------------------------------------------------------------------------------ 878 879 #Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) 880 #In Pixels 881 #Line # copies Rect of pixels ## 882 Copies Rect of pixels to dst. 883 884 Source Rect corners are (srcX, srcY) and Surface (width(), height()). 885 Destination Rect corners are (0, 0) and (dst.width(), dst.height()). 886 Copies each readable pixel intersecting both rectangles, without scaling, 887 converting to dst.colorType() and dst.alphaType() if required. 888 889 Pixels are readable when Surface is raster, or backed by a GPU. 890 891 The destination pixel storage must be allocated by the caller. 892 893 Pixel values are converted only if Color_Type and Alpha_Type 894 do not match. Only pixels within both source and destination rectangles 895 are copied. dst contents outside Rect intersection are unchanged. 896 897 Pass negative values for srcX or srcY to offset pixels across or down destination. 898 899 Does not copy, and returns false if: 900 901 #List 902 # Source and destination rectangles do not intersect. ## 903 # Pixmap pixels could not be allocated. ## 904 # dst.rowBytes() is too small to contain one row of pixels. ## 905 ## 906 907 #Param dst storage for pixels copied from Surface ## 908 #Param srcX offset into readable pixels on x-axis; may be negative ## 909 #Param srcY offset into readable pixels on y-axis; may be negative ## 910 911 #Return true if pixels were copied ## 912 913 #Example 914 #Height 32 915 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 916 auto surfCanvas = surf->getCanvas(); 917 surfCanvas->clear(SK_ColorRED); 918 SkPaint paint; 919 paint.setTextSize(40); 920 surfCanvas->drawString("&", 0, 32, paint); 921 std::vector<SkPMColor> storage; 922 storage.resize(surf->width() * surf->height()); 923 SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(), 924 surf->width() * sizeof(storage[0])); 925 if (surf->readPixels(pixmap, 0, 0)) { 926 SkBitmap surfBits; 927 surfBits.installPixels(pixmap); 928 canvas->drawBitmap(surfBits, 0, 0); 929 } 930 ## 931 932 #SeeAlso peekPixels writePixels 933 934 #Method ## 935 936 # ------------------------------------------------------------------------------ 937 938 #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, 939 int srcX, int srcY) 940 941 Copies Rect of pixels from Canvas into dstPixels. 942 943 Source Rect corners are (srcX, srcY) and Surface (width(), height()). 944 Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()). 945 Copies each readable pixel intersecting both rectangles, without scaling, 946 converting to dstInfo.colorType() and dstInfo.alphaType() if required. 947 948 Pixels are readable when Surface is raster, or backed by a GPU. 949 950 The destination pixel storage must be allocated by the caller. 951 952 Pixel values are converted only if Color_Type and Alpha_Type 953 do not match. Only pixels within both source and destination rectangles 954 are copied. dstPixels contents outside Rect intersection are unchanged. 955 956 Pass negative values for srcX or srcY to offset pixels across or down destination. 957 958 Does not copy, and returns false if: 959 960 #List 961 # Source and destination rectangles do not intersect. ## 962 # Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ## 963 # dstRowBytes is too small to contain one row of pixels. ## 964 ## 965 966 #Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ## 967 #Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ## 968 #Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ## 969 #Param srcX offset into readable pixels on x-axis; may be negative ## 970 #Param srcY offset into readable pixels on y-axis; may be negative ## 971 972 #Return true if pixels were copied ## 973 974 #Example 975 #Height 64 976 #Description 977 A black oval drawn on a red background provides an image to copy. 978 readPixels copies one quarter of the Surface into each of the four corners. 979 The copied quarter ovals overdraw the original oval. 980 ## 981 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 982 auto surfCanvas = surf->getCanvas(); 983 surfCanvas->clear(SK_ColorRED); 984 SkPaint paint; 985 surfCanvas->drawOval({4, 8, 58, 54}, paint); 986 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType); 987 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height())); 988 sk_bzero(data->writable_data(), info.minRowBytes() * info.height()); 989 for (int x : { 32, -32 } ) { 990 for (int y : { 32, -32 } ) { 991 surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y); 992 } 993 } 994 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes()); 995 canvas->drawImage(image, 0, 0); 996 ## 997 998 #SeeAlso peekPixels writePixels 999 1000 #Method ## 1001 1002 # ------------------------------------------------------------------------------ 1003 1004 #Method bool readPixels(const SkBitmap& dst, int srcX, int srcY) 1005 1006 Copies Rect of pixels from Surface into bitmap. 1007 1008 Source Rect corners are (srcX, srcY) and Surface (width(), height()). 1009 Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()). 1010 Copies each readable pixel intersecting both rectangles, without scaling, 1011 converting to dst.colorType() and dst.alphaType() if required. 1012 1013 Pixels are readable when Surface is raster, or backed by a GPU. 1014 1015 The destination pixel storage must be allocated by the caller. 1016 1017 Pixel values are converted only if Color_Type and Alpha_Type 1018 do not match. Only pixels within both source and destination rectangles 1019 are copied. dst contents outside Rect intersection are unchanged. 1020 1021 Pass negative values for srcX or srcY to offset pixels across or down destination. 1022 1023 Does not copy, and returns false if: 1024 1025 #List 1026 # Source and destination rectangles do not intersect. ## 1027 # Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ## 1028 # dst pixels could not be allocated. ## 1029 # dst.rowBytes() is too small to contain one row of pixels. ## 1030 ## 1031 1032 #Param dst storage for pixels copied from Surface ## 1033 #Param srcX offset into readable pixels on x-axis; may be negative ## 1034 #Param srcY offset into readable pixels on y-axis; may be negative ## 1035 1036 #Return true if pixels were copied ## 1037 1038 #Example 1039 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 1040 auto surfCanvas = surf->getCanvas(); 1041 surfCanvas->clear(SK_ColorGREEN); 1042 SkPaint paint; 1043 surfCanvas->drawOval({2, 10, 58, 54}, paint); 1044 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType); 1045 SkBitmap bitmap; 1046 bitmap.setInfo(info); 1047 bitmap.allocPixels(); 1048 for (int x : { 32, -32 } ) { 1049 for (int y : { 32, -32 } ) { 1050 surf->readPixels(bitmap, x, y); 1051 } 1052 } 1053 canvas->drawBitmap(bitmap, 0, 0); 1054 ## 1055 1056 #SeeAlso peekPixels writePixels 1057 1058 #Method ## 1059 1060 # ------------------------------------------------------------------------------ 1061 1062 #Method void writePixels(const SkPixmap& src, int dstX, int dstY) 1063 #In Pixels 1064 #Line # copies Rect of pixels ## 1065 Copies Rect of pixels from the src Pixmap to the Surface. 1066 1067 Source Rect corners are (0, 0) and (src.width(), src.height()). 1068 Destination Rect corners are (dstX, dstY) and 1069 #Formula # (dstX + Surface width(), dstY + Surface height()) ##. 1070 1071 Copies each readable pixel intersecting both rectangles, without scaling, 1072 converting to Surface SkColorType and SkAlphaType if required. 1073 1074 #Param src storage for pixels to copy to Surface ## 1075 #Param dstX x-axis position relative to Surface to begin copy; may be negative ## 1076 #Param dstY y-axis position relative to Surface to begin copy; may be negative ## 1077 1078 #Example 1079 #Image 4 1080 #Height 96 1081 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 1082 auto surfCanvas = surf->getCanvas(); 1083 surfCanvas->clear(SK_ColorRED); 1084 SkPaint paint; 1085 paint.setTextSize(40); 1086 surfCanvas->drawString("&", 16, 40, paint); 1087 SkPixmap pixmap; 1088 if (surf->peekPixels(&pixmap)) { 1089 surf->writePixels(pixmap, 25, 25); 1090 sk_sp<SkImage> image(surf->makeImageSnapshot()); 1091 canvas->drawImage(image, 0, 0); 1092 } 1093 ## 1094 1095 #SeeAlso readPixels peekPixels 1096 1097 #Method ## 1098 1099 # ------------------------------------------------------------------------------ 1100 1101 #Method void writePixels(const SkBitmap& src, int dstX, int dstY) 1102 1103 Copies Rect of pixels from the src Bitmap to the Surface. 1104 1105 Source Rect corners are (0, 0) and (src.width(), src.height()). 1106 Destination Rect corners are (dstX, dstY) and 1107 #Formula # (dstX + Surface width(), dstY + Surface height()) ##. 1108 1109 Copies each readable pixel intersecting both rectangles, without scaling, 1110 converting to Surface SkColorType and SkAlphaType if required. 1111 1112 #Param src storage for pixels to copy to Surface ## 1113 #Param dstX x-axis position relative to Surface to begin copy; may be negative ## 1114 #Param dstY y-axis position relative to Surface to begin copy; may be negative ## 1115 1116 #Example 1117 #Image 4 1118 #Height 96 1119 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 1120 auto surfCanvas = surf->getCanvas(); 1121 surfCanvas->clear(SK_ColorGREEN); 1122 surf->writePixels(source, 25, 25); 1123 sk_sp<SkImage> image(surf->makeImageSnapshot()); 1124 canvas->drawImage(image, 0, 0); 1125 ## 1126 1127 #SeeAlso readPixels peekPixels 1128 1129 #Method ## 1130 1131 # ------------------------------------------------------------------------------ 1132 1133 #Method const SkSurfaceProps& props() const 1134 #In Property 1135 #Line # returns Surface_Properties ## 1136 #Populate 1137 1138 #Example 1139 const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" }; 1140 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); 1141 SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]); 1142 #StdOut 1143 surf.props(): kRGB_H_SkPixelGeometry 1144 ## 1145 ## 1146 1147 #SeeAlso SkSurfaceProps 1148 1149 #Method ## 1150 1151 # ------------------------------------------------------------------------------ 1152 #Subtopic Utility 1153 #Line # rarely called management functions ## 1154 ## 1155 1156 #Method void flush() 1157 #In Utility 1158 #Line # resolves pending I/O ## 1159 #Populate 1160 1161 #NoExample 1162 ## 1163 1164 #SeeAlso GrBackendSemaphore 1165 1166 #Method ## 1167 1168 # ------------------------------------------------------------------------------ 1169 1170 #Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, 1171 GrBackendSemaphore signalSemaphores[]) 1172 #In Utility 1173 #Line # resolves pending I/O, and signal ## 1174 #Populate 1175 1176 #NoExample 1177 ## 1178 1179 #SeeAlso wait GrBackendSemaphore 1180 1181 #Method ## 1182 1183 # ------------------------------------------------------------------------------ 1184 1185 #Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) 1186 #In Utility 1187 #Line # pauses commands until signaled ## 1188 #Populate 1189 1190 #NoExample 1191 #ToDo this is copy and paste silliness masquerading as an example. Probably need gpu 1192 globals and definitely need gpu expertise to make a real example out of this 1193 also, note need to replace GrBackendObject with GrBackendTexture 1194 ## 1195 #Platform gpu 1196 #Height 64 1197 SkPaint paint; 1198 paint.setTextSize(32); 1199 GrContext* context = canvas->getGrContext(); 1200 if (!context) { 1201 canvas->drawString("GPU only!", 20, 40, paint); 1202 return; 1203 } 1204 GrBackendSemaphore semaphore; 1205 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( 1206 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64)); 1207 surface->flushAndSignalSemaphores(1, &semaphore); 1208 sk_sp<SkImage> image = surface->makeImageSnapshot(); 1209 GrBackendTexture backendTex = image->getBackendTexture(false); // unused 1210 SkASSERT(backendTex.isValid()); 1211 const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64, 1212 kRGBA_8888_SkColorType, kPremul_SkAlphaType); 1213 sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, 1214 childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr)); 1215 GrBackendTexture backendTexture; 1216 sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context, 1217 backendTexture, // undefined 1218 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr); 1219 SkCanvas* childCanvas = childSurface->getCanvas(); 1220 childCanvas->clear(SK_ColorRED); 1221 childSurface->wait(1, &semaphore); 1222 childCanvas->drawImage(childImage, 32, 0); 1223 childSurface->draw(canvas, 0, 0, nullptr); 1224 ## 1225 1226 #SeeAlso flushAndSignalSemaphores GrBackendSemaphore 1227 1228 #Method ## 1229 1230 # ------------------------------------------------------------------------------ 1231 1232 #Method bool characterize(SkSurfaceCharacterization* characterization) const 1233 #In Utility 1234 #Line # sets Surface_Characterization for threaded GPU processing ## 1235 #Populate 1236 1237 #Example 1238 #Platform gpu 1239 #Height 64 1240 SkPaint paint; 1241 paint.setTextSize(32); 1242 GrContext* context = canvas->getGrContext(); 1243 if (!context) { 1244 canvas->drawString("GPU only!", 20, 40, paint); 1245 return; 1246 } 1247 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget( 1248 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64)); 1249 SkSurfaceCharacterization characterization; 1250 if (!gpuSurface->characterize(&characterization)) { 1251 canvas->drawString("characterization unsupported", 20, 40, paint); 1252 return; 1253 } 1254 // start of threadable work 1255 SkDeferredDisplayListRecorder recorder(characterization); 1256 SkCanvas* subCanvas = recorder.getCanvas(); 1257 subCanvas->clear(SK_ColorGREEN); 1258 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach(); 1259 // end of threadable work 1260 gpuSurface->draw(displayList.get()); 1261 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot(); 1262 canvas->drawImage(std::move(img), 0, 0); 1263 ## 1264 1265 #SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList 1266 1267 #Method ## 1268 1269 # ------------------------------------------------------------------------------ 1270 1271 #Method bool draw(SkDeferredDisplayList* deferredDisplayList) 1272 #Populate 1273 1274 #Example 1275 #Height 64 1276 #Platform gpu cpu 1277 SkPaint paint; 1278 paint.setTextSize(16); 1279 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64); 1280 SkSurfaceCharacterization characterization; 1281 if (!gpuSurface->characterize(&characterization)) { 1282 canvas->drawString("characterization unsupported", 20, 40, paint); 1283 return; 1284 } 1285 // start of threadable work 1286 SkDeferredDisplayListRecorder recorder(characterization); 1287 SkCanvas* subCanvas = recorder.getCanvas(); 1288 subCanvas->clear(SK_ColorGREEN); 1289 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach(); 1290 // end of threadable work 1291 gpuSurface->draw(displayList.get()); 1292 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot(); 1293 canvas->drawImage(std::move(img), 0, 0); 1294 ## 1295 1296 #SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList 1297 1298 #Method ## 1299 1300 #Class SkSurface ## 1301 1302 #Topic Surface ## 1303