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