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
15class GrGLDistanceFieldA8TextGeoProc;
16class GrGLDistanceFieldPathGeoProc;
17class GrGLDistanceFieldLCDTextGeoProc;
18class GrInvariantOutput;
19
20enum 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 */
55class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
56public:
57 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
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<GrDistanceFieldA8TextGeoProc>(
70 caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords);
71 }
72#else
73 static GrGeometryProcessor* Make(SkArenaAlloc* arena,
74 const GrShaderCaps& caps,
75 const GrSurfaceProxyView* views,
76 int numActiveViews,
77 GrSamplerState params,
78 uint32_t flags,
79 const SkMatrix& localMatrixIfUsesLocalCoords) {
80 return arena->make<GrDistanceFieldA8TextGeoProc>(
81 caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords);
82 }
83#endif
84
85 ~GrDistanceFieldA8TextGeoProc() override {}
86
87 const char* name() const override { return "DistanceFieldA8Text"; }
88
89 const Attribute& inPosition() const { return fInPosition; }
90 const Attribute& inColor() const { return fInColor; }
91 const Attribute& inTextureCoords() const { return fInTextureCoords; }
92 const SkMatrix& localMatrix() const { return fLocalMatrix; }
93#ifdef SK_GAMMA_APPLY_TO_A8
94 float getDistanceAdjust() const { return fDistanceAdjust; }
95#endif
96 uint32_t getFlags() const { return fFlags; }
97 const SkISize& atlasDimensions() const { return fAtlasDimensions; }
98
99 void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState);
100
101 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
102
103 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
104
105private:
106 friend class ::SkArenaAlloc; // for access to ctor
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
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 typedef GrGeometryProcessor INHERITED;
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 */
142class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
143public:
144 static constexpr int kMaxTextures = 4;
145
146 /** The local matrix should be identity if local coords are not required by the GrPipeline. */
147 static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps,
148 const SkMatrix& matrix, bool wideColor,
149 const GrSurfaceProxyView* views, int numActiveViews,
150 GrSamplerState params, uint32_t flags) {
151 return arena->make<GrDistanceFieldPathGeoProc>(caps, matrix, wideColor, views,
152 numActiveViews, params, flags);
153 }
154
155 ~GrDistanceFieldPathGeoProc() override {}
156
157 const char* name() const override { return "DistanceFieldPath"; }
158
159 const Attribute& inPosition() const { return fInPosition; }
160 const Attribute& inColor() const { return fInColor; }
161 const Attribute& inTextureCoords() const { return fInTextureCoords; }
162 const SkMatrix& matrix() const { return fMatrix; }
163 uint32_t getFlags() const { return fFlags; }
164 const SkISize& atlasDimensions() const { return fAtlasDimensions; }
165
166 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
167
168 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
169
170 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
171
172private:
173 friend class ::SkArenaAlloc; // for access to ctor
174
175 GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
176 const SkMatrix& matrix,
177 bool wideColor,
178 const GrSurfaceProxyView* views,
179 int numActiveViews,
180 GrSamplerState,
181 uint32_t flags);
182
183 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
184
185 SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise
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 typedef GrGeometryProcessor INHERITED;
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 */
204class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
205public:
206 static constexpr int kMaxTextures = 4;
207
208 struct DistanceAdjust {
209 SkScalar fR, fG, fB;
210 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
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<GrDistanceFieldLCDTextGeoProc>(caps, views, numActiveViews, params,
232 distanceAdjust, flags,
233 localMatrixIfUsesLocalCoords);
234 }
235
236 ~GrDistanceFieldLCDTextGeoProc() override {}
237
238 const char* name() const override { return "DistanceFieldLCDText"; }
239
240 const Attribute& inPosition() const { return fInPosition; }
241 const Attribute& inColor() const { return fInColor; }
242 const Attribute& inTextureCoords() const { return fInTextureCoords; }
243 DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
244 uint32_t getFlags() const { return fFlags; }
245 const SkMatrix& localMatrix() const { return fLocalMatrix; }
246 const SkISize& atlasDimensions() const { return fAtlasDimensions; }
247
248 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
249
250 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
251
252 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
253
254private:
255 friend class ::SkArenaAlloc; // for access to ctor
256
257 GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views,
258 int numActiveViews, GrSamplerState params, DistanceAdjust wa,
259 uint32_t flags, const SkMatrix& localMatrix);
260
261 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
262
263 TextureSampler fTextureSamplers[kMaxTextures];
264 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[].
265 const SkMatrix fLocalMatrix;
266 DistanceAdjust fDistanceAdjust;
267 Attribute fInPosition;
268 Attribute fInColor;
269 Attribute fInTextureCoords;
270 uint32_t fFlags;
271
272 GR_DECLARE_GEOMETRY_PROCESSOR_TEST
273
274 typedef GrGeometryProcessor INHERITED;
275};
276
277#endif
278