• 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     SkString getShaderDfxInfo() const override;
98 
99     void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState);
100 
101     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
102 
103     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
104 
105 private:
106     class Impl;
107 
108     GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
109                                  const GrSurfaceProxyView* views,
110                                  int numActiveViews,
111                                  GrSamplerState params,
112 #ifdef SK_GAMMA_APPLY_TO_A8
113                                  float distanceAdjust,
114 #endif
115                                  uint32_t flags,
116                                  const SkMatrix& localMatrix);
117 
onTextureSampler(int i)118     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
119 
120     TextureSampler   fTextureSamplers[kMaxTextures];
121     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
122     SkMatrix         fLocalMatrix;
123     Attribute        fInPosition;
124     Attribute        fInColor;
125     Attribute        fInTextureCoords;
126     uint32_t         fFlags;
127 #ifdef SK_GAMMA_APPLY_TO_A8
128     float            fDistanceAdjust;
129 #endif
130 
131     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
132 
133     using INHERITED = GrGeometryProcessor;
134 };
135 
136 /**
137  * The output color of this effect is a modulation of the input color and a sample from a
138  * distance field texture (using a smoothed step function near 0.5).
139  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
140  * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
141  */
142 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
143 public:
144 #ifdef SK_ENABLE_SMALL_PAGE
145     inline static constexpr int kMaxTextures = 16;
146 #else
147     inline static constexpr int kMaxTextures = 4;
148 #endif
149 
150     /** 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)151     static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps,
152                                      const SkMatrix& matrix, bool wideColor,
153                                      const GrSurfaceProxyView* views, int numActiveViews,
154                                      GrSamplerState params, uint32_t flags) {
155         return arena->make([&](void* ptr) {
156             return new (ptr) GrDistanceFieldPathGeoProc(caps, matrix, wideColor, views,
157                                                         numActiveViews, params, flags);
158         });
159     }
160 
~GrDistanceFieldPathGeoProc()161     ~GrDistanceFieldPathGeoProc() override {}
162 
name()163     const char* name() const override { return "DistanceFieldPath"; }
164 
165     SkString getShaderDfxInfo() const override;
166 
167     void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
168 
169     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) 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 SkMatrix& matrix,
178                                bool wideColor,
179                                const GrSurfaceProxyView* views,
180                                int numActiveViews,
181                                GrSamplerState,
182                                uint32_t flags);
183 
onTextureSampler(int i)184     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
185 
186     SkMatrix         fMatrix;     // view matrix if perspective, local matrix otherwise
187     TextureSampler   fTextureSamplers[kMaxTextures];
188     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
189     Attribute        fInPosition;
190     Attribute        fInColor;
191     Attribute        fInTextureCoords;
192     uint32_t         fFlags;
193 
194     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
195 
196     using INHERITED = GrGeometryProcessor;
197 };
198 
199 /**
200  * The output color of this effect is a modulation of the input color and samples from a
201  * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
202  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
203  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
204  */
205 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
206 public:
207 #ifdef SK_ENABLE_SMALL_PAGE
208     inline static constexpr int kMaxTextures = 16;
209 #else
210     inline static constexpr int kMaxTextures = 4;
211 #endif
212 
213     struct DistanceAdjust {
214         SkScalar fR, fG, fB;
MakeDistanceAdjust215         static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
216             DistanceAdjust result;
217             result.fR = r; result.fG = g; result.fB = b;
218             return result;
219         }
220         bool operator==(const DistanceAdjust& wa) const {
221             return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
222         }
223         bool operator!=(const DistanceAdjust& wa) const {
224             return !(*this == wa);
225         }
226     };
227 
Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)228     static GrGeometryProcessor* Make(SkArenaAlloc* arena,
229                                      const GrShaderCaps& caps,
230                                      const GrSurfaceProxyView* views,
231                                      int numActiveViews,
232                                      GrSamplerState params,
233                                      DistanceAdjust distanceAdjust,
234                                      uint32_t flags,
235                                      const SkMatrix& localMatrixIfUsesLocalCoords) {
236         return arena->make([&](void* ptr) {
237             return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params,
238                                                            distanceAdjust, flags,
239                                                            localMatrixIfUsesLocalCoords);
240         });
241     }
242 
~GrDistanceFieldLCDTextGeoProc()243     ~GrDistanceFieldLCDTextGeoProc() override {}
244 
name()245     const char* name() const override { return "DistanceFieldLCDText"; }
246 
247     SkString getShaderDfxInfo() const override;
248 
249     void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
250 
251     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
252 
253     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
254 
255 private:
256     class Impl;
257 
258     GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views,
259                                   int numActiveViews, GrSamplerState params, DistanceAdjust wa,
260                                   uint32_t flags, const SkMatrix& localMatrix);
261 
onTextureSampler(int i)262     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
263 
264     TextureSampler   fTextureSamplers[kMaxTextures];
265     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
266     const SkMatrix   fLocalMatrix;
267     DistanceAdjust   fDistanceAdjust;
268     Attribute        fInPosition;
269     Attribute        fInColor;
270     Attribute        fInTextureCoords;
271     uint32_t         fFlags;
272 
273     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
274 
275     using INHERITED = GrGeometryProcessor;
276 };
277 
278 #endif
279