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