Home | History | Annotate | Download | only in core
      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