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