1 /*
2  * Copyright 2013 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 GrDistanceFieldGeoProc_DEFINED
9 #define GrDistanceFieldGeoProc_DEFINED
10 
11 #include "src/gpu/GrGeometryProcessor.h"
12 #include "src/gpu/GrProcessor.h"
13 
14 class GrGLDistanceFieldA8TextGeoProc;
15 class GrGLDistanceFieldPathGeoProc;
16 class GrGLDistanceFieldLCDTextGeoProc;
17 class GrInvariantOutput;
18 
19 enum GrDistanceFieldEffectFlags {
20     kSimilarity_DistanceFieldEffectFlag   = 0x01, // ctm is similarity matrix
21     kScaleOnly_DistanceFieldEffectFlag    = 0x02, // ctm has only scale and translate
22     kPerspective_DistanceFieldEffectFlag  = 0x04, // ctm has perspective (and positions are x,y,w)
23     kUseLCD_DistanceFieldEffectFlag       = 0x08, // use lcd text
24     kBGR_DistanceFieldEffectFlag          = 0x10, // lcd display has bgr order
25     kPortrait_DistanceFieldEffectFlag     = 0x20, // lcd display is in portrait mode (not used yet)
26     kGammaCorrect_DistanceFieldEffectFlag = 0x40, // assume gamma-correct output (linear blending)
27     kAliased_DistanceFieldEffectFlag      = 0x80, // monochrome output
28 
29     kInvalid_DistanceFieldEffectFlag      = 0x100,   // invalid state (for initialization)
30 
31     kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
32                                             kScaleOnly_DistanceFieldEffectFlag,
33     // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc
34     kNonLCD_DistanceFieldEffectMask       = kSimilarity_DistanceFieldEffectFlag |
35                                             kScaleOnly_DistanceFieldEffectFlag |
36                                             kPerspective_DistanceFieldEffectFlag |
37                                             kGammaCorrect_DistanceFieldEffectFlag |
38                                             kAliased_DistanceFieldEffectFlag,
39     // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc
40     kLCD_DistanceFieldEffectMask          = kSimilarity_DistanceFieldEffectFlag |
41                                             kScaleOnly_DistanceFieldEffectFlag |
42                                             kPerspective_DistanceFieldEffectFlag |
43                                             kUseLCD_DistanceFieldEffectFlag |
44                                             kBGR_DistanceFieldEffectFlag |
45                                             kGammaCorrect_DistanceFieldEffectFlag,
46 };
47 
48 /**
49  * The output color of this effect is a modulation of the input color and a sample from a
50  * distance field texture (using a smoothed step function near 0.5).
51  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
52  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
53  */
54 class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
55 public:
56     static constexpr int kMaxTextures = 4;
57 
58     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
59 #ifdef SK_GAMMA_APPLY_TO_A8
Make(const GrShaderCaps & caps,const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params,float lum,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)60     static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
61                                            const sk_sp<GrTextureProxy>* proxies,
62                                            int numActiveProxies,
63                                            const GrSamplerState& params, float lum, uint32_t flags,
64                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
65         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
66                 caps, proxies, numActiveProxies, params, lum, flags, localMatrixIfUsesLocalCoords));
67     }
68 #else
Make(const GrShaderCaps & caps,const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)69     static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
70                                            const sk_sp<GrTextureProxy>* proxies,
71                                            int numActiveProxies,
72                                            const GrSamplerState& params, uint32_t flags,
73                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
74         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
75                 caps, proxies, numActiveProxies, params, flags, localMatrixIfUsesLocalCoords));
76     }
77 #endif
78 
~GrDistanceFieldA8TextGeoProc()79     ~GrDistanceFieldA8TextGeoProc() override {}
80 
name()81     const char* name() const override { return "DistanceFieldA8Text"; }
82 
inPosition()83     const Attribute& inPosition() const { return fInPosition; }
inColor()84     const Attribute& inColor() const { return fInColor; }
inTextureCoords()85     const Attribute& inTextureCoords() const { return fInTextureCoords; }
localMatrix()86     const SkMatrix& localMatrix() const { return fLocalMatrix; }
87 #ifdef SK_GAMMA_APPLY_TO_A8
getDistanceAdjust()88     float getDistanceAdjust() const { return fDistanceAdjust; }
89 #endif
getFlags()90     uint32_t getFlags() const { return fFlags; }
atlasSize()91     const SkISize& atlasSize() const { return fAtlasSize; }
92 
93     void addNewProxies(const sk_sp<GrTextureProxy>* proxies, int numProxies, const GrSamplerState&);
94 
95     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
96 
97     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
98 
99 private:
100     GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
101                                  const sk_sp<GrTextureProxy>* proxies,
102                                  int numActiveProxies,
103                                  const GrSamplerState& params,
104 #ifdef SK_GAMMA_APPLY_TO_A8
105                                  float distanceAdjust,
106 #endif
107                                  uint32_t flags, const SkMatrix& localMatrix);
108 
onTextureSampler(int i)109     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
110 
111     TextureSampler   fTextureSamplers[kMaxTextures];
112     SkISize          fAtlasSize;  // size for all textures used with fTextureSamplers[].
113     SkMatrix         fLocalMatrix;
114     Attribute        fInPosition;
115     Attribute        fInColor;
116     Attribute        fInTextureCoords;
117     uint32_t         fFlags;
118 #ifdef SK_GAMMA_APPLY_TO_A8
119     float            fDistanceAdjust;
120 #endif
121 
122     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
123 
124     typedef GrGeometryProcessor INHERITED;
125 };
126 
127 /**
128  * The output color of this effect is a modulation of the input color and a sample from a
129  * distance field texture (using a smoothed step function near 0.5).
130  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
131  * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
132  */
133 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
134 public:
135     static constexpr int kMaxTextures = 4;
136 
137     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
Make(const GrShaderCaps & caps,const SkMatrix & matrix,bool wideColor,const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params,uint32_t flags)138     static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
139                                            const SkMatrix& matrix,
140                                            bool wideColor,
141                                            const sk_sp<GrTextureProxy>* proxies,
142                                            int numActiveProxies,
143                                            const GrSamplerState& params, uint32_t flags) {
144         return sk_sp<GrGeometryProcessor>(
145             new GrDistanceFieldPathGeoProc(caps, matrix, wideColor, proxies, numActiveProxies,
146                                            params, flags));
147     }
148 
~GrDistanceFieldPathGeoProc()149     ~GrDistanceFieldPathGeoProc() override {}
150 
name()151     const char* name() const override { return "DistanceFieldPath"; }
152 
inPosition()153     const Attribute& inPosition() const { return fInPosition; }
inColor()154     const Attribute& inColor() const { return fInColor; }
inTextureCoords()155     const Attribute& inTextureCoords() const { return fInTextureCoords; }
matrix()156     const SkMatrix& matrix() const { return fMatrix; }
getFlags()157     uint32_t getFlags() const { return fFlags; }
atlasSize()158     const SkISize& atlasSize() const { return fAtlasSize; }
159 
160     void addNewProxies(const sk_sp<GrTextureProxy>*, int numActiveProxies, const GrSamplerState&);
161 
162     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
163 
164     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
165 
166 private:
167     GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
168                                const SkMatrix& matrix,
169                                bool wideColor,
170                                const sk_sp<GrTextureProxy>* proxies,
171                                int numActiveProxies,
172                                const GrSamplerState&, uint32_t flags);
173 
onTextureSampler(int i)174     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
175 
176     SkMatrix         fMatrix;     // view matrix if perspective, local matrix otherwise
177     TextureSampler   fTextureSamplers[kMaxTextures];
178     SkISize          fAtlasSize;  // size for all textures used with fTextureSamplers[].
179     Attribute        fInPosition;
180     Attribute        fInColor;
181     Attribute        fInTextureCoords;
182     uint32_t         fFlags;
183 
184     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
185 
186     typedef GrGeometryProcessor INHERITED;
187 };
188 
189 /**
190  * The output color of this effect is a modulation of the input color and samples from a
191  * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
192  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
193  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
194  */
195 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
196 public:
197     static constexpr int kMaxTextures = 4;
198 
199     struct DistanceAdjust {
200         SkScalar fR, fG, fB;
MakeDistanceAdjust201         static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
202             DistanceAdjust result;
203             result.fR = r; result.fG = g; result.fB = b;
204             return result;
205         }
206         bool operator==(const DistanceAdjust& wa) const {
207             return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
208         }
209         bool operator!=(const DistanceAdjust& wa) const {
210             return !(*this == wa);
211         }
212     };
213 
Make(const GrShaderCaps & caps,const sk_sp<GrTextureProxy> * proxies,int numActiveProxies,const GrSamplerState & params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)214     static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps& caps,
215                                            const sk_sp<GrTextureProxy>* proxies,
216                                            int numActiveProxies,
217                                            const GrSamplerState& params,
218                                            DistanceAdjust distanceAdjust,
219                                            uint32_t flags,
220                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
221         return sk_sp<GrGeometryProcessor>(
222             new GrDistanceFieldLCDTextGeoProc(caps, proxies, numActiveProxies, params,
223                                               distanceAdjust, flags, localMatrixIfUsesLocalCoords));
224     }
225 
~GrDistanceFieldLCDTextGeoProc()226     ~GrDistanceFieldLCDTextGeoProc() override {}
227 
name()228     const char* name() const override { return "DistanceFieldLCDText"; }
229 
inPosition()230     const Attribute& inPosition() const { return fInPosition; }
inColor()231     const Attribute& inColor() const { return fInColor; }
inTextureCoords()232     const Attribute& inTextureCoords() const { return fInTextureCoords; }
getDistanceAdjust()233     DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
getFlags()234     uint32_t getFlags() const { return fFlags; }
localMatrix()235     const SkMatrix& localMatrix() const { return fLocalMatrix; }
atlasSize()236     const SkISize& atlasSize() const { return fAtlasSize; }
237 
238     void addNewProxies(const sk_sp<GrTextureProxy>*, int numActiveProxies, const GrSamplerState&);
239 
240     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
241 
242     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
243 
244 private:
245     GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const sk_sp<GrTextureProxy>* proxies,
246                                   int numActiveProxies, const GrSamplerState& params,
247                                   DistanceAdjust wa, uint32_t flags, const SkMatrix& localMatrix);
248 
onTextureSampler(int i)249     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
250 
251     TextureSampler   fTextureSamplers[kMaxTextures];
252     SkISize          fAtlasSize;  // size for all textures used with fTextureSamplers[].
253     const SkMatrix   fLocalMatrix;
254     DistanceAdjust   fDistanceAdjust;
255     Attribute        fInPosition;
256     Attribute        fInColor;
257     Attribute        fInTextureCoords;
258     uint32_t         fFlags;
259 
260     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
261 
262     typedef GrGeometryProcessor INHERITED;
263 };
264 
265 #endif
266