blob: 7c9508b9a5e7ac00298967db95d5b0a7da7f6826 [file] [log] [blame]
Cary Clarka560c472017-11-27 10:44:06 -05001#Topic Surface
Cary Clark137b8742018-05-30 09:21:49 -04002#Alias Surface_Reference ##
Cary Clarka560c472017-11-27 10:44:06 -05003
4#Class SkSurface
5
Cary Clark61313f32018-10-08 14:57:48 -04006#Code
7#Populate
8##
9
Cary Clarka560c472017-11-27 10:44:06 -050010SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be
Cary Clark77b3f3a2018-11-07 14:59:03 -050011allocated either in CPU memory, if a raster surface; or on the GPU, for a GrRenderTarget surface.
Cary Clarka560c472017-11-27 10:44:06 -050012SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
Cary Clark77b3f3a2018-11-07 14:59:03 -050013surface->getCanvas() to use that canvas. The caller should not delete the returned canvas;
14it is owned by surface.
15
Cary Clarka560c472017-11-27 10:44:06 -050016SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
17of the requested dimensions are zero, then nullptr will be returned.
18
Cary Clarka560c472017-11-27 10:44:06 -050019# ------------------------------------------------------------------------------
20
Mike Reed186669c2019-02-13 14:26:37 -050021#Typedef void* ReleaseContext
22#Line # context for release procs ##
23##
24
25#Typedef void (*RenderTargetReleaseProc)(ReleaseContext releaseContext)
26#Line # context for release procs ##
27##
28
29#Typedef void (*TextureReleaseProc)(ReleaseContext releaseContext)
30#Line # context for release procs ##
31##
32
33
Cary Clarka560c472017-11-27 10:44:06 -050034#Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
35 size_t rowBytes,
36 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040037#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050038#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040039#Populate
Cary Clarka560c472017-11-27 10:44:06 -050040
41#Example
42void draw(SkCanvas* ) {
43 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
44 const size_t size = info.computeMinByteSize();
45 SkAutoTMalloc<SkPMColor> storage(size);
46 SkPMColor* pixels = storage.get();
47 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes()));
48 SkCanvas* canvas = surface->getCanvas();
49 canvas->clear(SK_ColorWHITE);
50 SkPMColor pmWhite = pixels[0];
51 SkPaint paint;
52 canvas->drawPoint(1, 1, paint);
53 canvas->flush(); // ensure that point was drawn
54 for (int y = 0; y < info.height(); ++y) {
55 for (int x = 0; x < info.width(); ++x) {
56 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
57 }
58 SkDebugf("\n");
59 }
60}
61 #StdOut
62 ---
63 -x-
64 ---
65 ##
66##
67
68#SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect
69
70#Method ##
71
72# ------------------------------------------------------------------------------
73
74#Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
75 size_t rowBytes,
76 void (*releaseProc)(void* pixels, void* context),
77 void* context, const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040078#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050079#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040080#Populate
Cary Clarka560c472017-11-27 10:44:06 -050081
82#Example
83#Function
84static void release_direct_surface_storage(void* pixels, void* context) {
85 if (pixels == context) {
86 SkDebugf("expected release context\n");
87 }
88 sk_free(pixels);
89}
90
91##
92void draw(SkCanvas* ) {
93 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
94 const size_t rowBytes = info.minRowBytes();
95 void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes));
96 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes,
97 release_direct_surface_storage, pixels));
98 SkCanvas* canvas = surface->getCanvas();
99 canvas->clear(SK_ColorWHITE);
100 SkPMColor* colorPtr = (SkPMColor*) pixels;
101 SkPMColor pmWhite = colorPtr[0];
102 SkPaint paint;
103 canvas->drawPoint(1, 1, paint);
104 canvas->flush(); // ensure that point was drawn
105 for (int y = 0; y < info.height(); ++y) {
106 for (int x = 0; x < info.width(); ++x) {
107 SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x');
108 }
109 SkDebugf("\n");
110 }
111}
112#StdOut
113---
114-x-
115---
116expected release context
117##
118##
119
120#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster
121
122#Method ##
123
124# ------------------------------------------------------------------------------
125
126#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
127 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400128#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500129#Line # creates Surface from SkImageInfo ##
Cary Clark09d80c02018-10-31 12:14:03 -0400130#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500131
132#Example
133void draw(SkCanvas* ) {
134 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
135 const size_t rowBytes = 64;
136 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr));
137 SkCanvas* canvas = surface->getCanvas();
138 canvas->clear(SK_ColorWHITE);
139 SkPixmap pixmap;
140 if (surface->peekPixels(&pixmap)) {
141 const uint32_t* colorPtr = pixmap.addr32();
142 SkPMColor pmWhite = colorPtr[0];
143 SkPaint paint;
144 canvas->drawPoint(1, 1, paint);
145 canvas->flush(); // ensure that point was drawn
146 for (int y = 0; y < info.height(); ++y) {
147 for (int x = 0; x < info.width(); ++x) {
148 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
149 }
150 colorPtr += rowBytes / sizeof(colorPtr[0]);
151 SkDebugf("\n");
152 }
153 }
154}
155#StdOut
156---
157-x-
158---
159##
160##
161
162#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
163
164#Method ##
165
166# ------------------------------------------------------------------------------
167
168#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
169 const SkSurfaceProps* props = nullptr)
Cary Clark09d80c02018-10-31 12:14:03 -0400170#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500171
172#Example
173void draw(SkCanvas* ) {
174 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
175 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
176 SkCanvas* canvas = surface->getCanvas();
177 canvas->clear(SK_ColorWHITE);
178 SkPixmap pixmap;
179 if (surface->peekPixels(&pixmap)) {
180 const uint32_t* colorPtr = pixmap.addr32();
181 SkPMColor pmWhite = colorPtr[0];
182 SkPaint paint;
183 canvas->drawPoint(1, 1, paint);
184 canvas->flush(); // ensure that point was drawn
185 for (int y = 0; y < info.height(); ++y) {
186 for (int x = 0; x < info.width(); ++x) {
187 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
188 }
189 colorPtr += info.width();
190 SkDebugf("\n");
191 }
192 }
193}
194##
195
196#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
197
198#Method ##
199
200# ------------------------------------------------------------------------------
201
202#Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
203 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400204#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500205#Line # creates Surface from width, height matching output ##
Cary Clark09d80c02018-10-31 12:14:03 -0400206#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500207
208#Example
209void draw(SkCanvas* ) {
210 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3));
211 SkCanvas* canvas = surface->getCanvas();
212 canvas->clear(SK_ColorWHITE);
213 SkPixmap pixmap;
214 if (surface->peekPixels(&pixmap)) {
215 const uint32_t* colorPtr = pixmap.addr32();
216 SkPMColor pmWhite = colorPtr[0];
217 SkPaint paint;
218 canvas->drawPoint(1, 1, paint);
219 canvas->flush(); // ensure that point was drawn
220 for (int y = 0; y < surface->height(); ++y) {
221 for (int x = 0; x < surface->width(); ++x) {
222 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
223 }
224 colorPtr += surface->width();
225 SkDebugf("\n");
226 }
227 }
228}
229#StdOut
230---
231-x-
232---
233##
234##
235
236#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
237
238#Method ##
239
240# ------------------------------------------------------------------------------
241
242#Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
243 const GrBackendTexture& backendTexture,
244 GrSurfaceOrigin origin, int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500245 SkColorType colorType,
246 sk_sp<SkColorSpace> colorSpace,
Mike Reed186669c2019-02-13 14:26:37 -0500247 const SkSurfaceProps* surfaceProps,
248 TextureReleaseProc textureReleaseProc = nullptr,
249 ReleaseContext releaseContext = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400250#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400251#Line # creates Surface from GPU texture ##
Cary Clark09d80c02018-10-31 12:14:03 -0400252#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500253
254#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400255#Platform gpu cpu
256#Image 3
Cary Clarkf059e7c2017-12-20 14:53:21 -0500257 SkPaint paint;
258 paint.setTextSize(32);
259 GrContext* context = canvas->getGrContext();
260 if (!context) {
261 canvas->drawString("GPU only!", 20, 40, paint);
262 return;
263 }
264 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context,
Cary Clark06c20f32018-03-20 15:53:27 -0400265 backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
266 kRGBA_8888_SkColorType, nullptr, nullptr);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500267 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500268 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
269 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
270 canvas->drawImage(image, 0, 0);
271##
272
273#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
274
275#Method ##
276
277# ------------------------------------------------------------------------------
278
Cary Clarka560c472017-11-27 10:44:06 -0500279#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
280 const GrBackendRenderTarget& backendRenderTarget,
281 GrSurfaceOrigin origin,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500282 SkColorType colorType,
283 sk_sp<SkColorSpace> colorSpace,
Mike Reed186669c2019-02-13 14:26:37 -0500284 const SkSurfaceProps* surfaceProps,
285 RenderTargetReleaseProc releaseProc = nullptr,
286 ReleaseContext releaseContext = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400287#In Constructors
Cary Clark5ab52f62018-04-02 08:32:23 -0400288#Line # creates Surface from GPU render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400289#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500290
291#Example
292#ToDo remove !fiddle below once backEndTextureRenderTarget is available ##
293#Platform !fiddle gpu
294 SkPaint paint;
295 paint.setTextSize(32);
296 GrContext* context = canvas->getGrContext();
297 if (!context) {
298 canvas->drawString("GPU only!", 20, 40, paint);
299 return;
300 }
301 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context,
302 backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
303 nullptr, nullptr);
304 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500305 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
306 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
307 canvas->drawImage(image, 0, 0);
308##
309
310#SeeAlso MakeFromBackendTexture MakeRenderTarget
311
312#Method ##
313
314# ------------------------------------------------------------------------------
315
Cary Clarka560c472017-11-27 10:44:06 -0500316#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
317 const GrBackendTexture& backendTexture,
318 GrSurfaceOrigin origin,
319 int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500320 SkColorType colorType,
321 sk_sp<SkColorSpace> colorSpace,
322 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400323#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400324#Line # creates Surface from GPU back-end render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400325#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500326
327#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400328#ToDo example is bogus; gpuSurface should not make image ##
329#Platform gpu
330#Image 3
Brian Salomon49edccd2018-03-23 15:31:32 -0400331 SkPaint paint;
332 paint.setTextSize(32);
333 GrContext* context = canvas->getGrContext();
334 if (!context) {
335 canvas->drawString("GPU only!", 20, 40, paint);
336 return;
337 }
338 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(
339 context, backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
340 kRGBA_8888_SkColorType, nullptr, nullptr);
341 auto surfaceCanvas = gpuSurface->getCanvas();
342 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
343 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
344 canvas->drawImage(image, 0, 0);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500345##
346
347#SeeAlso MakeFromBackendRenderTarget MakeRenderTarget
348
349#Method ##
350
351# ------------------------------------------------------------------------------
352
Cary Clarka560c472017-11-27 10:44:06 -0500353#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
354 const SkImageInfo& imageInfo,
355 int sampleCount, GrSurfaceOrigin surfaceOrigin,
356 const SkSurfaceProps* surfaceProps,
357 bool shouldCreateWithMips = false)
Cary Clark61313f32018-10-08 14:57:48 -0400358#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500359#Line # creates Surface pointing to new GPU memory buffer ##
Cary Clark09d80c02018-10-31 12:14:03 -0400360#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500361
Cary Clarka560c472017-11-27 10:44:06 -0500362#Example
363#Platform gpu
364#Height 64
365 SkPaint paint;
366 paint.setTextSize(32);
367 GrContext* context = canvas->getGrContext();
368 if (!context) {
369 canvas->drawString("GPU only!", 20, 40, paint);
370 return;
371 }
372 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
373 for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
374 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
375 surfaceOrigin, nullptr));
376 auto surfaceCanvas = gpuSurface->getCanvas();
377 surfaceCanvas->clear(SK_ColorWHITE);
378 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
379 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
380 canvas->drawImage(image, 0, 0);
381 canvas->translate(0, 128);
382 }
383##
384
385#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
386
387#Method ##
388
389# ------------------------------------------------------------------------------
390
391#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
392 const SkImageInfo& imageInfo, int sampleCount,
393 const SkSurfaceProps* props)
Cary Clark09d80c02018-10-31 12:14:03 -0400394#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500395
396#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -0500397#Platform cpu gpu
Cary Clarka560c472017-11-27 10:44:06 -0500398#Description
399LCD text takes advantage of raster striping to improve resolution. Only one of
Cary Clark4855f782018-02-06 09:41:53 -0500400the four combinations is correct, depending on whether monitor LCD striping is
Cary Clarka560c472017-11-27 10:44:06 -0500401horizontal or vertical, and whether the order of the stripes is red blue green
402or red green blue.
403##
404void draw(SkCanvas* canvas) {
405 auto test_draw = [](SkCanvas* surfaceCanvas) -> void {
406 SkPaint paint;
407 paint.setAntiAlias(true);
408 paint.setLCDRenderText(true);
409 paint.setColor(0xFFBBBBBB);
410 surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint);
411 paint.setColor(SK_ColorWHITE);
412 paint.setTextSize(32);
413 surfaceCanvas->drawString("Pest", 0, 25, paint);
414 };
415 GrContext* context = canvas->getGrContext();
416 SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType);
Cary Clarka560c472017-11-27 10:44:06 -0500417 int y = 0;
418 for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry,
419 kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) {
420 SkSurfaceProps props(0, geometry);
Cary Clarka560c472017-11-27 10:44:06 -0500421 sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget(
422 context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props);
423 test_draw(surface->getCanvas());
424 surface->draw(canvas, 0, y, nullptr);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500425 sk_sp<SkImage> image(surface->makeImageSnapshot());
Cary Clarka560c472017-11-27 10:44:06 -0500426 SkAutoCanvasRestore acr(canvas, true);
427 canvas->scale(8, 8);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500428 canvas->drawImage(image, 12, y / 8);
Cary Clarka560c472017-11-27 10:44:06 -0500429 y += 64;
430 }
431}
432##
433
434#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
435
436#Method ##
437
438# ------------------------------------------------------------------------------
439
440#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
441 const SkImageInfo& imageInfo)
Cary Clark09d80c02018-10-31 12:14:03 -0400442#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500443
444#Example
445#Platform gpu
446 SkPaint paint;
447 paint.setTextSize(32);
448 GrContext* context = canvas->getGrContext();
449 if (!context) {
450 canvas->drawString("GPU only!", 20, 40, paint);
451 return;
452 }
453 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
454 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
455 auto surfaceCanvas = gpuSurface->getCanvas();
456 surfaceCanvas->clear(SK_ColorWHITE);
457 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
458 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
459 canvas->drawImage(image, 0, 0);
460##
461
462#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
463
464#Method ##
465
466# ------------------------------------------------------------------------------
467
Robert Phillips249a2572019-02-19 17:04:43 -0500468#Method static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context,
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400469 const SkSurfaceCharacterization& characterization,
470 SkBudgeted budgeted)
Cary Clark09d80c02018-10-31 12:14:03 -0400471#Populate
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400472
Cary Clark5ab52f62018-04-02 08:32:23 -0400473#NoExample
474##
475
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400476#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
477
478#Method ##
479
480# ------------------------------------------------------------------------------
481
Cary Clarka560c472017-11-27 10:44:06 -0500482#Method static sk_sp<SkSurface> MakeNull(int width, int height)
483
Cary Clark61313f32018-10-08 14:57:48 -0400484#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500485#Line # creates Surface without backing pixels ##
Cary Clark09d80c02018-10-31 12:14:03 -0400486#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500487
488#Example
489 SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ?
490 '=' : '!');
491 const int w = 37;
492 const int h = 1000;
493 auto surf = SkSurface::MakeNull(w, h);
494 auto nullCanvas = surf->getCanvas();
495 nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws
496 SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ?
497 '=' : '!');
498#StdOut
499SkSurface::MakeNull(0, 0) == nullptr
500surf->makeImageSnapshot() == nullptr
501##
502##
503
504#SeeAlso MakeRaster MakeRenderTarget
505
506#Method ##
507
508# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500509#Subtopic Property
Cary Clark4855f782018-02-06 09:41:53 -0500510#Line # member values ##
511##
Cary Clarka560c472017-11-27 10:44:06 -0500512
513#Method int width() const
514
Cary Clark4855f782018-02-06 09:41:53 -0500515#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500516#Line # returns pixel column count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400517#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500518
519#Example
520 const int width = 37;
521 const int height = 1000;
522 auto surf = SkSurface::MakeNull(width, height);
523 auto nullCanvas = surf->getCanvas();
524 SkDebugf("surface width=%d canvas width=%d\n", surf->width(),
525 nullCanvas->getBaseLayerSize().fWidth);
526#StdOut
527surface width=37 canvas width=37
528##
529##
530
531#SeeAlso height()
532
533#Method ##
534
535# ------------------------------------------------------------------------------
536
537#Method int height() const
Cary Clark4855f782018-02-06 09:41:53 -0500538#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500539#Line # returns pixel row count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400540#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500541
542#Example
543 const int width = 37;
544 const int height = 1000;
545 auto surf = SkSurface::MakeNull(width, height);
546 auto nullCanvas = surf->getCanvas();
547 SkDebugf("surface height=%d canvas height=%d\n", surf->height(),
548 nullCanvas->getBaseLayerSize().fHeight);
549#StdOut
550surface height=1000 canvas height=1000
551##
552##
553
554#SeeAlso width()
555
556#Method ##
557
558# ------------------------------------------------------------------------------
559
560#Method uint32_t generationID()
Cary Clark4855f782018-02-06 09:41:53 -0500561#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500562#Line # returns unique ID ##
Cary Clark09d80c02018-10-31 12:14:03 -0400563#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500564
565#Example
566 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
567 for (int i = 0; i < 3; ++i) {
568 SkDebugf("surface generationID: %d\n", surface->generationID());
569 if (0 == i) {
570 surface->getCanvas()->drawColor(SK_ColorBLACK);
571 } else {
572 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
573 }
574 }
575#StdOut
576surface generationID: 1
577surface generationID: 2
578surface generationID: 3
579##
580##
581
582#SeeAlso notifyContentWillChange ContentChangeMode getCanvas
583
584#Method ##
585
586# ------------------------------------------------------------------------------
587
588#Enum ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400589#Line # parameter options for notifyContentWillChange ##
Cary Clarka560c472017-11-27 10:44:06 -0500590#Code
591 enum ContentChangeMode {
592 kDiscard_ContentChangeMode,
593 kRetain_ContentChangeMode,
594 };
595##
596
597ContentChangeMode members are parameters to notifyContentWillChange.
598
599#Const kDiscard_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400600#Line # discards surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500601Pass to notifyContentWillChange to discard surface contents when
602the surface is cleared or overwritten.
603##
604#Const kRetain_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400605#Line # preserves surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500606Pass to notifyContentWillChange when to preserve surface contents.
607If a snapshot has been generated, this copies the Surface contents.
608##
609
610#SeeAlso notifyContentWillChange generationID
611
612#Enum ##
613
614# ------------------------------------------------------------------------------
615
Cary Clark4855f782018-02-06 09:41:53 -0500616#ToDo not crazy about misc catagory -- hopefully will become clear with time
617##
Cary Clarka560c472017-11-27 10:44:06 -0500618
Cary Clark4855f782018-02-06 09:41:53 -0500619#Subtopic Miscellaneous
Cary Clark4855f782018-02-06 09:41:53 -0500620#Line # other functions ##
621##
622
623#Method void notifyContentWillChange(ContentChangeMode mode)
624#In Miscellaneous
Cary Clarkab2621d2018-01-30 10:08:57 -0500625#Line # notifies that contents will be changed outside of Skia ##
Cary Clarkabaffd82018-11-15 08:25:12 -0500626#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500627
628#Example
629 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
630 for (int i = 0; i < 3; ++i) {
631 SkDebugf("surface generationID: %d\n", surface->generationID());
632 if (0 == i) {
633 surface->getCanvas()->drawColor(SK_ColorBLACK);
634 } else {
635 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
636 }
637 }
638##
639
640#SeeAlso ContentChangeMode generationID
641
642#Method ##
643
644# ------------------------------------------------------------------------------
645
646#Enum BackendHandleAccess
Cary Clark682c58d2018-05-16 07:07:07 -0400647#Line # options to read and write back-end object ##
Cary Clarka560c472017-11-27 10:44:06 -0500648#Code
649 enum BackendHandleAccess {
650 kFlushRead_BackendHandleAccess,
651 kFlushWrite_BackendHandleAccess,
652 kDiscardWrite_BackendHandleAccess,
653 };
Cary Clark7cfcbca2018-01-04 16:11:51 -0500654
655 static const BackendHandleAccess kFlushRead_TextureHandleAccess =
656 kFlushRead_BackendHandleAccess;
657 static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
658 kFlushWrite_BackendHandleAccess;
659 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
660 kDiscardWrite_BackendHandleAccess;
Cary Clarka560c472017-11-27 10:44:06 -0500661##
662
Cary Clark3cd22cc2017-12-01 11:49:58 -0500663#Const kFlushRead_BackendHandleAccess 0
Cary Clark682c58d2018-05-16 07:07:07 -0400664#Line # back-end object is readable ##
Cary Clarka560c472017-11-27 10:44:06 -0500665Caller may read from the back-end object.
666##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500667#Const kFlushWrite_BackendHandleAccess 1
Cary Clark682c58d2018-05-16 07:07:07 -0400668#Line # back-end object is writable ##
Cary Clarka560c472017-11-27 10:44:06 -0500669Caller may write to the back-end object.
670##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500671#Const kDiscardWrite_BackendHandleAccess 2
Cary Clark682c58d2018-05-16 07:07:07 -0400672#Line # back-end object must be overwritten ##
Cary Clarka560c472017-11-27 10:44:06 -0500673Caller must overwrite the entire back-end object.
674##
675
Cary Clark36122e72018-04-26 10:59:57 -0400676#NoExample
677// todo: need to update example to use GrBackendTexture instead of GrBackendObject
Cary Clarka560c472017-11-27 10:44:06 -0500678#Platform gpu
Cary Clark3cd22cc2017-12-01 11:49:58 -0500679 SkPaint paint;
680 paint.setTextSize(32);
681 GrContext* context = canvas->getGrContext();
682 if (!context) {
683 canvas->drawString("GPU only!", 20, 40, paint);
684 return;
685 }
686 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
687 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10));
688 int y = 20;
689 SkString str;
690 paint.setTextSize(16);
Cary Clark682c58d2018-05-16 07:07:07 -0400691 for (auto access : { SkSurface::kFlushRead_BackendHandleAccess,
Cary Clark3cd22cc2017-12-01 11:49:58 -0500692 SkSurface::kFlushWrite_BackendHandleAccess,
693 SkSurface::kDiscardWrite_BackendHandleAccess } ) {
694 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
695 str.printf("uniqueID=%d", image->uniqueID());
696 canvas->drawString(str, 20, y += 20, paint);
Greg Daniel6d138bf2018-05-03 16:54:03 -0400697 GrBackendTexture backendTex = gpuSurface->getBackendTexture(access);
698 str.printf("backendTex is %svalid", backendTex.isValid() ? '' : 'not ');
Cary Clark3cd22cc2017-12-01 11:49:58 -0500699 canvas->drawString(str, 20, y += 20, paint);
700 }
701 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
702 str.printf("final image uniqueID=%d", image->uniqueID());
703 canvas->drawString(str, 20, y += 20, paint);
Cary Clarka560c472017-11-27 10:44:06 -0500704##
705
Cary Clark36122e72018-04-26 10:59:57 -0400706#SeeAlso getBackendTexture getBackendRenderTarget
Cary Clarka560c472017-11-27 10:44:06 -0500707
708#Enum ##
709
710# ------------------------------------------------------------------------------
711
Robert Phillips8caf85f2018-04-05 09:30:38 -0400712#Method GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess)
713#In Property
714#Line # returns the GPU reference to texture ##
Cary Clark09d80c02018-10-31 12:14:03 -0400715#Populate
Robert Phillips8caf85f2018-04-05 09:30:38 -0400716
717#NoExample
718##
719
720#SeeAlso GrBackendTexture BackendHandleAccess getBackendRenderTarget
721
722#Method ##
723
724# ------------------------------------------------------------------------------
725
726#Method GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess)
727#In Property
728#Line # returns the GPU reference to render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400729#Populate
Robert Phillips8caf85f2018-04-05 09:30:38 -0400730
731#NoExample
732##
733
734#SeeAlso GrBackendRenderTarget BackendHandleAccess getBackendTexture
735
736#Method ##
737
738# ------------------------------------------------------------------------------
739
Cary Clarka560c472017-11-27 10:44:06 -0500740#Method SkCanvas* getCanvas()
Cary Clark4855f782018-02-06 09:41:53 -0500741#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500742#Line # returns Canvas that draws into Surface ##
Cary Clark09d80c02018-10-31 12:14:03 -0400743#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500744
745#Example
746#Height 64
747 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(64, 64));
748 SkCanvas* surfaceCanvas = surface->getCanvas();
749 surfaceCanvas->clear(SK_ColorBLUE);
750 SkPaint paint;
751 paint.setTextSize(40);
752 surfaceCanvas->drawString("\xF0\x9F\x98\x81", 12, 45, paint);
753 surface->draw(canvas, 0, 0, nullptr);
754##
755
Cary Clark4855f782018-02-06 09:41:53 -0500756#SeeAlso makeSurface makeImageSnapshot draw
Cary Clarka560c472017-11-27 10:44:06 -0500757
758#Method ##
759
760# ------------------------------------------------------------------------------
761
762#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo)
Cary Clark61313f32018-10-08 14:57:48 -0400763#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500764#Line # creates a compatible Surface ##
Cary Clark09d80c02018-10-31 12:14:03 -0400765#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500766
767#Example
768#Height 96
769 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
770 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
771 big->getCanvas()->clear(SK_ColorRED);
772 lil->getCanvas()->clear(SK_ColorBLACK);
773 SkPixmap pixmap;
774 if (big->peekPixels(&pixmap)) {
775 SkBitmap bigBits;
776 bigBits.installPixels(pixmap);
777 canvas->drawBitmap(bigBits, 0, 0);
778 }
779 if (lil->peekPixels(&pixmap)) {
780 SkBitmap lilBits;
781 lilBits.installPixels(pixmap);
782 canvas->drawBitmap(lilBits, 64, 64);
783 }
784##
785
Cary Clark4855f782018-02-06 09:41:53 -0500786#SeeAlso makeImageSnapshot getCanvas draw
Cary Clarka560c472017-11-27 10:44:06 -0500787
788#Method ##
789
790# ------------------------------------------------------------------------------
791
792#Method sk_sp<SkImage> makeImageSnapshot()
Cary Clark61313f32018-10-08 14:57:48 -0400793#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500794#Line # creates Image capturing Surface contents ##
Cary Clark09d80c02018-10-31 12:14:03 -0400795#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500796
797#Example
798#Height 64
799 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
800 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
801 big->getCanvas()->clear(SK_ColorRED);
802 lil->getCanvas()->clear(SK_ColorBLACK);
803 sk_sp<SkImage> early(big->makeImageSnapshot());
804 lil->draw(big->getCanvas(), 16, 16, nullptr);
805 sk_sp<SkImage> later(big->makeImageSnapshot());
806 canvas->drawImage(early, 0, 0);
807 canvas->drawImage(later, 128, 0);
808##
809
810#SeeAlso draw getCanvas
811
812#Method ##
813
814# ------------------------------------------------------------------------------
Mike Reed114bde82018-11-21 09:12:09 -0500815
816#Method sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds)
817#In Constructors
818#Line # creates Image capturing subset of Surface contents ##
819#Populate
820
821#Example
822#Height 64
823 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
824 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
825 big->getCanvas()->clear(SK_ColorRED);
826 lil->getCanvas()->clear(SK_ColorBLACK);
827 sk_sp<SkImage> early(big->makeImageSnapshot());
828 lil->draw(big->getCanvas(), 16, 16, nullptr);
829 sk_sp<SkImage> later(big->makeImageSnapshot({0, 0, 16, 16}));
830 canvas->drawImage(early, 0, 0);
831 canvas->drawImage(later, 0, 0);
832##
833
834#SeeAlso draw getCanvas
835
836#Method ##
837
838# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500839#Subtopic Pixels
Cary Clark4855f782018-02-06 09:41:53 -0500840#Line # functions with pixel access ##
841##
Cary Clarka560c472017-11-27 10:44:06 -0500842
843#Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
Cary Clark4855f782018-02-06 09:41:53 -0500844#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500845#Line # draws Surface contents to canvas ##
Cary Clark09d80c02018-10-31 12:14:03 -0400846#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500847
848#Example
849#Height 64
850 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
851 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
852 big->getCanvas()->clear(SK_ColorRED);
853 lil->getCanvas()->clear(SK_ColorBLACK);
854 lil->draw(big->getCanvas(), 16, 16, nullptr);
855 SkPixmap pixmap;
856 if (big->peekPixels(&pixmap)) {
857 SkBitmap bigBits;
858 bigBits.installPixels(pixmap);
859 canvas->drawBitmap(bigBits, 0, 0);
860 }
861##
862
863#SeeAlso makeImageSnapshot getCanvas
864
865#Method ##
866
867# ------------------------------------------------------------------------------
868
869#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark4855f782018-02-06 09:41:53 -0500870#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500871#Line # copies Surface parameters to Pixmap ##
Cary Clark09d80c02018-10-31 12:14:03 -0400872#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500873
874#Example
875#Height 64
876 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
877 auto surfCanvas = surf->getCanvas();
878 surfCanvas->clear(SK_ColorRED);
879 SkPaint paint;
880 paint.setTextSize(40);
881 surfCanvas->drawString("&", 16, 48, paint);
882 SkPixmap pixmap;
883 if (surf->peekPixels(&pixmap)) {
884 SkBitmap surfBits;
885 surfBits.installPixels(pixmap);
886 canvas->drawBitmap(surfBits, 0, 0);
887 }
888##
889
Mike Reed4c790bd2018-02-08 14:10:40 -0500890#SeeAlso readPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500891
892#Method ##
893
894# ------------------------------------------------------------------------------
895
896#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY)
Cary Clark4855f782018-02-06 09:41:53 -0500897#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500898#Line # copies Rect of pixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500899Copies Rect of pixels to dst.
900
Cary Clarkac47b882018-01-11 10:35:44 -0500901Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500902Destination Rect corners are (0, 0) and (dst.width(), dst.height()).
903Copies each readable pixel intersecting both rectangles, without scaling,
904converting to dst.colorType() and dst.alphaType() if required.
905
906Pixels are readable when Surface is raster, or backed by a GPU.
907
908The destination pixel storage must be allocated by the caller.
909
Cary Clark2dc84ad2018-01-26 12:56:22 -0500910Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500911do not match. Only pixels within both source and destination rectangles
912are copied. dst contents outside Rect intersection are unchanged.
913
914Pass negative values for srcX or srcY to offset pixels across or down destination.
915
916Does not copy, and returns false if:
917
918#List
919# Source and destination rectangles do not intersect. ##
920# Pixmap pixels could not be allocated. ##
921# dst.rowBytes() is too small to contain one row of pixels. ##
922##
923
924#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -0400925#Param srcX offset into readable pixels on x-axis; may be negative ##
926#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500927
928#Return true if pixels were copied ##
929
930#Example
931#Height 32
932 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
933 auto surfCanvas = surf->getCanvas();
934 surfCanvas->clear(SK_ColorRED);
935 SkPaint paint;
936 paint.setTextSize(40);
937 surfCanvas->drawString("&", 0, 32, paint);
938 std::vector<SkPMColor> storage;
939 storage.resize(surf->width() * surf->height());
940 SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(),
941 surf->width() * sizeof(storage[0]));
942 if (surf->readPixels(pixmap, 0, 0)) {
943 SkBitmap surfBits;
944 surfBits.installPixels(pixmap);
945 canvas->drawBitmap(surfBits, 0, 0);
946 }
947##
948
Mike Reed4c790bd2018-02-08 14:10:40 -0500949#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500950
951#Method ##
952
953# ------------------------------------------------------------------------------
954
955#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
956 int srcX, int srcY)
957
958Copies Rect of pixels from Canvas into dstPixels.
959
Cary Clarkac47b882018-01-11 10:35:44 -0500960Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500961Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
962Copies each readable pixel intersecting both rectangles, without scaling,
963converting to dstInfo.colorType() and dstInfo.alphaType() if required.
964
965Pixels are readable when Surface is raster, or backed by a GPU.
966
967The destination pixel storage must be allocated by the caller.
968
Cary Clark2dc84ad2018-01-26 12:56:22 -0500969Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500970do not match. Only pixels within both source and destination rectangles
971are copied. dstPixels contents outside Rect intersection are unchanged.
972
973Pass negative values for srcX or srcY to offset pixels across or down destination.
974
975Does not copy, and returns false if:
976
977#List
978# Source and destination rectangles do not intersect. ##
979# Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
980# dstRowBytes is too small to contain one row of pixels. ##
981##
982
Cary Clark2dc84ad2018-01-26 12:56:22 -0500983#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500984#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
985#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400986#Param srcX offset into readable pixels on x-axis; may be negative ##
987#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500988
989#Return true if pixels were copied ##
990
991#Example
992#Height 64
993#Description
994 A black oval drawn on a red background provides an image to copy.
995 readPixels copies one quarter of the Surface into each of the four corners.
996 The copied quarter ovals overdraw the original oval.
997##
998 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
999 auto surfCanvas = surf->getCanvas();
1000 surfCanvas->clear(SK_ColorRED);
1001 SkPaint paint;
1002 surfCanvas->drawOval({4, 8, 58, 54}, paint);
1003 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1004 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
1005 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
1006 for (int x : { 32, -32 } ) {
1007 for (int y : { 32, -32 } ) {
1008 surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Cary Clark682c58d2018-05-16 07:07:07 -04001009 }
Cary Clarka560c472017-11-27 10:44:06 -05001010 }
1011 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
1012 canvas->drawImage(image, 0, 0);
1013##
1014
Mike Reed4c790bd2018-02-08 14:10:40 -05001015#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -05001016
1017#Method ##
1018
1019# ------------------------------------------------------------------------------
1020
1021#Method bool readPixels(const SkBitmap& dst, int srcX, int srcY)
1022
1023Copies Rect of pixels from Surface into bitmap.
1024
Cary Clarkac47b882018-01-11 10:35:44 -05001025Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -05001026Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
1027Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001028converting to dst.colorType() and dst.alphaType() if required.
Cary Clarka560c472017-11-27 10:44:06 -05001029
1030Pixels are readable when Surface is raster, or backed by a GPU.
1031
1032The destination pixel storage must be allocated by the caller.
1033
Cary Clark2dc84ad2018-01-26 12:56:22 -05001034Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -05001035do not match. Only pixels within both source and destination rectangles
1036are copied. dst contents outside Rect intersection are unchanged.
1037
1038Pass negative values for srcX or srcY to offset pixels across or down destination.
1039
1040Does not copy, and returns false if:
1041
1042#List
1043# Source and destination rectangles do not intersect. ##
1044# Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ##
1045# dst pixels could not be allocated. ##
1046# dst.rowBytes() is too small to contain one row of pixels. ##
1047##
1048
1049#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001050#Param srcX offset into readable pixels on x-axis; may be negative ##
1051#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -05001052
1053#Return true if pixels were copied ##
1054
1055#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -05001056 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1057 auto surfCanvas = surf->getCanvas();
1058 surfCanvas->clear(SK_ColorGREEN);
1059 SkPaint paint;
1060 surfCanvas->drawOval({2, 10, 58, 54}, paint);
1061 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1062 SkBitmap bitmap;
1063 bitmap.setInfo(info);
1064 bitmap.allocPixels();
1065 for (int x : { 32, -32 } ) {
1066 for (int y : { 32, -32 } ) {
1067 surf->readPixels(bitmap, x, y);
Cary Clark682c58d2018-05-16 07:07:07 -04001068 }
Cary Clark3cd22cc2017-12-01 11:49:58 -05001069 }
1070 canvas->drawBitmap(bitmap, 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001071##
1072
Mike Reed4c790bd2018-02-08 14:10:40 -05001073#SeeAlso peekPixels writePixels
1074
1075#Method ##
1076
1077# ------------------------------------------------------------------------------
1078
1079#Method void writePixels(const SkPixmap& src, int dstX, int dstY)
Cary Clark56356312018-02-08 14:45:18 -05001080#In Pixels
1081#Line # copies Rect of pixels ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001082Copies Rect of pixels from the src Pixmap to the Surface.
1083
1084Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark682c58d2018-05-16 07:07:07 -04001085Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001086#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001087
Mike Reed4c790bd2018-02-08 14:10:40 -05001088Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001089converting to Surface SkColorType and SkAlphaType if required.
Mike Reed4c790bd2018-02-08 14:10:40 -05001090
1091#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001092#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1093#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001094
1095#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001096#Image 4
1097#Height 96
Cary Clark09d80c02018-10-31 12:14:03 -04001098 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1099 auto surfCanvas = surf->getCanvas();
1100 surfCanvas->clear(SK_ColorRED);
1101 SkPaint paint;
1102 paint.setTextSize(40);
1103 surfCanvas->drawString("&", 16, 40, paint);
1104 SkPixmap pixmap;
1105 if (surf->peekPixels(&pixmap)) {
1106 surf->writePixels(pixmap, 25, 25);
1107 sk_sp<SkImage> image(surf->makeImageSnapshot());
1108 canvas->drawImage(image, 0, 0);
Cary Clarkffb3d682018-05-17 12:17:28 -04001109 }
Mike Reed4c790bd2018-02-08 14:10:40 -05001110##
1111
1112#SeeAlso readPixels peekPixels
1113
1114#Method ##
1115
1116# ------------------------------------------------------------------------------
1117
1118#Method void writePixels(const SkBitmap& src, int dstX, int dstY)
1119
1120Copies Rect of pixels from the src Bitmap to the Surface.
1121
1122Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark56356312018-02-08 14:45:18 -05001123Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001124#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001125
Mike Reed4c790bd2018-02-08 14:10:40 -05001126Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001127converting to Surface SkColorType and SkAlphaType if required.
Mike Reed4c790bd2018-02-08 14:10:40 -05001128
1129#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001130#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1131#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001132
1133#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001134#Image 4
1135#Height 96
1136 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1137 auto surfCanvas = surf->getCanvas();
1138 surfCanvas->clear(SK_ColorGREEN);
1139 surf->writePixels(source, 25, 25);
1140 sk_sp<SkImage> image(surf->makeImageSnapshot());
1141 canvas->drawImage(image, 0, 0);
Mike Reed4c790bd2018-02-08 14:10:40 -05001142##
1143
1144#SeeAlso readPixels peekPixels
Cary Clarka560c472017-11-27 10:44:06 -05001145
1146#Method ##
1147
1148# ------------------------------------------------------------------------------
1149
1150#Method const SkSurfaceProps& props() const
Cary Clark4855f782018-02-06 09:41:53 -05001151#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05001152#Line # returns Surface_Properties ##
Cary Clark09d80c02018-10-31 12:14:03 -04001153#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001154
1155#Example
1156 const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" };
Cary Clark3cd22cc2017-12-01 11:49:58 -05001157 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001158 SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]);
1159#StdOut
1160surf.props(): kRGB_H_SkPixelGeometry
1161##
1162##
1163
1164#SeeAlso SkSurfaceProps
1165
1166#Method ##
1167
1168# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05001169#Subtopic Utility
Cary Clark4855f782018-02-06 09:41:53 -05001170#Line # rarely called management functions ##
1171##
Cary Clarka560c472017-11-27 10:44:06 -05001172
1173#Method void flush()
Cary Clark4855f782018-02-06 09:41:53 -05001174#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001175#Line # resolves pending I/O ##
Cary Clark09d80c02018-10-31 12:14:03 -04001176#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001177
1178#NoExample
1179##
1180
1181#SeeAlso GrBackendSemaphore
1182
1183#Method ##
1184
1185# ------------------------------------------------------------------------------
1186
1187#Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
1188 GrBackendSemaphore signalSemaphores[])
Cary Clark4855f782018-02-06 09:41:53 -05001189#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001190#Line # resolves pending I/O, and signal ##
Cary Clark09d80c02018-10-31 12:14:03 -04001191#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001192
1193#NoExample
1194##
1195
1196#SeeAlso wait GrBackendSemaphore
1197
1198#Method ##
1199
1200# ------------------------------------------------------------------------------
1201
1202#Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores)
Cary Clark4855f782018-02-06 09:41:53 -05001203#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001204#Line # pauses commands until signaled ##
Cary Clark09d80c02018-10-31 12:14:03 -04001205#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001206
Cary Clark1a8d7622018-03-05 13:26:16 -05001207#NoExample
Cary Clarka560c472017-11-27 10:44:06 -05001208#ToDo this is copy and paste silliness masquerading as an example. Probably need gpu
1209 globals and definitely need gpu expertise to make a real example out of this
Cary Clark36122e72018-04-26 10:59:57 -04001210 also, note need to replace GrBackendObject with GrBackendTexture
Cary Clarka560c472017-11-27 10:44:06 -05001211 ##
Cary Clark1a8d7622018-03-05 13:26:16 -05001212#Platform gpu
Cary Clarka560c472017-11-27 10:44:06 -05001213#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001214 SkPaint paint;
1215 paint.setTextSize(32);
1216 GrContext* context = canvas->getGrContext();
1217 if (!context) {
1218 canvas->drawString("GPU only!", 20, 40, paint);
1219 return;
1220 }
Cary Clarka560c472017-11-27 10:44:06 -05001221 GrBackendSemaphore semaphore;
Cary Clark3cd22cc2017-12-01 11:49:58 -05001222 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
1223 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001224 surface->flushAndSignalSemaphores(1, &semaphore);
1225 sk_sp<SkImage> image = surface->makeImageSnapshot();
Greg Daniel6d138bf2018-05-03 16:54:03 -04001226 GrBackendTexture backendTex = image->getBackendTexture(false); // unused
1227 SkASSERT(backendTex.isValid());
Cary Clarka560c472017-11-27 10:44:06 -05001228 const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64,
1229 kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1230 sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
1231 childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr));
1232 GrBackendTexture backendTexture;
1233 sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context,
1234 backendTexture, // undefined
1235 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr);
1236 SkCanvas* childCanvas = childSurface->getCanvas();
1237 childCanvas->clear(SK_ColorRED);
1238 childSurface->wait(1, &semaphore);
1239 childCanvas->drawImage(childImage, 32, 0);
Cary Clark3cd22cc2017-12-01 11:49:58 -05001240 childSurface->draw(canvas, 0, 0, nullptr);
Cary Clarka560c472017-11-27 10:44:06 -05001241##
1242
1243#SeeAlso flushAndSignalSemaphores GrBackendSemaphore
1244
1245#Method ##
1246
1247# ------------------------------------------------------------------------------
1248
1249#Method bool characterize(SkSurfaceCharacterization* characterization) const
Cary Clark4855f782018-02-06 09:41:53 -05001250#In Utility
1251#Line # sets Surface_Characterization for threaded GPU processing ##
Cary Clark09d80c02018-10-31 12:14:03 -04001252#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001253
1254#Example
1255#Platform gpu
1256#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001257 SkPaint paint;
1258 paint.setTextSize(32);
1259 GrContext* context = canvas->getGrContext();
1260 if (!context) {
1261 canvas->drawString("GPU only!", 20, 40, paint);
1262 return;
1263 }
1264 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1265 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
1266 SkSurfaceCharacterization characterization;
1267 if (!gpuSurface->characterize(&characterization)) {
1268 canvas->drawString("characterization unsupported", 20, 40, paint);
1269 return;
1270 }
Cary Clark682c58d2018-05-16 07:07:07 -04001271 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001272 SkDeferredDisplayListRecorder recorder(characterization);
1273 SkCanvas* subCanvas = recorder.getCanvas();
1274 subCanvas->clear(SK_ColorGREEN);
1275 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1276 // end of threadable work
1277 gpuSurface->draw(displayList.get());
1278 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1279 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001280##
1281
1282#SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList
1283
1284#Method ##
1285
1286# ------------------------------------------------------------------------------
1287
Cary Clark2f466242017-12-11 16:03:17 -05001288#Method bool draw(SkDeferredDisplayList* deferredDisplayList)
Cary Clark09d80c02018-10-31 12:14:03 -04001289#Populate
Cary Clark2f466242017-12-11 16:03:17 -05001290
Cary Clarka560c472017-11-27 10:44:06 -05001291#Example
1292#Height 64
1293#Platform gpu cpu
Cary Clark3cd22cc2017-12-01 11:49:58 -05001294 SkPaint paint;
1295 paint.setTextSize(16);
1296 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64);
1297 SkSurfaceCharacterization characterization;
1298 if (!gpuSurface->characterize(&characterization)) {
1299 canvas->drawString("characterization unsupported", 20, 40, paint);
1300 return;
1301 }
Cary Clark682c58d2018-05-16 07:07:07 -04001302 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001303 SkDeferredDisplayListRecorder recorder(characterization);
1304 SkCanvas* subCanvas = recorder.getCanvas();
1305 subCanvas->clear(SK_ColorGREEN);
1306 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1307 // end of threadable work
1308 gpuSurface->draw(displayList.get());
1309 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1310 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001311##
1312
1313#SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList
1314
1315#Method ##
1316
1317#Class SkSurface ##
1318
1319#Topic Surface ##