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 | const SkSurfaceProps* props = nullptr) { |
82 | return Raster(imageInfo, 0, props); |
83 | } |
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 | inline sk_sp<SkSurface> WrapPixels(const SkPixmap& pm, const SkSurfaceProps* props = nullptr) { |
113 | return WrapPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), props); |
114 | } |
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 | 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 | int height() const { return fHeight; } |
185 | |
186 | /** Returns an ImageInfo describing the surface. |
187 | */ |
188 | virtual SkImageInfo imageInfo() const { return SkImageInfo::MakeUnknown(width: fWidth, height: 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 | void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint = nullptr) { |
350 | this->draw(canvas, x, y, sampling: SkSamplingOptions(), paint); |
351 | } |
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 | 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. If this call returns false, then |
608 | the GPU back-end will not wait on any passed in semaphores, and the client will still own |
609 | the semaphores, regardless of the value of deleteSemaphoresAfterWait. |
610 | |
611 | If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case |
612 | it is the client's responsibility to not destroy or attempt to reuse the semaphores until it |
613 | knows that Skia has finished waiting on them. This can be done by using finishedProcs |
614 | on flush calls. |
615 | |
616 | @param numSemaphores size of waitSemaphores array |
617 | @param waitSemaphores array of semaphore containers |
618 | @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores |
619 | @return true if GPU is waiting on semaphores |
620 | */ |
621 | bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores, |
622 | bool deleteSemaphoresAfterWait = true); |
623 | |
624 | /** Initializes GrSurfaceCharacterization that can be used to perform GPU back-end |
625 | processing in a separate thread. Typically this is used to divide drawing |
626 | into multiple tiles. GrDeferredDisplayListRecorder records the drawing commands |
627 | for each tile. |
628 | |
629 | Return true if SkSurface supports characterization. raster surface returns false. |
630 | |
631 | @param characterization properties for parallel drawing |
632 | @return true if supported |
633 | |
634 | example: https://fiddle.skia.org/c/@Surface_characterize |
635 | */ |
636 | bool characterize(GrSurfaceCharacterization* characterization) const; |
637 | |
638 | protected: |
639 | SkSurface(int width, int height, const SkSurfaceProps* surfaceProps); |
640 | SkSurface(const SkImageInfo& imageInfo, const SkSurfaceProps* surfaceProps); |
641 | |
642 | // called by subclass if their contents have changed |
643 | void dirtyGenerationID() { |
644 | fGenerationID = 0; |
645 | } |
646 | |
647 | private: |
648 | const SkSurfaceProps fProps; |
649 | const int fWidth; |
650 | const int fHeight; |
651 | uint32_t fGenerationID; |
652 | |
653 | using INHERITED = SkRefCnt; |
654 | }; |
655 | |
656 | #endif |
657 | |