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