• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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 sk_sp<GrTextureProxy> proxies[kMaxTextures],const GrSamplerState & params,float lum,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)60     static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
61                                            const GrSamplerState& params, float lum, uint32_t flags,
62                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
63         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
64                 proxies, params, lum, flags, localMatrixIfUsesLocalCoords));
65     }
66 #else
Make(const sk_sp<GrTextureProxy> proxies[kMaxTextures],const GrSamplerState & params,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)67     static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
68                                            const GrSamplerState& params, uint32_t flags,
69                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
70         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldA8TextGeoProc(
71                 proxies, params, flags, localMatrixIfUsesLocalCoords));
72     }
73 #endif
74 
~GrDistanceFieldA8TextGeoProc()75     ~GrDistanceFieldA8TextGeoProc() override {}
76 
name()77     const char* name() const override { return "DistanceFieldA8Text"; }
78 
inPosition()79     const Attribute* inPosition() const { return fInPosition; }
inColor()80     const Attribute* inColor() const { return fInColor; }
inTextureCoords()81     const Attribute* inTextureCoords() const { return fInTextureCoords; }
localMatrix()82     const SkMatrix& localMatrix() const { return fLocalMatrix; }
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 addNewProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
89 
90     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
91 
92     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
93 
94 private:
95     GrDistanceFieldA8TextGeoProc(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
96                                  const GrSamplerState& params,
97 #ifdef SK_GAMMA_APPLY_TO_A8
98                                  float distanceAdjust,
99 #endif
100                                  uint32_t flags, const SkMatrix& localMatrix);
101 
102     TextureSampler   fTextureSamplers[kMaxTextures];
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     SkMatrix         fLocalMatrix;
111 
112     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
113 
114     typedef GrGeometryProcessor INHERITED;
115 };
116 
117 /**
118  * The output color of this effect is a modulation of the input color and a sample from a
119  * distance field texture (using a smoothed step function near 0.5).
120  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
121  * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
122  */
123 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
124 public:
125     static constexpr int kMaxTextures = 4;
126 
127     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
Make(const SkMatrix & matrix,const sk_sp<GrTextureProxy> proxies[kMaxTextures],const GrSamplerState & params,uint32_t flags)128     static sk_sp<GrGeometryProcessor> Make(const SkMatrix& matrix,
129                                            const sk_sp<GrTextureProxy> proxies[kMaxTextures],
130                                            const GrSamplerState& params, uint32_t flags) {
131         return sk_sp<GrGeometryProcessor>(
132             new GrDistanceFieldPathGeoProc(matrix, proxies, params, flags));
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; }
matrix()142     const SkMatrix& matrix() const { return fMatrix; }
getFlags()143     uint32_t getFlags() const { return fFlags; }
144 
145     void addNewProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
146 
147     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
148 
149     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
150 
151 private:
152     GrDistanceFieldPathGeoProc(const SkMatrix& matrix,
153                                const sk_sp<GrTextureProxy> proxies[kMaxTextures],
154                                const GrSamplerState&, uint32_t flags);
155 
156     SkMatrix         fMatrix;      // view matrix if perspective, local matrix otherwise
157     TextureSampler   fTextureSamplers[kMaxTextures];
158     uint32_t         fFlags;
159     const Attribute* fInPosition;
160     const Attribute* fInColor;
161     const Attribute* fInTextureCoords;
162 
163     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
164 
165     typedef GrGeometryProcessor INHERITED;
166 };
167 
168 /**
169  * The output color of this effect is a modulation of the input color and samples from a
170  * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
171  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
172  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
173  */
174 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
175 public:
176     struct DistanceAdjust {
177         SkScalar fR, fG, fB;
MakeDistanceAdjust178         static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
179             DistanceAdjust result;
180             result.fR = r; result.fG = g; result.fB = b;
181             return result;
182         }
183         bool operator==(const DistanceAdjust& wa) const {
184             return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
185         }
186         bool operator!=(const DistanceAdjust& wa) const {
187             return !(*this == wa);
188         }
189     };
190 
191     static constexpr int kMaxTextures = 4;
192 
Make(const sk_sp<GrTextureProxy> proxies[kMaxTextures],const GrSamplerState & params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)193     static sk_sp<GrGeometryProcessor> Make(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
194                                            const GrSamplerState& params,
195                                            DistanceAdjust distanceAdjust,
196                                            uint32_t flags,
197                                            const SkMatrix& localMatrixIfUsesLocalCoords) {
198         return sk_sp<GrGeometryProcessor>(new GrDistanceFieldLCDTextGeoProc(
199                 proxies, params, distanceAdjust, flags, localMatrixIfUsesLocalCoords));
200     }
201 
~GrDistanceFieldLCDTextGeoProc()202     ~GrDistanceFieldLCDTextGeoProc() override {}
203 
name()204     const char* name() const override { return "DistanceFieldLCDText"; }
205 
inPosition()206     const Attribute* inPosition() const { return fInPosition; }
inColor()207     const Attribute* inColor() const { return fInColor; }
inTextureCoords()208     const Attribute* inTextureCoords() const { return fInTextureCoords; }
getDistanceAdjust()209     DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
getFlags()210     uint32_t getFlags() const { return fFlags; }
localMatrix()211     const SkMatrix& localMatrix() const { return fLocalMatrix; }
212 
213     void addNewProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
214 
215     void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
216 
217     GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
218 
219 private:
220     GrDistanceFieldLCDTextGeoProc(const sk_sp<GrTextureProxy> proxies[kMaxTextures],
221                                   const GrSamplerState& params, DistanceAdjust wa, uint32_t flags,
222                                   const SkMatrix& localMatrix);
223 
224     TextureSampler   fTextureSamplers[kMaxTextures];
225     DistanceAdjust   fDistanceAdjust;
226     uint32_t         fFlags;
227     const Attribute* fInPosition;
228     const Attribute* fInColor;
229     const Attribute* fInTextureCoords;
230     const SkMatrix   fLocalMatrix;
231 
232     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
233 
234     typedef GrGeometryProcessor INHERITED;
235 };
236 
237 #endif
238