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 "GrProcessor.h"
12 #include "GrGeometryProcessor.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     kUseLCD_DistanceFieldEffectFlag       = 0x04, // use lcd text
23     kBGR_DistanceFieldEffectFlag          = 0x08, // lcd display has bgr order
24     kPortrait_DistanceFieldEffectFlag     = 0x10, // lcd display is in portrait mode (not used yet)
25     kGammaCorrect_DistanceFieldEffectFlag = 0x20, // assume gamma-correct output (linear blending)
26 
27     kInvalid_DistanceFieldEffectFlag    = 0x80,   // invalid state (for initialization)
28 
29     kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
30                                             kScaleOnly_DistanceFieldEffectFlag,
31     // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc
32     kNonLCD_DistanceFieldEffectMask       = kSimilarity_DistanceFieldEffectFlag |
33                                             kScaleOnly_DistanceFieldEffectFlag |
34                                             kGammaCorrect_DistanceFieldEffectFlag,
35     // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc
36     kLCD_DistanceFieldEffectMask          = kSimilarity_DistanceFieldEffectFlag |
37                                             kScaleOnly_DistanceFieldEffectFlag |
38                                             kUseLCD_DistanceFieldEffectFlag |
39                                             kBGR_DistanceFieldEffectFlag |
40                                             kGammaCorrect_DistanceFieldEffectFlag,
41 };
42 
43 /**
44  * The output color of this effect is a modulation of the input color and a sample from a
45  * distance field texture (using a smoothed step function near 0.5).
46  * It allows explicit specification of the filtering and wrap modes (GrSamplerParams). The input
47  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
48  */
49 class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
50 public:
51 #ifdef SK_GAMMA_APPLY_TO_A8
Make(GrResourceProvider * resourceProvider,GrColor color,const SkMatrix & viewMatrix,sk_sp<GrTextureProxy> proxy,const GrSamplerParams & params,float lum,uint32_t flags,bool usesLocalCoords)52     static sk_sp<GrGeometryProcessor> Make(GrResourceProvider* resourceProvider,
53                                            GrColor color, const SkMatrix& viewMatrix,
54                                            sk_sp<GrTextureProxy> proxy,
55                                            const GrSamplerParams& params,
56                                            float lum, uint32_t flags, bool usesLocalCoords) {
57         return sk_sp<GrGeometryProcessor>(
58             new GrDistanceFieldA8TextGeoProc(resourceProvider, color, viewMatrix, std::move(proxy),
59                                              params, lum, flags, usesLocalCoords));
60     }
61 #else
62     static sk_sp<GrGeometryProcessor> Make(GrResourceProvider* resourceProvider,
63                                            GrColor color, const SkMatrix& viewMatrix,
64                                            sk_sp<GrTextureProxy> proxy,
65                                            const GrSamplerParams& params,
66                                            uint32_t flags, bool usesLocalCoords) {
67         return sk_sp<GrGeometryProcessor>(
68             new GrDistanceFieldA8TextGeoProc(resourceProvider, color, viewMatrix, std::move(proxy),
69                                              params, flags, usesLocalCoords));
70     }
71 #endif
72 
~GrDistanceFieldA8TextGeoProc()73     ~GrDistanceFieldA8TextGeoProc() override {}
74 
name()75     const char* name() const override { return "DistanceFieldA8Text"; }
76 
inPosition()77     const Attribute* inPosition() const { return fInPosition; }
inColor()78     const Attribute* inColor() const { return fInColor; }
inTextureCoords()79     const Attribute* inTextureCoords() const { return fInTextureCoords; }
color()80     GrColor color() const { return fColor; }
viewMatrix()81     const SkMatrix& viewMatrix() const { return fViewMatrix; }
usesLocalCoords()82     bool usesLocalCoords() const { return fUsesLocalCoords; }
83 #ifdef SK_GAMMA_APPLY_TO_A8
getDistanceAdjust()84     float getDistanceAdjust() const { return fDistanceAdjust; }
85 #endif
getFlags()86     uint32_t getFlags() const { return fFlags; }
87 
88     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
89 
90     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
91 
92 private:
93     GrDistanceFieldA8TextGeoProc(GrResourceProvider*, GrColor, const SkMatrix& viewMatrix,
94                                  sk_sp<GrTextureProxy> proxy, const GrSamplerParams& params,
95 #ifdef SK_GAMMA_APPLY_TO_A8
96                                  float distanceAdjust,
97 #endif
98                                  uint32_t flags, bool usesLocalCoords);
99 
100     GrColor          fColor;
101     SkMatrix         fViewMatrix;
102     TextureSampler   fTextureSampler;
103 #ifdef SK_GAMMA_APPLY_TO_A8
104     float            fDistanceAdjust;
105 #endif
106     uint32_t         fFlags;
107     const Attribute* fInPosition;
108     const Attribute* fInColor;
109     const Attribute* fInTextureCoords;
110     bool             fUsesLocalCoords;
111 
112     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
113 
114     typedef GrGeometryProcessor INHERITED;
115 };
116 
117 
118 /**
119 * The output color of this effect is a modulation of the input color and a sample from a
120 * distance field texture (using a smoothed step function near 0.5).
121 * It allows explicit specification of the filtering and wrap modes (GrSamplerParams). The input
122 * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
123 */
124 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
125 public:
Make(GrResourceProvider * resourceProvider,GrColor color,const SkMatrix & viewMatrix,sk_sp<GrTextureProxy> proxy,const GrSamplerParams & params,uint32_t flags,bool usesLocalCoords)126     static sk_sp<GrGeometryProcessor> Make(GrResourceProvider* resourceProvider, GrColor color,
127                                            const SkMatrix& viewMatrix, sk_sp<GrTextureProxy> proxy,
128                                            const GrSamplerParams& params,
129                                            uint32_t flags, bool usesLocalCoords) {
130         return sk_sp<GrGeometryProcessor>(
131             new GrDistanceFieldPathGeoProc(resourceProvider, color, viewMatrix, std::move(proxy),
132                                            params, flags, usesLocalCoords));
133     }
134 
~GrDistanceFieldPathGeoProc()135     ~GrDistanceFieldPathGeoProc() override {}
136 
name()137     const char* name() const override { return "DistanceFieldPath"; }
138 
inPosition()139     const Attribute* inPosition() const { return fInPosition; }
inColor()140     const Attribute* inColor() const { return fInColor; }
inTextureCoords()141     const Attribute* inTextureCoords() const { return fInTextureCoords; }
color()142     GrColor color() const { return fColor; }
viewMatrix()143     const SkMatrix& viewMatrix() const { return fViewMatrix; }
getFlags()144     uint32_t getFlags() const { return fFlags; }
usesLocalCoords()145     bool usesLocalCoords() const { return fUsesLocalCoords; }
146 
147     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
148 
149     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
150 
151 private:
152     GrDistanceFieldPathGeoProc(GrResourceProvider*, GrColor, const SkMatrix& viewMatrix,
153                                sk_sp<GrTextureProxy>, const GrSamplerParams&, uint32_t flags,
154                                bool usesLocalCoords);
155 
156     GrColor          fColor;
157     SkMatrix         fViewMatrix;
158     TextureSampler   fTextureSampler;
159     uint32_t         fFlags;
160     const Attribute* fInPosition;
161     const Attribute* fInColor;
162     const Attribute* fInTextureCoords;
163     bool             fUsesLocalCoords;
164 
165     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
166 
167     typedef GrGeometryProcessor INHERITED;
168 };
169 
170 /**
171  * The output color of this effect is a modulation of the input color and samples from a
172  * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
173  * It allows explicit specification of the filtering and wrap modes (GrSamplerParams). The input
174  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
175  */
176 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
177 public:
178     struct DistanceAdjust {
179         SkScalar fR, fG, fB;
MakeDistanceAdjust180         static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
181             DistanceAdjust result;
182             result.fR = r; result.fG = g; result.fB = b;
183             return result;
184         }
185         bool operator==(const DistanceAdjust& wa) const {
186             return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
187         }
188         bool operator!=(const DistanceAdjust& wa) const {
189             return !(*this == wa);
190         }
191     };
192 
Make(GrResourceProvider * resourceProvider,GrColor color,const SkMatrix & viewMatrix,sk_sp<GrTextureProxy> proxy,const GrSamplerParams & params,DistanceAdjust distanceAdjust,uint32_t flags,bool usesLocalCoords)193     static sk_sp<GrGeometryProcessor> Make(GrResourceProvider* resourceProvider, GrColor color,
194                                            const SkMatrix& viewMatrix,
195                                            sk_sp<GrTextureProxy> proxy,
196                                            const GrSamplerParams& params,
197                                            DistanceAdjust distanceAdjust, uint32_t flags,
198                                            bool usesLocalCoords) {
199         return sk_sp<GrGeometryProcessor>(
200             new GrDistanceFieldLCDTextGeoProc(resourceProvider, color, viewMatrix, std::move(proxy),
201                                               params, distanceAdjust,
202                                               flags, usesLocalCoords));
203     }
204 
~GrDistanceFieldLCDTextGeoProc()205     ~GrDistanceFieldLCDTextGeoProc() override {}
206 
name()207     const char* name() const override { return "DistanceFieldLCDText"; }
208 
inPosition()209     const Attribute* inPosition() const { return fInPosition; }
inColor()210     const Attribute* inColor() const { return fInColor; }
inTextureCoords()211     const Attribute* inTextureCoords() const { return fInTextureCoords; }
getDistanceAdjust()212     DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
color()213     GrColor color() const { return fColor; }
viewMatrix()214     const SkMatrix& viewMatrix() const { return fViewMatrix; }
getFlags()215     uint32_t getFlags() const { return fFlags; }
usesLocalCoords()216     bool usesLocalCoords() const { return fUsesLocalCoords; }
217 
218     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
219 
220     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
221 
222 private:
223     GrDistanceFieldLCDTextGeoProc(GrResourceProvider*, GrColor, const SkMatrix& viewMatrix,
224                                   sk_sp<GrTextureProxy> proxy, const GrSamplerParams& params,
225                                   DistanceAdjust wa, uint32_t flags,
226                                   bool usesLocalCoords);
227 
228     GrColor          fColor;
229     SkMatrix         fViewMatrix;
230     TextureSampler   fTextureSampler;
231     DistanceAdjust   fDistanceAdjust;
232     uint32_t         fFlags;
233     const Attribute* fInPosition;
234     const Attribute* fInColor;
235     const Attribute* fInTextureCoords;
236     bool             fUsesLocalCoords;
237 
238     GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
239 
240     typedef GrGeometryProcessor INHERITED;
241 };
242 
243 #endif
244