Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2016 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 SkSpecialImage_DEFINED
      9 #define SkSpecialImage_DEFINED
     10 
     11 #include "SkNextID.h"
     12 #include "SkRefCnt.h"
     13 #include "SkSurfaceProps.h"
     14 
     15 #include "SkImageFilter.h" // for OutputProperties
     16 #include "SkImageInfo.h"   // for SkAlphaType
     17 
     18 class GrContext;
     19 class GrTextureProxy;
     20 class SkBitmap;
     21 class SkCanvas;
     22 class SkImage;
     23 struct SkImageInfo;
     24 class SkPaint;
     25 class SkPixmap;
     26 class SkSpecialSurface;
     27 class SkSurface;
     28 
     29 enum {
     30     kNeedNewImageUniqueID_SpecialImage = 0
     31 };
     32 
     33 /**
     34  * This is a restricted form of SkImage solely intended for internal use. It
     35  * differs from SkImage in that:
     36  *      - it can only be backed by raster or gpu (no generators)
     37  *      - it can be backed by a GrTextureProxy larger than its nominal bounds
     38  *      - it can't be drawn tiled
     39  *      - it can't be drawn with MIPMAPs
     40  * It is similar to SkImage in that it abstracts how the pixels are stored/represented.
     41  *
     42  * Note: the contents of the backing storage outside of the subset rect are undefined.
     43  */
     44 class SkSpecialImage : public SkRefCnt {
     45 public:
     46     typedef void* ReleaseContext;
     47     typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext);
     48 
     49     const SkSurfaceProps& props() const { return fProps; }
     50 
     51     int width() const { return fSubset.width(); }
     52     int height() const { return fSubset.height(); }
     53     const SkIRect& subset() const { return fSubset; }
     54     SkColorSpace* getColorSpace() const;
     55 
     56     uint32_t uniqueID() const { return fUniqueID; }
     57     virtual SkAlphaType alphaType() const = 0;
     58     virtual size_t getSize() const = 0;
     59 
     60     /**
     61      *  Ensures that a special image is backed by a texture (when GrContext is non-null). If no
     62      *  transformation is required, the returned image may be the same as this special image.
     63      *  If this special image is from a different GrContext, this will fail.
     64      */
     65     sk_sp<SkSpecialImage> makeTextureImage(GrContext*);
     66 
     67     /**
     68      *  Draw this SpecialImage into the canvas.
     69      */
     70     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
     71 
     72     static sk_sp<SkSpecialImage> MakeFromImage(const SkIRect& subset,
     73                                                sk_sp<SkImage>,
     74                                                SkColorSpace* dstColorSpace,
     75                                                const SkSurfaceProps* = nullptr);
     76     static sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset,
     77                                                 const SkBitmap&,
     78                                                 const SkSurfaceProps* = nullptr);
     79 #if SK_SUPPORT_GPU
     80     static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrContext*,
     81                                                      const SkIRect& subset,
     82                                                      uint32_t uniqueID,
     83                                                      sk_sp<GrTextureProxy>,
     84                                                      sk_sp<SkColorSpace>,
     85                                                      const SkSurfaceProps* = nullptr,
     86                                                      SkAlphaType at = kPremul_SkAlphaType);
     87 #endif
     88 
     89     /**
     90      *  Create a new special surface with a backend that is compatible with this special image.
     91      */
     92     sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps,
     93                                         const SkISize& size,
     94                                         SkAlphaType at = kPremul_SkAlphaType) const;
     95 
     96     /**
     97      * Create a new surface with a backend that is compatible with this special image.
     98      * TODO: switch this to makeSurface once we resolved the naming issue
     99      */
    100     sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps,
    101                                       const SkISize& size,
    102                                       SkAlphaType at = kPremul_SkAlphaType) const;
    103 
    104     /**
    105      * Extract a subset of this special image and return it as a special image.
    106      * It may or may not point to the same backing memory.
    107      */
    108     sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const;
    109 
    110     /**
    111      * Create an SkImage from the contents of this special image optionally extracting a subset.
    112      * It may or may not point to the same backing memory.
    113      * Note: when no 'subset' parameter is specified the the entire SkSpecialImage will be
    114      * returned - including whatever extra padding may have resulted from a loose fit!
    115      * When the 'subset' parameter is specified the returned image will be tight even if that
    116      * entails a copy!
    117      */
    118     sk_sp<SkImage> asImage(const SkIRect* subset = nullptr) const;
    119 
    120     /**
    121      *  If the SpecialImage is backed by a gpu texture, return true.
    122      */
    123     bool isTextureBacked() const;
    124 
    125     /**
    126      * Return the GrContext if the SkSpecialImage is GrTexture-backed
    127      */
    128     GrContext* getContext() const;
    129 
    130 #if SK_SUPPORT_GPU
    131     /**
    132      *  Regardless of the underlying backing store, return the contents as a GrTextureProxy.
    133      *  The active portion of the texture can be retrieved via 'subset'.
    134      */
    135     sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*) const;
    136 #endif
    137 
    138     /**
    139      *  Regardless of the underlying backing store, return the contents as an SkBitmap
    140      *
    141      *  The returned ImageInfo represents the backing memory. Use 'subset'
    142      *  to get the active portion's dimensions.
    143      */
    144     bool getROPixels(SkBitmap*) const;
    145 
    146 protected:
    147     SkSpecialImage(const SkIRect& subset, uint32_t uniqueID, const SkSurfaceProps*);
    148 
    149 private:
    150     const SkSurfaceProps fProps;
    151     const SkIRect        fSubset;
    152     const uint32_t       fUniqueID;
    153 
    154     typedef SkRefCnt INHERITED;
    155 };
    156 
    157 #endif
    158