blob: d5511442ef7e6c3ab0d149379e31fa0fb449811c [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
21#Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
22 size_t rowBytes,
23 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040024#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050025#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040026#Populate
Cary Clarka560c472017-11-27 10:44:06 -050027
28#Example
29void draw(SkCanvas* ) {
30 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
31 const size_t size = info.computeMinByteSize();
32 SkAutoTMalloc<SkPMColor> storage(size);
33 SkPMColor* pixels = storage.get();
34 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes()));
35 SkCanvas* canvas = surface->getCanvas();
36 canvas->clear(SK_ColorWHITE);
37 SkPMColor pmWhite = pixels[0];
38 SkPaint paint;
39 canvas->drawPoint(1, 1, paint);
40 canvas->flush(); // ensure that point was drawn
41 for (int y = 0; y < info.height(); ++y) {
42 for (int x = 0; x < info.width(); ++x) {
43 SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
44 }
45 SkDebugf("\n");
46 }
47}
48 #StdOut
49 ---
50 -x-
51 ---
52 ##
53##
54
55#SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect
56
57#Method ##
58
59# ------------------------------------------------------------------------------
60
61#Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels,
62 size_t rowBytes,
63 void (*releaseProc)(void* pixels, void* context),
64 void* context, const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -040065#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -050066#Line # creates Surface from SkImageInfo and Pixel_Storage ##
Cary Clark09d80c02018-10-31 12:14:03 -040067#Populate
Cary Clarka560c472017-11-27 10:44:06 -050068
69#Example
70#Function
71static void release_direct_surface_storage(void* pixels, void* context) {
72 if (pixels == context) {
73 SkDebugf("expected release context\n");
74 }
75 sk_free(pixels);
76}
77
78##
79void draw(SkCanvas* ) {
80 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
81 const size_t rowBytes = info.minRowBytes();
82 void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes));
83 sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes,
84 release_direct_surface_storage, pixels));
85 SkCanvas* canvas = surface->getCanvas();
86 canvas->clear(SK_ColorWHITE);
87 SkPMColor* colorPtr = (SkPMColor*) pixels;
88 SkPMColor pmWhite = colorPtr[0];
89 SkPaint paint;
90 canvas->drawPoint(1, 1, paint);
91 canvas->flush(); // ensure that point was drawn
92 for (int y = 0; y < info.height(); ++y) {
93 for (int x = 0; x < info.width(); ++x) {
94 SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x');
95 }
96 SkDebugf("\n");
97 }
98}
99#StdOut
100---
101-x-
102---
103expected release context
104##
105##
106
107#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster
108
109#Method ##
110
111# ------------------------------------------------------------------------------
112
113#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes,
114 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400115#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500116#Line # creates Surface from SkImageInfo ##
Cary Clark09d80c02018-10-31 12:14:03 -0400117#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500118
119#Example
120void draw(SkCanvas* ) {
121 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
122 const size_t rowBytes = 64;
123 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr));
124 SkCanvas* canvas = surface->getCanvas();
125 canvas->clear(SK_ColorWHITE);
126 SkPixmap pixmap;
127 if (surface->peekPixels(&pixmap)) {
128 const uint32_t* colorPtr = pixmap.addr32();
129 SkPMColor pmWhite = colorPtr[0];
130 SkPaint paint;
131 canvas->drawPoint(1, 1, paint);
132 canvas->flush(); // ensure that point was drawn
133 for (int y = 0; y < info.height(); ++y) {
134 for (int x = 0; x < info.width(); ++x) {
135 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
136 }
137 colorPtr += rowBytes / sizeof(colorPtr[0]);
138 SkDebugf("\n");
139 }
140 }
141}
142#StdOut
143---
144-x-
145---
146##
147##
148
149#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
150
151#Method ##
152
153# ------------------------------------------------------------------------------
154
155#Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo,
156 const SkSurfaceProps* props = nullptr)
Cary Clark09d80c02018-10-31 12:14:03 -0400157#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500158
159#Example
160void draw(SkCanvas* ) {
161 SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3);
162 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
163 SkCanvas* canvas = surface->getCanvas();
164 canvas->clear(SK_ColorWHITE);
165 SkPixmap pixmap;
166 if (surface->peekPixels(&pixmap)) {
167 const uint32_t* colorPtr = pixmap.addr32();
168 SkPMColor pmWhite = colorPtr[0];
169 SkPaint paint;
170 canvas->drawPoint(1, 1, paint);
171 canvas->flush(); // ensure that point was drawn
172 for (int y = 0; y < info.height(); ++y) {
173 for (int x = 0; x < info.width(); ++x) {
174 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
175 }
176 colorPtr += info.width();
177 SkDebugf("\n");
178 }
179 }
180}
181##
182
183#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
184
185#Method ##
186
187# ------------------------------------------------------------------------------
188
189#Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height,
190 const SkSurfaceProps* surfaceProps = nullptr)
Cary Clark61313f32018-10-08 14:57:48 -0400191#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500192#Line # creates Surface from width, height matching output ##
Cary Clark09d80c02018-10-31 12:14:03 -0400193#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500194
195#Example
196void draw(SkCanvas* ) {
197 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3));
198 SkCanvas* canvas = surface->getCanvas();
199 canvas->clear(SK_ColorWHITE);
200 SkPixmap pixmap;
201 if (surface->peekPixels(&pixmap)) {
202 const uint32_t* colorPtr = pixmap.addr32();
203 SkPMColor pmWhite = colorPtr[0];
204 SkPaint paint;
205 canvas->drawPoint(1, 1, paint);
206 canvas->flush(); // ensure that point was drawn
207 for (int y = 0; y < surface->height(); ++y) {
208 for (int x = 0; x < surface->width(); ++x) {
209 SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x');
210 }
211 colorPtr += surface->width();
212 SkDebugf("\n");
213 }
214 }
215}
216#StdOut
217---
218-x-
219---
220##
221##
222
223#SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc
224
225#Method ##
226
227# ------------------------------------------------------------------------------
228
229#Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context,
230 const GrBackendTexture& backendTexture,
231 GrSurfaceOrigin origin, int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500232 SkColorType colorType,
233 sk_sp<SkColorSpace> colorSpace,
234 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400235#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400236#Line # creates Surface from GPU texture ##
Cary Clark09d80c02018-10-31 12:14:03 -0400237#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500238
239#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400240#Platform gpu cpu
241#Image 3
Cary Clarkf059e7c2017-12-20 14:53:21 -0500242 SkPaint paint;
243 paint.setTextSize(32);
244 GrContext* context = canvas->getGrContext();
245 if (!context) {
246 canvas->drawString("GPU only!", 20, 40, paint);
247 return;
248 }
249 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context,
Cary Clark06c20f32018-03-20 15:53:27 -0400250 backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
251 kRGBA_8888_SkColorType, nullptr, nullptr);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500252 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500253 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
254 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
255 canvas->drawImage(image, 0, 0);
256##
257
258#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
259
260#Method ##
261
262# ------------------------------------------------------------------------------
263
Cary Clarka560c472017-11-27 10:44:06 -0500264#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
265 const GrBackendRenderTarget& backendRenderTarget,
266 GrSurfaceOrigin origin,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500267 SkColorType colorType,
268 sk_sp<SkColorSpace> colorSpace,
269 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400270#In Constructors
Cary Clark5ab52f62018-04-02 08:32:23 -0400271#Line # creates Surface from GPU render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400272#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500273
274#Example
275#ToDo remove !fiddle below once backEndTextureRenderTarget is available ##
276#Platform !fiddle gpu
277 SkPaint paint;
278 paint.setTextSize(32);
279 GrContext* context = canvas->getGrContext();
280 if (!context) {
281 canvas->drawString("GPU only!", 20, 40, paint);
282 return;
283 }
284 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context,
285 backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
286 nullptr, nullptr);
287 auto surfaceCanvas = gpuSurface->getCanvas();
Cary Clarkf059e7c2017-12-20 14:53:21 -0500288 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
289 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
290 canvas->drawImage(image, 0, 0);
291##
292
293#SeeAlso MakeFromBackendTexture MakeRenderTarget
294
295#Method ##
296
297# ------------------------------------------------------------------------------
298
Cary Clarka560c472017-11-27 10:44:06 -0500299#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
300 const GrBackendTexture& backendTexture,
301 GrSurfaceOrigin origin,
302 int sampleCnt,
Cary Clarkf059e7c2017-12-20 14:53:21 -0500303 SkColorType colorType,
304 sk_sp<SkColorSpace> colorSpace,
305 const SkSurfaceProps* surfaceProps)
Cary Clark61313f32018-10-08 14:57:48 -0400306#In Constructors
Cary Clark06c20f32018-03-20 15:53:27 -0400307#Line # creates Surface from GPU back-end render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400308#Populate
Cary Clarkf059e7c2017-12-20 14:53:21 -0500309
310#Example
Cary Clark06c20f32018-03-20 15:53:27 -0400311#ToDo example is bogus; gpuSurface should not make image ##
312#Platform gpu
313#Image 3
Brian Salomon49edccd2018-03-23 15:31:32 -0400314 SkPaint paint;
315 paint.setTextSize(32);
316 GrContext* context = canvas->getGrContext();
317 if (!context) {
318 canvas->drawString("GPU only!", 20, 40, paint);
319 return;
320 }
321 sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget(
322 context, backEndTexture, kTopLeft_GrSurfaceOrigin, 0,
323 kRGBA_8888_SkColorType, nullptr, nullptr);
324 auto surfaceCanvas = gpuSurface->getCanvas();
325 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
326 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
327 canvas->drawImage(image, 0, 0);
Cary Clarkf059e7c2017-12-20 14:53:21 -0500328##
329
330#SeeAlso MakeFromBackendRenderTarget MakeRenderTarget
331
332#Method ##
333
334# ------------------------------------------------------------------------------
335
Cary Clarka560c472017-11-27 10:44:06 -0500336#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
337 const SkImageInfo& imageInfo,
338 int sampleCount, GrSurfaceOrigin surfaceOrigin,
339 const SkSurfaceProps* surfaceProps,
340 bool shouldCreateWithMips = false)
Cary Clark61313f32018-10-08 14:57:48 -0400341#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500342#Line # creates Surface pointing to new GPU memory buffer ##
Cary Clark09d80c02018-10-31 12:14:03 -0400343#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500344
Cary Clarka560c472017-11-27 10:44:06 -0500345#Example
346#Platform gpu
347#Height 64
348 SkPaint paint;
349 paint.setTextSize(32);
350 GrContext* context = canvas->getGrContext();
351 if (!context) {
352 canvas->drawString("GPU only!", 20, 40, paint);
353 return;
354 }
355 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
356 for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) {
357 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
358 surfaceOrigin, nullptr));
359 auto surfaceCanvas = gpuSurface->getCanvas();
360 surfaceCanvas->clear(SK_ColorWHITE);
361 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
362 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
363 canvas->drawImage(image, 0, 0);
364 canvas->translate(0, 128);
365 }
366##
367
368#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
369
370#Method ##
371
372# ------------------------------------------------------------------------------
373
374#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
375 const SkImageInfo& imageInfo, int sampleCount,
376 const SkSurfaceProps* props)
Cary Clark09d80c02018-10-31 12:14:03 -0400377#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500378
379#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -0500380#Platform cpu gpu
Cary Clarka560c472017-11-27 10:44:06 -0500381#Description
382LCD text takes advantage of raster striping to improve resolution. Only one of
Cary Clark4855f782018-02-06 09:41:53 -0500383the four combinations is correct, depending on whether monitor LCD striping is
Cary Clarka560c472017-11-27 10:44:06 -0500384horizontal or vertical, and whether the order of the stripes is red blue green
385or red green blue.
386##
387void draw(SkCanvas* canvas) {
388 auto test_draw = [](SkCanvas* surfaceCanvas) -> void {
389 SkPaint paint;
390 paint.setAntiAlias(true);
391 paint.setLCDRenderText(true);
392 paint.setColor(0xFFBBBBBB);
393 surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint);
394 paint.setColor(SK_ColorWHITE);
395 paint.setTextSize(32);
396 surfaceCanvas->drawString("Pest", 0, 25, paint);
397 };
398 GrContext* context = canvas->getGrContext();
399 SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType);
Cary Clarka560c472017-11-27 10:44:06 -0500400 int y = 0;
401 for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry,
402 kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) {
403 SkSurfaceProps props(0, geometry);
Cary Clarka560c472017-11-27 10:44:06 -0500404 sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget(
405 context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props);
406 test_draw(surface->getCanvas());
407 surface->draw(canvas, 0, y, nullptr);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500408 sk_sp<SkImage> image(surface->makeImageSnapshot());
Cary Clarka560c472017-11-27 10:44:06 -0500409 SkAutoCanvasRestore acr(canvas, true);
410 canvas->scale(8, 8);
Cary Clark3cd22cc2017-12-01 11:49:58 -0500411 canvas->drawImage(image, 12, y / 8);
Cary Clarka560c472017-11-27 10:44:06 -0500412 y += 64;
413 }
414}
415##
416
417#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
418
419#Method ##
420
421# ------------------------------------------------------------------------------
422
423#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
424 const SkImageInfo& imageInfo)
Cary Clark09d80c02018-10-31 12:14:03 -0400425#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500426
427#Example
428#Platform gpu
429 SkPaint paint;
430 paint.setTextSize(32);
431 GrContext* context = canvas->getGrContext();
432 if (!context) {
433 canvas->drawString("GPU only!", 20, 40, paint);
434 return;
435 }
436 SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType);
437 auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
438 auto surfaceCanvas = gpuSurface->getCanvas();
439 surfaceCanvas->clear(SK_ColorWHITE);
440 surfaceCanvas->drawString("GPU rocks!", 20, 40, paint);
441 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
442 canvas->drawImage(image, 0, 0);
443##
444
445#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
446
447#Method ##
448
449# ------------------------------------------------------------------------------
450
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400451#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context,
452 const SkSurfaceCharacterization& characterization,
453 SkBudgeted budgeted)
Cary Clark09d80c02018-10-31 12:14:03 -0400454#Populate
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400455
Cary Clark5ab52f62018-04-02 08:32:23 -0400456#NoExample
457##
458
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400459#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
460
461#Method ##
462
463# ------------------------------------------------------------------------------
464
Cary Clarka560c472017-11-27 10:44:06 -0500465#Method static sk_sp<SkSurface> MakeNull(int width, int height)
466
Cary Clark61313f32018-10-08 14:57:48 -0400467#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500468#Line # creates Surface without backing pixels ##
Cary Clark09d80c02018-10-31 12:14:03 -0400469#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500470
471#Example
472 SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ?
473 '=' : '!');
474 const int w = 37;
475 const int h = 1000;
476 auto surf = SkSurface::MakeNull(w, h);
477 auto nullCanvas = surf->getCanvas();
478 nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws
479 SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ?
480 '=' : '!');
481#StdOut
482SkSurface::MakeNull(0, 0) == nullptr
483surf->makeImageSnapshot() == nullptr
484##
485##
486
487#SeeAlso MakeRaster MakeRenderTarget
488
489#Method ##
490
491# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500492#Subtopic Property
Cary Clark4855f782018-02-06 09:41:53 -0500493#Line # member values ##
494##
Cary Clarka560c472017-11-27 10:44:06 -0500495
496#Method int width() const
497
Cary Clark4855f782018-02-06 09:41:53 -0500498#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500499#Line # returns pixel column count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400500#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500501
502#Example
503 const int width = 37;
504 const int height = 1000;
505 auto surf = SkSurface::MakeNull(width, height);
506 auto nullCanvas = surf->getCanvas();
507 SkDebugf("surface width=%d canvas width=%d\n", surf->width(),
508 nullCanvas->getBaseLayerSize().fWidth);
509#StdOut
510surface width=37 canvas width=37
511##
512##
513
514#SeeAlso height()
515
516#Method ##
517
518# ------------------------------------------------------------------------------
519
520#Method int height() const
Cary Clark4855f782018-02-06 09:41:53 -0500521#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500522#Line # returns pixel row count ##
Cary Clark09d80c02018-10-31 12:14:03 -0400523#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500524
525#Example
526 const int width = 37;
527 const int height = 1000;
528 auto surf = SkSurface::MakeNull(width, height);
529 auto nullCanvas = surf->getCanvas();
530 SkDebugf("surface height=%d canvas height=%d\n", surf->height(),
531 nullCanvas->getBaseLayerSize().fHeight);
532#StdOut
533surface height=1000 canvas height=1000
534##
535##
536
537#SeeAlso width()
538
539#Method ##
540
541# ------------------------------------------------------------------------------
542
543#Method uint32_t generationID()
Cary Clark4855f782018-02-06 09:41:53 -0500544#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500545#Line # returns unique ID ##
Cary Clark09d80c02018-10-31 12:14:03 -0400546#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500547
548#Example
549 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
550 for (int i = 0; i < 3; ++i) {
551 SkDebugf("surface generationID: %d\n", surface->generationID());
552 if (0 == i) {
553 surface->getCanvas()->drawColor(SK_ColorBLACK);
554 } else {
555 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
556 }
557 }
558#StdOut
559surface generationID: 1
560surface generationID: 2
561surface generationID: 3
562##
563##
564
565#SeeAlso notifyContentWillChange ContentChangeMode getCanvas
566
567#Method ##
568
569# ------------------------------------------------------------------------------
570
571#Enum ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400572#Line # parameter options for notifyContentWillChange ##
Cary Clarka560c472017-11-27 10:44:06 -0500573#Code
574 enum ContentChangeMode {
575 kDiscard_ContentChangeMode,
576 kRetain_ContentChangeMode,
577 };
578##
579
580ContentChangeMode members are parameters to notifyContentWillChange.
581
582#Const kDiscard_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400583#Line # discards surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500584Pass to notifyContentWillChange to discard surface contents when
585the surface is cleared or overwritten.
586##
587#Const kRetain_ContentChangeMode
Cary Clark682c58d2018-05-16 07:07:07 -0400588#Line # preserves surface on change ##
Cary Clarka560c472017-11-27 10:44:06 -0500589Pass to notifyContentWillChange when to preserve surface contents.
590If a snapshot has been generated, this copies the Surface contents.
591##
592
593#SeeAlso notifyContentWillChange generationID
594
595#Enum ##
596
597# ------------------------------------------------------------------------------
598
Cary Clark4855f782018-02-06 09:41:53 -0500599#ToDo not crazy about misc catagory -- hopefully will become clear with time
600##
Cary Clarka560c472017-11-27 10:44:06 -0500601
Cary Clark4855f782018-02-06 09:41:53 -0500602#Subtopic Miscellaneous
Cary Clark4855f782018-02-06 09:41:53 -0500603#Line # other functions ##
604##
605
606#Method void notifyContentWillChange(ContentChangeMode mode)
607#In Miscellaneous
Cary Clarkab2621d2018-01-30 10:08:57 -0500608#Line # notifies that contents will be changed outside of Skia ##
Cary Clarkabaffd82018-11-15 08:25:12 -0500609#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500610
611#Example
612 auto surface = SkSurface::MakeRasterN32Premul(1, 1);
613 for (int i = 0; i < 3; ++i) {
614 SkDebugf("surface generationID: %d\n", surface->generationID());
615 if (0 == i) {
616 surface->getCanvas()->drawColor(SK_ColorBLACK);
617 } else {
618 surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
619 }
620 }
621##
622
623#SeeAlso ContentChangeMode generationID
624
625#Method ##
626
627# ------------------------------------------------------------------------------
628
629#Enum BackendHandleAccess
Cary Clark682c58d2018-05-16 07:07:07 -0400630#Line # options to read and write back-end object ##
Cary Clarka560c472017-11-27 10:44:06 -0500631#Code
632 enum BackendHandleAccess {
633 kFlushRead_BackendHandleAccess,
634 kFlushWrite_BackendHandleAccess,
635 kDiscardWrite_BackendHandleAccess,
636 };
Cary Clark7cfcbca2018-01-04 16:11:51 -0500637
638 static const BackendHandleAccess kFlushRead_TextureHandleAccess =
639 kFlushRead_BackendHandleAccess;
640 static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
641 kFlushWrite_BackendHandleAccess;
642 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
643 kDiscardWrite_BackendHandleAccess;
Cary Clarka560c472017-11-27 10:44:06 -0500644##
645
Cary Clark3cd22cc2017-12-01 11:49:58 -0500646#Const kFlushRead_BackendHandleAccess 0
Cary Clark682c58d2018-05-16 07:07:07 -0400647#Line # back-end object is readable ##
Cary Clarka560c472017-11-27 10:44:06 -0500648Caller may read from the back-end object.
649##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500650#Const kFlushWrite_BackendHandleAccess 1
Cary Clark682c58d2018-05-16 07:07:07 -0400651#Line # back-end object is writable ##
Cary Clarka560c472017-11-27 10:44:06 -0500652Caller may write to the back-end object.
653##
Cary Clark3cd22cc2017-12-01 11:49:58 -0500654#Const kDiscardWrite_BackendHandleAccess 2
Cary Clark682c58d2018-05-16 07:07:07 -0400655#Line # back-end object must be overwritten ##
Cary Clarka560c472017-11-27 10:44:06 -0500656Caller must overwrite the entire back-end object.
657##
658
Cary Clark36122e72018-04-26 10:59:57 -0400659#NoExample
660// todo: need to update example to use GrBackendTexture instead of GrBackendObject
Cary Clarka560c472017-11-27 10:44:06 -0500661#Platform gpu
Cary Clark3cd22cc2017-12-01 11:49:58 -0500662 SkPaint paint;
663 paint.setTextSize(32);
664 GrContext* context = canvas->getGrContext();
665 if (!context) {
666 canvas->drawString("GPU only!", 20, 40, paint);
667 return;
668 }
669 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
670 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10));
671 int y = 20;
672 SkString str;
673 paint.setTextSize(16);
Cary Clark682c58d2018-05-16 07:07:07 -0400674 for (auto access : { SkSurface::kFlushRead_BackendHandleAccess,
Cary Clark3cd22cc2017-12-01 11:49:58 -0500675 SkSurface::kFlushWrite_BackendHandleAccess,
676 SkSurface::kDiscardWrite_BackendHandleAccess } ) {
677 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
678 str.printf("uniqueID=%d", image->uniqueID());
679 canvas->drawString(str, 20, y += 20, paint);
Greg Daniel6d138bf2018-05-03 16:54:03 -0400680 GrBackendTexture backendTex = gpuSurface->getBackendTexture(access);
681 str.printf("backendTex is %svalid", backendTex.isValid() ? '' : 'not ');
Cary Clark3cd22cc2017-12-01 11:49:58 -0500682 canvas->drawString(str, 20, y += 20, paint);
683 }
684 sk_sp<SkImage> image(gpuSurface->makeImageSnapshot());
685 str.printf("final image uniqueID=%d", image->uniqueID());
686 canvas->drawString(str, 20, y += 20, paint);
Cary Clarka560c472017-11-27 10:44:06 -0500687##
688
Cary Clark36122e72018-04-26 10:59:57 -0400689#SeeAlso getBackendTexture getBackendRenderTarget
Cary Clarka560c472017-11-27 10:44:06 -0500690
691#Enum ##
692
693# ------------------------------------------------------------------------------
694
Robert Phillips8caf85f2018-04-05 09:30:38 -0400695#Method GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess)
696#In Property
697#Line # returns the GPU reference to texture ##
Cary Clark09d80c02018-10-31 12:14:03 -0400698#Populate
Robert Phillips8caf85f2018-04-05 09:30:38 -0400699
700#NoExample
701##
702
703#SeeAlso GrBackendTexture BackendHandleAccess getBackendRenderTarget
704
705#Method ##
706
707# ------------------------------------------------------------------------------
708
709#Method GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess)
710#In Property
711#Line # returns the GPU reference to render target ##
Cary Clark09d80c02018-10-31 12:14:03 -0400712#Populate
Robert Phillips8caf85f2018-04-05 09:30:38 -0400713
714#NoExample
715##
716
717#SeeAlso GrBackendRenderTarget BackendHandleAccess getBackendTexture
718
719#Method ##
720
721# ------------------------------------------------------------------------------
722
Cary Clarka560c472017-11-27 10:44:06 -0500723#Method SkCanvas* getCanvas()
Cary Clark4855f782018-02-06 09:41:53 -0500724#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -0500725#Line # returns Canvas that draws into Surface ##
Cary Clark09d80c02018-10-31 12:14:03 -0400726#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500727
728#Example
729#Height 64
730 sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(64, 64));
731 SkCanvas* surfaceCanvas = surface->getCanvas();
732 surfaceCanvas->clear(SK_ColorBLUE);
733 SkPaint paint;
734 paint.setTextSize(40);
735 surfaceCanvas->drawString("\xF0\x9F\x98\x81", 12, 45, paint);
736 surface->draw(canvas, 0, 0, nullptr);
737##
738
Cary Clark4855f782018-02-06 09:41:53 -0500739#SeeAlso makeSurface makeImageSnapshot draw
Cary Clarka560c472017-11-27 10:44:06 -0500740
741#Method ##
742
743# ------------------------------------------------------------------------------
744
745#Method sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo)
Cary Clark61313f32018-10-08 14:57:48 -0400746#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500747#Line # creates a compatible Surface ##
Cary Clark09d80c02018-10-31 12:14:03 -0400748#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500749
750#Example
751#Height 96
752 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
753 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
754 big->getCanvas()->clear(SK_ColorRED);
755 lil->getCanvas()->clear(SK_ColorBLACK);
756 SkPixmap pixmap;
757 if (big->peekPixels(&pixmap)) {
758 SkBitmap bigBits;
759 bigBits.installPixels(pixmap);
760 canvas->drawBitmap(bigBits, 0, 0);
761 }
762 if (lil->peekPixels(&pixmap)) {
763 SkBitmap lilBits;
764 lilBits.installPixels(pixmap);
765 canvas->drawBitmap(lilBits, 64, 64);
766 }
767##
768
Cary Clark4855f782018-02-06 09:41:53 -0500769#SeeAlso makeImageSnapshot getCanvas draw
Cary Clarka560c472017-11-27 10:44:06 -0500770
771#Method ##
772
773# ------------------------------------------------------------------------------
774
775#Method sk_sp<SkImage> makeImageSnapshot()
Cary Clark61313f32018-10-08 14:57:48 -0400776#In Constructors
Cary Clarkab2621d2018-01-30 10:08:57 -0500777#Line # creates Image capturing Surface contents ##
Cary Clark09d80c02018-10-31 12:14:03 -0400778#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500779
780#Example
781#Height 64
782 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
783 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
784 big->getCanvas()->clear(SK_ColorRED);
785 lil->getCanvas()->clear(SK_ColorBLACK);
786 sk_sp<SkImage> early(big->makeImageSnapshot());
787 lil->draw(big->getCanvas(), 16, 16, nullptr);
788 sk_sp<SkImage> later(big->makeImageSnapshot());
789 canvas->drawImage(early, 0, 0);
790 canvas->drawImage(later, 128, 0);
791##
792
793#SeeAlso draw getCanvas
794
795#Method ##
796
797# ------------------------------------------------------------------------------
Mike Reed114bde82018-11-21 09:12:09 -0500798
799#Method sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds)
800#In Constructors
801#Line # creates Image capturing subset of Surface contents ##
802#Populate
803
804#Example
805#Height 64
806 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
807 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
808 big->getCanvas()->clear(SK_ColorRED);
809 lil->getCanvas()->clear(SK_ColorBLACK);
810 sk_sp<SkImage> early(big->makeImageSnapshot());
811 lil->draw(big->getCanvas(), 16, 16, nullptr);
812 sk_sp<SkImage> later(big->makeImageSnapshot({0, 0, 16, 16}));
813 canvas->drawImage(early, 0, 0);
814 canvas->drawImage(later, 0, 0);
815##
816
817#SeeAlso draw getCanvas
818
819#Method ##
820
821# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -0500822#Subtopic Pixels
Cary Clark4855f782018-02-06 09:41:53 -0500823#Line # functions with pixel access ##
824##
Cary Clarka560c472017-11-27 10:44:06 -0500825
826#Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
Cary Clark4855f782018-02-06 09:41:53 -0500827#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500828#Line # draws Surface contents to canvas ##
Cary Clark09d80c02018-10-31 12:14:03 -0400829#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500830
831#Example
832#Height 64
833 sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64));
834 sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType)));
835 big->getCanvas()->clear(SK_ColorRED);
836 lil->getCanvas()->clear(SK_ColorBLACK);
837 lil->draw(big->getCanvas(), 16, 16, nullptr);
838 SkPixmap pixmap;
839 if (big->peekPixels(&pixmap)) {
840 SkBitmap bigBits;
841 bigBits.installPixels(pixmap);
842 canvas->drawBitmap(bigBits, 0, 0);
843 }
844##
845
846#SeeAlso makeImageSnapshot getCanvas
847
848#Method ##
849
850# ------------------------------------------------------------------------------
851
852#Method bool peekPixels(SkPixmap* pixmap)
Cary Clark4855f782018-02-06 09:41:53 -0500853#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500854#Line # copies Surface parameters to Pixmap ##
Cary Clark09d80c02018-10-31 12:14:03 -0400855#Populate
Cary Clarka560c472017-11-27 10:44:06 -0500856
857#Example
858#Height 64
859 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
860 auto surfCanvas = surf->getCanvas();
861 surfCanvas->clear(SK_ColorRED);
862 SkPaint paint;
863 paint.setTextSize(40);
864 surfCanvas->drawString("&", 16, 48, paint);
865 SkPixmap pixmap;
866 if (surf->peekPixels(&pixmap)) {
867 SkBitmap surfBits;
868 surfBits.installPixels(pixmap);
869 canvas->drawBitmap(surfBits, 0, 0);
870 }
871##
872
Mike Reed4c790bd2018-02-08 14:10:40 -0500873#SeeAlso readPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500874
875#Method ##
876
877# ------------------------------------------------------------------------------
878
879#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY)
Cary Clark4855f782018-02-06 09:41:53 -0500880#In Pixels
Cary Clarkab2621d2018-01-30 10:08:57 -0500881#Line # copies Rect of pixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500882Copies Rect of pixels to dst.
883
Cary Clarkac47b882018-01-11 10:35:44 -0500884Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500885Destination Rect corners are (0, 0) and (dst.width(), dst.height()).
886Copies each readable pixel intersecting both rectangles, without scaling,
887converting to dst.colorType() and dst.alphaType() if required.
888
889Pixels are readable when Surface is raster, or backed by a GPU.
890
891The destination pixel storage must be allocated by the caller.
892
Cary Clark2dc84ad2018-01-26 12:56:22 -0500893Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500894do not match. Only pixels within both source and destination rectangles
895are copied. dst contents outside Rect intersection are unchanged.
896
897Pass negative values for srcX or srcY to offset pixels across or down destination.
898
899Does not copy, and returns false if:
900
901#List
902# Source and destination rectangles do not intersect. ##
903# Pixmap pixels could not be allocated. ##
904# dst.rowBytes() is too small to contain one row of pixels. ##
905##
906
907#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -0400908#Param srcX offset into readable pixels on x-axis; may be negative ##
909#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500910
911#Return true if pixels were copied ##
912
913#Example
914#Height 32
915 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
916 auto surfCanvas = surf->getCanvas();
917 surfCanvas->clear(SK_ColorRED);
918 SkPaint paint;
919 paint.setTextSize(40);
920 surfCanvas->drawString("&", 0, 32, paint);
921 std::vector<SkPMColor> storage;
922 storage.resize(surf->width() * surf->height());
923 SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(),
924 surf->width() * sizeof(storage[0]));
925 if (surf->readPixels(pixmap, 0, 0)) {
926 SkBitmap surfBits;
927 surfBits.installPixels(pixmap);
928 canvas->drawBitmap(surfBits, 0, 0);
929 }
930##
931
Mike Reed4c790bd2018-02-08 14:10:40 -0500932#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500933
934#Method ##
935
936# ------------------------------------------------------------------------------
937
938#Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
939 int srcX, int srcY)
940
941Copies Rect of pixels from Canvas into dstPixels.
942
Cary Clarkac47b882018-01-11 10:35:44 -0500943Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -0500944Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()).
945Copies each readable pixel intersecting both rectangles, without scaling,
946converting to dstInfo.colorType() and dstInfo.alphaType() if required.
947
948Pixels are readable when Surface is raster, or backed by a GPU.
949
950The destination pixel storage must be allocated by the caller.
951
Cary Clark2dc84ad2018-01-26 12:56:22 -0500952Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -0500953do not match. Only pixels within both source and destination rectangles
954are copied. dstPixels contents outside Rect intersection are unchanged.
955
956Pass negative values for srcX or srcY to offset pixels across or down destination.
957
958Does not copy, and returns false if:
959
960#List
961# Source and destination rectangles do not intersect. ##
962# Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ##
963# dstRowBytes is too small to contain one row of pixels. ##
964##
965
Cary Clark2dc84ad2018-01-26 12:56:22 -0500966#Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ##
Cary Clarka560c472017-11-27 10:44:06 -0500967#Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ##
968#Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ##
Cary Clark5538c132018-06-14 12:28:14 -0400969#Param srcX offset into readable pixels on x-axis; may be negative ##
970#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -0500971
972#Return true if pixels were copied ##
973
974#Example
975#Height 64
976#Description
977 A black oval drawn on a red background provides an image to copy.
978 readPixels copies one quarter of the Surface into each of the four corners.
979 The copied quarter ovals overdraw the original oval.
980##
981 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
982 auto surfCanvas = surf->getCanvas();
983 surfCanvas->clear(SK_ColorRED);
984 SkPaint paint;
985 surfCanvas->drawOval({4, 8, 58, 54}, paint);
986 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
987 sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height()));
988 sk_bzero(data->writable_data(), info.minRowBytes() * info.height());
989 for (int x : { 32, -32 } ) {
990 for (int y : { 32, -32 } ) {
991 surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y);
Cary Clark682c58d2018-05-16 07:07:07 -0400992 }
Cary Clarka560c472017-11-27 10:44:06 -0500993 }
994 sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes());
995 canvas->drawImage(image, 0, 0);
996##
997
Mike Reed4c790bd2018-02-08 14:10:40 -0500998#SeeAlso peekPixels writePixels
Cary Clarka560c472017-11-27 10:44:06 -0500999
1000#Method ##
1001
1002# ------------------------------------------------------------------------------
1003
1004#Method bool readPixels(const SkBitmap& dst, int srcX, int srcY)
1005
1006Copies Rect of pixels from Surface into bitmap.
1007
Cary Clarkac47b882018-01-11 10:35:44 -05001008Source Rect corners are (srcX, srcY) and Surface (width(), height()).
Cary Clarka560c472017-11-27 10:44:06 -05001009Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()).
1010Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001011converting to dst.colorType() and dst.alphaType() if required.
Cary Clarka560c472017-11-27 10:44:06 -05001012
1013Pixels are readable when Surface is raster, or backed by a GPU.
1014
1015The destination pixel storage must be allocated by the caller.
1016
Cary Clark2dc84ad2018-01-26 12:56:22 -05001017Pixel values are converted only if Color_Type and Alpha_Type
Cary Clarka560c472017-11-27 10:44:06 -05001018do not match. Only pixels within both source and destination rectangles
1019are copied. dst contents outside Rect intersection are unchanged.
1020
1021Pass negative values for srcX or srcY to offset pixels across or down destination.
1022
1023Does not copy, and returns false if:
1024
1025#List
1026# Source and destination rectangles do not intersect. ##
1027# Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ##
1028# dst pixels could not be allocated. ##
1029# dst.rowBytes() is too small to contain one row of pixels. ##
1030##
1031
1032#Param dst storage for pixels copied from Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001033#Param srcX offset into readable pixels on x-axis; may be negative ##
1034#Param srcY offset into readable pixels on y-axis; may be negative ##
Cary Clarka560c472017-11-27 10:44:06 -05001035
1036#Return true if pixels were copied ##
1037
1038#Example
Cary Clark3cd22cc2017-12-01 11:49:58 -05001039 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1040 auto surfCanvas = surf->getCanvas();
1041 surfCanvas->clear(SK_ColorGREEN);
1042 SkPaint paint;
1043 surfCanvas->drawOval({2, 10, 58, 54}, paint);
1044 SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
1045 SkBitmap bitmap;
1046 bitmap.setInfo(info);
1047 bitmap.allocPixels();
1048 for (int x : { 32, -32 } ) {
1049 for (int y : { 32, -32 } ) {
1050 surf->readPixels(bitmap, x, y);
Cary Clark682c58d2018-05-16 07:07:07 -04001051 }
Cary Clark3cd22cc2017-12-01 11:49:58 -05001052 }
1053 canvas->drawBitmap(bitmap, 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001054##
1055
Mike Reed4c790bd2018-02-08 14:10:40 -05001056#SeeAlso peekPixels writePixels
1057
1058#Method ##
1059
1060# ------------------------------------------------------------------------------
1061
1062#Method void writePixels(const SkPixmap& src, int dstX, int dstY)
Cary Clark56356312018-02-08 14:45:18 -05001063#In Pixels
1064#Line # copies Rect of pixels ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001065Copies Rect of pixels from the src Pixmap to the Surface.
1066
1067Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark682c58d2018-05-16 07:07:07 -04001068Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001069#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001070
Mike Reed4c790bd2018-02-08 14:10:40 -05001071Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001072converting to Surface SkColorType and SkAlphaType if required.
Mike Reed4c790bd2018-02-08 14:10:40 -05001073
1074#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001075#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1076#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001077
1078#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001079#Image 4
1080#Height 96
Cary Clark09d80c02018-10-31 12:14:03 -04001081 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1082 auto surfCanvas = surf->getCanvas();
1083 surfCanvas->clear(SK_ColorRED);
1084 SkPaint paint;
1085 paint.setTextSize(40);
1086 surfCanvas->drawString("&", 16, 40, paint);
1087 SkPixmap pixmap;
1088 if (surf->peekPixels(&pixmap)) {
1089 surf->writePixels(pixmap, 25, 25);
1090 sk_sp<SkImage> image(surf->makeImageSnapshot());
1091 canvas->drawImage(image, 0, 0);
Cary Clarkffb3d682018-05-17 12:17:28 -04001092 }
Mike Reed4c790bd2018-02-08 14:10:40 -05001093##
1094
1095#SeeAlso readPixels peekPixels
1096
1097#Method ##
1098
1099# ------------------------------------------------------------------------------
1100
1101#Method void writePixels(const SkBitmap& src, int dstX, int dstY)
1102
1103Copies Rect of pixels from the src Bitmap to the Surface.
1104
1105Source Rect corners are (0, 0) and (src.width(), src.height()).
Cary Clark56356312018-02-08 14:45:18 -05001106Destination Rect corners are (dstX, dstY) and
Cary Clark2be81cf2018-09-13 12:04:30 -04001107#Formula # (dstX + Surface width(), dstY + Surface height()) ##.
Cary Clark80247e52018-07-11 16:18:41 -04001108
Mike Reed4c790bd2018-02-08 14:10:40 -05001109Copies each readable pixel intersecting both rectangles, without scaling,
Cary Clark77b3f3a2018-11-07 14:59:03 -05001110converting to Surface SkColorType and SkAlphaType if required.
Mike Reed4c790bd2018-02-08 14:10:40 -05001111
1112#Param src storage for pixels to copy to Surface ##
Cary Clark5538c132018-06-14 12:28:14 -04001113#Param dstX x-axis position relative to Surface to begin copy; may be negative ##
1114#Param dstY y-axis position relative to Surface to begin copy; may be negative ##
Mike Reed4c790bd2018-02-08 14:10:40 -05001115
1116#Example
Cary Clarkffb3d682018-05-17 12:17:28 -04001117#Image 4
1118#Height 96
1119 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
1120 auto surfCanvas = surf->getCanvas();
1121 surfCanvas->clear(SK_ColorGREEN);
1122 surf->writePixels(source, 25, 25);
1123 sk_sp<SkImage> image(surf->makeImageSnapshot());
1124 canvas->drawImage(image, 0, 0);
Mike Reed4c790bd2018-02-08 14:10:40 -05001125##
1126
1127#SeeAlso readPixels peekPixels
Cary Clarka560c472017-11-27 10:44:06 -05001128
1129#Method ##
1130
1131# ------------------------------------------------------------------------------
1132
1133#Method const SkSurfaceProps& props() const
Cary Clark4855f782018-02-06 09:41:53 -05001134#In Property
Cary Clarkab2621d2018-01-30 10:08:57 -05001135#Line # returns Surface_Properties ##
Cary Clark09d80c02018-10-31 12:14:03 -04001136#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001137
1138#Example
1139 const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" };
Cary Clark3cd22cc2017-12-01 11:49:58 -05001140 sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001141 SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]);
1142#StdOut
1143surf.props(): kRGB_H_SkPixelGeometry
1144##
1145##
1146
1147#SeeAlso SkSurfaceProps
1148
1149#Method ##
1150
1151# ------------------------------------------------------------------------------
Cary Clark4855f782018-02-06 09:41:53 -05001152#Subtopic Utility
Cary Clark4855f782018-02-06 09:41:53 -05001153#Line # rarely called management functions ##
1154##
Cary Clarka560c472017-11-27 10:44:06 -05001155
1156#Method void flush()
Cary Clark4855f782018-02-06 09:41:53 -05001157#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001158#Line # resolves pending I/O ##
Cary Clark09d80c02018-10-31 12:14:03 -04001159#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001160
1161#NoExample
1162##
1163
1164#SeeAlso GrBackendSemaphore
1165
1166#Method ##
1167
1168# ------------------------------------------------------------------------------
1169
1170#Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
1171 GrBackendSemaphore signalSemaphores[])
Cary Clark4855f782018-02-06 09:41:53 -05001172#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001173#Line # resolves pending I/O, and signal ##
Cary Clark09d80c02018-10-31 12:14:03 -04001174#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001175
1176#NoExample
1177##
1178
1179#SeeAlso wait GrBackendSemaphore
1180
1181#Method ##
1182
1183# ------------------------------------------------------------------------------
1184
1185#Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores)
Cary Clark4855f782018-02-06 09:41:53 -05001186#In Utility
Cary Clark682c58d2018-05-16 07:07:07 -04001187#Line # pauses commands until signaled ##
Cary Clark09d80c02018-10-31 12:14:03 -04001188#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001189
Cary Clark1a8d7622018-03-05 13:26:16 -05001190#NoExample
Cary Clarka560c472017-11-27 10:44:06 -05001191#ToDo this is copy and paste silliness masquerading as an example. Probably need gpu
1192 globals and definitely need gpu expertise to make a real example out of this
Cary Clark36122e72018-04-26 10:59:57 -04001193 also, note need to replace GrBackendObject with GrBackendTexture
Cary Clarka560c472017-11-27 10:44:06 -05001194 ##
Cary Clark1a8d7622018-03-05 13:26:16 -05001195#Platform gpu
Cary Clarka560c472017-11-27 10:44:06 -05001196#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001197 SkPaint paint;
1198 paint.setTextSize(32);
1199 GrContext* context = canvas->getGrContext();
1200 if (!context) {
1201 canvas->drawString("GPU only!", 20, 40, paint);
1202 return;
1203 }
Cary Clarka560c472017-11-27 10:44:06 -05001204 GrBackendSemaphore semaphore;
Cary Clark3cd22cc2017-12-01 11:49:58 -05001205 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
1206 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
Cary Clarka560c472017-11-27 10:44:06 -05001207 surface->flushAndSignalSemaphores(1, &semaphore);
1208 sk_sp<SkImage> image = surface->makeImageSnapshot();
Greg Daniel6d138bf2018-05-03 16:54:03 -04001209 GrBackendTexture backendTex = image->getBackendTexture(false); // unused
1210 SkASSERT(backendTex.isValid());
Cary Clarka560c472017-11-27 10:44:06 -05001211 const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64,
1212 kRGBA_8888_SkColorType, kPremul_SkAlphaType);
1213 sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo,
1214 childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr));
1215 GrBackendTexture backendTexture;
1216 sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context,
1217 backendTexture, // undefined
1218 kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr);
1219 SkCanvas* childCanvas = childSurface->getCanvas();
1220 childCanvas->clear(SK_ColorRED);
1221 childSurface->wait(1, &semaphore);
1222 childCanvas->drawImage(childImage, 32, 0);
Cary Clark3cd22cc2017-12-01 11:49:58 -05001223 childSurface->draw(canvas, 0, 0, nullptr);
Cary Clarka560c472017-11-27 10:44:06 -05001224##
1225
1226#SeeAlso flushAndSignalSemaphores GrBackendSemaphore
1227
1228#Method ##
1229
1230# ------------------------------------------------------------------------------
1231
1232#Method bool characterize(SkSurfaceCharacterization* characterization) const
Cary Clark4855f782018-02-06 09:41:53 -05001233#In Utility
1234#Line # sets Surface_Characterization for threaded GPU processing ##
Cary Clark09d80c02018-10-31 12:14:03 -04001235#Populate
Cary Clarka560c472017-11-27 10:44:06 -05001236
1237#Example
1238#Platform gpu
1239#Height 64
Cary Clark3cd22cc2017-12-01 11:49:58 -05001240 SkPaint paint;
1241 paint.setTextSize(32);
1242 GrContext* context = canvas->getGrContext();
1243 if (!context) {
1244 canvas->drawString("GPU only!", 20, 40, paint);
1245 return;
1246 }
1247 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget(
1248 context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
1249 SkSurfaceCharacterization characterization;
1250 if (!gpuSurface->characterize(&characterization)) {
1251 canvas->drawString("characterization unsupported", 20, 40, paint);
1252 return;
1253 }
Cary Clark682c58d2018-05-16 07:07:07 -04001254 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001255 SkDeferredDisplayListRecorder recorder(characterization);
1256 SkCanvas* subCanvas = recorder.getCanvas();
1257 subCanvas->clear(SK_ColorGREEN);
1258 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1259 // end of threadable work
1260 gpuSurface->draw(displayList.get());
1261 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1262 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001263##
1264
1265#SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList
1266
1267#Method ##
1268
1269# ------------------------------------------------------------------------------
1270
Cary Clark2f466242017-12-11 16:03:17 -05001271#Method bool draw(SkDeferredDisplayList* deferredDisplayList)
Cary Clark09d80c02018-10-31 12:14:03 -04001272#Populate
Cary Clark2f466242017-12-11 16:03:17 -05001273
Cary Clarka560c472017-11-27 10:44:06 -05001274#Example
1275#Height 64
1276#Platform gpu cpu
Cary Clark3cd22cc2017-12-01 11:49:58 -05001277 SkPaint paint;
1278 paint.setTextSize(16);
1279 sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64);
1280 SkSurfaceCharacterization characterization;
1281 if (!gpuSurface->characterize(&characterization)) {
1282 canvas->drawString("characterization unsupported", 20, 40, paint);
1283 return;
1284 }
Cary Clark682c58d2018-05-16 07:07:07 -04001285 // start of threadable work
Cary Clark3cd22cc2017-12-01 11:49:58 -05001286 SkDeferredDisplayListRecorder recorder(characterization);
1287 SkCanvas* subCanvas = recorder.getCanvas();
1288 subCanvas->clear(SK_ColorGREEN);
1289 std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach();
1290 // end of threadable work
1291 gpuSurface->draw(displayList.get());
1292 sk_sp<SkImage> img = gpuSurface->makeImageSnapshot();
1293 canvas->drawImage(std::move(img), 0, 0);
Cary Clarka560c472017-11-27 10:44:06 -05001294##
1295
1296#SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList
1297
1298#Method ##
1299
1300#Class SkSurface ##
1301
1302#Topic Surface ##