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