/src/skia/include/core/SkSurface.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2012 Google Inc. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license that can be |
5 | | * found in the LICENSE file. |
6 | | */ |
7 | | |
8 | | #ifndef SkSurface_DEFINED |
9 | | #define SkSurface_DEFINED |
10 | | |
11 | | #include "include/core/SkImage.h" |
12 | | #include "include/core/SkImageInfo.h" |
13 | | #include "include/core/SkPixmap.h" |
14 | | #include "include/core/SkRefCnt.h" |
15 | | #include "include/core/SkSamplingOptions.h" |
16 | | #include "include/core/SkScalar.h" |
17 | | #include "include/core/SkSurfaceProps.h" |
18 | | #include "include/core/SkTypes.h" |
19 | | |
20 | | #include <cstddef> |
21 | | #include <cstdint> |
22 | | #include <memory> |
23 | | |
24 | | class GrBackendSemaphore; |
25 | | class GrBackendTexture; |
26 | | class GrRecordingContext; |
27 | | class GrSurfaceCharacterization; |
28 | | enum GrSurfaceOrigin : int; |
29 | | class SkBitmap; |
30 | | class SkCanvas; |
31 | | class SkCapabilities; |
32 | | class SkColorSpace; |
33 | | class SkPaint; |
34 | | class SkSurface; |
35 | | struct SkIRect; |
36 | | struct SkISize; |
37 | | |
38 | | namespace skgpu::graphite { |
39 | | class Recorder; |
40 | | } |
41 | | |
42 | | namespace SkSurfaces { |
43 | | |
44 | | enum class BackendSurfaceAccess { |
45 | | kNoAccess, //!< back-end surface will not be used by client |
46 | | kPresent, //!< back-end surface will be used for presenting to screen |
47 | | }; |
48 | | |
49 | | /** Returns SkSurface without backing pixels. Drawing to SkCanvas returned from SkSurface |
50 | | has no effect. Calling makeImageSnapshot() on returned SkSurface returns nullptr. |
51 | | |
52 | | @param width one or greater |
53 | | @param height one or greater |
54 | | @return SkSurface if width and height are positive; otherwise, nullptr |
55 | | |
56 | | example: https://fiddle.skia.org/c/@Surface_MakeNull |
57 | | */ |
58 | | SK_API sk_sp<SkSurface> Null(int width, int height); |
59 | | |
60 | | /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into those allocated |
61 | | pixels, which are zeroed before use. Pixel memory size is imageInfo.height() times |
62 | | imageInfo.minRowBytes() or rowBytes, if provided and non-zero. |
63 | | |
64 | | Pixel memory is deleted when SkSurface is deleted. |
65 | | |
66 | | Validity constraints include: |
67 | | - info dimensions are greater than zero; |
68 | | - info contains SkColorType and SkAlphaType supported by raster surface. |
69 | | |
70 | | @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, |
71 | | of raster surface; width and height must be greater than zero |
72 | | @param rowBytes interval from one SkSurface row to the next. |
73 | | @param props LCD striping orientation and setting for device independent fonts; |
74 | | may be nullptr |
75 | | @return SkSurface if parameters are valid and memory was allocated, else nullptr. |
76 | | */ |
77 | | SK_API sk_sp<SkSurface> Raster(const SkImageInfo& imageInfo, |
78 | | size_t rowBytes, |
79 | | const SkSurfaceProps* surfaceProps); |
80 | | inline sk_sp<SkSurface> Raster(const SkImageInfo& imageInfo, |
81 | 65.2k | const SkSurfaceProps* props = nullptr) { |
82 | 65.2k | return Raster(imageInfo, 0, props); |
83 | 65.2k | } |
84 | | |
85 | | /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into the |
86 | | provided pixels. |
87 | | |
88 | | SkSurface is returned if all parameters are valid. |
89 | | Valid parameters include: |
90 | | info dimensions are greater than zero; |
91 | | info contains SkColorType and SkAlphaType supported by raster surface; |
92 | | pixels is not nullptr; |
93 | | rowBytes is large enough to contain info width pixels of SkColorType. |
94 | | |
95 | | Pixel buffer size should be info height times computed rowBytes. |
96 | | Pixels are not initialized. |
97 | | To access pixels after drawing, peekPixels() or readPixels(). |
98 | | |
99 | | @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, |
100 | | of raster surface; width and height must be greater than zero |
101 | | @param pixels pointer to destination pixels buffer |
102 | | @param rowBytes interval from one SkSurface row to the next |
103 | | @param surfaceProps LCD striping orientation and setting for device independent fonts; |
104 | | may be nullptr |
105 | | @return SkSurface if all parameters are valid; otherwise, nullptr |
106 | | */ |
107 | | |
108 | | SK_API sk_sp<SkSurface> WrapPixels(const SkImageInfo& imageInfo, |
109 | | void* pixels, |
110 | | size_t rowBytes, |
111 | | const SkSurfaceProps* surfaceProps = nullptr); |
112 | 0 | inline sk_sp<SkSurface> WrapPixels(const SkPixmap& pm, const SkSurfaceProps* props = nullptr) { |
113 | 0 | return WrapPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), props); |
114 | 0 | } |
115 | | |
116 | | using PixelsReleaseProc = void(void* pixels, void* context); |
117 | | |
118 | | /** Allocates raster SkSurface. SkCanvas returned by SkSurface draws directly into the provided |
119 | | pixels. releaseProc is called with pixels and context when SkSurface is deleted. |
120 | | |
121 | | SkSurface is returned if all parameters are valid. |
122 | | Valid parameters include: |
123 | | info dimensions are greater than zero; |
124 | | info contains SkColorType and SkAlphaType supported by raster surface; |
125 | | pixels is not nullptr; |
126 | | rowBytes is large enough to contain info width pixels of SkColorType. |
127 | | |
128 | | Pixel buffer size should be info height times computed rowBytes. |
129 | | Pixels are not initialized. |
130 | | To access pixels after drawing, call flush() or peekPixels(). |
131 | | |
132 | | @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, |
133 | | of raster surface; width and height must be greater than zero |
134 | | @param pixels pointer to destination pixels buffer |
135 | | @param rowBytes interval from one SkSurface row to the next |
136 | | @param releaseProc called when SkSurface is deleted; may be nullptr |
137 | | @param context passed to releaseProc; may be nullptr |
138 | | @param surfaceProps LCD striping orientation and setting for device independent fonts; |
139 | | may be nullptr |
140 | | @return SkSurface if all parameters are valid; otherwise, nullptr |
141 | | */ |
142 | | SK_API sk_sp<SkSurface> WrapPixels(const SkImageInfo& imageInfo, |
143 | | void* pixels, |
144 | | size_t rowBytes, |
145 | | PixelsReleaseProc, |
146 | | void* context, |
147 | | const SkSurfaceProps* surfaceProps = nullptr); |
148 | | } // namespace SkSurfaces |
149 | | |
150 | | /** \class SkSurface |
151 | | SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be |
152 | | allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface). |
153 | | SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call |
154 | | surface->getCanvas() to use that canvas (but don't delete it, it is owned by the surface). |
155 | | SkSurface always has non-zero dimensions. If there is a request for a new surface, and either |
156 | | of the requested dimensions are zero, then nullptr will be returned. |
157 | | |
158 | | Clients should *not* subclass SkSurface as there is a lot of internal machinery that is |
159 | | not publicly accessible. |
160 | | */ |
161 | | class SK_API SkSurface : public SkRefCnt { |
162 | | public: |
163 | | /** Is this surface compatible with the provided characterization? |
164 | | |
165 | | This method can be used to determine if an existing SkSurface is a viable destination |
166 | | for an GrDeferredDisplayList. |
167 | | |
168 | | @param characterization The characterization for which a compatibility check is desired |
169 | | @return true if this surface is compatible with the characterization; |
170 | | false otherwise |
171 | | */ |
172 | | bool isCompatible(const GrSurfaceCharacterization& characterization) const; |
173 | | |
174 | | /** Returns pixel count in each row; may be zero or greater. |
175 | | |
176 | | @return number of pixel columns |
177 | | */ |
178 | 45 | int width() const { return fWidth; } |
179 | | |
180 | | /** Returns pixel row count; may be zero or greater. |
181 | | |
182 | | @return number of pixel rows |
183 | | */ |
184 | 45 | int height() const { return fHeight; } |
185 | | |
186 | | /** Returns an ImageInfo describing the surface. |
187 | | */ |
188 | 0 | virtual SkImageInfo imageInfo() const { return SkImageInfo::MakeUnknown(fWidth, fHeight); } |
189 | | |
190 | | /** Returns unique value identifying the content of SkSurface. Returned value changes |
191 | | each time the content changes. Content is changed by drawing, or by calling |
192 | | notifyContentWillChange(). |
193 | | |
194 | | @return unique content identifier |
195 | | |
196 | | example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange |
197 | | */ |
198 | | uint32_t generationID(); |
199 | | |
200 | | /** \enum SkSurface::ContentChangeMode |
201 | | ContentChangeMode members are parameters to notifyContentWillChange(). |
202 | | */ |
203 | | enum ContentChangeMode { |
204 | | kDiscard_ContentChangeMode, //!< discards surface on change |
205 | | kRetain_ContentChangeMode, //!< preserves surface on change |
206 | | }; |
207 | | |
208 | | /** Notifies that SkSurface contents will be changed by code outside of Skia. |
209 | | Subsequent calls to generationID() return a different value. |
210 | | |
211 | | TODO: Can kRetain_ContentChangeMode be deprecated? |
212 | | |
213 | | example: https://fiddle.skia.org/c/@Surface_notifyContentWillChange |
214 | | */ |
215 | | void notifyContentWillChange(ContentChangeMode mode); |
216 | | |
217 | | /** Returns the recording context being used by the SkSurface. |
218 | | |
219 | | @return the recording context, if available; nullptr otherwise |
220 | | */ |
221 | | GrRecordingContext* recordingContext() const; |
222 | | |
223 | | /** Returns the recorder being used by the SkSurface. |
224 | | |
225 | | @return the recorder, if available; nullptr otherwise |
226 | | */ |
227 | | skgpu::graphite::Recorder* recorder() const; |
228 | | |
229 | | enum class BackendHandleAccess { |
230 | | kFlushRead, //!< back-end object is readable |
231 | | kFlushWrite, //!< back-end object is writable |
232 | | kDiscardWrite, //!< back-end object must be overwritten |
233 | | |
234 | | // Legacy names, remove when clients are migrated |
235 | | kFlushRead_BackendHandleAccess = kFlushRead, |
236 | | kFlushWrite_BackendHandleAccess = kFlushWrite, |
237 | | kDiscardWrite_BackendHandleAccess = kDiscardWrite, |
238 | | }; |
239 | | |
240 | | // Legacy names, remove when clients are migrated |
241 | | static constexpr BackendHandleAccess kFlushRead_BackendHandleAccess = |
242 | | BackendHandleAccess::kFlushRead; |
243 | | static constexpr BackendHandleAccess kFlushWrite_BackendHandleAccess = |
244 | | BackendHandleAccess::kFlushWrite; |
245 | | static constexpr BackendHandleAccess kDiscardWrite_BackendHandleAccess = |
246 | | BackendHandleAccess::kDiscardWrite; |
247 | | |
248 | | /** Caller data passed to TextureReleaseProc; may be nullptr. */ |
249 | | using ReleaseContext = void*; |
250 | | /** User function called when supplied texture may be deleted. */ |
251 | | using TextureReleaseProc = void (*)(ReleaseContext); |
252 | | |
253 | | /** If the surface was made via MakeFromBackendTexture then it's backing texture may be |
254 | | substituted with a different texture. The contents of the previous backing texture are |
255 | | copied into the new texture. SkCanvas state is preserved. The original sample count is |
256 | | used. The GrBackendFormat and dimensions of replacement texture must match that of |
257 | | the original. |
258 | | |
259 | | Upon success textureReleaseProc is called when it is safe to delete the texture in the |
260 | | backend API (accounting only for use of the texture by this surface). If SkSurface creation |
261 | | fails textureReleaseProc is called before this function returns. |
262 | | |
263 | | @param backendTexture the new backing texture for the surface |
264 | | @param mode Retain or discard current Content |
265 | | @param TextureReleaseProc function called when texture can be released |
266 | | @param ReleaseContext state passed to textureReleaseProc |
267 | | */ |
268 | | virtual bool replaceBackendTexture(const GrBackendTexture& backendTexture, |
269 | | GrSurfaceOrigin origin, |
270 | | ContentChangeMode mode = kRetain_ContentChangeMode, |
271 | | TextureReleaseProc = nullptr, |
272 | | ReleaseContext = nullptr) = 0; |
273 | | |
274 | | /** Returns SkCanvas that draws into SkSurface. Subsequent calls return the same SkCanvas. |
275 | | SkCanvas returned is managed and owned by SkSurface, and is deleted when SkSurface |
276 | | is deleted. |
277 | | |
278 | | @return drawing SkCanvas for SkSurface |
279 | | |
280 | | example: https://fiddle.skia.org/c/@Surface_getCanvas |
281 | | */ |
282 | | SkCanvas* getCanvas(); |
283 | | |
284 | | /** Returns SkCapabilities that describes the capabilities of the SkSurface's device. |
285 | | |
286 | | @return SkCapabilities of SkSurface's device. |
287 | | */ |
288 | | sk_sp<const SkCapabilities> capabilities(); |
289 | | |
290 | | /** Returns a compatible SkSurface, or nullptr. Returned SkSurface contains |
291 | | the same raster, GPU, or null properties as the original. Returned SkSurface |
292 | | does not share the same pixels. |
293 | | |
294 | | Returns nullptr if imageInfo width or height are zero, or if imageInfo |
295 | | is incompatible with SkSurface. |
296 | | |
297 | | @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace, |
298 | | of SkSurface; width and height must be greater than zero |
299 | | @return compatible SkSurface or nullptr |
300 | | |
301 | | example: https://fiddle.skia.org/c/@Surface_makeSurface |
302 | | */ |
303 | | sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo); |
304 | | |
305 | | /** Calls makeSurface(ImageInfo) with the same ImageInfo as this surface, but with the |
306 | | * specified width and height. |
307 | | */ |
308 | | sk_sp<SkSurface> makeSurface(int width, int height); |
309 | | |
310 | | /** Returns SkImage capturing SkSurface contents. Subsequent drawing to SkSurface contents |
311 | | are not captured. SkImage allocation is accounted for if SkSurface was created with |
312 | | skgpu::Budgeted::kYes. |
313 | | |
314 | | @return SkImage initialized with SkSurface contents |
315 | | |
316 | | example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot |
317 | | */ |
318 | | sk_sp<SkImage> makeImageSnapshot(); |
319 | | |
320 | | /** |
321 | | * Like the no-parameter version, this returns an image of the current surface contents. |
322 | | * This variant takes a rectangle specifying the subset of the surface that is of interest. |
323 | | * These bounds will be sanitized before being used. |
324 | | * - If bounds extends beyond the surface, it will be trimmed to just the intersection of |
325 | | * it and the surface. |
326 | | * - If bounds does not intersect the surface, then this returns nullptr. |
327 | | * - If bounds == the surface, then this is the same as calling the no-parameter variant. |
328 | | |
329 | | example: https://fiddle.skia.org/c/@Surface_makeImageSnapshot_2 |
330 | | */ |
331 | | sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds); |
332 | | |
333 | | /** Draws SkSurface contents to canvas, with its top-left corner at (x, y). |
334 | | |
335 | | If SkPaint paint is not nullptr, apply SkColorFilter, alpha, SkImageFilter, and SkBlendMode. |
336 | | |
337 | | @param canvas SkCanvas drawn into |
338 | | @param x horizontal offset in SkCanvas |
339 | | @param y vertical offset in SkCanvas |
340 | | @param sampling what technique to use when sampling the surface pixels |
341 | | @param paint SkPaint containing SkBlendMode, SkColorFilter, SkImageFilter, |
342 | | and so on; or nullptr |
343 | | |
344 | | example: https://fiddle.skia.org/c/@Surface_draw |
345 | | */ |
346 | | void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkSamplingOptions& sampling, |
347 | | const SkPaint* paint); |
348 | | |
349 | 0 | void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint = nullptr) { |
350 | 0 | this->draw(canvas, x, y, SkSamplingOptions(), paint); |
351 | 0 | } |
352 | | |
353 | | /** Copies SkSurface pixel address, row bytes, and SkImageInfo to SkPixmap, if address |
354 | | is available, and returns true. If pixel address is not available, return |
355 | | false and leave SkPixmap unchanged. |
356 | | |
357 | | pixmap contents become invalid on any future change to SkSurface. |
358 | | |
359 | | @param pixmap storage for pixel state if pixels are readable; otherwise, ignored |
360 | | @return true if SkSurface has direct access to pixels |
361 | | |
362 | | example: https://fiddle.skia.org/c/@Surface_peekPixels |
363 | | */ |
364 | | bool peekPixels(SkPixmap* pixmap); |
365 | | |
366 | | /** Copies SkRect of pixels to dst. |
367 | | |
368 | | Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). |
369 | | Destination SkRect corners are (0, 0) and (dst.width(), dst.height()). |
370 | | Copies each readable pixel intersecting both rectangles, without scaling, |
371 | | converting to dst.colorType() and dst.alphaType() if required. |
372 | | |
373 | | Pixels are readable when SkSurface is raster, or backed by a GPU. |
374 | | |
375 | | The destination pixel storage must be allocated by the caller. |
376 | | |
377 | | Pixel values are converted only if SkColorType and SkAlphaType |
378 | | do not match. Only pixels within both source and destination rectangles |
379 | | are copied. dst contents outside SkRect intersection are unchanged. |
380 | | |
381 | | Pass negative values for srcX or srcY to offset pixels across or down destination. |
382 | | |
383 | | Does not copy, and returns false if: |
384 | | - Source and destination rectangles do not intersect. |
385 | | - SkPixmap pixels could not be allocated. |
386 | | - dst.rowBytes() is too small to contain one row of pixels. |
387 | | |
388 | | @param dst storage for pixels copied from SkSurface |
389 | | @param srcX offset into readable pixels on x-axis; may be negative |
390 | | @param srcY offset into readable pixels on y-axis; may be negative |
391 | | @return true if pixels were copied |
392 | | |
393 | | example: https://fiddle.skia.org/c/@Surface_readPixels |
394 | | */ |
395 | | bool readPixels(const SkPixmap& dst, int srcX, int srcY); |
396 | | |
397 | | /** Copies SkRect of pixels from SkCanvas into dstPixels. |
398 | | |
399 | | Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). |
400 | | Destination SkRect corners are (0, 0) and (dstInfo.width(), dstInfo.height()). |
401 | | Copies each readable pixel intersecting both rectangles, without scaling, |
402 | | converting to dstInfo.colorType() and dstInfo.alphaType() if required. |
403 | | |
404 | | Pixels are readable when SkSurface is raster, or backed by a GPU. |
405 | | |
406 | | The destination pixel storage must be allocated by the caller. |
407 | | |
408 | | Pixel values are converted only if SkColorType and SkAlphaType |
409 | | do not match. Only pixels within both source and destination rectangles |
410 | | are copied. dstPixels contents outside SkRect intersection are unchanged. |
411 | | |
412 | | Pass negative values for srcX or srcY to offset pixels across or down destination. |
413 | | |
414 | | Does not copy, and returns false if: |
415 | | - Source and destination rectangles do not intersect. |
416 | | - SkSurface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). |
417 | | - dstRowBytes is too small to contain one row of pixels. |
418 | | |
419 | | @param dstInfo width, height, SkColorType, and SkAlphaType of dstPixels |
420 | | @param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger |
421 | | @param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger |
422 | | @param srcX offset into readable pixels on x-axis; may be negative |
423 | | @param srcY offset into readable pixels on y-axis; may be negative |
424 | | @return true if pixels were copied |
425 | | */ |
426 | | bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, |
427 | | int srcX, int srcY); |
428 | | |
429 | | /** Copies SkRect of pixels from SkSurface into bitmap. |
430 | | |
431 | | Source SkRect corners are (srcX, srcY) and SkSurface (width(), height()). |
432 | | Destination SkRect corners are (0, 0) and (bitmap.width(), bitmap.height()). |
433 | | Copies each readable pixel intersecting both rectangles, without scaling, |
434 | | converting to bitmap.colorType() and bitmap.alphaType() if required. |
435 | | |
436 | | Pixels are readable when SkSurface is raster, or backed by a GPU. |
437 | | |
438 | | The destination pixel storage must be allocated by the caller. |
439 | | |
440 | | Pixel values are converted only if SkColorType and SkAlphaType |
441 | | do not match. Only pixels within both source and destination rectangles |
442 | | are copied. dst contents outside SkRect intersection are unchanged. |
443 | | |
444 | | Pass negative values for srcX or srcY to offset pixels across or down destination. |
445 | | |
446 | | Does not copy, and returns false if: |
447 | | - Source and destination rectangles do not intersect. |
448 | | - SkSurface pixels could not be converted to dst.colorType() or dst.alphaType(). |
449 | | - dst pixels could not be allocated. |
450 | | - dst.rowBytes() is too small to contain one row of pixels. |
451 | | |
452 | | @param dst storage for pixels copied from SkSurface |
453 | | @param srcX offset into readable pixels on x-axis; may be negative |
454 | | @param srcY offset into readable pixels on y-axis; may be negative |
455 | | @return true if pixels were copied |
456 | | |
457 | | example: https://fiddle.skia.org/c/@Surface_readPixels_3 |
458 | | */ |
459 | | bool readPixels(const SkBitmap& dst, int srcX, int srcY); |
460 | | |
461 | | using AsyncReadResult = SkImage::AsyncReadResult; |
462 | | |
463 | | /** Client-provided context that is passed to client-provided ReadPixelsContext. */ |
464 | | using ReadPixelsContext = void*; |
465 | | |
466 | | /** Client-provided callback to asyncRescaleAndReadPixels() or |
467 | | asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure. |
468 | | */ |
469 | | using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>); |
470 | | |
471 | | /** Controls the gamma that rescaling occurs in for asyncRescaleAndReadPixels() and |
472 | | asyncRescaleAndReadPixelsYUV420(). |
473 | | */ |
474 | | using RescaleGamma = SkImage::RescaleGamma; |
475 | | using RescaleMode = SkImage::RescaleMode; |
476 | | |
477 | | /** Makes surface pixel data available to caller, possibly asynchronously. It can also rescale |
478 | | the surface pixels. |
479 | | |
480 | | Currently asynchronous reads are only supported on the GPU backend and only when the |
481 | | underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all |
482 | | other cases this operates synchronously. |
483 | | |
484 | | Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is |
485 | | rescaled to the size indicated by 'info', is then converted to the color space, color type, |
486 | | and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the surface |
487 | | causes failure. |
488 | | |
489 | | When the pixel data is ready the caller's ReadPixelsCallback is called with a |
490 | | AsyncReadResult containing pixel data in the requested color type, alpha type, and color |
491 | | space. The AsyncReadResult will have count() == 1. Upon failure the callback is called |
492 | | with nullptr for AsyncReadResult. For a GPU surface this flushes work but a submit must |
493 | | occur to guarantee a finite time before the callback is called. |
494 | | |
495 | | The data is valid for the lifetime of AsyncReadResult with the exception that if the |
496 | | SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned |
497 | | or destroyed. |
498 | | |
499 | | @param info info of the requested pixels |
500 | | @param srcRect subrectangle of surface to read |
501 | | @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether |
502 | | the source data is transformed to a linear gamma before rescaling. |
503 | | @param rescaleMode controls the technique of the rescaling |
504 | | @param callback function to call with result of the read |
505 | | @param context passed to callback |
506 | | */ |
507 | | void asyncRescaleAndReadPixels(const SkImageInfo& info, |
508 | | const SkIRect& srcRect, |
509 | | RescaleGamma rescaleGamma, |
510 | | RescaleMode rescaleMode, |
511 | | ReadPixelsCallback callback, |
512 | | ReadPixelsContext context); |
513 | | |
514 | | /** |
515 | | Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The |
516 | | RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three |
517 | | planes ordered y, u, v. The u and v planes are half the width and height of the resized |
518 | | rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize' |
519 | | width and height are not even. A 'srcRect' that is not contained by the bounds of the |
520 | | surface causes failure. |
521 | | |
522 | | When the pixel data is ready the caller's ReadPixelsCallback is called with a |
523 | | AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3. |
524 | | Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU surface this |
525 | | flushes work but a submit must occur to guarantee a finite time before the callback is |
526 | | called. |
527 | | |
528 | | The data is valid for the lifetime of AsyncReadResult with the exception that if the |
529 | | SkSurface is GPU-backed the data is immediately invalidated if the context is abandoned |
530 | | or destroyed. |
531 | | |
532 | | @param yuvColorSpace The transformation from RGB to YUV. Applied to the resized image |
533 | | after it is converted to dstColorSpace. |
534 | | @param dstColorSpace The color space to convert the resized image to, after rescaling. |
535 | | @param srcRect The portion of the surface to rescale and convert to YUV planes. |
536 | | @param dstSize The size to rescale srcRect to |
537 | | @param rescaleGamma controls whether rescaling is done in the surface's gamma or whether |
538 | | the source data is transformed to a linear gamma before rescaling. |
539 | | @param rescaleMode controls the sampling technique of the rescaling |
540 | | @param callback function to call with the planar read result |
541 | | @param context passed to callback |
542 | | */ |
543 | | void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, |
544 | | sk_sp<SkColorSpace> dstColorSpace, |
545 | | const SkIRect& srcRect, |
546 | | const SkISize& dstSize, |
547 | | RescaleGamma rescaleGamma, |
548 | | RescaleMode rescaleMode, |
549 | | ReadPixelsCallback callback, |
550 | | ReadPixelsContext context); |
551 | | |
552 | | /** |
553 | | * Identical to asyncRescaleAndReadPixelsYUV420 but a fourth plane is returned in the |
554 | | * AsyncReadResult passed to 'callback'. The fourth plane contains the alpha chanel at the |
555 | | * same full resolution as the Y plane. |
556 | | */ |
557 | | void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace, |
558 | | sk_sp<SkColorSpace> dstColorSpace, |
559 | | const SkIRect& srcRect, |
560 | | const SkISize& dstSize, |
561 | | RescaleGamma rescaleGamma, |
562 | | RescaleMode rescaleMode, |
563 | | ReadPixelsCallback callback, |
564 | | ReadPixelsContext context); |
565 | | |
566 | | /** Copies SkRect of pixels from the src SkPixmap to the SkSurface. |
567 | | |
568 | | Source SkRect corners are (0, 0) and (src.width(), src.height()). |
569 | | Destination SkRect corners are (dstX, dstY) and |
570 | | (dstX + Surface width(), dstY + Surface height()). |
571 | | |
572 | | Copies each readable pixel intersecting both rectangles, without scaling, |
573 | | converting to SkSurface colorType() and SkSurface alphaType() if required. |
574 | | |
575 | | @param src storage for pixels to copy to SkSurface |
576 | | @param dstX x-axis position relative to SkSurface to begin copy; may be negative |
577 | | @param dstY y-axis position relative to SkSurface to begin copy; may be negative |
578 | | |
579 | | example: https://fiddle.skia.org/c/@Surface_writePixels |
580 | | */ |
581 | | void writePixels(const SkPixmap& src, int dstX, int dstY); |
582 | | |
583 | | /** Copies SkRect of pixels from the src SkBitmap to the SkSurface. |
584 | | |
585 | | Source SkRect corners are (0, 0) and (src.width(), src.height()). |
586 | | Destination SkRect corners are (dstX, dstY) and |
587 | | (dstX + Surface width(), dstY + Surface height()). |
588 | | |
589 | | Copies each readable pixel intersecting both rectangles, without scaling, |
590 | | converting to SkSurface colorType() and SkSurface alphaType() if required. |
591 | | |
592 | | @param src storage for pixels to copy to SkSurface |
593 | | @param dstX x-axis position relative to SkSurface to begin copy; may be negative |
594 | | @param dstY y-axis position relative to SkSurface to begin copy; may be negative |
595 | | |
596 | | example: https://fiddle.skia.org/c/@Surface_writePixels_2 |
597 | | */ |
598 | | void writePixels(const SkBitmap& src, int dstX, int dstY); |
599 | | |
600 | | /** Returns SkSurfaceProps for surface. |
601 | | |
602 | | @return LCD striping orientation and setting for device independent fonts |
603 | | */ |
604 | 63.0k | const SkSurfaceProps& props() const { return fProps; } |
605 | | |
606 | | /** Inserts a list of GPU semaphores that the current GPU-backed API must wait on before |
607 | | executing any more commands on the GPU for this surface. We only guarantee blocking |
608 | | transfer and fragment shader work, but may block earlier stages as well depending on the |
609 | | backend. |
610 | | If this call returns false, then the GPU back-end will not wait on any passed in |
611 | | semaphores, and the client will still own the semaphores, regardless of the value of |
612 | | deleteSemaphoresAfterWait. |
613 | | |
614 | | If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case |
615 | | it is the client's responsibility to not destroy or attempt to reuse the semaphores until it |
616 | | knows that Skia has finished waiting on them. This can be done by using finishedProcs |
617 | | on flush calls. |
618 | | |
619 | | @param numSemaphores size of waitSemaphores array |
620 | | @param waitSemaphores array of semaphore containers |
621 | | @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores |
622 | | @return true if GPU is waiting on semaphores |
623 | | */ |
624 | | bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, |
625 | | bool deleteSemaphoresAfterWait = true); |
626 | | |
627 | | /** Initializes GrSurfaceCharacterization that can be used to perform GPU back-end |
628 | | processing in a separate thread. Typically this is used to divide drawing |
629 | | into multiple tiles. GrDeferredDisplayListRecorder records the drawing commands |
630 | | for each tile. |
631 | | |
632 | | Return true if SkSurface supports characterization. raster surface returns false. |
633 | | |
634 | | @param characterization properties for parallel drawing |
635 | | @return true if supported |
636 | | |
637 | | example: https://fiddle.skia.org/c/@Surface_characterize |
638 | | */ |
639 | | bool characterize(GrSurfaceCharacterization* characterization) const; |
640 | | |
641 | | protected: |
642 | | SkSurface(int width, int height, const SkSurfaceProps* surfaceProps); |
643 | | SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps); |
644 | | |
645 | | // called by subclass if their contents have changed |
646 | 335k | void dirtyGenerationID() { |
647 | 335k | fGenerationID = 0; |
648 | 335k | } |
649 | | |
650 | | private: |
651 | | const SkSurfaceProps fProps; |
652 | | const int fWidth; |
653 | | const int fHeight; |
654 | | uint32_t fGenerationID; |
655 | | |
656 | | using INHERITED = SkRefCnt; |
657 | | }; |
658 | | |
659 | | #endif |