• 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     inline static constexpr int kMaxTextures = 4;
58 
59     /** The local matrix should be identity if local coords are not required by the GrPipeline. */
60 #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)61     static GrGeometryProcessor* Make(SkArenaAlloc* arena,
62                                      const GrShaderCaps& caps,
63                                      const GrSurfaceProxyView* views,
64                                      int numActiveViews,
65                                      GrSamplerState params,
66                                      float lum,
67                                      uint32_t flags,
68                                      const SkMatrix& localMatrixIfUsesLocalCoords) {
69         return arena->make([&](void* ptr) {
70             return new (ptr) GrDistanceFieldA8TextGeoProc(
71                     caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords);
72         });
73     }
74 #else
Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)75     static GrGeometryProcessor* Make(SkArenaAlloc* arena,
76                                      const GrShaderCaps& caps,
77                                      const GrSurfaceProxyView* views,
78                                      int numActiveViews,
79                                      GrSamplerState params,
80                                      uint32_t flags,
81                                      const SkMatrix& localMatrixIfUsesLocalCoords) {
82         return arena->make([&](void* ptr) {
83             return new (ptr) GrDistanceFieldA8TextGeoProc(
84                     caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords);
85         });
86     }
87 #endif
88 
~GrDistanceFieldA8TextGeoProc()89     ~GrDistanceFieldA8TextGeoProc() override {}
90 
name()91     const char* name() const override { return "DistanceFieldA8Text"; }
92 
93     void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState);
94 
95     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
96 
97     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
98 
99 private:
100     class Impl;
101 
102     GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
103                                  const GrSurfaceProxyView* views,
104                                  int numActiveViews,
105                                  GrSamplerState params,
106 #ifdef SK_GAMMA_APPLY_TO_A8
107                                  float distanceAdjust,
108 #endif
109                                  uint32_t flags,
110                                  const SkMatrix& localMatrix);
111 
onTextureSampler(int i)112     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
113 
114     TextureSampler   fTextureSamplers[kMaxTextures];
115     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
116     SkMatrix         fLocalMatrix;
117     Attribute        fInPosition;
118     Attribute        fInColor;
119     Attribute        fInTextureCoords;
120     uint32_t         fFlags;
121 #ifdef SK_GAMMA_APPLY_TO_A8
122     float            fDistanceAdjust;
123 #endif
124 
125     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
126 
127     using INHERITED = GrGeometryProcessor;
128 };
129 
130 /**
131  * The output color of this effect is a modulation of the input color and a sample from a
132  * distance field texture (using a smoothed step function near 0.5).
133  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
134  * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
135  */
136 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
137 public:
138     inline static constexpr int kMaxTextures = 4;
139 
140     /** 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)141     static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps,
142                                      const SkMatrix& matrix, bool wideColor,
143                                      const GrSurfaceProxyView* views, int numActiveViews,
144                                      GrSamplerState params, uint32_t flags) {
145         return arena->make([&](void* ptr) {
146             return new (ptr) GrDistanceFieldPathGeoProc(caps, matrix, wideColor, views,
147                                                         numActiveViews, params, flags);
148         });
149     }
150 
~GrDistanceFieldPathGeoProc()151     ~GrDistanceFieldPathGeoProc() override {}
152 
name()153     const char* name() const override { return "DistanceFieldPath"; }
154 
155     void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
156 
157     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
158 
159     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
160 
161 private:
162     class Impl;
163 
164     GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
165                                const SkMatrix& matrix,
166                                bool wideColor,
167                                const GrSurfaceProxyView* views,
168                                int numActiveViews,
169                                GrSamplerState,
170                                uint32_t flags);
171 
onTextureSampler(int i)172     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
173 
174     SkMatrix         fMatrix;     // view matrix if perspective, local matrix otherwise
175     TextureSampler   fTextureSamplers[kMaxTextures];
176     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
177     Attribute        fInPosition;
178     Attribute        fInColor;
179     Attribute        fInTextureCoords;
180     uint32_t         fFlags;
181 
182     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
183 
184     using INHERITED = GrGeometryProcessor;
185 };
186 
187 /**
188  * The output color of this effect is a modulation of the input color and samples from a
189  * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
190  * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
191  * coords are a custom attribute. Gamma correction is handled via a texture LUT.
192  */
193 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
194 public:
195     inline static constexpr int kMaxTextures = 4;
196 
197     struct DistanceAdjust {
198         SkScalar fR, fG, fB;
MakeDistanceAdjust199         static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
200             DistanceAdjust result;
201             result.fR = r; result.fG = g; result.fB = b;
202             return result;
203         }
204         bool operator==(const DistanceAdjust& wa) const {
205             return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
206         }
207         bool operator!=(const DistanceAdjust& wa) const {
208             return !(*this == wa);
209         }
210     };
211 
Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)212     static GrGeometryProcessor* Make(SkArenaAlloc* arena,
213                                      const GrShaderCaps& caps,
214                                      const GrSurfaceProxyView* views,
215                                      int numActiveViews,
216                                      GrSamplerState params,
217                                      DistanceAdjust distanceAdjust,
218                                      uint32_t flags,
219                                      const SkMatrix& localMatrixIfUsesLocalCoords) {
220         return arena->make([&](void* ptr) {
221             return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params,
222                                                            distanceAdjust, flags,
223                                                            localMatrixIfUsesLocalCoords);
224         });
225     }
226 
~GrDistanceFieldLCDTextGeoProc()227     ~GrDistanceFieldLCDTextGeoProc() override {}
228 
name()229     const char* name() const override { return "DistanceFieldLCDText"; }
230 
231     void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
232 
233     void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
234 
235     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
236 
237 private:
238     class Impl;
239 
240     GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views,
241                                   int numActiveViews, GrSamplerState params, DistanceAdjust wa,
242                                   uint32_t flags, const SkMatrix& localMatrix);
243 
onTextureSampler(int i)244     const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
245 
246     TextureSampler   fTextureSamplers[kMaxTextures];
247     SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
248     const SkMatrix   fLocalMatrix;
249     DistanceAdjust   fDistanceAdjust;
250     Attribute        fInPosition;
251     Attribute        fInColor;
252     Attribute        fInTextureCoords;
253     uint32_t         fFlags;
254 
255     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
256 
257     using INHERITED = GrGeometryProcessor;
258 };
259 
260 #endif
261