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