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 */ 99 static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) { 100 return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr); 101 } 102 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 */ 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 */ 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 249 int width() const { return fWidth; } 250 int height() const { return fHeight; } 251 SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } 252 SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } 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; 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 { 440 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