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