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