SkSurface_Reference.bmh revision ab2621d3e2d2055096b9fbebf16ee443e4ea90fb
1#Topic Surface
2#Alias Surface_Reference
3
4#Class SkSurface
5
6SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be
7allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface).
8SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
9surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface).
10SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
11of the requested dimensions are zero, then nullptr will be returned.
12
13#Topic Overview
14
15#Subtopic Subtopics
16#ToDo manually add subtopics ##
17#Table
18#Legend
19# topics # description ##
20#Legend ##
21# Constructors     # functions that construct SkIPoint16  ##
22# Member_Functions # static functions and member methods  ##
23#Table ##
24##
25
26#Subtopic Constructors
27#Table
28#Legend
29# name                                 # description                     ##
30#Legend ##
31# MakeFromBackendRenderTarget          # creates Surface from GPU memory buffer ##
32# MakeFromBackendTexture               # creates Surface from GPU-backed texture ##
33# MakeFromBackendTextureAsRenderTarget # creates Surface from GPU-backed texture ##
34# MakeNull                             # creates Surface without backing pixels ##
35# MakeRaster                           # creates Surface from SkImageInfo ##
36# MakeRasterDirect                     # creates Surface from SkImageInfo and Pixel_Storage ##
37# MakeRasterDirectReleaseProc          # creates Surface from SkImageInfo and Pixel_Storage ##
38# MakeRasterN32Premul                  # creates Surface from width, height matching output ##
39# MakeRenderTarget                     # creates Surface pointing to new GPU memory buffer ##
40# SkCanvas::makeSurface                # creates Surface matching Canvas Image_Info, Surface_Properties ##
41# makeSurface                          # creates a compatible Surface ##
42#Table ##
43#Subtopic ##
44
45#Subtopic Member_Functions
46#Table
47#Legend
48# description                          # function ##
49#Legend ##
50# MakeFromBackendRenderTarget          # creates Surface from GPU memory buffer ##
51# MakeFromBackendTexture               # creates Surface from GPU-backed texture ##
52# MakeFromBackendTextureAsRenderTarget # creates Surface from GPU-backed texture ##
53# MakeNull                             # creates Surface without backing pixels ##
54# MakeRaster                           # creates Surface from SkImageInfo ##
55# MakeRasterDirect                     # creates Surface from SkImageInfo and Pixel_Storage ##
56# MakeRasterDirectReleaseProc          # creates Surface from SkImageInfo and Pixel_Storage ##
57# MakeRasterN32Premul                  # creates Surface from width, height matching output ##
58# MakeRenderTarget                     # creates Surface pointing to new GPU memory buffer ##
59# characterize()                       # sets Surface_Characterization for threaded pre-processing ##
60# draw()                               # draws Surface contents to canvas ##
61# flush()                              # resolve pending I/O ##
62# flushAndSignalSemaphores             # resolve pending I/O, and signal ##
63# generationID                         # returns unique ID ##
64# getCanvas                            # returns Canvas that draws into Surface ##
65# getRenderTargetHandle                # returns the GPU reference to render target ##
66# getTextureHandle                     # returns the GPU reference to texture ##
67# height()                             # returns pixel row count ##
68# makeImageSnapshot                    # creates Image capturing Surface contents ##
69# makeSurface                          # creates a compatible Surface ##
70# notifyContentWillChange              # notifies that contents will be changed outside of Skia ##
71# peekPixels                           # copies Surface parameters to Pixmap ##
72# prepareForExternalIO                 # to be deprecated ##
73# props()                              # returns Surface_Properties ##
74# readPixels                           # copies Rect of pixels ##
75# wait()                               # rause commands until signaled ##
76# width()                              # returns pixel column count ##
77#Table ##
78#Subtopic ##
79
80#Topic ##
81
82# ------------------------------------------------------------------------------
83
84#Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
85                                             size_t rowBytes,
86                                             const SkSurfaceProps* surfaceProps = nullptr)
87#Line # creates Surface from SkImageInfo and Pixel_Storage ##
88
89Allocates raster Surface. Canvas returned by Surface draws directly into pixels.
90
91Surface is returned if all parameters are valid.
92Valid parameters include:
93info dimensions are greater than zero;
94info contains Color_Type and Alpha_Type supported by Raster_Surface;
95pixels is not nullptr;
96rowBytes is large enough to contain info width pixels of Color_Type.
97
98Pixel buffer size should be info height times computed rowBytes.
99Pixels are not initialized.
100To access pixels after drawing, call flush() or peekPixels.
101
102#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
103                  of Raster_Surface; width and height must be greater than zero
104##
105#Param pixels  pointer to destination pixels buffer ##
106#Param rowBytes  interval from one Surface row to the next ##
107#Param surfaceProps  LCD striping orientation and setting for device independent fonts;
108              may be nullptr
109##
110
111#Return Surface if all parameters are valid; otherwise, nullptr ##
112
113#Example
114void draw(SkCanvas* ) {
115    SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
116    const size_t size = info.computeMinByteSize();
117    SkAutoTMalloc<SkPMColor> storage(size);
118    SkPMColor* pixels = storage.get();
119    sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes()));
120    SkCanvas* canvas = surface->getCanvas();
121    canvas->clear(SK_ColorWHITE);
122    SkPMColor pmWhite = pixels[0];
123    SkPaint paint;
124    canvas->drawPoint(1, 1, paint);
125    canvas->flush();  // ensure that point was drawn
126    for (int y = 0; y < info.height(); ++y) {
127        for (int x = 0; x < info.width(); ++x) {
128            SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
129        }
130        SkDebugf("\n");
131    }
132}
133    #StdOut
134        ---
135        -x-
136        ---
137    ##
138##
139
140#SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect
141
142#Method ##
143
144# ------------------------------------------------------------------------------
145
146#Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
147                                    size_t rowBytes,
148                                    void (*releaseProc)(void* pixels, void* context),
149                                    void* context, const SkSurfaceProps* surfaceProps = nullptr)
150#Line # creates Surface from SkImageInfo and Pixel_Storage ##
151
152Allocates raster Surface. Canvas returned by Surface draws directly into pixels.
153releaseProc is called with pixels and context when Surface is deleted.
154
155Surface is returned if all parameters are valid.
156Valid parameters include:
157info dimensions are greater than zero;
158info contains Color_Type and Alpha_Type supported by Raster_Surface;
159pixels is not nullptr;
160rowBytes is large enough to contain info width pixels of Color_Type.
161
162Pixel buffer size should be info height times computed rowBytes.
163Pixels are not initialized.
164To access pixels after drawing, call flush() or peekPixels.
165
166#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
167                  of Raster_Surface; width and height must be greater than zero
168##
169#Param pixels  pointer to destination pixels buffer ##
170#Param rowBytes  interval from one Surface row to the next ##
171#Param releaseProc  called when Surface is deleted; may be nullptr ##
172#Param context  passed to releaseProc; may be nullptr ##
173#Param surfaceProps  LCD striping orientation and setting for device independent fonts;
174              may be nullptr
175##
176
177#Return Surface if all parameters are valid; otherwise, nullptr ##
178
179#Example
180#Function
181static void release_direct_surface_storage(void* pixels, void* context) {
182    if (pixels == context) {
183        SkDebugf("expected release context\n");
184    }
185    sk_free(pixels);
186}
187
188##
189void draw(SkCanvas* ) {
190    SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
191    const size_t rowBytes = info.minRowBytes();
192    void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes));
193    sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes,
194            release_direct_surface_storage, pixels));
195    SkCanvas* canvas = surface->getCanvas();
196    canvas->clear(SK_ColorWHITE);
197    SkPMColor* colorPtr = (SkPMColor*) pixels;
198    SkPMColor pmWhite = colorPtr[0];
199    SkPaint paint;
200    canvas->drawPoint(1, 1, paint);
201    canvas->flush();  // ensure that point was drawn
202    for (int y = 0; y < info.height(); ++y) {
203        for (int x = 0; x < info.width(); ++x) {
204            SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x');
205        }
206        SkDebugf("\n");
207    }
208}
209#StdOut
210---
211-x-
212---
213expected release context
214##
215##
216
217#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster
218
219#Method ##
220
221# ------------------------------------------------------------------------------
222
223#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
224                                       const SkSurfaceProps* surfaceProps)
225#Line # creates Surface from SkImageInfo ##
226
227Allocates raster Surface. Canvas returned by Surface draws directly into pixels.
228Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
229rowBytes, or times imageInfo.minRowBytes() if rowBytes is zero.
230Pixel memory is deleted when Surface is deleted.
231
232Surface is returned if all parameters are valid.
233Valid parameters include:
234info dimensions are greater than zero;
235info contains Color_Type and Alpha_Type supported by Raster_Surface;
236rowBytes is large enough to contain info width pixels of Color_Type, or is zero.
237
238If rowBytes is not zero, subsequent images returned by makeImageSnapshot
239have the same rowBytes.
240
241#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
242                  of Raster_Surface; width and height must be greater than zero
243##
244#Param rowBytes  interval from one Surface row to the next; may be zero ##
245#Param surfaceProps  LCD striping orientation and setting for device independent fonts;
246              may be nullptr
247##
248
249#Return Surface if all parameters are valid; otherwise, nullptr ##
250
251#Example
252void draw(SkCanvas* ) {
253    SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
254    const size_t rowBytes = 64;
255    sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr));
256    SkCanvas* canvas = surface->getCanvas();
257    canvas->clear(SK_ColorWHITE);
258    SkPixmap pixmap;
259    if (surface->peekPixels(&pixmap)) {
260        const uint32_t* colorPtr = pixmap.addr32();
261        SkPMColor pmWhite = colorPtr[0];
262        SkPaint paint;
263        canvas->drawPoint(1, 1, paint);
264        canvas->flush();  // ensure that point was drawn
265        for (int y = 0; y < info.height(); ++y) {
266            for (int x = 0; x < info.width(); ++x) {
267                SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
268            }
269            colorPtr += rowBytes / sizeof(colorPtr[0]);
270            SkDebugf("\n");
271        }
272    }
273}
274#StdOut
275---
276-x-
277---
278##
279##
280
281#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
282
283#Method ##
284
285# ------------------------------------------------------------------------------
286
287#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
288                                       const SkSurfaceProps* props = nullptr)
289
290Allocates raster Surface. Canvas returned by Surface draws directly into pixels.
291Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times
292imageInfo.minRowBytes().
293Pixel memory is deleted when Surface is deleted.
294
295Surface is returned if all parameters are valid.
296Valid parameters include:
297info dimensions are greater than zero;
298info contains Color_Type and Alpha_Type supported by Raster_Surface.
299
300#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
301                  of Raster_Surface; width and height must be greater than zero
302##
303#Param props  LCD striping orientation and setting for device independent fonts;
304              may be nullptr
305##
306
307#Return Surface if all parameters are valid; otherwise, nullptr ##
308
309#Example
310void draw(SkCanvas* ) {
311    SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
312    sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
313    SkCanvas* canvas = surface->getCanvas();
314    canvas->clear(SK_ColorWHITE);
315    SkPixmap pixmap;
316    if (surface->peekPixels(&pixmap)) {
317        const uint32_t* colorPtr = pixmap.addr32();
318        SkPMColor pmWhite = colorPtr[0];
319        SkPaint paint;
320        canvas->drawPoint(1, 1, paint);
321        canvas->flush();  // ensure that point was drawn
322        for (int y = 0; y < info.height(); ++y) {
323            for (int x = 0; x < info.width(); ++x) {
324                SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
325            }
326            colorPtr += info.width();
327            SkDebugf("\n");
328        }
329    }
330}
331##
332
333#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
334
335#Method ##
336
337# ------------------------------------------------------------------------------
338
339#Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
340                                                const SkSurfaceProps* surfaceProps = nullptr)
341#Line # creates Surface from width, height matching output ##
342
343Allocates raster Surface. Canvas returned by Surface draws directly into pixels.
344Allocates and zeroes pixel memory. Pixel memory size is height times width times
345four. Pixel memory is deleted when Surface is deleted.
346
347Internally, sets Image_Info to width, height, Native_Color_Type, and
348kPremul_SkAlphaType.
349
350Surface is returned if width and height are greater than zero.
351
352Use to create Surface that matches SkPMColor, the native pixel arrangement on
353the platform. Surface drawn to output device skips converting its pixel format.
354
355#Param width  pixel column count; must be greater than zero ##
356#Param height  pixel row count; must be greater than zero ##
357#Param surfaceProps  LCD striping orientation and setting for device independent
358                     fonts; may be nullptr
359##
360
361#Return Surface if all parameters are valid; otherwise, nullptr ##
362
363#Example
364void draw(SkCanvas* ) {
365    sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3));
366    SkCanvas* canvas = surface->getCanvas();
367    canvas->clear(SK_ColorWHITE);
368    SkPixmap pixmap;
369    if (surface->peekPixels(&pixmap)) {
370        const uint32_t* colorPtr = pixmap.addr32();
371        SkPMColor pmWhite = colorPtr[0];
372        SkPaint paint;
373        canvas->drawPoint(1, 1, paint);
374        canvas->flush();  // ensure that point was drawn
375        for (int y = 0; y < surface->height(); ++y) {
376            for (int x = 0; x < surface->width(); ++x) {
377                SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
378            }
379            colorPtr += surface->width();
380            SkDebugf("\n");
381        }
382    }
383}
384#StdOut
385---
386-x-
387---
388##
389##
390
391#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
392
393#Method ##
394
395# ------------------------------------------------------------------------------
396
397#Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
398                                                   const GrBackendTexture& backendTexture,
399                                                   GrSurfaceOrigin origin, int sampleCnt,
400                                                   sk_sp<SkColorSpace> colorSpace,
401                                                   const SkSurfaceProps* surfaceProps)
402#Line # creates Surface from GPU-backed texture ##
403
404Wraps a GPU-backed texture into Surface. Caller must ensure the texture is
405valid for the lifetime of returned Surface. If sampleCnt greater than zero,
406creates an intermediate MSAA Surface which is used for drawing backendTexture.
407
408Surface is returned if all parameters are valid. backendTexture is valid if
409its pixel configuration agrees with colorSpace and context; for instance, if
410backendTexture has an sRGB configuration, then context must support sRGB,
411and colorSpace must be present. Further, backendTexture width and height must
412not exceed context capabilities, and the context must be able to support
413back-end textures.
414
415If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
416
417#Param context  GPU_Context ##
418#Param backendTexture  texture residing on GPU ##
419#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
420#Param sampleCnt  samples per pixel, or 0 to disable full scene anti-aliasing ##
421#Param colorSpace  range of colors ##
422#Param surfaceProps  LCD striping orientation and setting for device independent
423                     fonts; may be nullptr
424##
425
426#Return Surface if all parameters are valid; otherwise, nullptr ##
427
428#Example
429#ToDo  remove !fiddle below once backEndTextureRenderTarget is available ##
430#Platform !fiddle gpu cpu
431    SkPaint paint;
432    paint.setTextSize(32);
433    GrContext* context = canvas->getGrContext();
434    if (!context) {
435         canvas->drawString("GPU only!", 20, 40, paint);
436         return;
437    }
438    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context,
439            backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin, 0, nullptr, nullptr);
440    auto surfaceCanvas = gpuSurface->getCanvas();
441    surfaceCanvas->clear(SK_ColorWHITE);
442    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
443    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
444    canvas->drawImage(image, 0, 0);
445##
446
447#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
448
449#Method ##
450
451# ------------------------------------------------------------------------------
452
453#Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
454                                                   const GrBackendTexture& backendTexture,
455                                                   GrSurfaceOrigin origin, int sampleCnt,
456                                                   SkColorType colorType,
457                                                   sk_sp<SkColorSpace> colorSpace,
458                                                   const SkSurfaceProps* surfaceProps)
459
460Wraps a GPU-backed texture into Surface. Caller must ensure the texture is
461valid for the lifetime of returned Surface. If sampleCnt greater than zero,
462creates an intermediate MSAA Surface which is used for drawing backendTexture.
463
464Surface is returned if all parameters are valid. backendTexture is valid if
465its pixel configuration agrees with colorSpace and context; for instance, if
466backendTexture has an sRGB configuration, then context must support sRGB,
467and colorSpace must be present. Further, backendTexture width and height must
468not exceed context capabilities, and the context must be able to support
469back-end textures.
470
471If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
472
473#Param context  GPU_Context ##
474#Param backendTexture  texture residing on GPU ##
475#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
476#Param sampleCnt  samples per pixel, or 0 to disable full scene anti-aliasing ##
477#Param colorType  one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
478                          kRGB_565_SkColorType, kARGB_4444_SkColorType,
479                          kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
480                          kGray_8_SkColorType, kRGBA_F16_SkColorType
481##
482#Param colorSpace  range of colors ##
483#Param surfaceProps  LCD striping orientation and setting for device independent
484                     fonts; may be nullptr
485##
486
487#Return Surface if all parameters are valid; otherwise, nullptr ##
488
489#Example
490#ToDo  remove !fiddle below once backEndTextureRenderTarget is available ##
491#Platform !fiddle gpu cpu
492    SkPaint paint;
493    paint.setTextSize(32);
494    GrContext* context = canvas->getGrContext();
495    if (!context) {
496         canvas->drawString("GPU only!", 20, 40, paint);
497         return;
498    }
499    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context,
500            backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin,
501            kRGBA_8888_SkColorType, 0, nullptr, nullptr);
502    auto surfaceCanvas = gpuSurface->getCanvas();
503    surfaceCanvas->clear(SK_ColorWHITE);
504    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
505    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
506    canvas->drawImage(image, 0, 0);
507##
508
509#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
510
511#Method ##
512
513# ------------------------------------------------------------------------------
514
515#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
516                                                const GrBackendRenderTarget& backendRenderTarget,
517                                                GrSurfaceOrigin origin,
518                                                sk_sp<SkColorSpace> colorSpace,
519                                                const SkSurfaceProps* surfaceProps)
520#Line # creates Surface from GPU memory buffer ##
521
522Wraps a GPU-backed buffer into Surface. Caller must ensure render target is
523valid for the lifetime of returned Surface.
524
525Surface is returned if all parameters are valid. backendRenderTarget is valid if
526its pixel configuration agrees with colorSpace and context; for instance, if
527backendRenderTarget has an sRGB configuration, then context must support sRGB,
528and colorSpace must be present. Further, backendRenderTarget width and height must
529not exceed context capabilities, and the context must be able to support
530back-end render targets.
531
532If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
533
534#Param context  GPU_Context ##
535#Param backendRenderTarget  GPU intermediate memory buffer ##
536#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
537#Param colorSpace  range of colors ##
538#Param surfaceProps  LCD striping orientation and setting for device independent
539                     fonts; may be nullptr
540##
541
542#Return Surface if all parameters are valid; otherwise, nullptr ##
543
544#Example
545#ToDo  remove !fiddle below once backEndTextureRenderTarget is available ##
546#Platform !fiddle gpu
547    SkPaint paint;
548    paint.setTextSize(32);
549    GrContext* context = canvas->getGrContext();
550    if (!context) {
551         canvas->drawString("GPU only!", 20, 40, paint);
552         return;
553    }
554    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context,
555            backEndRenderTarget, kTopLeft_GrSurfaceOrigin, nullptr, nullptr);
556    auto surfaceCanvas = gpuSurface->getCanvas();
557    surfaceCanvas->clear(SK_ColorWHITE);
558    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
559    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
560    canvas->drawImage(image, 0, 0);
561##
562
563#SeeAlso MakeFromBackendTexture MakeRenderTarget
564
565#Method ##
566
567# ------------------------------------------------------------------------------
568
569#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
570                                                const GrBackendRenderTarget& backendRenderTarget,
571                                                GrSurfaceOrigin origin,
572                                                SkColorType colorType,
573                                                sk_sp<SkColorSpace> colorSpace,
574                                                const SkSurfaceProps* surfaceProps)
575
576Wraps a GPU-backed buffer into Surface. Caller must ensure render target is
577valid for the lifetime of returned Surface.
578
579Surface is returned if all parameters are valid. backendRenderTarget is valid if
580its pixel configuration agrees with colorSpace and context; for instance, if
581backendRenderTarget has an sRGB configuration, then context must support sRGB,
582and colorSpace must be present. Further, backendRenderTarget width and height must
583not exceed context capabilities, and the context must be able to support
584back-end render targets.
585
586If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
587
588#Param context  GPU_Context ##
589#Param backendRenderTarget  GPU intermediate memory buffer ##
590#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
591#Param colorType  one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
592                          kRGB_565_SkColorType, kARGB_4444_SkColorType,
593                          kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
594                          kGray_8_SkColorType, kRGBA_F16_SkColorType
595##
596#Param colorSpace  range of colors ##
597#Param surfaceProps  LCD striping orientation and setting for device independent
598                     fonts; may be nullptr
599##
600
601#Return Surface if all parameters are valid; otherwise, nullptr ##
602
603#Example
604#ToDo  remove !fiddle below once backEndTextureRenderTarget is available ##
605#Platform !fiddle gpu
606    SkPaint paint;
607    paint.setTextSize(32);
608    GrContext* context = canvas->getGrContext();
609    if (!context) {
610         canvas->drawString("GPU only!", 20, 40, paint);
611         return;
612    }
613    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context,
614            backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
615            nullptr, nullptr);
616    auto surfaceCanvas = gpuSurface->getCanvas();
617    surfaceCanvas->clear(SK_ColorWHITE);
618    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
619    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
620    canvas->drawImage(image, 0, 0);
621##
622
623#SeeAlso MakeFromBackendTexture MakeRenderTarget
624
625#Method ##
626
627# ------------------------------------------------------------------------------
628
629#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
630                                                            const GrBackendTexture& backendTexture,
631                                                            GrSurfaceOrigin origin,
632                                                            int sampleCnt,
633                                                            sk_sp<SkColorSpace> colorSpace,
634                                                            const SkSurfaceProps* surfaceProps)
635#Line # creates Surface from GPU-backed texture ##
636
637Used to wrap a GPU-backed texture as a SkSurface. Skia will treat the texture as
638a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
639the associated render target objects (but not the provided texture). Skia will not assume
640ownership of the texture and the client must ensure the texture is valid for the lifetime
641of the SkSurface.
642
643If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
644
645#Param context  GPU_Context ##
646#Param backendTexture  texture residing on GPU ##
647#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
648#Param sampleCnt  samples per pixel, or 0 to disable full scene anti-aliasing ##
649#Param colorSpace  range of colors ##
650#Param surfaceProps  LCD striping orientation and setting for device independent
651                     fonts; may be nullptr
652##
653
654#Return Surface if all parameters are valid; otherwise, nullptr ##
655
656#Example
657#Platform !fiddle gpu
658    SkPaint paint;
659    paint.setTextSize(32);
660    GrContext* context = canvas->getGrContext();
661    if (!context) {
662         canvas->drawString("GPU only!", 20, 40, paint);
663         return;
664    }
665    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(
666            context, backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin, 0,
667            nullptr, nullptr);
668    auto surfaceCanvas = gpuSurface->getCanvas();
669    surfaceCanvas->clear(SK_ColorWHITE);
670    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
671    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
672    canvas->drawImage(image, 0, 0);
673##
674
675#SeeAlso MakeFromBackendRenderTarget MakeRenderTarget
676
677#Method ##
678
679# ------------------------------------------------------------------------------
680
681#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
682                                                            const GrBackendTexture& backendTexture,
683                                                            GrSurfaceOrigin origin,
684                                                            int sampleCnt,
685                                                            SkColorType colorType,
686                                                            sk_sp<SkColorSpace> colorSpace,
687                                                            const SkSurfaceProps* surfaceProps)
688
689Used to wrap a GPU-backed texture as a SkSurface. Skia will treat the texture as
690a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
691the associated render target objects (but not the provided texture). Skia will not assume
692ownership of the texture and the client must ensure the texture is valid for the lifetime
693of the SkSurface.
694
695If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
696
697#Param context  GPU_Context ##
698#Param backendTexture  texture residing on GPU ##
699#Param origin   one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
700#Param sampleCnt  samples per pixel, or 0 to disable full scene anti-aliasing ##
701#Param colorType  one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
702                          kRGB_565_SkColorType, kARGB_4444_SkColorType,
703                          kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
704                          kGray_8_SkColorType, kRGBA_F16_SkColorType
705##
706#Param colorSpace  range of colors ##
707#Param surfaceProps  LCD striping orientation and setting for device independent
708                     fonts; may be nullptr
709##
710
711#Return Surface if all parameters are valid; otherwise, nullptr ##
712
713#Example
714#Platform !fiddle gpu
715    SkPaint paint;
716    paint.setTextSize(32);
717    GrContext* context = canvas->getGrContext();
718    if (!context) {
719         canvas->drawString("GPU only!", 20, 40, paint);
720         return;
721    }
722    sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(
723            context, backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin, 0,
724            kRGBA_8888_SkColorType, nullptr, nullptr);
725    auto surfaceCanvas = gpuSurface->getCanvas();
726    surfaceCanvas->clear(SK_ColorWHITE);
727    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
728    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
729    canvas->drawImage(image, 0, 0);
730##
731
732#SeeAlso MakeFromBackendRenderTarget MakeRenderTarget
733
734#Method ##
735
736# ------------------------------------------------------------------------------
737
738#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
739                                             const SkImageInfo& imageInfo,
740                                             int sampleCount, GrSurfaceOrigin surfaceOrigin,
741                                             const SkSurfaceProps* surfaceProps,
742                                             bool shouldCreateWithMips = false)
743#Line # creates Surface pointing to new GPU memory buffer ##
744
745Returns offscreen Surface on GPU indicated by context. Allocates memory for
746pixels, based on the width, height, and Color_Type in ImageInfo.  budgeted
747selects whether allocation for offscreen pixels is tracked by context. imageInfo
748describes the pixel format in Color_Type, and transparency in
749Alpha_Type, and color matching in Color_Space.
750
751sampleCount requests the number of samples per pixel. 
752Pass zero to disable Multi_Sample_Anti_Aliasing.  The request is rounded
753up to the next supported count, or rounded down if it is larger than the
754maximum supported count.
755
756surfaceOrigin pins either the top-left or the bottom-left corner to the origin.
757
758shouldCreateWithMips hints that Image returned by makeImageSnapshot is Mip_Map.
759
760If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr.
761
762#Param context  GPU_Context ##
763#Param budgeted  one of: SkBudgeted::kNo, SkBudgeted::kYes ##
764#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space;
765                  width, or height, or both, may be zero
766##
767#Param sampleCount  samples per pixel, or 0 to disable full scene anti-aliasing ##
768#Param surfaceOrigin  one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ##
769#Param surfaceProps  LCD striping orientation and setting for device independent
770                     fonts; may be nullptr
771##
772#Param shouldCreateWithMips  hint that Surface will host Mip_Map images ##
773
774#Return Surface if all parameters are valid; otherwise, nullptr ##
775
776#ToDo not sure that this example is relevant; surfaceOrigin doesn't appear to do anything ##
777#Example
778#Platform gpu
779#Height 64
780    SkPaint paint;
781    paint.setTextSize(32);
782    GrContext* context = canvas->getGrContext();
783    if (!context) {
784         canvas->drawString("GPU only!", 20, 40, paint);
785         return;
786    }
787    SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
788    for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
789        auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
790               surfaceOrigin, nullptr));
791        auto surfaceCanvas = gpuSurface->getCanvas();
792        surfaceCanvas->clear(SK_ColorWHITE);
793        surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
794        sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
795        canvas->drawImage(image, 0, 0);
796       canvas->translate(0, 128);
797    }
798##
799
800#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
801
802#Method ##
803
804# ------------------------------------------------------------------------------
805
806#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
807                                             const SkImageInfo& imageInfo, int sampleCount,
808                                             const SkSurfaceProps* props)
809
810Returns offscreen Surface on GPU indicated by context. Allocates memory for
811pixels, based on the width, height, and Color_Type in ImageInfo.  budgeted
812selects whether allocation for offscreen pixels is tracked by context. imageInfo
813describes the pixel format in Color_Type, and transparency in
814Alpha_Type, and color matching in Color_Space.
815
816sampleCount requests the number of samples per pixel. 
817Pass zero to disable Multi_Sample_Anti_Aliasing.  The request is rounded
818up to the next supported count, or rounded down if it is larger than the
819maximum supported count.
820
821Surface bottom-left corner is pinned to the origin.
822
823#Param context  GPU_Context ##
824#Param budgeted  one of: SkBudgeted::kNo, SkBudgeted::kYes ##
825#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
826                  of Raster_Surface; width, or height, or both, may be zero
827##
828#Param sampleCount  samples per pixel, or 0 to disable Multi_Sample_Anti_Aliasing ##
829#Param props  LCD striping orientation and setting for device independent
830              fonts; may be nullptr
831##
832
833#Return Surface if all parameters are valid; otherwise, nullptr ##
834
835#Example
836#Platform cpu gpu
837#Description
838LCD text takes advantage of raster striping to improve resolution. Only one of
839the four combinations is correct, depending on whether the monitor's LCD is
840horizontal or vertical, and whether the order of the stripes is red blue green
841or red green blue.
842##
843void draw(SkCanvas* canvas) {
844    auto test_draw = [](SkCanvas* surfaceCanvas) -> void {
845        SkPaint paint;
846        paint.setAntiAlias(true);
847        paint.setLCDRenderText(true);
848        paint.setColor(0xFFBBBBBB);
849        surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint);
850        paint.setColor(SK_ColorWHITE);
851        paint.setTextSize(32);
852        surfaceCanvas->drawString("Pest", 0, 25, paint);
853    };
854    GrContext* context = canvas->getGrContext();
855    SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType);
856    int y = 0;
857    for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry,
858                           kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) {
859        SkSurfaceProps props(0, geometry);
860        sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget(
861                context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props);
862        test_draw(surface->getCanvas());
863        surface->draw(canvas, 0, y, nullptr);
864        sk_sp<SkImage> image(surface->makeImageSnapshot());
865        SkAutoCanvasRestore acr(canvas, true);
866        canvas->scale(8, 8);
867        canvas->drawImage(image, 12, y / 8);
868        y += 64;
869    }
870}
871##
872
873#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
874
875#Method ##
876
877# ------------------------------------------------------------------------------
878
879#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
880                                             const SkImageInfo& imageInfo)
881
882Returns offscreen Surface on GPU indicated by context. Allocates memory for
883pixels, based on the width, height, and Color_Type in ImageInfo.  budgeted
884selects whether allocation for offscreen pixels is tracked by context. imageInfo
885describes the pixel format in Color_Type, and transparency in
886Alpha_Type, and color matching in Color_Space.
887
888Surface bottom-left corner is pinned to the origin.
889
890#Param context  GPU_Context ##
891#Param budgeted  one of: SkBudgeted::kNo, SkBudgeted::kYes ##
892#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
893                  of Raster_Surface; width, or height, or both, may be zero
894##
895
896#Return Surface if all parameters are valid; otherwise, nullptr ##
897
898#Example
899#Platform gpu
900    SkPaint paint;
901    paint.setTextSize(32);
902    GrContext* context = canvas->getGrContext();
903    if (!context) {
904         canvas->drawString("GPU only!", 20, 40, paint);
905         return;
906    }
907    SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
908    auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
909    auto surfaceCanvas = gpuSurface->getCanvas();
910    surfaceCanvas->clear(SK_ColorWHITE);
911    surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
912    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
913    canvas->drawImage(image, 0, 0);
914##
915
916#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
917
918#Method ##
919
920# ------------------------------------------------------------------------------
921
922#Method static sk_sp<SkSurface> MakeNull(int width, int height)
923
924#Line # creates Surface without backing pixels ##
925Returns Surface without backing pixels. Drawing to Canvas returned from Surface
926has no effect. Calling makeImageSnapshot() on returned Surface returns nullptr.
927
928#Param width  one or greater ##
929#Param height  one or greater ##
930
931#Return Surface if width and height are positive; otherwise, nullptr ##
932
933#Example
934    SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ?
935             '=' : '!');
936    const int w = 37;
937    const int h = 1000;
938    auto surf = SkSurface::MakeNull(w, h);
939    auto nullCanvas = surf->getCanvas();
940    nullCanvas->drawPaint(SkPaint());   // does not crash, nothing draws
941    SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ?
942            '=' : '!');
943#StdOut
944SkSurface::MakeNull(0, 0) == nullptr
945surf->makeImageSnapshot() == nullptr
946##
947##
948
949#SeeAlso MakeRaster MakeRenderTarget
950
951#Method ##
952
953# ------------------------------------------------------------------------------
954
955#Method int width() const
956
957#Line # returns pixel column count ##
958Returns pixel count in each row; may be zero or greater.
959
960#Return number of pixel columns ##
961
962#Example
963    const int width = 37;
964    const int height = 1000;
965    auto surf = SkSurface::MakeNull(width, height);
966    auto nullCanvas = surf->getCanvas();
967    SkDebugf("surface width=%d  canvas width=%d\n", surf->width(),
968             nullCanvas->getBaseLayerSize().fWidth);
969#StdOut
970surface width=37  canvas width=37
971##
972##
973
974#SeeAlso height()
975
976#Method ##
977
978# ------------------------------------------------------------------------------
979
980#Method int height() const
981
982#Line # returns pixel row count ##
983Returns pixel row count; may be zero or greater.
984
985#Return number of pixel rows ##
986
987#Example
988    const int width = 37;
989    const int height = 1000;
990    auto surf = SkSurface::MakeNull(width, height);
991    auto nullCanvas = surf->getCanvas();
992    SkDebugf("surface height=%d  canvas height=%d\n", surf->height(),
993             nullCanvas->getBaseLayerSize().fHeight);
994#StdOut
995surface height=1000  canvas height=1000
996##
997##
998
999#SeeAlso width()
1000
1001#Method ##
1002
1003# ------------------------------------------------------------------------------
1004
1005#Method uint32_t generationID()
1006
1007#Line # returns unique ID ##
1008Returns unique value identifying the content of Surface. Returned value changes
1009each time the content changes. Content is changed by drawing, or by calling
1010notifyContentWillChange.
1011
1012#Return unique content identifier ##
1013
1014#Example
1015    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
1016    for (int i = 0; i < 3; ++i) {
1017        SkDebugf("surface generationID: %d\n", surface->generationID());
1018        if (0 == i) {
1019            surface->getCanvas()->drawColor(SK_ColorBLACK);
1020        } else {
1021            surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
1022        }
1023    }
1024#StdOut
1025surface generationID: 1
1026surface generationID: 2
1027surface generationID: 3
1028##
1029##
1030
1031#SeeAlso notifyContentWillChange ContentChangeMode getCanvas
1032
1033#Method ##
1034
1035# ------------------------------------------------------------------------------
1036
1037#Enum ContentChangeMode
1038
1039#Code
1040    enum ContentChangeMode {
1041        kDiscard_ContentChangeMode,
1042        kRetain_ContentChangeMode,
1043    };
1044##
1045
1046ContentChangeMode members are parameters to notifyContentWillChange.
1047
1048#Const kDiscard_ContentChangeMode
1049Pass to notifyContentWillChange to discard surface contents when
1050the surface is cleared or overwritten.
1051##
1052#Const kRetain_ContentChangeMode
1053Pass to notifyContentWillChange when to preserve surface contents.
1054If a snapshot has been generated, this copies the Surface contents.
1055##
1056
1057#SeeAlso notifyContentWillChange generationID
1058
1059#Enum ##
1060
1061# ------------------------------------------------------------------------------
1062
1063#Method void notifyContentWillChange(ContentChangeMode mode)
1064
1065#Line # notifies that contents will be changed outside of Skia ##
1066Notifies that Surface contents will be changed by code outside of Skia.
1067Subsequent calls to generationID return a different value.
1068
1069mode is normally passed as kRetain_ContentChangeMode.
1070
1071#Private
1072CAN WE DEPRECATE THIS?
1073##
1074
1075#Param mode  one of: kDiscard_ContentChangeMode, kRetain_ContentChangeMode ##
1076
1077#Example
1078    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
1079    for (int i = 0; i < 3; ++i) {
1080        SkDebugf("surface generationID: %d\n", surface->generationID());
1081        if (0 == i) {
1082            surface->getCanvas()->drawColor(SK_ColorBLACK);
1083        } else {
1084            surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
1085        }
1086    }
1087##
1088
1089#SeeAlso ContentChangeMode generationID
1090
1091#Method ##
1092
1093# ------------------------------------------------------------------------------
1094
1095#Enum BackendHandleAccess
1096
1097#Code
1098    enum BackendHandleAccess {
1099        kFlushRead_BackendHandleAccess,
1100        kFlushWrite_BackendHandleAccess,
1101        kDiscardWrite_BackendHandleAccess,
1102    };
1103
1104    static const BackendHandleAccess kFlushRead_TextureHandleAccess =
1105            kFlushRead_BackendHandleAccess;
1106    static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
1107            kFlushWrite_BackendHandleAccess;
1108    static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
1109            kDiscardWrite_BackendHandleAccess;
1110##
1111
1112#Const kFlushRead_BackendHandleAccess 0
1113Caller may read from the back-end object.
1114##
1115#Const kFlushWrite_BackendHandleAccess 1
1116Caller may write to the back-end object.
1117##
1118#Const kDiscardWrite_BackendHandleAccess 2
1119Caller must overwrite the entire back-end object.
1120##
1121
1122#Const kFlushRead_TextureHandleAccess 0
1123Deprecated.
1124#Deprecated 
1125##
1126##
1127#Const kFlushWrite_TextureHandleAccess 1
1128Deprecated.
1129#Deprecated 
1130##
1131##
1132#Const kDiscardWrite_TextureHandleAccess 2
1133Deprecated.
1134#Deprecated 
1135##
1136##
1137
1138#Example
1139#Platform gpu
1140    SkPaint paint;
1141    paint.setTextSize(32);
1142    GrContext* context = canvas->getGrContext();
1143    if (!context) {
1144         canvas->drawString("GPU only!", 20, 40, paint);
1145         return;
1146    }
1147    sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1148            context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10));
1149    int y = 20;
1150    SkString str;
1151    paint.setTextSize(16);
1152    for (auto access : { SkSurface::kFlushRead_BackendHandleAccess, 
1153                         SkSurface::kFlushWrite_BackendHandleAccess,
1154                         SkSurface::kDiscardWrite_BackendHandleAccess } ) {
1155        sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
1156        str.printf("uniqueID=%d", image->uniqueID());
1157        canvas->drawString(str, 20, y += 20, paint);
1158        GrBackendObject backendObject = gpuSurface->getTextureHandle(access);
1159        str.printf("backendObject %c= 0", backendObject != 0 ? '!' : '=');
1160        canvas->drawString(str, 20, y += 20, paint);
1161    }
1162    sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
1163    str.printf("final image uniqueID=%d", image->uniqueID());
1164    canvas->drawString(str, 20, y += 20, paint);
1165##
1166
1167#SeeAlso getTextureHandle getRenderTargetHandle
1168
1169#Enum ##
1170
1171# ------------------------------------------------------------------------------
1172
1173#Method GrBackendObject getTextureHandle(BackendHandleAccess backendHandleAccess)
1174
1175#Line # returns the GPU reference to texture ##
1176Returns the GPU back-end reference of the texture used by Surface, or zero
1177if Surface is not backed by a GPU texture.
1178
1179The returned texture handle is only valid until the next draw into Surface,
1180or when Surface is deleted.
1181
1182#Param backendHandleAccess  one of:  kFlushRead_BackendHandleAccess,
1183        kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess
1184##
1185
1186#Return GPU texture reference ##
1187
1188#Example
1189#Platform gpu
1190#Height 64
1191    SkPaint paint;
1192    paint.setTextSize(32);
1193    GrContext* context = canvas->getGrContext();
1194    if (!context) {
1195         canvas->drawString("GPU only!", 20, 40, paint);
1196         return;
1197    }
1198    sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1199            context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10));
1200    GrBackendObject backendObject = gpuSurface->getTextureHandle(
1201            SkSurface::kFlushRead_BackendHandleAccess);
1202    if (backendObject) {
1203        SkString str;
1204        str.printf("backendObject=%08x", backendObject);
1205        paint.setTextSize(16);
1206        canvas->drawString(str, 20, 40, paint);
1207    }
1208##
1209
1210#SeeAlso getRenderTargetHandle GrBackendObject BackendHandleAccess
1211
1212#Method ##
1213
1214# ------------------------------------------------------------------------------
1215
1216#Method bool getRenderTargetHandle(GrBackendObject* backendObject,
1217                               BackendHandleAccess backendHandleAccess)
1218#Line # returns the GPU reference to render target ##
1219
1220Returns true and stores the GPU back-end reference of the render target used
1221by Surface in backendObject.
1222
1223Return false if Surface is not backed by a GPU render target, and leaves
1224backendObject unchanged.
1225
1226The returned render target handle is only valid until the next draw into Surface,
1227or when Surface is deleted.
1228
1229In OpenGL this returns the frame buffer object ID.
1230
1231#Param backendObject  GPU intermediate memory buffer ##
1232#Param backendHandleAccess  one of:  kFlushRead_BackendHandleAccess,
1233        kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess
1234##
1235
1236#Return true if Surface is backed by GPU texture ##
1237
1238#Example
1239#Platform gpu
1240#Height 64
1241    SkPaint paint;
1242    paint.setTextSize(32);
1243    GrContext* context = canvas->getGrContext();
1244    if (!context) {
1245         canvas->drawString("GPU only!", 20, 40, paint);
1246         return;
1247    }
1248    sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1249            context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10));
1250    GrBackendObject backendObject;
1251    if (gpuSurface->getRenderTargetHandle(&backendObject, 
1252            SkSurface::kFlushRead_BackendHandleAccess)) {
1253        SkString str;
1254        str.printf("backendObject=%d", backendObject);
1255        paint.setTextSize(16);
1256        canvas->drawString(str, 20, 40, paint);
1257    }
1258##
1259
1260#SeeAlso getTextureHandle GrBackendObject BackendHandleAccess
1261
1262#Method ##
1263
1264# ------------------------------------------------------------------------------
1265
1266#Method SkCanvas* getCanvas()
1267
1268#Line # returns Canvas that draws into Surface ##
1269Returns Canvas that draws into Surface. Subsequent calls return the same Canvas.
1270Canvas returned is managed and owned by Surface, and is deleted when Surface
1271is deleted.
1272
1273#Return drawing Canvas for Surface ##
1274
1275#Example
1276#Height 64
1277    sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(64, 64));
1278    SkCanvas* surfaceCanvas = surface->getCanvas();
1279    surfaceCanvas->clear(SK_ColorBLUE);
1280    SkPaint paint;
1281    paint.setTextSize(40);
1282    surfaceCanvas->drawString("\xF0\x9F\x98\x81", 12, 45, paint);
1283    surface->draw(canvas, 0, 0, nullptr);
1284##
1285
1286#SeeAlso makeSurface makeImageSnapshot draw()
1287
1288#Method ##
1289
1290# ------------------------------------------------------------------------------
1291
1292#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo)
1293
1294#Line # creates a compatible Surface ##
1295Returns a compatible Surface, or nullptr. Returned Surface contains
1296the same raster, GPU, or null properties as the original. Returned Surface
1297does not share the same pixels.
1298
1299Returns nullptr if imageInfo width or height are zero, or if imageInfo
1300is incompatible with Surface.
1301 
1302#Param imageInfo  width, height, Color_Type, Alpha_Type, Color_Space,
1303                  of Surface; width and height must be greater than zero
1304##
1305
1306#Return compatible Surface or nullptr ##
1307
1308#Example
1309#Height 96
1310    sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
1311    sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
1312    big->getCanvas()->clear(SK_ColorRED);
1313    lil->getCanvas()->clear(SK_ColorBLACK);
1314    SkPixmap pixmap;
1315    if (big->peekPixels(&pixmap)) {
1316        SkBitmap bigBits;
1317        bigBits.installPixels(pixmap);
1318        canvas->drawBitmap(bigBits, 0, 0);
1319    }
1320    if (lil->peekPixels(&pixmap)) {
1321        SkBitmap lilBits;
1322        lilBits.installPixels(pixmap);
1323        canvas->drawBitmap(lilBits, 64, 64);
1324    }
1325##
1326
1327#SeeAlso makeImageSnapshot getCanvas draw()
1328
1329#Method ##
1330
1331# ------------------------------------------------------------------------------
1332
1333#Method sk_sp<SkImage> makeImageSnapshot()
1334
1335#Line # creates Image capturing Surface contents ##
1336Returns Image capturing Surface contents. Subsequent drawing to Surface contents
1337are not captured. Image allocation is accounted for if Surface was created with
1338SkBudgeted::kYes.
1339
1340#Return Image initialized with Surface contents ##
1341
1342#Example
1343#Height 64
1344    sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
1345    sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
1346    big->getCanvas()->clear(SK_ColorRED);
1347    lil->getCanvas()->clear(SK_ColorBLACK);
1348    sk_sp<SkImage> early(big->makeImageSnapshot());
1349    lil->draw(big->getCanvas(), 16, 16, nullptr);
1350    sk_sp<SkImage> later(big->makeImageSnapshot());
1351    canvas->drawImage(early, 0, 0);
1352    canvas->drawImage(later, 128, 0);
1353##
1354
1355#SeeAlso draw getCanvas
1356
1357#Method ##
1358
1359# ------------------------------------------------------------------------------
1360
1361#Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
1362
1363#Line # draws Surface contents to canvas ##
1364Draws Surface contents to canvas, with its top-left corner at (x, y).
1365
1366If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter,
1367Blend_Mode, and Draw_Looper.
1368
1369#Param canvas  Canvas drawn into ##
1370#Param x  horizontal offset in Canvas ##
1371#Param y  vertical offset in Canvas ##
1372#Param paint  Paint containing Blend_Mode, Color_Filter, Image_Filter,
1373              and so on; or nullptr 
1374##
1375
1376#Example
1377#Height 64
1378    sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
1379    sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
1380    big->getCanvas()->clear(SK_ColorRED);
1381    lil->getCanvas()->clear(SK_ColorBLACK);
1382    lil->draw(big->getCanvas(), 16, 16, nullptr);
1383    SkPixmap pixmap;
1384    if (big->peekPixels(&pixmap)) {
1385        SkBitmap bigBits;
1386        bigBits.installPixels(pixmap);
1387        canvas->drawBitmap(bigBits, 0, 0);
1388    }
1389##
1390
1391#SeeAlso makeImageSnapshot getCanvas
1392
1393#Method ##
1394
1395# ------------------------------------------------------------------------------
1396
1397#Method bool peekPixels(SkPixmap* pixmap)
1398
1399#Line # copies Surface parameters to Pixmap ##
1400Copies Surface pixel address, row bytes, and Image_Info to Pixmap, if address
1401is available, and returns true. If pixel address is not available, return
1402false and leave Pixmap unchanged.
1403
1404pixmap contents become invalid on any future change to Surface.
1405
1406#Param pixmap  storage for pixel state if pixels are readable; otherwise, ignored ##
1407
1408#Return true if Surface has direct access to pixels ##
1409
1410#Example
1411#Height 64
1412    sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1413    auto surfCanvas = surf->getCanvas();
1414    surfCanvas->clear(SK_ColorRED);
1415    SkPaint paint;
1416    paint.setTextSize(40);
1417    surfCanvas->drawString("&", 16, 48, paint);
1418    SkPixmap pixmap;
1419    if (surf->peekPixels(&pixmap)) {
1420        SkBitmap surfBits;
1421        surfBits.installPixels(pixmap);
1422        canvas->drawBitmap(surfBits, 0, 0);
1423    }
1424##
1425
1426#SeeAlso readPixels
1427
1428#Method ##
1429
1430# ------------------------------------------------------------------------------
1431
1432#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY)
1433
1434#Line # copies Rect of pixels ##
1435Copies Rect of pixels to dst.
1436
1437Source Rect corners are (srcX, srcY) and Surface (width(), height()).
1438Destination Rect corners are (0, 0) and (dst.width(), dst.height()).
1439Copies each readable pixel intersecting both rectangles, without scaling,
1440converting to dst.colorType() and dst.alphaType() if required.
1441
1442Pixels are readable when Surface is raster, or backed by a GPU.
1443
1444The destination pixel storage must be allocated by the caller.
1445
1446Pixel values are converted only if Color_Type and Alpha_Type
1447do not match. Only pixels within both source and destination rectangles
1448are copied. dst contents outside Rect intersection are unchanged.
1449
1450Pass negative values for srcX or srcY to offset pixels across or down destination.
1451
1452Does not copy, and returns false if:
1453
1454#List
1455# Source and destination rectangles do not intersect. ##
1456# Pixmap pixels could not be allocated. ##
1457# dst.rowBytes() is too small to contain one row of pixels. ##
1458##
1459
1460#Param dst  storage for pixels copied from Surface ##
1461#Param srcX  offset into readable pixels in x; may be negative ##
1462#Param srcY  offset into readable pixels in y; may be negative ##
1463
1464#Return true if pixels were copied ##
1465
1466#Example
1467#Height 32
1468    sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1469    auto surfCanvas = surf->getCanvas();
1470    surfCanvas->clear(SK_ColorRED);
1471    SkPaint paint;
1472    paint.setTextSize(40);
1473    surfCanvas->drawString("&", 0, 32, paint);
1474    std::vector<SkPMColor> storage;
1475    storage.resize(surf->width() * surf->height());
1476    SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(),
1477                    surf->width() * sizeof(storage[0]));
1478    if (surf->readPixels(pixmap, 0, 0)) {
1479        SkBitmap surfBits;
1480        surfBits.installPixels(pixmap);
1481        canvas->drawBitmap(surfBits, 0, 0);
1482    }
1483##
1484
1485#SeeAlso peekPixels
1486
1487#Method ##
1488
1489# ------------------------------------------------------------------------------
1490
1491#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
1492                    int srcX, int srcY)
1493
1494Copies Rect of pixels from Canvas into dstPixels.
1495
1496Source Rect corners are (srcX, srcY) and Surface (width(), height()).
1497Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
1498Copies each readable pixel intersecting both rectangles, without scaling,
1499converting to dstInfo.colorType() and dstInfo.alphaType() if required.
1500
1501Pixels are readable when Surface is raster, or backed by a GPU.
1502
1503The destination pixel storage must be allocated by the caller.
1504
1505Pixel values are converted only if Color_Type and Alpha_Type
1506do not match. Only pixels within both source and destination rectangles
1507are copied. dstPixels contents outside Rect intersection are unchanged.
1508
1509Pass negative values for srcX or srcY to offset pixels across or down destination.
1510
1511Does not copy, and returns false if:
1512
1513#List
1514# Source and destination rectangles do not intersect. ##
1515# Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
1516# dstRowBytes is too small to contain one row of pixels. ##
1517##
1518
1519#Param dstInfo  width, height, Color_Type, and Alpha_Type of dstPixels ##
1520#Param dstPixels  storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
1521#Param dstRowBytes  size of one destination row; dstInfo.width() times pixel size, or larger ##
1522#Param srcX  offset into readable pixels in x; may be negative ##
1523#Param srcY  offset into readable pixels in y; may be negative ##
1524
1525#Return true if pixels were copied ##
1526
1527#Example
1528#Height 64
1529#Description
1530    A black oval drawn on a red background provides an image to copy.
1531    readPixels copies one quarter of the Surface into each of the four corners.
1532    The copied quarter ovals overdraw the original oval.
1533##
1534    sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1535    auto surfCanvas = surf->getCanvas();
1536    surfCanvas->clear(SK_ColorRED);
1537    SkPaint paint;
1538    surfCanvas->drawOval({4, 8, 58, 54}, paint);
1539    SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1540    sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1541    sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1542    for (int x : { 32, -32 } ) {
1543        for (int y : { 32, -32 } ) {
1544            surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
1545        } 
1546    }
1547    sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1548    canvas->drawImage(image, 0, 0);
1549##
1550
1551#SeeAlso peekPixels
1552
1553#Method ##
1554
1555# ------------------------------------------------------------------------------
1556
1557#Method bool readPixels(const SkBitmap& dst, int srcX, int srcY)
1558
1559Copies Rect of pixels from Surface into bitmap.
1560
1561Source Rect corners are (srcX, srcY) and Surface (width(), height()).
1562Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
1563Copies each readable pixel intersecting both rectangles, without scaling,
1564converting to bitmap.colorType() and bitmap.alphaType() if required.
1565
1566Pixels are readable when Surface is raster, or backed by a GPU.
1567
1568The destination pixel storage must be allocated by the caller.
1569
1570Pixel values are converted only if Color_Type and Alpha_Type
1571do not match. Only pixels within both source and destination rectangles
1572are copied. dst contents outside Rect intersection are unchanged.
1573
1574Pass negative values for srcX or srcY to offset pixels across or down destination.
1575
1576Does not copy, and returns false if:
1577
1578#List
1579# Source and destination rectangles do not intersect. ##
1580# Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ##
1581# dst pixels could not be allocated. ##
1582# dst.rowBytes() is too small to contain one row of pixels. ##
1583##
1584
1585#Param dst  storage for pixels copied from Surface ##
1586#Param srcX  offset into readable pixels in x; may be negative ##
1587#Param srcY  offset into readable pixels in y; may be negative ##
1588
1589#Return true if pixels were copied ##
1590
1591#Example
1592    sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1593    auto surfCanvas = surf->getCanvas();
1594    surfCanvas->clear(SK_ColorGREEN);
1595    SkPaint paint;
1596    surfCanvas->drawOval({2, 10, 58, 54}, paint);
1597    SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1598    SkBitmap bitmap;
1599    bitmap.setInfo(info);
1600    bitmap.allocPixels();
1601    for (int x : { 32, -32 } ) {
1602        for (int y : { 32, -32 } ) {
1603            surf->readPixels(bitmap, x, y);
1604        } 
1605    }
1606    canvas->drawBitmap(bitmap, 0, 0);
1607##
1608
1609#SeeAlso peekPixels
1610
1611#Method ##
1612
1613# ------------------------------------------------------------------------------
1614
1615#Method const SkSurfaceProps& props() const
1616
1617#Line # returns Surface_Properties ##
1618Returns Surface_Properties for surface.
1619
1620#Return LCD striping orientation and setting for device independent fonts ##
1621
1622#Example
1623    const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" };
1624    sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1625    SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]);
1626#StdOut
1627surf.props(): kRGB_H_SkPixelGeometry
1628##
1629##
1630
1631#SeeAlso SkSurfaceProps
1632
1633#Method ##
1634
1635# ------------------------------------------------------------------------------
1636
1637#Method void prepareForExternalIO()
1638
1639#Line # to be deprecated ##
1640To be deprecated.
1641
1642#NoExample
1643##
1644
1645#Method ##
1646
1647# ------------------------------------------------------------------------------
1648
1649#Method void flush()
1650
1651#Line # resolve pending I/O ##
1652Issues pending Surface commands to the GPU-backed API and resolves any Surface MSAA.
1653
1654Skia flushes as needed, so it is not necessary to call this if Skia manages
1655drawing and object lifetime. Call when interleaving Skia calls with native
1656GPU calls.
1657
1658#NoExample
1659##
1660
1661#SeeAlso GrBackendSemaphore
1662
1663#Method ##
1664
1665# ------------------------------------------------------------------------------
1666
1667#Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
1668                                                   GrBackendSemaphore signalSemaphores[])
1669#Line # resolve pending I/O, and signal ##
1670
1671Issues pending Surface commands to the GPU-backed API and resolves any Surface MSAA.
1672After issuing all commands, signalSemaphores of count numSemaphores semaphores
1673are signaled by the GPU.
1674
1675For each GrBackendSemaphore in signalSemaphores:
1676if GrBackendSemaphore is initialized, the GPU back-end uses the semaphore as is;
1677otherwise, a new semaphore is created and initializes GrBackendSemaphore.
1678
1679The caller must delete the semaphores created and returned in signalSemaphores.
1680GrBackendSemaphore can be deleted as soon as this function returns.
1681
1682If the back-end API is OpenGL only uninitialized GrBackendSemaphores are supported.
1683
1684If the back-end API is Vulkan semaphores may be initialized or uninitialized.
1685If uninitialized, created semaphores are valid only with the VkDevice
1686with which they were created.
1687
1688If GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not create or
1689add any semaphores to signal on the GPU; the caller should not instruct the GPU
1690to wait on any of the semaphores. 
1691
1692Pending surface commands are flushed regardless of the return result.
1693
1694#Param numSemaphores  size of signalSemaphores array ##
1695#Param signalSemaphores  array of semaphore containers ##
1696
1697#Return one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo ##
1698
1699#NoExample
1700##
1701
1702#SeeAlso wait GrBackendSemaphore
1703
1704#Method ##
1705
1706# ------------------------------------------------------------------------------
1707
1708#Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores)
1709
1710#Line # rause commands until signaled ##
1711Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
1712executing any more commands on the GPU for this surface. Skia will take ownership of the
1713underlying semaphores and delete them once they have been signaled and waited on.
1714If this call returns false, then the GPU back-end will not wait on any passed in semaphores,
1715and the client will still own the semaphores.
1716
1717#Param numSemaphores  size of waitSemaphores array ##
1718#Param waitSemaphores  array of semaphore containers ##
1719
1720#Return true if GPU is waiting on semaphores ##
1721
1722#Example
1723#ToDo this is copy and paste silliness masquerading as an example. Probably need gpu
1724      globals and definitely need gpu expertise to make a real example out of this
1725 ##
1726#Platform !fiddle gpu
1727#Height 64
1728    SkPaint paint;
1729    paint.setTextSize(32);
1730    GrContext* context = canvas->getGrContext();
1731    if (!context) {
1732         canvas->drawString("GPU only!", 20, 40, paint);
1733         return;
1734    }
1735    GrBackendSemaphore semaphore;
1736    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
1737            context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
1738    surface->flushAndSignalSemaphores(1, &semaphore);
1739    sk_sp<SkImage> image = surface->makeImageSnapshot();
1740    GrBackendObject backendImage = image->getTextureHandle(false); // unused
1741    SkASSERT(backendImage);
1742    const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64,
1743              kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1744    sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
1745              childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr));
1746    GrBackendTexture backendTexture;
1747    sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context,
1748              backendTexture,   // undefined
1749              kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr);
1750    SkCanvas* childCanvas = childSurface->getCanvas();
1751    childCanvas->clear(SK_ColorRED);
1752    childSurface->wait(1, &semaphore);
1753    childCanvas->drawImage(childImage, 32, 0);
1754    childSurface->draw(canvas, 0, 0, nullptr);
1755##
1756
1757#SeeAlso flushAndSignalSemaphores GrBackendSemaphore
1758
1759#Method ##
1760
1761# ------------------------------------------------------------------------------
1762
1763#Method bool characterize(SkSurfaceCharacterization* characterization) const
1764
1765#Line # sets Surface_Characterization for threaded pre-processing ##
1766Initializes Surface_Characterization that can be used to perform GPU back-end
1767pre-processing in a separate thread. Typically this is used to divide drawing
1768into multiple tiles. DeferredDisplayListRecorder records the drawing commands
1769for each tile.
1770
1771Return true if Surface supports characterization. Raster_Surface returns false.
1772
1773#Param characterization  properties for parallel drawing ##
1774
1775#Return true if supported ##
1776
1777#Example
1778#Platform gpu
1779#Height 64
1780    SkPaint paint;
1781    paint.setTextSize(32);
1782    GrContext* context = canvas->getGrContext();
1783    if (!context) {
1784         canvas->drawString("GPU only!", 20, 40, paint);
1785         return;
1786    }
1787    sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1788            context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
1789    SkSurfaceCharacterization characterization;
1790    if (!gpuSurface->characterize(&characterization)) {
1791         canvas->drawString("characterization unsupported", 20, 40, paint);
1792         return;
1793    }
1794    // start of threadable work 
1795    SkDeferredDisplayListRecorder recorder(characterization);
1796    SkCanvas* subCanvas = recorder.getCanvas();
1797    subCanvas->clear(SK_ColorGREEN);
1798    std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1799    // end of threadable work
1800    gpuSurface->draw(displayList.get());
1801    sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1802    canvas->drawImage(std::move(img), 0, 0);
1803##
1804
1805#SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList
1806
1807#Method ##
1808
1809# ------------------------------------------------------------------------------
1810
1811#Method bool draw(SkDeferredDisplayList* deferredDisplayList)
1812
1813Draws deferred display list created using SkDeferredDisplayListRecorder.
1814Has no effect and returns false if Surface_Characterization stored in
1815deferredDisplayList is not compatible with Surface.
1816
1817Raster_Surface returns false.
1818
1819#Param deferredDisplayList  drawing commands ##
1820
1821#Return false if deferredDisplayList is not compatible ##
1822
1823#Example
1824#Height 64
1825#Platform gpu cpu
1826    SkPaint paint;
1827    paint.setTextSize(16);
1828    sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64);
1829    SkSurfaceCharacterization characterization;
1830    if (!gpuSurface->characterize(&characterization)) {
1831         canvas->drawString("characterization unsupported", 20, 40, paint);
1832         return;
1833    }
1834    // start of threadable work 
1835    SkDeferredDisplayListRecorder recorder(characterization);
1836    SkCanvas* subCanvas = recorder.getCanvas();
1837    subCanvas->clear(SK_ColorGREEN);
1838    std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1839    // end of threadable work
1840    gpuSurface->draw(displayList.get());
1841    sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1842    canvas->drawImage(std::move(img), 0, 0);
1843##
1844
1845#SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList
1846
1847#Method ##
1848
1849#Class SkSurface ##
1850
1851#Topic Surface ##
1852