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 
props()49     const SkSurfaceProps& props() const { return fProps; }
50 
width()51     int width() const { return fSubset.width(); }
height()52     int height() const { return fSubset.height(); }
subset()53     const SkIRect& subset() const { return fSubset; }
54     SkColorSpace* getColorSpace() const;
55 
uniqueID()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