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