• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SkImage_DEFINED
9 #define SkImage_DEFINED
10 
11 #include "SkFilterQuality.h"
12 #include "SkImageInfo.h"
13 #include "SkImageEncoder.h"
14 #include "SkRefCnt.h"
15 #include "SkScalar.h"
16 #include "SkShader.h"
17 
18 class SkData;
19 class SkCanvas;
20 class SkColorTable;
21 class SkImageGenerator;
22 class SkPaint;
23 class SkPicture;
24 class SkPixelSerializer;
25 class SkString;
26 class SkSurface;
27 class GrBackendTexture;
28 class GrContext;
29 class GrContextThreadSafeProxy;
30 class GrTexture;
31 
32 struct AHardwareBuffer;
33 
34 /**
35  *  SkImage is an abstraction for drawing a rectagle of pixels, though the
36  *  particular type of image could be actually storing its data on the GPU, or
37  *  as drawing commands (picture or PDF or otherwise), ready to be played back
38  *  into another canvas.
39  *
40  *  The content of SkImage is always immutable, though the actual storage may
41  *  change, if for example that image can be re-created via encoded data or
42  *  other means.
43  *
44  *  SkImage always has a non-zero dimensions. If there is a request to create a new image, either
45  *  directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be
46  *  returned.
47  */
48 class SK_API SkImage : public SkRefCnt {
49 public:
50     typedef SkImageInfo Info;
51     typedef void* ReleaseContext;
52 
53     static sk_sp<SkImage> MakeRasterCopy(const SkPixmap&);
54     static sk_sp<SkImage> MakeRasterData(const Info&, sk_sp<SkData> pixels, size_t rowBytes);
55 
56     typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext);
57 
58     /**
59      *  Return a new Image referencing the specified pixels. These must remain valid and unchanged
60      *  until the specified release-proc is called, indicating that Skia no longer has a reference
61      *  to the pixels.
62      *
63      *  Returns NULL if the requested pixmap info is unsupported.
64      */
65     static sk_sp<SkImage> MakeFromRaster(const SkPixmap&, RasterReleaseProc, ReleaseContext);
66 
67     /**
68      *  Construct a new image from the specified bitmap. If the bitmap is marked immutable, and
69      *  its pixel memory is shareable, it may be shared instead of copied.
70      */
71     static sk_sp<SkImage> MakeFromBitmap(const SkBitmap&);
72 
73     /**
74      *  Construct a new SkImage based on the given ImageGenerator. Returns NULL on error.
75      *  This function will always take ownership of the passed generator.
76      *
77      *  If a subset is specified, it must be contained within the generator's bounds.
78      */
79     static sk_sp<SkImage> MakeFromGenerator(std::unique_ptr<SkImageGenerator>,
80                                             const SkIRect* subset = nullptr);
81 
82     /**
83      *  Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
84      *  which can mean that the format of the encoded data was not recognized/supported.
85      *
86      *  If a subset is specified, it must be contained within the encoded data's bounds.
87      */
88     static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);
89 
90     /**
91      *  Create a new image from the specified descriptor. Note - the caller is responsible for
92      *  managing the lifetime of the underlying platform texture.
93      *
94      *  Will return NULL if the specified descriptor is unsupported.
95      *
96      *  It is preferred to use the new methods which take a GrBackendTexture instead of a
97      *  GrBackendTextureDesc. This method will eventually be removed.
98      */
MakeFromTexture(GrContext * ctx,const GrBackendTextureDesc & desc)99     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
100         return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr);
101     }
102 
MakeFromTexture(GrContext * ctx,const GrBackendTextureDesc & de,SkAlphaType at)103     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& de,
104                                           SkAlphaType at) {
105         return MakeFromTexture(ctx, de, at, nullptr, nullptr, nullptr);
106     }
107 
108     typedef void (*TextureReleaseProc)(ReleaseContext);
109 
110     /**
111      *  Create a new image from the specified descriptor. The underlying platform texture must stay
112      *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
113      *  no longer is holding a reference to it.
114      *
115      *  Will return NULL if the specified descriptor is unsupported.
116      *
117      *  It is preferred to use the new methods which take a GrBackendTexture instead of a
118      *  GrBackendTextureDesc. This method will eventually be removed.
119      */
MakeFromTexture(GrContext * ctx,const GrBackendTextureDesc & desc,SkAlphaType at,TextureReleaseProc trp,ReleaseContext rc)120     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
121                                           SkAlphaType at, TextureReleaseProc trp,
122                                           ReleaseContext rc) {
123         return MakeFromTexture(ctx, desc, at, nullptr, trp, rc);
124     }
125 
126     /**
127     *  Create a new image from the specified descriptor. The underlying platform texture must stay
128     *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
129     *  no longer is holding a reference to it.
130     *
131     *  Will return NULL if the specified descriptor is unsupported.
132      *
133      *  It is preferred to use the new methods which take a GrBackendTexture instead of a
134      *  GrBackendTextureDesc. This method will eventually be removed.
135     */
136     static sk_sp<SkImage> MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
137                                           sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext);
138 
139     /**
140      *  Create a new image from the specified descriptor. Note - the caller is responsible for
141      *  managing the lifetime of the underlying platform texture.
142      *
143      *  Will return NULL if the specified backend texture is unsupported.
144      */
MakeFromTexture(GrContext * ctx,const GrBackendTexture & tex,GrSurfaceOrigin origin,SkAlphaType at,sk_sp<SkColorSpace> cs)145     static sk_sp<SkImage> MakeFromTexture(GrContext* ctx,
146                                           const GrBackendTexture& tex, GrSurfaceOrigin origin,
147                                           SkAlphaType at, sk_sp<SkColorSpace> cs) {
148         return MakeFromTexture(ctx, tex, origin, at, cs, nullptr, nullptr);
149     }
150 
151     /**
152      *  Create a new image from the GrBackendTexture. The underlying platform texture must stay
153      *  valid and unaltered until the specified release-proc is invoked, indicating that Skia
154      *  no longer is holding a reference to it.
155      *
156      *  Will return NULL if the specified backend texture is unsupported.
157      */
158     static sk_sp<SkImage> MakeFromTexture(GrContext*,
159                                           const GrBackendTexture&, GrSurfaceOrigin origin,
160                                           SkAlphaType, sk_sp<SkColorSpace>,
161                                           TextureReleaseProc, ReleaseContext);
162 
163     /**
164      *  Decodes and uploads the encoded data to a GPU backed image using the supplied GrContext.
165      *  That image can be safely used by other GrContexts, across thread boundaries. The GrContext
166      *  used here, and the ones used to draw this image later must be in the same GL share group,
167      *  or otherwise be able to share resources.
168      *
169      *  When the image's ref count reaches zero, the original GrContext will destroy the texture,
170      *  asynchronously.
171      *
172      *  The texture will be decoded and uploaded to be suitable for use with surfaces that have the
173      *  supplied destination color space. The color space of the image itself will be determined
174      *  from the encoded data.
175      */
176     static sk_sp<SkImage> MakeCrossContextFromEncoded(GrContext*, sk_sp<SkData>, bool buildMips,
177                                                       SkColorSpace* dstColorSpace);
178 
179     /**
180      *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
181      *  texture when the image is released.
182      *
183      *  Will return NULL if the specified descriptor is unsupported.
184      *
185      *  It is preferred to use the new methods which take a GrBackendTexture instead of a
186      *  GrBackendTextureDesc. This method will eventually be removed.
187      */
188     static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
189                                                  SkAlphaType = kPremul_SkAlphaType,
190                                                  sk_sp<SkColorSpace> = nullptr);
191 
192     /**
193      *  Create a new image from the specified descriptor. Note - Skia will delete or recycle the
194      *  texture when the image is released.
195      *
196      *  Will return NULL if the specified backend texture is unsupported.
197      */
198     static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*,
199                                                  const GrBackendTexture&, GrSurfaceOrigin,
200                                                  SkAlphaType = kPremul_SkAlphaType,
201                                                  sk_sp<SkColorSpace> = nullptr);
202 
203     /**
204      *  Create a new image by copying the pixels from the specified y, u, v textures. The data
205      *  from the textures is immediately ingested into the image and the textures can be modified or
206      *  deleted after the function returns. The image will have the dimensions of the y texture.
207      */
208     static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
209                                                   const GrBackendObject yuvTextureHandles[3],
210                                                   const SkISize yuvSizes[3],
211                                                   GrSurfaceOrigin,
212                                                   sk_sp<SkColorSpace> = nullptr);
213 
214     /**
215      *  Create a new image by copying the pixels from the specified y and uv textures. The data
216      *  from the textures is immediately ingested into the image and the textures can be modified or
217      *  deleted after the function returns. The image will have the dimensions of the y texture.
218      */
219     static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext*, SkYUVColorSpace,
220                                                    const GrBackendObject nv12TextureHandles[2],
221                                                    const SkISize nv12Sizes[2], GrSurfaceOrigin,
222                                                    sk_sp<SkColorSpace> = nullptr);
223 
224     enum class BitDepth {
225         kU8,
226         kF16,
227     };
228 
229     /**
230      *  Create a new image from the specified picture.
231      *  On creation of the SkImage, snap the SkPicture to a particular BitDepth and SkColorSpace.
232      */
233     static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
234                                           const SkMatrix*, const SkPaint*, BitDepth,
235                                           sk_sp<SkColorSpace>);
236 
237 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
238     /**
239      *  Create a new image from the an Android hardware buffer.
240      *  The new image takes a reference on the buffer.
241      */
242     static sk_sp<SkImage> MakeFromAHardwareBuffer(AHardwareBuffer*,
243                                                  SkAlphaType = kPremul_SkAlphaType,
244                                                  sk_sp<SkColorSpace> = nullptr);
245 #endif
246 
247     ///////////////////////////////////////////////////////////////////////////////////////////////
248 
width()249     int width() const { return fWidth; }
height()250     int height() const { return fHeight; }
dimensions()251     SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
bounds()252     SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
uniqueID()253     uint32_t uniqueID() const { return fUniqueID; }
254     SkAlphaType alphaType() const;
255 
256     /**
257      *  Returns the color space of the SkImage.
258      *
259      *  This is the color space that was supplied on creation of the SkImage or a color
260      *  space that was parsed from encoded data.  This color space is not guaranteed to be
261      *  renderable.  Can return nullptr if the SkImage was created without a color space.
262      */
263     SkColorSpace* colorSpace() const;
264     sk_sp<SkColorSpace> refColorSpace() const;
265 
266     /**
267      *  Returns true fi the image will be drawn as a mask, with no intrinsic color of its own.
268      */
269     bool isAlphaOnly() const;
isOpaque()270     bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
271 
272     sk_sp<SkShader> makeShader(SkShader::TileMode, SkShader::TileMode,
273                                const SkMatrix* localMatrix = nullptr) const;
274     /**
275      *  Helper version of makeShader() that specifies Clamp tilemode.
276      */
277     sk_sp<SkShader> makeShader(const SkMatrix* localMatrix = nullptr) const {
278         return this->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, localMatrix);
279     }
280 
281     /**
282      *  If the image has direct access to its pixels (i.e. they are in local RAM)
283      *  return true, and if not null, return in the pixmap parameter the info about the
284      *  images pixels.
285      *
286      *  On failure, return false and ignore the pixmap parameter.
287      */
288     bool peekPixels(SkPixmap* pixmap) const;
289 
290     // DEPRECATED - currently used by Canvas2DLayerBridge in Chromium.
291     GrTexture* getTexture() const;
292 
293     /**
294      *  Returns true if the image is texture backed.
295      */
296     bool isTextureBacked() const;
297 
298     /**
299      *  Returns true if the image is able to be drawn to a particular type of device. If context
300      *  is nullptr, tests for drawability to CPU devices. Otherwise, tests for drawability to a GPU
301      *  device backed by context.
302      *
303      *  Texture-backed images may become invalid if their underlying GrContext is abandoned. Some
304      *  generator-backed images may be invalid for CPU and/or GPU.
305      */
306     bool isValid(GrContext* context) const;
307 
308     /**
309      *  Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the
310      *  GrContext will issue to the backend API any deferred IO operations on the texture before
311      *  returning.
312      *  If 'origin' is supplied it will be filled in with the origin of the content drawn
313      *  into the image.
314      */
315     GrBackendObject getTextureHandle(bool flushPendingGrContextIO,
316                                      GrSurfaceOrigin* origin = nullptr) const;
317 
318     /**
319      *  Hints to image calls where the system might cache computed intermediates (e.g. the results
320      *  of decoding or a read-back from the GPU. Passing kAllow signals that the system's default
321      *  behavior is fine. Passing kDisallow signals that caching should be avoided.
322      */
323      enum CachingHint {
324         kAllow_CachingHint,
325         kDisallow_CachingHint,
326     };
327 
328     /**
329      *  Copy the pixels from the image into the specified buffer (pixels + rowBytes),
330      *  converting them into the requested format (dstInfo). The image pixels are read
331      *  starting at the specified (srcX,srcY) location.
332      *
333      *  The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
334      *
335      *      srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
336      *
337      *  srcR is intersected with the bounds of the image. If this intersection is not empty,
338      *  then we have two sets of pixels (of equal size). Replace the dst pixels with the
339      *  corresponding src pixels, performing any colortype/alphatype transformations needed
340      *  (in the case where the src and dst have different colortypes or alphatypes).
341      *
342      *  This call can fail, returning false, for several reasons:
343      *  - If srcR does not intersect the image bounds.
344      *  - If the requested colortype/alphatype cannot be converted from the image's types.
345      */
346     bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
347                     int srcX, int srcY, CachingHint = kAllow_CachingHint) const;
348 
349     bool readPixels(const SkPixmap& dst, int srcX, int srcY,
350                     CachingHint = kAllow_CachingHint) const;
351 
352     /**
353      *  Copy the pixels from this image into the dst pixmap, converting as needed into dst's
354      *  colortype/alphatype. If the conversion cannot be performed, false is returned.
355      *
356      *  If dst's dimensions differ from the src dimension, the image will be scaled, applying the
357      *  specified filter-quality.
358      */
359     bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const;
360 
361     /**
362      *  Encode the image's pixels and return the result as SkData.
363      *
364      *  If the image type cannot be encoded, or the requested encoder format is
365      *  not supported, this will return NULL.
366      */
367     sk_sp<SkData> encodeToData(SkEncodedImageFormat, int quality) const;
368 
369     /**
370      *  Encode the image and return the result as SkData.  This will attempt to reuse existing
371      *  encoded data (as returned by refEncodedData).
372      *
373      *  We defer to the SkPixelSerializer both for vetting existing encoded data
374      *  (useEncodedData) and for encoding the image (encode) when no such data is
375      *  present or is rejected by the serializer.
376      *
377      *  If not specified, we use a default serializer which 1) always accepts existing data
378      *  (in any format) and 2) encodes to PNG.
379      *
380      *  If no compatible encoded data exists and encoding fails, this method will also
381      *  fail (return NULL).
382      */
383     sk_sp<SkData> encodeToData(SkPixelSerializer* = nullptr) const;
384 
385     /**
386      *  If the image already has its contents in encoded form (e.g. PNG or JPEG), return that
387      *  as SkData. If the image does not already has its contents in encoded form, return NULL.
388      *
389      *  Note: to force the image to return its contents as encoded data, use encodeToData(...).
390      */
391     sk_sp<SkData> refEncodedData() const;
392 
393     const char* toString(SkString*) const;
394 
395     /**
396      *  Return a new image that is a subset of this image. The underlying implementation may
397      *  share the pixels, or it may make a copy.
398      *
399      *  If subset does not intersect the bounds of this image, or the copy/share cannot be made,
400      *  NULL will be returned.
401      */
402     sk_sp<SkImage> makeSubset(const SkIRect& subset) const;
403 
404     /**
405      *  Ensures that an image is backed by a texture (when GrContext is non-null), suitable for use
406      *  with surfaces that have the supplied destination color space. If no transformation is
407      *  required, the returned image may be the same as this image. If this image is from a
408      *  different GrContext, this will fail.
409      */
410     sk_sp<SkImage> makeTextureImage(GrContext*, SkColorSpace* dstColorSpace) const;
411 
412     /**
413      * If the image is texture-backed this will make a raster copy of it (or nullptr if reading back
414      * the pixels fails). Otherwise, it returns the original image.
415      */
416     sk_sp<SkImage> makeNonTextureImage() const;
417     /**
418      *  Apply a given image filter to this image, and return the filtered result.
419      *
420      *  The subset represents the active portion of this image. The return value is similarly an
421      *  SkImage, with an active subset (outSubset). This is usually used with texture-backed
422      *  images, where the texture may be approx-match and thus larger than the required size.
423      *
424      *  clipBounds constrains the device-space extent of the image which may be produced to the
425      *  given rect.
426      *
427      *  offset is the amount to translate the resulting image relative to the src when it is drawn.
428      *  This is an out-param.
429      *
430      *  If the result image cannot be created, or the result would be transparent black, null
431      *  is returned, in which case the offset and outSubset parameters should be ignored by the
432      *  caller.
433      */
434     sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
435                                   const SkIRect& clipBounds, SkIRect* outSubset,
436                                   SkIPoint* offset) const;
437 
438     /** Drawing params for which a deferred texture image data should be optimized. */
439     struct DeferredTextureImageUsageParams {
DeferredTextureImageUsageParamsDeferredTextureImageUsageParams440         DeferredTextureImageUsageParams(const SkMatrix matrix, const SkFilterQuality quality,
441                                         int preScaleMipLevel)
442             : fMatrix(matrix), fQuality(quality), fPreScaleMipLevel(preScaleMipLevel) {}
443         SkMatrix        fMatrix;
444         SkFilterQuality fQuality;
445         int             fPreScaleMipLevel;
446     };
447 
448     /**
449      * This method allows clients to capture the data necessary to turn a SkImage into a texture-
450      * backed image. If the original image is codec-backed this will decode into a format optimized
451      * for the context represented by the proxy. This method is thread safe with respect to the
452      * GrContext whence the proxy came. Clients allocate and manage the storage of the deferred
453      * texture data and control its lifetime. No cleanup is required, thus it is safe to simply free
454      * the memory out from under the data.
455      *
456      * The same method is used both for getting the size necessary for pre-uploaded texture data
457      * and for retrieving the data. The params array represents the set of draws over which to
458      * optimize the pre-upload data.
459      *
460      * When called with a null buffer this returns the size that the client must allocate in order
461      * to create deferred texture data for this image (or zero if this is an inappropriate
462      * candidate). The buffer allocated by the client should be 8 byte aligned.
463      *
464      * When buffer is not null this fills in the deferred texture data for this image in the
465      * provided buffer (assuming this is an appropriate candidate image and the buffer is
466      * appropriately aligned). Upon success the size written is returned, otherwise 0.
467      *
468      * dstColorSpace is the color space of the surface where this texture will ultimately be used.
469      * If the method determines that mip-maps are needed, this helps determine the correct strategy
470      * for building them (gamma-correct or not).
471      *
472      * dstColorType is the color type of the surface where this texture will ultimately be used.
473      * This determines the format with which the image will be uploaded to the GPU. If dstColorType
474      * does not support color spaces (low bit depth types such as ARGB_4444), then dstColorSpace
475      * must be null.
476      */
477     size_t getDeferredTextureImageData(const GrContextThreadSafeProxy&,
478                                        const DeferredTextureImageUsageParams[],
479                                        int paramCnt,
480                                        void* buffer,
481                                        SkColorSpace* dstColorSpace = nullptr,
482                                        SkColorType dstColorType = kN32_SkColorType) const;
483 
484     /**
485      * Returns a texture-backed image from data produced in SkImage::getDeferredTextureImageData.
486      * The context must be the context that provided the proxy passed to
487      * getDeferredTextureImageData.
488      */
489     static sk_sp<SkImage> MakeFromDeferredTextureImageData(GrContext*, const void*, SkBudgeted);
490 
491     // Helper functions to convert to SkBitmap
492 
493     enum LegacyBitmapMode {
494         kRO_LegacyBitmapMode,
495         kRW_LegacyBitmapMode,
496     };
497 
498     /**
499      *  Attempt to create a bitmap with the same pixels as the image. The result will always be
500      *  a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here).
501      *
502      *  If the mode is kRO (read-only), the resulting bitmap will be marked as immutable.
503      *
504      *  On succcess, returns true. On failure, returns false and the bitmap parameter will be reset
505      *  to empty.
506      */
507     bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
508 
509     /**
510      *  Returns true if the image is backed by an image-generator or other src that creates
511      *  (and caches) its pixels / texture on-demand.
512      */
513     bool isLazyGenerated() const;
514 
515     /**
516      *  If |target| is supported, returns an SkImage in the |target| color space.
517      *  Otherwise, returns nullptr.
518      *
519      *  This will leave the image as is if it already in the |target| color space.
520      *  Otherwise, it will convert the pixels from the src color space to the |target|
521      *  color space.  If this->colorSpace() is nullptr, the src color space will be
522      *  treated as sRGB.
523      *
524      *  If |premulBehavior| is kIgnore, any premultiplication or unpremultiplication will
525      *  be performed in the gamma encoded space.  If it is kRespect, premultiplication is
526      *  assumed to be linear.
527      */
528     sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target,
529                                   SkTransferFunctionBehavior premulBehavior) const;
530 
531 private:
532     SkImage(int width, int height, uint32_t uniqueID);
533     friend class SkImage_Base;
534 
535     static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
536                                                 const GrMipLevel texels[], int mipLevelCount,
537                                                 SkBudgeted, SkDestinationSurfaceColorMode);
538 
539     const int       fWidth;
540     const int       fHeight;
541     const uint32_t  fUniqueID;
542 
543     typedef SkRefCnt INHERITED;
544 };
545 
546 #endif
547