Plumb dst color space in many places, rather than "mode"
[platform/upstream/libSkiaSharp.git] / src / core / SkSpecialImage.h
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 GrSurfaceProxy;
20 class GrTexture;
21 class GrTextureProxy;
22 class SkBitmap;
23 class SkCanvas;
24 class SkImage;
25 struct SkImageInfo;
26 class SkPaint;
27 class SkPixmap;
28 class SkSpecialSurface;
29 class SkSurface;
30
31 enum {
32     kNeedNewImageUniqueID_SpecialImage = 0
33 };
34
35 /**
36  * This is a restricted form of SkImage solely intended for internal use. It
37  * differs from SkImage in that:
38  *      - it can only be backed by raster or gpu (no generators)
39  *      - it can be backed by a GrTexture larger than its nominal bounds
40  *      - it can't be drawn tiled
41  *      - it can't be drawn with MIPMAPs
42  * It is similar to SkImage in that it abstracts how the pixels are stored/represented.
43  *
44  * Note: the contents of the backing storage outside of the subset rect are undefined.
45  */
46 class SkSpecialImage : public SkRefCnt {
47 public:
48     typedef void* ReleaseContext;
49     typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext);
50
51     const SkSurfaceProps& props() const { return fProps; }
52
53     int width() const { return fSubset.width(); }
54     int height() const { return fSubset.height(); }
55     const SkIRect& subset() const { return fSubset; }
56     SkColorSpace* getColorSpace() const;
57
58     uint32_t uniqueID() const { return fUniqueID; }
59     virtual SkAlphaType alphaType() const = 0;
60     virtual size_t getSize() const = 0;
61
62     /**
63      *  Ensures that a special image is backed by a texture (when GrContext is non-null). If no
64      *  transformation is required, the returned image may be the same as this special image.
65      *  If this special image is from a different GrContext, this will fail.
66      */
67     sk_sp<SkSpecialImage> makeTextureImage(GrContext*);
68
69     /**
70      *  Draw this SpecialImage into the canvas.
71      */
72     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
73
74     static sk_sp<SkSpecialImage> MakeFromImage(const SkIRect& subset,
75                                                sk_sp<SkImage>,
76                                                SkColorSpace* dstColorSpace,
77                                                const SkSurfaceProps* = nullptr);
78     static sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset,
79                                                 const SkBitmap&,
80                                                 const SkSurfaceProps* = nullptr);
81 #if SK_SUPPORT_GPU
82     static sk_sp<SkSpecialImage> MakeFromGpu(const SkIRect& subset,
83                                              uint32_t uniqueID,
84                                              sk_sp<GrTexture>,
85                                              sk_sp<SkColorSpace>,
86                                              const SkSurfaceProps* = nullptr,
87                                              SkAlphaType at = kPremul_SkAlphaType);
88
89     static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrContext*,
90                                                      const SkIRect& subset,
91                                                      uint32_t uniqueID,
92                                                      sk_sp<GrSurfaceProxy>,
93                                                      sk_sp<SkColorSpace>,
94                                                      const SkSurfaceProps* = nullptr,
95                                                      SkAlphaType at = kPremul_SkAlphaType);
96 #endif
97
98     /**
99      *  Create a new special surface with a backend that is compatible with this special image.
100      */
101     sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps,
102                                         const SkISize& size,
103                                         SkAlphaType at = kPremul_SkAlphaType) const;
104
105     /**
106      * Create a new surface with a backend that is compatible with this special image.
107      * TODO: switch this to makeSurface once we resolved the naming issue
108      */
109     sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps,
110                                       const SkISize& size,
111                                       SkAlphaType at = kPremul_SkAlphaType) const;
112
113     /**
114      * Extract a subset of this special image and return it as a special image.
115      * It may or may not point to the same backing memory.
116      */
117     sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const;
118
119     /**
120      * Extract a subset of this special image and return it as an SkImage.
121      * It may or may not point to the same backing memory.
122      * TODO: switch this to makeSurface once we resolved the naming issue
123      */
124     sk_sp<SkImage> makeTightSubset(const SkIRect& subset) const;
125
126     // TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
127     /**
128      *  If the SpecialImage is backed by a gpu texture, return true.
129      */
130     bool isTextureBacked() const;
131
132     /**
133      * Return the GrContext if the SkSpecialImage is GrTexture-backed
134      */
135     GrContext* getContext() const;
136
137 #if SK_SUPPORT_GPU
138     /**
139      *  Regardless of the underlying backing store, return the contents as a GrTexture.
140      *  The active portion of the texture can be retrieved via 'subset'.
141      */
142     sk_sp<GrTexture> asTextureRef(GrContext*) const;
143
144     /**
145      *  The same as above but return the contents as a GrTextureProxy.
146      */
147     sk_sp<GrTextureProxy> asTextureProxy(GrContext*) const;
148 #endif
149
150     // TODO: hide this whe the imagefilter all have a consistent draw path (see skbug.com/5063)
151     /**
152      *  Regardless of the underlying backing store, return the contents as an SkBitmap
153      *
154      *  The returned ImageInfo represents the backing memory. Use 'subset'
155      *  to get the active portion's dimensions.
156      */
157     bool getROPixels(SkBitmap*) const;
158
159 protected:
160     SkSpecialImage(const SkIRect& subset, uint32_t uniqueID, const SkSurfaceProps*);
161
162 private:
163     const SkSurfaceProps fProps;
164     const SkIRect        fSubset;
165     const uint32_t       fUniqueID;
166
167     typedef SkRefCnt INHERITED;
168 };
169
170 #endif