blob: dacd00f8420f45efbcf3784e91b7da241befaf65 [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
11allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface).
12SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call
13surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface).
14SkSurface always has non-zero dimensions. If there is a request for a new surface, and either
15of the requested dimensions are zero, then nullptr will be returned.
16
Cary Clarka560c472017-11-27 10:44:06 -050017# ------------------------------------------------------------------------------
18
19#Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
20 size_t rowBytes,
21 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040022#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050023#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040024#Populate
Cary Clarka560c472017-11-27 10:44:06 -050025
26#Example
27void draw(SkCanvas* ) {
28 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
29 const size_t size = info.computeMinByteSize();
30 SkAutoTMalloc<SkPMColor> storage(size);
31 SkPMColor* pixels = storage.get();
32 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes()));
33 SkCanvas* canvas = surface->getCanvas();
34 canvas->clear(SK_ColorWHITE);
35 SkPMColor pmWhite = pixels[0];
36 SkPaint paint;
37 canvas->drawPoint(1, 1, paint);
38 canvas->flush(); // ensure that point was drawn
39 for (int y = 0; y < info.height(); ++y) {
40 for (int x = 0; x < info.width(); ++x) {
41 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
42 }
43 SkDebugf("\n");
44 }
45}
46 #StdOut
47 ---
48 -x-
49 ---
50 ##
51##
52
53#SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect
54
55#Method ##
56
57# ------------------------------------------------------------------------------
58
59#Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
60 size_t rowBytes,
61 void (*releaseProc)(void* pixels, void* context),
62 void* context, const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040063#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050064#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040065#Populate
Cary Clarka560c472017-11-27 10:44:06 -050066
67#Example
68#Function
69static void release_direct_surface_storage(void* pixels, void* context) {
70 if (pixels == context) {
71 SkDebugf("expected release context\n");
72 }
73 sk_free(pixels);
74}
75
76##
77void draw(SkCanvas* ) {
78 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
79 const size_t rowBytes = info.minRowBytes();
80 void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes));
81 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes,
82 release_direct_surface_storage, pixels));
83 SkCanvas* canvas = surface->getCanvas();
84 canvas->clear(SK_ColorWHITE);
85 SkPMColor* colorPtr = (SkPMColor*) pixels;
86 SkPMColor pmWhite = colorPtr[0];
87 SkPaint paint;
88 canvas->drawPoint(1, 1, paint);
89 canvas->flush(); // ensure that point was drawn
90 for (int y = 0; y < info.height(); ++y) {
91 for (int x = 0; x < info.width(); ++x) {
92 SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x');
93 }
94 SkDebugf("\n");
95 }
96}
97#StdOut
98---
99-x-
100---
101expected release context
102##
103##
104
105#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster
106
107#Method ##
108
109# ------------------------------------------------------------------------------
110
111#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
112 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400113#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500114#Line # creates Surface from SkImageInfo ##
Cary Clark09d80c02018-10-31 12:14:03 -0400115#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500116
117#Example
118void draw(SkCanvas* ) {
119 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
120 const size_t rowBytes = 64;
121 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr));
122 SkCanvas* canvas = surface->getCanvas();
123 canvas->clear(SK_ColorWHITE);
124 SkPixmap pixmap;
125 if (surface->peekPixels(&pixmap)) {
126 const uint32_t* colorPtr = pixmap.addr32();
127 SkPMColor pmWhite = colorPtr[0];
128 SkPaint paint;
129 canvas->drawPoint(1, 1, paint);
130 canvas->flush(); // ensure that point was drawn
131 for (int y = 0; y < info.height(); ++y) {
132 for (int x = 0; x < info.width(); ++x) {
133 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
134 }
135 colorPtr += rowBytes / sizeof(colorPtr[0]);
136 SkDebugf("\n");
137 }
138 }
139}
140#StdOut
141---
142-x-
143---
144##
145##
146
147#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
148
149#Method ##
150
151# ------------------------------------------------------------------------------
152
153#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
154 const SkSurfaceProps* props = nullptr)
Cary Clark09d80c02018-10-31 12:14:03 -0400155#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500156
157#Example
158void draw(SkCanvas* ) {
159 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
160 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
161 SkCanvas* canvas = surface->getCanvas();
162 canvas->clear(SK_ColorWHITE);
163 SkPixmap pixmap;
164 if (surface->peekPixels(&pixmap)) {
165 const uint32_t* colorPtr = pixmap.addr32();
166 SkPMColor pmWhite = colorPtr[0];
167 SkPaint paint;
168 canvas->drawPoint(1, 1, paint);
169 canvas->flush(); // ensure that point was drawn
170 for (int y = 0; y < info.height(); ++y) {
171 for (int x = 0; x < info.width(); ++x) {
172 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
173 }
174 colorPtr += info.width();
175 SkDebugf("\n");
176 }
177 }
178}
179##
180
181#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
182
183#Method ##
184
185# ------------------------------------------------------------------------------
186
187#Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
188 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400189#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500190#Line # creates Surface from width, height matching output ##
Cary Clark09d80c02018-10-31 12:14:03 -0400191#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500192
193#Example
194void draw(SkCanvas* ) {
195 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3));
196 SkCanvas* canvas = surface->getCanvas();
197 canvas->clear(SK_ColorWHITE);
198 SkPixmap pixmap;
199 if (surface->peekPixels(&pixmap)) {
200 const uint32_t* colorPtr = pixmap.addr32();
201 SkPMColor pmWhite = colorPtr[0];
202 SkPaint paint;
203 canvas->drawPoint(1, 1, paint);
204 canvas->flush(); // ensure that point was drawn
205 for (int y = 0; y < surface->height(); ++y) {
206 for (int x = 0; x < surface->width(); ++x) {
207 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
208 }
209 colorPtr += surface->width();
210 SkDebugf("\n");
211 }
212 }
213}
214#StdOut
215---
216-x-
217---
218##
219##
220
221#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
222
223#Method ##
224
225# ------------------------------------------------------------------------------
226
227#Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
228 const GrBackendTexture& backendTexture,
229 GrSurfaceOrigin origin, int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500230 SkColorType colorType,
231 sk_sp<SkColorSpace> colorSpace,
232 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400233#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400234#Line # creates Surface from GPU texture ##
Cary Clark09d80c02018-10-31 12:14:03 -0400235#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500236
237#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400238#Platform gpu cpu
239#Image 3
Cary Clarkf059e7c2017-12-20 14:53:21 -0500240 SkPaint paint;
241 paint.setTextSize(32);
242 GrContext* context = canvas->getGrContext();
243 if (!context) {
244 canvas->drawString("GPU only!", 20, 40, paint);
245 return;
246 }
247 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context,
Cary Clark06c20f32018-03-20 15:53:27 -0400248 backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
249 kRGBA_8888_SkColorType, nullptr, nullptr);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500250 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500251 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
252 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
253 canvas->drawImage(image, 0, 0);
254##
255
256#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
257
258#Method ##
259
260# ------------------------------------------------------------------------------
261
Cary Clarka560c472017-11-27 10:44:06 -0500262#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
263 const GrBackendRenderTarget& backendRenderTarget,
264 GrSurfaceOrigin origin,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500265 SkColorType colorType,
266 sk_sp<SkColorSpace> colorSpace,
267 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400268#In Constructors
Cary Clark5ab52f62018-04-02 08:32:23 -0400269#Line # creates Surface from GPU render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400270#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500271
272#Example
273#ToDo remove !fiddle below once backEndTextureRenderTarget is available ##
274#Platform !fiddle gpu
275 SkPaint paint;
276 paint.setTextSize(32);
277 GrContext* context = canvas->getGrContext();
278 if (!context) {
279 canvas->drawString("GPU only!", 20, 40, paint);
280 return;
281 }
282 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context,
283 backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
284 nullptr, nullptr);
285 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500286 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
287 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
288 canvas->drawImage(image, 0, 0);
289##
290
291#SeeAlso MakeFromBackendTexture MakeRenderTarget
292
293#Method ##
294
295# ------------------------------------------------------------------------------
296
Cary Clarka560c472017-11-27 10:44:06 -0500297#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
298 const GrBackendTexture& backendTexture,
299 GrSurfaceOrigin origin,
300 int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500301 SkColorType colorType,
302 sk_sp<SkColorSpace> colorSpace,
303 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400304#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400305#Line # creates Surface from GPU back-end render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400306#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500307
308#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400309#ToDo example is bogus; gpuSurface should not make image ##
310#Platform gpu
311#Image 3
Brian Salomon49edccd2018-03-23 15:31:32 -0400312 SkPaint paint;
313 paint.setTextSize(32);
314 GrContext* context = canvas->getGrContext();
315 if (!context) {
316 canvas->drawString("GPU only!", 20, 40, paint);
317 return;
318 }
319 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(
320 context, backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
321 kRGBA_8888_SkColorType, nullptr, nullptr);
322 auto surfaceCanvas = gpuSurface->getCanvas();
323 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
324 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
325 canvas->drawImage(image, 0, 0);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500326##
327
328#SeeAlso MakeFromBackendRenderTarget MakeRenderTarget
329
330#Method ##
331
332# ------------------------------------------------------------------------------
333
Cary Clarka560c472017-11-27 10:44:06 -0500334#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
335 const SkImageInfo& imageInfo,
336 int sampleCount, GrSurfaceOrigin surfaceOrigin,
337 const SkSurfaceProps* surfaceProps,
338 bool shouldCreateWithMips = false)
Cary Clark61313f32018-10-08 14:57:48 -0400339#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500340#Line # creates Surface pointing to new GPU memory buffer ##
Cary Clark09d80c02018-10-31 12:14:03 -0400341#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500342
Cary Clarka560c472017-11-27 10:44:06 -0500343#Example
344#Platform gpu
345#Height 64
346 SkPaint paint;
347 paint.setTextSize(32);
348 GrContext* context = canvas->getGrContext();
349 if (!context) {
350 canvas->drawString("GPU only!", 20, 40, paint);
351 return;
352 }
353 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
354 for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
355 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
356 surfaceOrigin, nullptr));
357 auto surfaceCanvas = gpuSurface->getCanvas();
358 surfaceCanvas->clear(SK_ColorWHITE);
359 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
360 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
361 canvas->drawImage(image, 0, 0);
362 canvas->translate(0, 128);
363 }
364##
365
366#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
367
368#Method ##
369
370# ------------------------------------------------------------------------------
371
372#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
373 const SkImageInfo& imageInfo, int sampleCount,
374 const SkSurfaceProps* props)
Cary Clark09d80c02018-10-31 12:14:03 -0400375#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500376
377#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -0500378#Platform cpu gpu
Cary Clarka560c472017-11-27 10:44:06 -0500379#Description
380LCD text takes advantage of raster striping to improve resolution. Only one of
Cary Clark4855f782018-02-06 09:41:53 -0500381the four combinations is correct, depending on whether monitor LCD striping is
Cary Clarka560c472017-11-27 10:44:06 -0500382horizontal or vertical, and whether the order of the stripes is red blue green
383or red green blue.
384##
385void draw(SkCanvas* canvas) {
386 auto test_draw = [](SkCanvas* surfaceCanvas) -> void {
387 SkPaint paint;
388 paint.setAntiAlias(true);
389 paint.setLCDRenderText(true);
390 paint.setColor(0xFFBBBBBB);
391 surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint);
392 paint.setColor(SK_ColorWHITE);
393 paint.setTextSize(32);
394 surfaceCanvas->drawString("Pest", 0, 25, paint);
395 };
396 GrContext* context = canvas->getGrContext();
397 SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType);
Cary Clarka560c472017-11-27 10:44:06 -0500398 int y = 0;
399 for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry,
400 kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) {
401 SkSurfaceProps props(0, geometry);
Cary Clarka560c472017-11-27 10:44:06 -0500402 sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget(
403 context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props);
404 test_draw(surface->getCanvas());
405 surface->draw(canvas, 0, y, nullptr);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500406 sk_sp<SkImage> image(surface->makeImageSnapshot());
Cary Clarka560c472017-11-27 10:44:06 -0500407 SkAutoCanvasRestore acr(canvas, true);
408 canvas->scale(8, 8);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500409 canvas->drawImage(image, 12, y / 8);
Cary Clarka560c472017-11-27 10:44:06 -0500410 y += 64;
411 }
412}
413##
414
415#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
416
417#Method ##
418
419# ------------------------------------------------------------------------------
420
421#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
422 const SkImageInfo& imageInfo)
Cary Clark09d80c02018-10-31 12:14:03 -0400423#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500424
425#Example
426#Platform gpu
427 SkPaint paint;
428 paint.setTextSize(32);
429 GrContext* context = canvas->getGrContext();
430 if (!context) {
431 canvas->drawString("GPU only!", 20, 40, paint);
432 return;
433 }
434 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
435 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
436 auto surfaceCanvas = gpuSurface->getCanvas();
437 surfaceCanvas->clear(SK_ColorWHITE);
438 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
439 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
440 canvas->drawImage(image, 0, 0);
441##
442
443#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
444
445#Method ##
446
447# ------------------------------------------------------------------------------
448
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400449#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context,
450 const SkSurfaceCharacterization& characterization,
451 SkBudgeted budgeted)
Cary Clark09d80c02018-10-31 12:14:03 -0400452#Populate
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400453
Cary Clark5ab52f62018-04-02 08:32:23 -0400454#NoExample
455##
456
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400457#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
458
459#Method ##
460
461# ------------------------------------------------------------------------------
462
Cary Clarka560c472017-11-27 10:44:06 -0500463#Method static sk_sp<SkSurface> MakeNull(int width, int height)
464
Cary Clark61313f32018-10-08 14:57:48 -0400465#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500466#Line # creates Surface without backing pixels ##
Cary Clark09d80c02018-10-31 12:14:03 -0400467#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500468
469#Example
470 SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ?
471 '=' : '!');
472 const int w = 37;
473 const int h = 1000;
474 auto surf = SkSurface::MakeNull(w, h);
475 auto nullCanvas = surf->getCanvas();
476 nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws
477 SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ?
478 '=' : '!');
479#StdOut
480SkSurface::MakeNull(0, 0) == nullptr
481surf->makeImageSnapshot() == nullptr
482##
483##
484
485#SeeAlso MakeRaster MakeRenderTarget
486
487#Method ##
488
489# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500490#Subtopic Property
Cary Clark4855f782018-02-06 09:41:53 -0500491#Line # member values ##
492##
Cary Clarka560c472017-11-27 10:44:06 -0500493
494#Method int width() const
495
Cary Clark4855f782018-02-06 09:41:53 -0500496#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500497#Line # returns pixel column count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400498#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500499
500#Example
501 const int width = 37;
502 const int height = 1000;
503 auto surf = SkSurface::MakeNull(width, height);
504 auto nullCanvas = surf->getCanvas();
505 SkDebugf("surface width=%d canvas width=%d\n", surf->width(),
506 nullCanvas->getBaseLayerSize().fWidth);
507#StdOut
508surface width=37 canvas width=37
509##
510##
511
512#SeeAlso height()
513
514#Method ##
515
516# ------------------------------------------------------------------------------
517
518#Method int height() const
Cary Clark4855f782018-02-06 09:41:53 -0500519#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500520#Line # returns pixel row count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400521#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500522
523#Example
524 const int width = 37;
525 const int height = 1000;
526 auto surf = SkSurface::MakeNull(width, height);
527 auto nullCanvas = surf->getCanvas();
528 SkDebugf("surface height=%d canvas height=%d\n", surf->height(),
529 nullCanvas->getBaseLayerSize().fHeight);
530#StdOut
531surface height=1000 canvas height=1000
532##
533##
534
535#SeeAlso width()
536
537#Method ##
538
539# ------------------------------------------------------------------------------
540
541#Method uint32_t generationID()
Cary Clark4855f782018-02-06 09:41:53 -0500542#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500543#Line # returns unique ID ##
Cary Clark09d80c02018-10-31 12:14:03 -0400544#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500545
546#Example
547 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
548 for (int i = 0; i < 3; ++i) {
549 SkDebugf("surface generationID: %d\n", surface->generationID());
550 if (0 == i) {
551 surface->getCanvas()->drawColor(SK_ColorBLACK);
552 } else {
553 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
554 }
555 }
556#StdOut
557surface generationID: 1
558surface generationID: 2
559surface generationID: 3
560##
561##
562
563#SeeAlso notifyContentWillChange ContentChangeMode getCanvas
564
565#Method ##
566
567# ------------------------------------------------------------------------------
568
569#Enum ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400570#Line # parameter options for notifyContentWillChange ##
Cary Clarka560c472017-11-27 10:44:06 -0500571#Code
572 enum ContentChangeMode {
573 kDiscard_ContentChangeMode,
574 kRetain_ContentChangeMode,
575 };
576##
577
578ContentChangeMode members are parameters to notifyContentWillChange.
579
580#Const kDiscard_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400581#Line # discards surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500582Pass to notifyContentWillChange to discard surface contents when
583the surface is cleared or overwritten.
584##
585#Const kRetain_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400586#Line # preserves surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500587Pass to notifyContentWillChange when to preserve surface contents.
588If a snapshot has been generated, this copies the Surface contents.
589##
590
591#SeeAlso notifyContentWillChange generationID
592
593#Enum ##
594
595# ------------------------------------------------------------------------------
596
Cary Clark4855f782018-02-06 09:41:53 -0500597#ToDo not crazy about misc catagory -- hopefully will become clear with time
598##
Cary Clarka560c472017-11-27 10:44:06 -0500599
Cary Clark4855f782018-02-06 09:41:53 -0500600#Subtopic Miscellaneous
Cary Clark4855f782018-02-06 09:41:53 -0500601#Line # other functions ##
602##
603
604#Method void notifyContentWillChange(ContentChangeMode mode)
605#In Miscellaneous
Cary Clarkab2621d2018-01-30 10:08:57 -0500606#Line # notifies that contents will be changed outside of Skia ##
Cary Clarka560c472017-11-27 10:44:06 -0500607Notifies that Surface contents will be changed by code outside of Skia.
608Subsequent calls to generationID return a different value.
609
610mode is normally passed as kRetain_ContentChangeMode.
611
612#Private
Cary Clark682c58d2018-05-16 07:07:07 -0400613Can we deprecate this?
Cary Clarka560c472017-11-27 10:44:06 -0500614##
615
616#Param mode one of: kDiscard_ContentChangeMode, kRetain_ContentChangeMode ##
617
618#Example
619 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
620 for (int i = 0; i < 3; ++i) {
621 SkDebugf("surface generationID: %d\n", surface->generationID());
622 if (0 == i) {
623 surface->getCanvas()->drawColor(SK_ColorBLACK);
624 } else {
625 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
626 }
627 }
628##
629
630#SeeAlso ContentChangeMode generationID
631
632#Method ##
633
634# ------------------------------------------------------------------------------
635
636#Enum BackendHandleAccess
Cary Clark682c58d2018-05-16 07:07:07 -0400637#Line # options to read and write back-end object ##
Cary Clarka560c472017-11-27 10:44:06 -0500638#Code
639 enum BackendHandleAccess {
640 kFlushRead_BackendHandleAccess,
641 kFlushWrite_BackendHandleAccess,
642 kDiscardWrite_BackendHandleAccess,
643 };
Cary Clark7cfcbca2018-01-04 16:11:51 -0500644
645 static const BackendHandleAccess kFlushRead_TextureHandleAccess =
646 kFlushRead_BackendHandleAccess;
647 static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
648 kFlushWrite_BackendHandleAccess;
649 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
650 kDiscardWrite_BackendHandleAccess;
Cary Clarka560c472017-11-27 10:44:06 -0500651##
652
Cary Clark3cd22cc2017-12-01 11:49:58 -0500653#Const kFlushRead_BackendHandleAccess 0
Cary Clark682c58d2018-05-16 07:07:07 -0400654#Line # back-end object is readable ##
Cary Clarka560c472017-11-27 10:44:06 -0500655Caller may read from the back-end object.
656##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500657#Const kFlushWrite_BackendHandleAccess 1
Cary Clark682c58d2018-05-16 07:07:07 -0400658#Line # back-end object is writable ##
Cary Clarka560c472017-11-27 10:44:06 -0500659Caller may write to the back-end object.
660##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500661#Const kDiscardWrite_BackendHandleAccess 2
Cary Clark682c58d2018-05-16 07:07:07 -0400662#Line # back-end object must be overwritten ##
Cary Clarka560c472017-11-27 10:44:06 -0500663Caller must overwrite the entire back-end object.
664##
665
Cary Clark7cfcbca2018-01-04 16:11:51 -0500666#Const kFlushRead_TextureHandleAccess 0
Cary Clark682c58d2018-05-16 07:07:07 -0400667#Deprecated
Cary Clark7cfcbca2018-01-04 16:11:51 -0500668##
Cary Clark7cfcbca2018-01-04 16:11:51 -0500669#Const kFlushWrite_TextureHandleAccess 1
Cary Clark682c58d2018-05-16 07:07:07 -0400670#Deprecated
Cary Clark7cfcbca2018-01-04 16:11:51 -0500671##
Cary Clark7cfcbca2018-01-04 16:11:51 -0500672#Const kDiscardWrite_TextureHandleAccess 2
Cary Clark682c58d2018-05-16 07:07:07 -0400673#Deprecated
Cary Clark7cfcbca2018-01-04 16:11:51 -0500674##
Cary Clark7cfcbca2018-01-04 16:11:51 -0500675
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# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500815#Subtopic Pixels
Cary Clark4855f782018-02-06 09:41:53 -0500816#Line # functions with pixel access ##
817##
Cary Clarka560c472017-11-27 10:44:06 -0500818
819#Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
Cary Clark4855f782018-02-06 09:41:53 -0500820#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500821#Line # draws Surface contents to canvas ##
Cary Clark09d80c02018-10-31 12:14:03 -0400822#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500823
824#Example
825#Height 64
826 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
827 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
828 big->getCanvas()->clear(SK_ColorRED);
829 lil->getCanvas()->clear(SK_ColorBLACK);
830 lil->draw(big->getCanvas(), 16, 16, nullptr);
831 SkPixmap pixmap;
832 if (big->peekPixels(&pixmap)) {
833 SkBitmap bigBits;
834 bigBits.installPixels(pixmap);
835 canvas->drawBitmap(bigBits, 0, 0);
836 }
837##
838
839#SeeAlso makeImageSnapshot getCanvas
840
841#Method ##
842
843# ------------------------------------------------------------------------------
844
845#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark4855f782018-02-06 09:41:53 -0500846#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500847#Line # copies Surface parameters to Pixmap ##
Cary Clark09d80c02018-10-31 12:14:03 -0400848#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500849
850#Example
851#Height 64
852 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
853 auto surfCanvas = surf->getCanvas();
854 surfCanvas->clear(SK_ColorRED);
855 SkPaint paint;
856 paint.setTextSize(40);
857 surfCanvas->drawString("&", 16, 48, paint);
858 SkPixmap pixmap;
859 if (surf->peekPixels(&pixmap)) {
860 SkBitmap surfBits;
861 surfBits.installPixels(pixmap);
862 canvas->drawBitmap(surfBits, 0, 0);
863 }
864##
865
Mike Reed4c790bd2018-02-08 14:10:40 -0500866#SeeAlso readPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500867
868#Method ##
869
870# ------------------------------------------------------------------------------
871
872#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY)
Cary Clark4855f782018-02-06 09:41:53 -0500873#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500874#Line # copies Rect of pixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500875Copies Rect of pixels to dst.
876
Cary Clarkac47b882018-01-11 10:35:44 -0500877Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500878Destination Rect corners are (0, 0) and (dst.width(), dst.height()).
879Copies each readable pixel intersecting both rectangles, without scaling,
880converting to dst.colorType() and dst.alphaType() if required.
881
882Pixels are readable when Surface is raster, or backed by a GPU.
883
884The destination pixel storage must be allocated by the caller.
885
Cary Clark2dc84ad2018-01-26 12:56:22 -0500886Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500887do not match. Only pixels within both source and destination rectangles
888are copied. dst contents outside Rect intersection are unchanged.
889
890Pass negative values for srcX or srcY to offset pixels across or down destination.
891
892Does not copy, and returns false if:
893
894#List
895# Source and destination rectangles do not intersect. ##
896# Pixmap pixels could not be allocated. ##
897# dst.rowBytes() is too small to contain one row of pixels. ##
898##
899
900#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -0400901#Param srcX offset into readable pixels on x-axis; may be negative ##
902#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500903
904#Return true if pixels were copied ##
905
906#Example
907#Height 32
908 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
909 auto surfCanvas = surf->getCanvas();
910 surfCanvas->clear(SK_ColorRED);
911 SkPaint paint;
912 paint.setTextSize(40);
913 surfCanvas->drawString("&", 0, 32, paint);
914 std::vector<SkPMColor> storage;
915 storage.resize(surf->width() * surf->height());
916 SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(),
917 surf->width() * sizeof(storage[0]));
918 if (surf->readPixels(pixmap, 0, 0)) {
919 SkBitmap surfBits;
920 surfBits.installPixels(pixmap);
921 canvas->drawBitmap(surfBits, 0, 0);
922 }
923##
924
Mike Reed4c790bd2018-02-08 14:10:40 -0500925#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500926
927#Method ##
928
929# ------------------------------------------------------------------------------
930
931#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
932 int srcX, int srcY)
933
934Copies Rect of pixels from Canvas into dstPixels.
935
Cary Clarkac47b882018-01-11 10:35:44 -0500936Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500937Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
938Copies each readable pixel intersecting both rectangles, without scaling,
939converting to dstInfo.colorType() and dstInfo.alphaType() if required.
940
941Pixels are readable when Surface is raster, or backed by a GPU.
942
943The destination pixel storage must be allocated by the caller.
944
Cary Clark2dc84ad2018-01-26 12:56:22 -0500945Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500946do not match. Only pixels within both source and destination rectangles
947are copied. dstPixels contents outside Rect intersection are unchanged.
948
949Pass negative values for srcX or srcY to offset pixels across or down destination.
950
951Does not copy, and returns false if:
952
953#List
954# Source and destination rectangles do not intersect. ##
955# Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
956# dstRowBytes is too small to contain one row of pixels. ##
957##
958
Cary Clark2dc84ad2018-01-26 12:56:22 -0500959#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500960#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
961#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400962#Param srcX offset into readable pixels on x-axis; may be negative ##
963#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500964
965#Return true if pixels were copied ##
966
967#Example
968#Height 64
969#Description
970 A black oval drawn on a red background provides an image to copy.
971 readPixels copies one quarter of the Surface into each of the four corners.
972 The copied quarter ovals overdraw the original oval.
973##
974 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
975 auto surfCanvas = surf->getCanvas();
976 surfCanvas->clear(SK_ColorRED);
977 SkPaint paint;
978 surfCanvas->drawOval({4, 8, 58, 54}, paint);
979 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
980 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
981 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
982 for (int x : { 32, -32 } ) {
983 for (int y : { 32, -32 } ) {
984 surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Cary Clark682c58d2018-05-16 07:07:07 -0400985 }
Cary Clarka560c472017-11-27 10:44:06 -0500986 }
987 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
988 canvas->drawImage(image, 0, 0);
989##
990
Mike Reed4c790bd2018-02-08 14:10:40 -0500991#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500992
993#Method ##
994
995# ------------------------------------------------------------------------------
996
997#Method bool readPixels(const SkBitmap& dst, int srcX, int srcY)
998
999Copies Rect of pixels from Surface into bitmap.
1000
Cary Clarkac47b882018-01-11 10:35:44 -05001001Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -05001002Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
1003Copies each readable pixel intersecting both rectangles, without scaling,
1004converting to bitmap.colorType() and bitmap.alphaType() if required.
1005
1006Pixels are readable when Surface is raster, or backed by a GPU.
1007
1008The destination pixel storage must be allocated by the caller.
1009
Cary Clark2dc84ad2018-01-26 12:56:22 -05001010Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -05001011do not match. Only pixels within both source and destination rectangles
1012are copied. dst contents outside Rect intersection are unchanged.
1013
1014Pass negative values for srcX or srcY to offset pixels across or down destination.
1015
1016Does not copy, and returns false if:
1017
1018#List
1019# Source and destination rectangles do not intersect. ##
1020# Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ##
1021# dst pixels could not be allocated. ##
1022# dst.rowBytes() is too small to contain one row of pixels. ##
1023##
1024
1025#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001026#Param srcX offset into readable pixels on x-axis; may be negative ##
1027#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -05001028
1029#Return true if pixels were copied ##
1030
1031#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -05001032 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1033 auto surfCanvas = surf->getCanvas();
1034 surfCanvas->clear(SK_ColorGREEN);
1035 SkPaint paint;
1036 surfCanvas->drawOval({2, 10, 58, 54}, paint);
1037 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1038 SkBitmap bitmap;
1039 bitmap.setInfo(info);
1040 bitmap.allocPixels();
1041 for (int x : { 32, -32 } ) {
1042 for (int y : { 32, -32 } ) {
1043 surf->readPixels(bitmap, x, y);
Cary Clark682c58d2018-05-16 07:07:07 -04001044 }
Cary Clark3cd22cc2017-12-01 11:49:58 -05001045 }
1046 canvas->drawBitmap(bitmap, 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001047##
1048
Mike Reed4c790bd2018-02-08 14:10:40 -05001049#SeeAlso peekPixels writePixels
1050
1051#Method ##
1052
1053# ------------------------------------------------------------------------------
1054
1055#Method void writePixels(const SkPixmap& src, int dstX, int dstY)
Cary Clark56356312018-02-08 14:45:18 -05001056#In Pixels
1057#Line # copies Rect of pixels ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001058Copies Rect of pixels from the src Pixmap to the Surface.
1059
1060Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark682c58d2018-05-16 07:07:07 -04001061Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001062#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001063
Mike Reed4c790bd2018-02-08 14:10:40 -05001064Copies each readable pixel intersecting both rectangles, without scaling,
1065converting to Surface colorType() and Surface alphaType() if required.
1066
1067#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001068#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1069#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001070
1071#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001072#Image 4
1073#Height 96
Cary Clark09d80c02018-10-31 12:14:03 -04001074 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1075 auto surfCanvas = surf->getCanvas();
1076 surfCanvas->clear(SK_ColorRED);
1077 SkPaint paint;
1078 paint.setTextSize(40);
1079 surfCanvas->drawString("&", 16, 40, paint);
1080 SkPixmap pixmap;
1081 if (surf->peekPixels(&pixmap)) {
1082 surf->writePixels(pixmap, 25, 25);
1083 sk_sp<SkImage> image(surf->makeImageSnapshot());
1084 canvas->drawImage(image, 0, 0);
Cary Clarkffb3d682018-05-17 12:17:28 -04001085 }
Mike Reed4c790bd2018-02-08 14:10:40 -05001086##
1087
1088#SeeAlso readPixels peekPixels
1089
1090#Method ##
1091
1092# ------------------------------------------------------------------------------
1093
1094#Method void writePixels(const SkBitmap& src, int dstX, int dstY)
1095
1096Copies Rect of pixels from the src Bitmap to the Surface.
1097
1098Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark56356312018-02-08 14:45:18 -05001099Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001100#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001101
Mike Reed4c790bd2018-02-08 14:10:40 -05001102Copies each readable pixel intersecting both rectangles, without scaling,
1103converting to Surface colorType() and Surface alphaType() if required.
1104
1105#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001106#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1107#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001108
1109#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001110#Image 4
1111#Height 96
1112 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1113 auto surfCanvas = surf->getCanvas();
1114 surfCanvas->clear(SK_ColorGREEN);
1115 surf->writePixels(source, 25, 25);
1116 sk_sp<SkImage> image(surf->makeImageSnapshot());
1117 canvas->drawImage(image, 0, 0);
Mike Reed4c790bd2018-02-08 14:10:40 -05001118##
1119
1120#SeeAlso readPixels peekPixels
Cary Clarka560c472017-11-27 10:44:06 -05001121
1122#Method ##
1123
1124# ------------------------------------------------------------------------------
1125
1126#Method const SkSurfaceProps& props() const
Cary Clark4855f782018-02-06 09:41:53 -05001127#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05001128#Line # returns Surface_Properties ##
Cary Clark09d80c02018-10-31 12:14:03 -04001129#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001130
1131#Example
1132 const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" };
Cary Clark3cd22cc2017-12-01 11:49:58 -05001133 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001134 SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]);
1135#StdOut
1136surf.props(): kRGB_H_SkPixelGeometry
1137##
1138##
1139
1140#SeeAlso SkSurfaceProps
1141
1142#Method ##
1143
1144# ------------------------------------------------------------------------------
1145
1146#Method void prepareForExternalIO()
Cary Clark4855f782018-02-06 09:41:53 -05001147#Deprecated soon
Cary Clarka560c472017-11-27 10:44:06 -05001148#Method ##
1149
1150# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05001151#Subtopic Utility
Cary Clark4855f782018-02-06 09:41:53 -05001152#Line # rarely called management functions ##
1153##
Cary Clarka560c472017-11-27 10:44:06 -05001154
1155#Method void flush()
Cary Clark4855f782018-02-06 09:41:53 -05001156#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001157#Line # resolves pending I/O ##
Cary Clark09d80c02018-10-31 12:14:03 -04001158#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001159
1160#NoExample
1161##
1162
1163#SeeAlso GrBackendSemaphore
1164
1165#Method ##
1166
1167# ------------------------------------------------------------------------------
1168
1169#Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
1170 GrBackendSemaphore signalSemaphores[])
Cary Clark4855f782018-02-06 09:41:53 -05001171#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001172#Line # resolves pending I/O, and signal ##
Cary Clark09d80c02018-10-31 12:14:03 -04001173#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001174
1175#NoExample
1176##
1177
1178#SeeAlso wait GrBackendSemaphore
1179
1180#Method ##
1181
1182# ------------------------------------------------------------------------------
1183
1184#Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores)
Cary Clark4855f782018-02-06 09:41:53 -05001185#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001186#Line # pauses commands until signaled ##
Cary Clark09d80c02018-10-31 12:14:03 -04001187#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001188
Cary Clark1a8d7622018-03-05 13:26:16 -05001189#NoExample
Cary Clarka560c472017-11-27 10:44:06 -05001190#ToDo this is copy and paste silliness masquerading as an example. Probably need gpu
1191 globals and definitely need gpu expertise to make a real example out of this
Cary Clark36122e72018-04-26 10:59:57 -04001192 also, note need to replace GrBackendObject with GrBackendTexture
Cary Clarka560c472017-11-27 10:44:06 -05001193 ##
Cary Clark1a8d7622018-03-05 13:26:16 -05001194#Platform gpu
Cary Clarka560c472017-11-27 10:44:06 -05001195#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001196 SkPaint paint;
1197 paint.setTextSize(32);
1198 GrContext* context = canvas->getGrContext();
1199 if (!context) {
1200 canvas->drawString("GPU only!", 20, 40, paint);
1201 return;
1202 }
Cary Clarka560c472017-11-27 10:44:06 -05001203 GrBackendSemaphore semaphore;
Cary Clark3cd22cc2017-12-01 11:49:58 -05001204 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
1205 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001206 surface->flushAndSignalSemaphores(1, &semaphore);
1207 sk_sp<SkImage> image = surface->makeImageSnapshot();
Greg Daniel6d138bf2018-05-03 16:54:03 -04001208 GrBackendTexture backendTex = image->getBackendTexture(false); // unused
1209 SkASSERT(backendTex.isValid());
Cary Clarka560c472017-11-27 10:44:06 -05001210 const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64,
1211 kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1212 sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
1213 childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr));
1214 GrBackendTexture backendTexture;
1215 sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context,
1216 backendTexture, // undefined
1217 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr);
1218 SkCanvas* childCanvas = childSurface->getCanvas();
1219 childCanvas->clear(SK_ColorRED);
1220 childSurface->wait(1, &semaphore);
1221 childCanvas->drawImage(childImage, 32, 0);
Cary Clark3cd22cc2017-12-01 11:49:58 -05001222 childSurface->draw(canvas, 0, 0, nullptr);
Cary Clarka560c472017-11-27 10:44:06 -05001223##
1224
1225#SeeAlso flushAndSignalSemaphores GrBackendSemaphore
1226
1227#Method ##
1228
1229# ------------------------------------------------------------------------------
1230
1231#Method bool characterize(SkSurfaceCharacterization* characterization) const
Cary Clark4855f782018-02-06 09:41:53 -05001232#In Utility
1233#Line # sets Surface_Characterization for threaded GPU processing ##
Cary Clark09d80c02018-10-31 12:14:03 -04001234#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001235
1236#Example
1237#Platform gpu
1238#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001239 SkPaint paint;
1240 paint.setTextSize(32);
1241 GrContext* context = canvas->getGrContext();
1242 if (!context) {
1243 canvas->drawString("GPU only!", 20, 40, paint);
1244 return;
1245 }
1246 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1247 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
1248 SkSurfaceCharacterization characterization;
1249 if (!gpuSurface->characterize(&characterization)) {
1250 canvas->drawString("characterization unsupported", 20, 40, paint);
1251 return;
1252 }
Cary Clark682c58d2018-05-16 07:07:07 -04001253 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001254 SkDeferredDisplayListRecorder recorder(characterization);
1255 SkCanvas* subCanvas = recorder.getCanvas();
1256 subCanvas->clear(SK_ColorGREEN);
1257 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1258 // end of threadable work
1259 gpuSurface->draw(displayList.get());
1260 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1261 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001262##
1263
1264#SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList
1265
1266#Method ##
1267
1268# ------------------------------------------------------------------------------
1269
Cary Clark2f466242017-12-11 16:03:17 -05001270#Method bool draw(SkDeferredDisplayList* deferredDisplayList)
Cary Clark09d80c02018-10-31 12:14:03 -04001271#Populate
Cary Clark2f466242017-12-11 16:03:17 -05001272
Cary Clarka560c472017-11-27 10:44:06 -05001273#Example
1274#Height 64
1275#Platform gpu cpu
Cary Clark3cd22cc2017-12-01 11:49:58 -05001276 SkPaint paint;
1277 paint.setTextSize(16);
1278 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64);
1279 SkSurfaceCharacterization characterization;
1280 if (!gpuSurface->characterize(&characterization)) {
1281 canvas->drawString("characterization unsupported", 20, 40, paint);
1282 return;
1283 }
Cary Clark682c58d2018-05-16 07:07:07 -04001284 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001285 SkDeferredDisplayListRecorder recorder(characterization);
1286 SkCanvas* subCanvas = recorder.getCanvas();
1287 subCanvas->clear(SK_ColorGREEN);
1288 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1289 // end of threadable work
1290 gpuSurface->draw(displayList.get());
1291 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1292 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001293##
1294
1295#SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList
1296
1297#Method ##
1298
1299#Class SkSurface ##
1300
1301#Topic Surface ##