blob: c5c903b204fc8add574c9a0f419a87e5f4e525c6 [file] [log] [blame]
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +00001/*
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#include "GrBezierEffect.h"
9
10#include "gl/GrGLEffect.h"
11#include "gl/GrGLSL.h"
12#include "GrTBackendEffectFactory.h"
13
14class GrGLConicEffect : public GrGLEffect {
15public:
16 GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
17
18 virtual void emitCode(GrGLShaderBuilder* builder,
19 const GrDrawEffect& drawEffect,
20 EffectKey key,
21 const char* outputColor,
22 const char* inputColor,
23 const TextureSamplerArray&) SK_OVERRIDE;
24
25 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
26
27 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
28
29private:
30 GrBezierEdgeType fEdgeType;
31
32 typedef GrGLEffect INHERITED;
33};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000034
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000035GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
36 const GrDrawEffect& drawEffect)
37 : INHERITED (factory) {
38 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
39 fEdgeType = ce.getEdgeType();
40}
41
42void GrGLConicEffect::emitCode(GrGLShaderBuilder* builder,
43 const GrDrawEffect& drawEffect,
44 EffectKey key,
45 const char* outputColor,
46 const char* inputColor,
47 const TextureSamplerArray& samplers) {
48 const char *vsName, *fsName;
49
50 builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
51 &vsName, &fsName);
52 const SkString* attr0Name =
53 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
54 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
55
56 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
57
58 switch (fEdgeType) {
59 case kHairAA_GrBezierEdgeType: {
60 SkAssertResult(builder->enableFeature(
61 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
62 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
63 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
64 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
65 "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
66 fsName, fsName, fsName);
67 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
68 "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
69 fsName, fsName, fsName);
70 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
71 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
72 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
73 fsName, fsName);
74 builder->fsCodeAppend("\t\tfunc = abs(func);\n");
75 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
76 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
77 // Add line below for smooth cubic ramp
78 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
79 break;
80 }
81 case kFillAA_GrBezierEdgeType: {
82 SkAssertResult(builder->enableFeature(
83 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
84 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
85 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
86 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
87 "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
88 fsName, fsName, fsName);
89 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
90 "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
91 fsName, fsName, fsName);
92 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
93 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
94 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
95 fsName, fsName);
96 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
97 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
98 // Add line below for smooth cubic ramp
99 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
100 break;
101 }
102 case kFillNoAA_GrBezierEdgeType: {
103 builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
104 fsName, fsName);
105 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
106 break;
107 }
108 }
109
110 SkString modulate;
111 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
112 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
113}
114
115GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
116 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
117 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
118}
119
120//////////////////////////////////////////////////////////////////////////////
121
122GrConicEffect::~GrConicEffect() {}
123
124const GrBackendEffectFactory& GrConicEffect::getFactory() const {
125 return GrTBackendEffectFactory<GrConicEffect>::getInstance();
126}
127
128GrConicEffect::GrConicEffect(GrBezierEdgeType edgeType) : GrEffect() {
129 this->addVertexAttrib(kVec4f_GrSLType);
130 fEdgeType = edgeType;
131}
132
133bool GrConicEffect::onIsEqual(const GrEffect& other) const {
134 const GrConicEffect& ce = CastEffect<GrConicEffect>(other);
135 return (ce.fEdgeType == fEdgeType);
136}
137
138//////////////////////////////////////////////////////////////////////////////
139
140GR_DEFINE_EFFECT_TEST(GrConicEffect);
141
142GrEffectRef* GrConicEffect::TestCreate(SkMWCRandom* random,
143 GrContext*,
144 const GrDrawTargetCaps& caps,
145 GrTexture*[]) {
146 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
147 return GrConicEffect::Create(edgeType, caps);
148}
149
150//////////////////////////////////////////////////////////////////////////////
151// Quad
152//////////////////////////////////////////////////////////////////////////////
153
154class GrGLQuadEffect : public GrGLEffect {
155public:
156 GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
157
158 virtual void emitCode(GrGLShaderBuilder* builder,
159 const GrDrawEffect& drawEffect,
160 EffectKey key,
161 const char* outputColor,
162 const char* inputColor,
163 const TextureSamplerArray&) SK_OVERRIDE;
164
165 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
166
167 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
168
169private:
170 GrBezierEdgeType fEdgeType;
171
172 typedef GrGLEffect INHERITED;
173};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000174
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000175GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
176 const GrDrawEffect& drawEffect)
177 : INHERITED (factory) {
178 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
179 fEdgeType = ce.getEdgeType();
180}
181
182void GrGLQuadEffect::emitCode(GrGLShaderBuilder* builder,
183 const GrDrawEffect& drawEffect,
184 EffectKey key,
185 const char* outputColor,
186 const char* inputColor,
187 const TextureSamplerArray& samplers) {
188 const char *vsName, *fsName;
189
190 const SkString* attrName =
191 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
192 builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
193
194 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
195
196 switch (fEdgeType) {
197 case kHairAA_GrBezierEdgeType: {
198 SkAssertResult(builder->enableFeature(
199 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
200 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
201 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
202 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
203 "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
204 fsName, fsName);
205 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
206 fsName);
207 builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
208 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
209 // Add line below for smooth cubic ramp
210 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
211 break;
212 }
213 case kFillAA_GrBezierEdgeType: {
214 SkAssertResult(builder->enableFeature(
215 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
216 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
217 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
218 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
219 "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
220 fsName, fsName);
221 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
222 fsName);
223 builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
224 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
225 // Add line below for smooth cubic ramp
226 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
227 break;
228 }
229 case kFillNoAA_GrBezierEdgeType: {
230 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
231 fsName);
232 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
233 break;
234 }
235 }
236
237 SkString modulate;
238 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
239 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
240
241 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
242}
243
244GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
245 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
246 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
247}
248
249//////////////////////////////////////////////////////////////////////////////
250
251GrQuadEffect::~GrQuadEffect() {}
252
253const GrBackendEffectFactory& GrQuadEffect::getFactory() const {
254 return GrTBackendEffectFactory<GrQuadEffect>::getInstance();
255}
256
257GrQuadEffect::GrQuadEffect(GrBezierEdgeType edgeType) : GrEffect() {
258 this->addVertexAttrib(kVec4f_GrSLType);
259 fEdgeType = edgeType;
260}
261
262bool GrQuadEffect::onIsEqual(const GrEffect& other) const {
263 const GrQuadEffect& ce = CastEffect<GrQuadEffect>(other);
264 return (ce.fEdgeType == fEdgeType);
265}
266
267//////////////////////////////////////////////////////////////////////////////
268
269GR_DEFINE_EFFECT_TEST(GrQuadEffect);
270
271GrEffectRef* GrQuadEffect::TestCreate(SkMWCRandom* random,
272 GrContext*,
273 const GrDrawTargetCaps& caps,
274 GrTexture*[]) {
275 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
276 return GrQuadEffect::Create(edgeType, caps);
277}
278
279//////////////////////////////////////////////////////////////////////////////
280// Cubic
281//////////////////////////////////////////////////////////////////////////////
282
283class GrGLCubicEffect : public GrGLEffect {
284public:
285 GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
286
287 virtual void emitCode(GrGLShaderBuilder* builder,
288 const GrDrawEffect& drawEffect,
289 EffectKey key,
290 const char* outputColor,
291 const char* inputColor,
292 const TextureSamplerArray&) SK_OVERRIDE;
293
294 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
295
296 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
297
298private:
299 GrBezierEdgeType fEdgeType;
300
301 typedef GrGLEffect INHERITED;
302};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000303
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000304GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
305 const GrDrawEffect& drawEffect)
306 : INHERITED (factory) {
307 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
308 fEdgeType = ce.getEdgeType();
309}
310
311void GrGLCubicEffect::emitCode(GrGLShaderBuilder* builder,
312 const GrDrawEffect& drawEffect,
313 EffectKey key,
314 const char* outputColor,
315 const char* inputColor,
316 const TextureSamplerArray& samplers) {
317 const char *vsName, *fsName;
318
319 builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
320 &vsName, &fsName);
321 const SkString* attr0Name =
322 builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
323 builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
324
325 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
326
327 switch (fEdgeType) {
328 case kHairAA_GrBezierEdgeType: {
329 SkAssertResult(builder->enableFeature(
330 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
331 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
332 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
333 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
334 "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
335 fsName, fsName, fsName, fsName);
336 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
337 "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
338 fsName, fsName, fsName, fsName);
339 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
340 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
341 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
342 fsName, fsName, fsName, fsName, fsName);
343 builder->fsCodeAppend("\t\tfunc = abs(func);\n");
344 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
345 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
346 // Add line below for smooth cubic ramp
347 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
348 break;
349 }
350 case kFillAA_GrBezierEdgeType: {
351 SkAssertResult(builder->enableFeature(
352 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
353 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
354 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
355 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
356 "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
357 fsName, fsName, fsName, fsName);
358 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
359 "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
360 fsName, fsName, fsName, fsName);
361 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
362 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
363 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
364 fsName, fsName, fsName, fsName, fsName);
365 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
366 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
367 // Add line below for smooth cubic ramp
368 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
369 break;
370 }
371 case kFillNoAA_GrBezierEdgeType: {
372 builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
373 fsName, fsName, fsName, fsName, fsName);
374 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
375 break;
376 }
377 }
378
379 SkString modulate;
380 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
381 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
382}
383
384GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
385 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
386 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
387}
388
389//////////////////////////////////////////////////////////////////////////////
390
391GrCubicEffect::~GrCubicEffect() {}
392
393const GrBackendEffectFactory& GrCubicEffect::getFactory() const {
394 return GrTBackendEffectFactory<GrCubicEffect>::getInstance();
395}
396
397GrCubicEffect::GrCubicEffect(GrBezierEdgeType edgeType) : GrEffect() {
398 this->addVertexAttrib(kVec4f_GrSLType);
399 fEdgeType = edgeType;
400}
401
402bool GrCubicEffect::onIsEqual(const GrEffect& other) const {
403 const GrCubicEffect& ce = CastEffect<GrCubicEffect>(other);
404 return (ce.fEdgeType == fEdgeType);
405}
406
407//////////////////////////////////////////////////////////////////////////////
408
409GR_DEFINE_EFFECT_TEST(GrCubicEffect);
410
411GrEffectRef* GrCubicEffect::TestCreate(SkMWCRandom* random,
412 GrContext*,
413 const GrDrawTargetCaps& caps,
414 GrTexture*[]) {
415 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
416 return GrCubicEffect::Create(edgeType, caps);
417}