blob: 0bcfc75bef5cbbcb4ac40bf9c71321a832d70d91 [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
joshualitt47bb3822014-10-07 16:43:25 -070010#include "gl/builders/GrGLProgramBuilder.h"
joshualittb0a8a372014-09-23 09:50:21 -070011#include "gl/GrGLProcessor.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000012#include "gl/GrGLSL.h"
joshualitt249af152014-09-15 11:41:13 -070013#include "gl/GrGLGeometryProcessor.h"
joshualittb0a8a372014-09-23 09:50:21 -070014#include "GrTBackendProcessorFactory.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000015
joshualitt249af152014-09-15 11:41:13 -070016class GrGLConicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000017public:
joshualitt87f48d92014-12-04 10:41:40 -080018 GrGLConicEffect(const GrBackendProcessorFactory&,
19 const GrGeometryProcessor&,
20 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000021
joshualittc369e7c2014-10-22 10:56:26 -070022 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000023
joshualitt87f48d92014-12-04 10:41:40 -080024 static inline void GenKey(const GrGeometryProcessor&,
25 const GrBatchTracker&,
26 const GrGLCaps&,
27 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000028
joshualitt87f48d92014-12-04 10:41:40 -080029 virtual void setData(const GrGLProgramDataManager&,
30 const GrGeometryProcessor&,
31 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000032
33private:
joshualittb0a8a372014-09-23 09:50:21 -070034 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000035
joshualitt249af152014-09-15 11:41:13 -070036 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000037};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000038
joshualittb0a8a372014-09-23 09:50:21 -070039GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
joshualitt87f48d92014-12-04 10:41:40 -080040 const GrGeometryProcessor& processor,
41 const GrBatchTracker& bt)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000042 : INHERITED (factory) {
joshualitt87f48d92014-12-04 10:41:40 -080043 const GrConicEffect& ce = processor.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000044 fEdgeType = ce.getEdgeType();
45}
46
joshualittc369e7c2014-10-22 10:56:26 -070047void GrGLConicEffect::emitCode(const EmitArgs& args) {
joshualitt2dd1ae02014-12-03 06:24:10 -080048 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
49 const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
50
joshualitt74077b92014-10-24 11:26:03 -070051 GrGLVertToFrag v(kVec4f_GrSLType);
52 args.fPB->addVarying("ConicCoeffs", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -080053 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000054
joshualitt2dd1ae02014-12-03 06:24:10 -080055 // setup coord outputs
56 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
57 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -070058
joshualitt4973d9d2014-11-08 09:24:25 -080059 // setup position varying
60 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080061 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080062
joshualittc369e7c2014-10-22 10:56:26 -070063 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070064 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000065
66 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -070067 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070068 SkAssertResult(fsBuilder->enableFeature(
69 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -070070 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
71 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070072 fsBuilder->codeAppendf("float dfdx ="
73 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -070074 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070075 fsBuilder->codeAppendf("float dfdy ="
76 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -070077 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070078 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
79 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -070080 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
81 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070082 fsBuilder->codeAppend("func = abs(func);");
83 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
84 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000085 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -070086 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000087 break;
88 }
joshualittb0a8a372014-09-23 09:50:21 -070089 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070090 SkAssertResult(fsBuilder->enableFeature(
91 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -070092 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
93 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070094 fsBuilder->codeAppendf("float dfdx ="
95 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -070096 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070097 fsBuilder->codeAppendf("float dfdy ="
98 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -070099 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700100 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
101 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -0700102 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
103 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700104 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
105 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000106 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700107 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000108 break;
109 }
joshualittb0a8a372014-09-23 09:50:21 -0700110 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700111 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
112 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700113 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000114 break;
115 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000116 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000117 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000118 }
119
joshualitt2dd1ae02014-12-03 06:24:10 -0800120 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000121}
122
joshualitt87f48d92014-12-04 10:41:40 -0800123void GrGLConicEffect::GenKey(const GrGeometryProcessor& processor,
124 const GrBatchTracker&,
125 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700126 GrProcessorKeyBuilder* b) {
127 const GrConicEffect& ce = processor.cast<GrConicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700128 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
129 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000130}
131
132//////////////////////////////////////////////////////////////////////////////
133
134GrConicEffect::~GrConicEffect() {}
135
joshualittb0a8a372014-09-23 09:50:21 -0700136const GrBackendGeometryProcessorFactory& GrConicEffect::getFactory() const {
137 return GrTBackendGeometryProcessorFactory<GrConicEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000138}
139
joshualittb0a8a372014-09-23 09:50:21 -0700140GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType)
joshualitt2dd1ae02014-12-03 06:24:10 -0800141 : fEdgeType(edgeType) {
142 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
143 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
144 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000145}
146
bsalomon0e08fc12014-10-15 08:19:04 -0700147bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700148 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000149 return (ce.fEdgeType == fEdgeType);
150}
151
152//////////////////////////////////////////////////////////////////////////////
153
joshualittb0a8a372014-09-23 09:50:21 -0700154GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000155
joshualittb0a8a372014-09-23 09:50:21 -0700156GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
157 GrContext*,
158 const GrDrawTargetCaps& caps,
159 GrTexture*[]) {
160 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000161 do {
joshualittb0a8a372014-09-23 09:50:21 -0700162 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
163 random->nextULessThan(kGrProcessorEdgeTypeCnt));
164 gp = GrConicEffect::Create(edgeType, caps);
165 } while (NULL == gp);
166 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000167}
168
169//////////////////////////////////////////////////////////////////////////////
170// Quad
171//////////////////////////////////////////////////////////////////////////////
172
joshualitt249af152014-09-15 11:41:13 -0700173class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000174public:
joshualitt87f48d92014-12-04 10:41:40 -0800175 GrGLQuadEffect(const GrBackendProcessorFactory&,
176 const GrGeometryProcessor&,
177 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000178
joshualittc369e7c2014-10-22 10:56:26 -0700179 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000180
joshualitt87f48d92014-12-04 10:41:40 -0800181 static inline void GenKey(const GrGeometryProcessor&,
182 const GrBatchTracker&,
183 const GrGLCaps&,
184 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000185
joshualitt87f48d92014-12-04 10:41:40 -0800186 virtual void setData(const GrGLProgramDataManager&,
187 const GrGeometryProcessor&,
188 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000189
190private:
joshualittb0a8a372014-09-23 09:50:21 -0700191 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000192
joshualitt249af152014-09-15 11:41:13 -0700193 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000194};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000195
joshualittb0a8a372014-09-23 09:50:21 -0700196GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
joshualitt87f48d92014-12-04 10:41:40 -0800197 const GrGeometryProcessor& processor,
198 const GrBatchTracker& bt)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000199 : INHERITED (factory) {
joshualitt87f48d92014-12-04 10:41:40 -0800200 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000201 fEdgeType = ce.getEdgeType();
202}
203
joshualittc369e7c2014-10-22 10:56:26 -0700204void GrGLQuadEffect::emitCode(const EmitArgs& args) {
joshualitt2dd1ae02014-12-03 06:24:10 -0800205 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
206 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
207
joshualitt74077b92014-10-24 11:26:03 -0700208 GrGLVertToFrag v(kVec4f_GrSLType);
209 args.fPB->addVarying("HairQuadEdge", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -0800210 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000211
joshualitt2dd1ae02014-12-03 06:24:10 -0800212 // setup coord outputs
213 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
214 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700215
joshualitt4973d9d2014-11-08 09:24:25 -0800216 // setup position varying
217 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800218 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800219
joshualittc369e7c2014-10-22 10:56:26 -0700220 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700221 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700222
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000223 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700224 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700225 SkAssertResult(fsBuilder->enableFeature(
226 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700227 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
228 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700229 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
230 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700231 v.fsIn(), v.fsIn());
232 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700233 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
234 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000235 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700236 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000237 break;
238 }
joshualittb0a8a372014-09-23 09:50:21 -0700239 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700240 SkAssertResult(fsBuilder->enableFeature(
241 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700242 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
243 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700244 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
245 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700246 v.fsIn(), v.fsIn());
247 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700248 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
249 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000250 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700251 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000252 break;
253 }
joshualittb0a8a372014-09-23 09:50:21 -0700254 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700255 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700256 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000257 break;
258 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000259 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000260 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000261 }
262
joshualitt2dd1ae02014-12-03 06:24:10 -0800263 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000264}
265
joshualitt87f48d92014-12-04 10:41:40 -0800266void GrGLQuadEffect::GenKey(const GrGeometryProcessor& processor,
267 const GrBatchTracker&,
268 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700269 GrProcessorKeyBuilder* b) {
270 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700271 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
272 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000273}
274
275//////////////////////////////////////////////////////////////////////////////
276
277GrQuadEffect::~GrQuadEffect() {}
278
joshualittb0a8a372014-09-23 09:50:21 -0700279const GrBackendGeometryProcessorFactory& GrQuadEffect::getFactory() const {
280 return GrTBackendGeometryProcessorFactory<GrQuadEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000281}
282
joshualittb0a8a372014-09-23 09:50:21 -0700283GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType)
joshualitt2dd1ae02014-12-03 06:24:10 -0800284 : fEdgeType(edgeType) {
285 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
286 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
287 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000288}
289
bsalomon0e08fc12014-10-15 08:19:04 -0700290bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700291 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000292 return (ce.fEdgeType == fEdgeType);
293}
294
295//////////////////////////////////////////////////////////////////////////////
296
joshualittb0a8a372014-09-23 09:50:21 -0700297GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000298
joshualittb0a8a372014-09-23 09:50:21 -0700299GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
300 GrContext*,
301 const GrDrawTargetCaps& caps,
302 GrTexture*[]) {
303 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000304 do {
joshualittb0a8a372014-09-23 09:50:21 -0700305 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
306 random->nextULessThan(kGrProcessorEdgeTypeCnt));
307 gp = GrQuadEffect::Create(edgeType, caps);
308 } while (NULL == gp);
309 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000310}
311
312//////////////////////////////////////////////////////////////////////////////
313// Cubic
314//////////////////////////////////////////////////////////////////////////////
315
joshualitt249af152014-09-15 11:41:13 -0700316class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000317public:
joshualitt87f48d92014-12-04 10:41:40 -0800318 GrGLCubicEffect(const GrBackendProcessorFactory&,
319 const GrGeometryProcessor&,
320 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000321
joshualittc369e7c2014-10-22 10:56:26 -0700322 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000323
joshualitt87f48d92014-12-04 10:41:40 -0800324 static inline void GenKey(const GrGeometryProcessor&,
325 const GrBatchTracker&,
326 const GrGLCaps&,
327 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000328
joshualitt87f48d92014-12-04 10:41:40 -0800329 virtual void setData(const GrGLProgramDataManager&,
330 const GrGeometryProcessor&,
331 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000332
333private:
joshualittb0a8a372014-09-23 09:50:21 -0700334 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000335
joshualitt249af152014-09-15 11:41:13 -0700336 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000337};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000338
joshualittb0a8a372014-09-23 09:50:21 -0700339GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
joshualitt87f48d92014-12-04 10:41:40 -0800340 const GrGeometryProcessor& processor,
341 const GrBatchTracker&)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000342 : INHERITED (factory) {
joshualittb0a8a372014-09-23 09:50:21 -0700343 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000344 fEdgeType = ce.getEdgeType();
345}
346
joshualittc369e7c2014-10-22 10:56:26 -0700347void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700348 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800349 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
350
351 GrGLVertToFrag v(kVec4f_GrSLType);
joshualitted8bdc52014-12-03 09:29:52 -0800352 args.fPB->addVarying("CubicCoeffs", &v, GrGLShaderVar::kHigh_Precision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800353 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
354
355 // setup coord outputs
356 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
357 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700358
joshualitt4973d9d2014-11-08 09:24:25 -0800359 // setup position varying
360 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800361 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800362
joshualittc369e7c2014-10-22 10:56:26 -0700363 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700364
365 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
366 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
367 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
368 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
369 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
370 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
371 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
372 GrGLShaderVar func("func", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
373
374 fsBuilder->declAppend(edgeAlpha);
375 fsBuilder->declAppend(dklmdx);
376 fsBuilder->declAppend(dklmdy);
377 fsBuilder->declAppend(dfdx);
378 fsBuilder->declAppend(dfdy);
379 fsBuilder->declAppend(gF);
380 fsBuilder->declAppend(gFM);
381 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000382
383 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700384 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700385 SkAssertResult(fsBuilder->enableFeature(
386 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700387 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
388 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700389 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700390 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
391 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700392 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700393 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
394 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700395 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
396 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
397 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700398 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700399 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
400 fsBuilder->codeAppendf("%s = %s / %s;",
401 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
402 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
403 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000404 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700405 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
406 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
407 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000408 break;
409 }
joshualittb0a8a372014-09-23 09:50:21 -0700410 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700411 SkAssertResult(fsBuilder->enableFeature(
412 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700413 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
414 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700415 fsBuilder->codeAppendf("%s ="
416 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700417 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
418 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700419 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700420 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
421 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700422 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
423 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
424 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700425 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700426 fsBuilder->codeAppendf("%s = %s / %s;",
427 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
428 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
429 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000430 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700431 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
432 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
433 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000434 break;
435 }
joshualittb0a8a372014-09-23 09:50:21 -0700436 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700437 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700438 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700439 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000440 break;
441 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000442 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000443 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000444 }
445
joshualitt2dd1ae02014-12-03 06:24:10 -0800446
447 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000448}
449
joshualitt87f48d92014-12-04 10:41:40 -0800450void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
451 const GrBatchTracker&,
452 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700453 GrProcessorKeyBuilder* b) {
454 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700455 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
456 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000457}
458
459//////////////////////////////////////////////////////////////////////////////
460
461GrCubicEffect::~GrCubicEffect() {}
462
joshualittb0a8a372014-09-23 09:50:21 -0700463const GrBackendGeometryProcessorFactory& GrCubicEffect::getFactory() const {
464 return GrTBackendGeometryProcessorFactory<GrCubicEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000465}
466
joshualittb0a8a372014-09-23 09:50:21 -0700467GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType)
joshualitt2dd1ae02014-12-03 06:24:10 -0800468 : fEdgeType(edgeType) {
469 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
470 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
471 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000472}
473
bsalomon0e08fc12014-10-15 08:19:04 -0700474bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700475 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000476 return (ce.fEdgeType == fEdgeType);
477}
478
479//////////////////////////////////////////////////////////////////////////////
480
joshualittb0a8a372014-09-23 09:50:21 -0700481GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000482
joshualittb0a8a372014-09-23 09:50:21 -0700483GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
484 GrContext*,
485 const GrDrawTargetCaps& caps,
486 GrTexture*[]) {
487 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000488 do {
joshualittb0a8a372014-09-23 09:50:21 -0700489 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
490 random->nextULessThan(kGrProcessorEdgeTypeCnt));
491 gp = GrCubicEffect::Create(edgeType, caps);
492 } while (NULL == gp);
493 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000494}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700495