blob: 488af1585f0f5b0c4869e5fd73da391dcb496740 [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
joshualitt30ba4362014-08-21 20:18:45 -07008#include "gl/builders/GrGLProgramBuilder.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +00009#include "GrBezierEffect.h"
10
11#include "gl/GrGLEffect.h"
12#include "gl/GrGLSL.h"
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000013#include "gl/GrGLVertexEffect.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000014#include "GrTBackendEffectFactory.h"
15
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000016class GrGLConicEffect : public GrGLVertexEffect {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000017public:
18 GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
19
joshualitt30ba4362014-08-21 20:18:45 -070020 virtual void emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000021 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -070022 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000023 const char* outputColor,
24 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +000025 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000026 const TextureSamplerArray&) SK_OVERRIDE;
27
bsalomon63e99f72014-07-21 08:03:14 -070028 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000029
kkinnunen7510b222014-07-30 00:04:16 -070030 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000031
32private:
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000033 GrEffectEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000034
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000035 typedef GrGLVertexEffect INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000036};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000037
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000038GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
39 const GrDrawEffect& drawEffect)
40 : INHERITED (factory) {
41 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
42 fEdgeType = ce.getEdgeType();
43}
44
joshualitt30ba4362014-08-21 20:18:45 -070045void GrGLConicEffect::emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000046 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -070047 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000048 const char* outputColor,
49 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +000050 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000051 const TextureSamplerArray& samplers) {
52 const char *vsName, *fsName;
53
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000054 builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000055 &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000056
joshualitt30ba4362014-08-21 20:18:45 -070057 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
58 const SkString* attr0Name =
59 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
egdanielb2f94d12014-08-29 10:08:36 -070060 vsBuilder->codeAppendf("%s = %s;", vsName, attr0Name->c_str());
joshualitt30ba4362014-08-21 20:18:45 -070061
62 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070063 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000064
65 switch (fEdgeType) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000066 case kHairlineAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070067 SkAssertResult(fsBuilder->enableFeature(
68 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -070069 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
70 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
71 fsBuilder->codeAppendf("float dfdx ="
72 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
73 fsName, fsName, fsName);
74 fsBuilder->codeAppendf("float dfdy ="
75 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
76 fsName, fsName, fsName);
77 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
78 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
79 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName,
80 fsName, fsName);
81 fsBuilder->codeAppend("func = abs(func);");
82 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
83 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000084 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -070085 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000086 break;
87 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000088 case kFillAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070089 SkAssertResult(fsBuilder->enableFeature(
90 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -070091 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
92 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
93 fsBuilder->codeAppendf("float dfdx ="
94 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
95 fsName, fsName, fsName);
96 fsBuilder->codeAppendf("float dfdy ="
97 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
98 fsName, fsName, fsName);
99 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
100 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
101 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
102 fsName, fsName);
103 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
104 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000105 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700106 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000107 break;
108 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000109 case kFillBW_GrEffectEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700110 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
111 fsName, fsName);
112 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000113 break;
114 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000115 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000116 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000117 }
118
egdanielb2f94d12014-08-29 10:08:36 -0700119 fsBuilder->codeAppendf("%s = %s;", outputColor,
egdaniel9bd5bbf2014-08-29 11:12:30 -0700120 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000121}
122
bsalomon63e99f72014-07-21 08:03:14 -0700123void GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
124 GrEffectKeyBuilder* b) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000125 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700126 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
127 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000128}
129
130//////////////////////////////////////////////////////////////////////////////
131
132GrConicEffect::~GrConicEffect() {}
133
134const GrBackendEffectFactory& GrConicEffect::getFactory() const {
135 return GrTBackendEffectFactory<GrConicEffect>::getInstance();
136}
137
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000138GrConicEffect::GrConicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000139 this->addVertexAttrib(kVec4f_GrSLType);
140 fEdgeType = edgeType;
141}
142
143bool GrConicEffect::onIsEqual(const GrEffect& other) const {
144 const GrConicEffect& ce = CastEffect<GrConicEffect>(other);
145 return (ce.fEdgeType == fEdgeType);
146}
147
148//////////////////////////////////////////////////////////////////////////////
149
150GR_DEFINE_EFFECT_TEST(GrConicEffect);
151
bsalomon83d081a2014-07-08 09:56:10 -0700152GrEffect* GrConicEffect::TestCreate(SkRandom* random,
153 GrContext*,
154 const GrDrawTargetCaps& caps,
155 GrTexture*[]) {
156 GrEffect* effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000157 do {
158 GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
159 random->nextULessThan(kGrEffectEdgeTypeCnt));
160 effect = GrConicEffect::Create(edgeType, caps);
161 } while (NULL == effect);
162 return effect;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000163}
164
165//////////////////////////////////////////////////////////////////////////////
166// Quad
167//////////////////////////////////////////////////////////////////////////////
168
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000169class GrGLQuadEffect : public GrGLVertexEffect {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000170public:
171 GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
172
joshualitt30ba4362014-08-21 20:18:45 -0700173 virtual void emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000174 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -0700175 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000176 const char* outputColor,
177 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000178 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000179 const TextureSamplerArray&) SK_OVERRIDE;
180
bsalomon63e99f72014-07-21 08:03:14 -0700181 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000182
kkinnunen7510b222014-07-30 00:04:16 -0700183 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000184
185private:
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000186 GrEffectEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000187
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000188 typedef GrGLVertexEffect INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000189};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000190
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000191GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
192 const GrDrawEffect& drawEffect)
193 : INHERITED (factory) {
194 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
195 fEdgeType = ce.getEdgeType();
196}
197
joshualitt30ba4362014-08-21 20:18:45 -0700198void GrGLQuadEffect::emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000199 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -0700200 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000201 const char* outputColor,
202 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000203 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000204 const TextureSamplerArray& samplers) {
205 const char *vsName, *fsName;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000206 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000207
joshualitt30ba4362014-08-21 20:18:45 -0700208 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
209 const SkString* attrName =
210 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
egdanielb2f94d12014-08-29 10:08:36 -0700211 vsBuilder->codeAppendf("%s = %s;", vsName, attrName->c_str());
joshualitt30ba4362014-08-21 20:18:45 -0700212
213 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700214 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700215
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000216 switch (fEdgeType) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000217 case kHairlineAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700218 SkAssertResult(fsBuilder->enableFeature(
219 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdanielb2f94d12014-08-29 10:08:36 -0700220 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
221 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
222 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
223 " 2.0 * %s.x * duvdy.x - duvdy.y);",
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000224 fsName, fsName);
egdanielb2f94d12014-08-29 10:08:36 -0700225 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
226 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
227 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000228 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700229 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000230 break;
231 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000232 case kFillAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700233 SkAssertResult(fsBuilder->enableFeature(
234 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdanielb2f94d12014-08-29 10:08:36 -0700235 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
236 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
237 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
238 " 2.0 * %s.x * duvdy.x - duvdy.y);",
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000239 fsName, fsName);
egdanielb2f94d12014-08-29 10:08:36 -0700240 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
241 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
242 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000243 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700244 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000245 break;
246 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000247 case kFillBW_GrEffectEdgeType: {
egdanielb2f94d12014-08-29 10:08:36 -0700248 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
249 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000250 break;
251 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000252 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000253 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000254 }
255
egdanielb2f94d12014-08-29 10:08:36 -0700256 fsBuilder->codeAppendf("%s = %s;", outputColor,
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000257 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000258}
259
bsalomon63e99f72014-07-21 08:03:14 -0700260void GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
261 GrEffectKeyBuilder* b) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000262 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700263 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
264 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000265}
266
267//////////////////////////////////////////////////////////////////////////////
268
269GrQuadEffect::~GrQuadEffect() {}
270
271const GrBackendEffectFactory& GrQuadEffect::getFactory() const {
272 return GrTBackendEffectFactory<GrQuadEffect>::getInstance();
273}
274
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000275GrQuadEffect::GrQuadEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000276 this->addVertexAttrib(kVec4f_GrSLType);
277 fEdgeType = edgeType;
278}
279
280bool GrQuadEffect::onIsEqual(const GrEffect& other) const {
281 const GrQuadEffect& ce = CastEffect<GrQuadEffect>(other);
282 return (ce.fEdgeType == fEdgeType);
283}
284
285//////////////////////////////////////////////////////////////////////////////
286
287GR_DEFINE_EFFECT_TEST(GrQuadEffect);
288
bsalomon83d081a2014-07-08 09:56:10 -0700289GrEffect* GrQuadEffect::TestCreate(SkRandom* random,
290 GrContext*,
291 const GrDrawTargetCaps& caps,
292 GrTexture*[]) {
293 GrEffect* effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000294 do {
295 GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
296 random->nextULessThan(kGrEffectEdgeTypeCnt));
297 effect = GrQuadEffect::Create(edgeType, caps);
298 } while (NULL == effect);
299 return effect;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000300}
301
302//////////////////////////////////////////////////////////////////////////////
303// Cubic
304//////////////////////////////////////////////////////////////////////////////
305
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000306class GrGLCubicEffect : public GrGLVertexEffect {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000307public:
308 GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
309
joshualitt30ba4362014-08-21 20:18:45 -0700310 virtual void emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000311 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -0700312 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000313 const char* outputColor,
314 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000315 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000316 const TextureSamplerArray&) SK_OVERRIDE;
317
bsalomon63e99f72014-07-21 08:03:14 -0700318 static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000319
kkinnunen7510b222014-07-30 00:04:16 -0700320 virtual void setData(const GrGLProgramDataManager&, const GrDrawEffect&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000321
322private:
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000323 GrEffectEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000324
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000325 typedef GrGLVertexEffect INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000326};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000327
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000328GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
329 const GrDrawEffect& drawEffect)
330 : INHERITED (factory) {
331 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
332 fEdgeType = ce.getEdgeType();
333}
334
joshualitt30ba4362014-08-21 20:18:45 -0700335void GrGLCubicEffect::emitCode(GrGLFullProgramBuilder* builder,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000336 const GrDrawEffect& drawEffect,
bsalomon63e99f72014-07-21 08:03:14 -0700337 const GrEffectKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000338 const char* outputColor,
339 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000340 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000341 const TextureSamplerArray& samplers) {
342 const char *vsName, *fsName;
343
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000344 builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
egdaniel6db91282014-09-02 08:02:38 -0700345 &vsName, &fsName, GrGLShaderVar::kHigh_Precision);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000346
joshualitt30ba4362014-08-21 20:18:45 -0700347 GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();
348 const SkString* attr0Name =
349 vsBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
egdanielb2f94d12014-08-29 10:08:36 -0700350 vsBuilder->codeAppendf("%s = %s;", vsName, attr0Name->c_str());
joshualitt30ba4362014-08-21 20:18:45 -0700351
352 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700353
354 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
355 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
356 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
357 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
358 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
359 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
360 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
361 GrGLShaderVar func("func", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
362
363 fsBuilder->declAppend(edgeAlpha);
364 fsBuilder->declAppend(dklmdx);
365 fsBuilder->declAppend(dklmdy);
366 fsBuilder->declAppend(dfdx);
367 fsBuilder->declAppend(dfdy);
368 fsBuilder->declAppend(gF);
369 fsBuilder->declAppend(gFM);
370 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000371
372 switch (fEdgeType) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000373 case kHairlineAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700374 SkAssertResult(fsBuilder->enableFeature(
375 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -0700376 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
377 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
378 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
379 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
380 dklmdx.c_str(), fsName, dklmdx.c_str());
381 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
382 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
383 dklmdy.c_str(), fsName, dklmdy.c_str());
384 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
385 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
386 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
387 func.c_str(), fsName, fsName, fsName, fsName, fsName);
388 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
389 fsBuilder->codeAppendf("%s = %s / %s;",
390 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
391 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
392 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000393 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700394 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
395 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
396 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000397 break;
398 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000399 case kFillAA_GrEffectEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700400 SkAssertResult(fsBuilder->enableFeature(
401 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -0700402 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
403 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
404 fsBuilder->codeAppendf("%s ="
405 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
406 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
407 dklmdx.c_str(), fsName, dklmdx.c_str());
408 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
409 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
410 dklmdy.c_str(), fsName, dklmdy.c_str());
411 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
412 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
413 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
414 func.c_str(), fsName, fsName, fsName, fsName, fsName);
415 fsBuilder->codeAppendf("%s = %s / %s;",
416 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
417 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
418 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000419 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700420 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
421 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
422 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000423 break;
424 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000425 case kFillBW_GrEffectEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700426 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
427 edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName);
428 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000429 break;
430 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000431 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000432 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000433 }
434
egdanielb2f94d12014-08-29 10:08:36 -0700435 fsBuilder->codeAppendf("%s = %s;", outputColor,
egdaniel9bd5bbf2014-08-29 11:12:30 -0700436 (GrGLSLExpr4(inputColor) * GrGLSLExpr1(edgeAlpha.c_str())).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000437}
438
bsalomon63e99f72014-07-21 08:03:14 -0700439void GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
440 GrEffectKeyBuilder* b) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000441 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700442 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
443 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000444}
445
446//////////////////////////////////////////////////////////////////////////////
447
448GrCubicEffect::~GrCubicEffect() {}
449
450const GrBackendEffectFactory& GrCubicEffect::getFactory() const {
451 return GrTBackendEffectFactory<GrCubicEffect>::getInstance();
452}
453
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000454GrCubicEffect::GrCubicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000455 this->addVertexAttrib(kVec4f_GrSLType);
456 fEdgeType = edgeType;
457}
458
459bool GrCubicEffect::onIsEqual(const GrEffect& other) const {
460 const GrCubicEffect& ce = CastEffect<GrCubicEffect>(other);
461 return (ce.fEdgeType == fEdgeType);
462}
463
464//////////////////////////////////////////////////////////////////////////////
465
466GR_DEFINE_EFFECT_TEST(GrCubicEffect);
467
bsalomon83d081a2014-07-08 09:56:10 -0700468GrEffect* GrCubicEffect::TestCreate(SkRandom* random,
469 GrContext*,
470 const GrDrawTargetCaps& caps,
471 GrTexture*[]) {
472 GrEffect* effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000473 do {
474 GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
475 random->nextULessThan(kGrEffectEdgeTypeCnt));
476 effect = GrCubicEffect::Create(edgeType, caps);
477 } while (NULL == effect);
478 return effect;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000479}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700480