Line data Source code
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 GrTextureProxy 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 3 : class SkSpecialImage : public SkRefCnt {
47 : public:
48 : typedef void* ReleaseContext;
49 : typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext);
50 :
51 0 : const SkSurfaceProps& props() const { return fProps; }
52 :
53 0 : int width() const { return fSubset.width(); }
54 0 : int height() const { return fSubset.height(); }
55 0 : const SkIRect& subset() const { return fSubset; }
56 : SkColorSpace* getColorSpace() const;
57 :
58 0 : 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> MakeDeferredFromGpu(GrContext*,
83 : const SkIRect& subset,
84 : uint32_t uniqueID,
85 : sk_sp<GrTextureProxy>,
86 : sk_sp<SkColorSpace>,
87 : const SkSurfaceProps* = nullptr,
88 : SkAlphaType at = kPremul_SkAlphaType);
89 : #endif
90 :
91 : /**
92 : * Create a new special surface with a backend that is compatible with this special image.
93 : */
94 : sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps,
95 : const SkISize& size,
96 : SkAlphaType at = kPremul_SkAlphaType) const;
97 :
98 : /**
99 : * Create a new surface with a backend that is compatible with this special image.
100 : * TODO: switch this to makeSurface once we resolved the naming issue
101 : */
102 : sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps,
103 : const SkISize& size,
104 : SkAlphaType at = kPremul_SkAlphaType) const;
105 :
106 : /**
107 : * Extract a subset of this special image and return it as a special image.
108 : * It may or may not point to the same backing memory.
109 : */
110 : sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const;
111 :
112 : /**
113 : * Create an SkImage from the contents of this special image optionally extracting a subset.
114 : * It may or may not point to the same backing memory.
115 : * Note: when no 'subset' parameter is specified the the entire SkSpecialImage will be
116 : * returned - including whatever extra padding may have resulted from a loose fit!
117 : * When the 'subset' parameter is specified the returned image will be tight even if that
118 : * entails a copy!
119 : */
120 : sk_sp<SkImage> asImage(const SkIRect* subset = nullptr) const;
121 :
122 : // TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
123 : /**
124 : * If the SpecialImage is backed by a gpu texture, return true.
125 : */
126 : bool isTextureBacked() const;
127 :
128 : /**
129 : * Return the GrContext if the SkSpecialImage is GrTexture-backed
130 : */
131 : GrContext* getContext() const;
132 :
133 : #if SK_SUPPORT_GPU
134 : /**
135 : * Regardless of the underlying backing store, return the contents as a GrTextureProxy.
136 : * The active portion of the texture can be retrieved via 'subset'.
137 : */
138 : sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*) const;
139 : #endif
140 :
141 : // TODO: hide this whe the imagefilter all have a consistent draw path (see skbug.com/5063)
142 : /**
143 : * Regardless of the underlying backing store, return the contents as an SkBitmap
144 : *
145 : * The returned ImageInfo represents the backing memory. Use 'subset'
146 : * to get the active portion's dimensions.
147 : */
148 : bool getROPixels(SkBitmap*) const;
149 :
150 : protected:
151 : SkSpecialImage(const SkIRect& subset, uint32_t uniqueID, const SkSurfaceProps*);
152 :
153 : private:
154 : const SkSurfaceProps fProps;
155 : const SkIRect fSubset;
156 : const uint32_t fUniqueID;
157 :
158 : typedef SkRefCnt INHERITED;
159 : };
160 :
161 : #endif
|