blob: 6ad1537f6253e046f5aa612dfef7701716b36bfe [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
joshualittb0a8a372014-09-23 09:50:21 -070010#include "gl/GrGLProcessor.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000011#include "gl/GrGLSL.h"
joshualitt249af152014-09-15 11:41:13 -070012#include "gl/GrGLGeometryProcessor.h"
joshualitteb2a6762014-12-04 11:35:33 -080013#include "gl/builders/GrGLProgramBuilder.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000014
joshualitt249af152014-09-15 11:41:13 -070015class GrGLConicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000016public:
joshualitteb2a6762014-12-04 11:35:33 -080017 GrGLConicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -080018 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000019
joshualittc369e7c2014-10-22 10:56:26 -070020 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000021
joshualitt87f48d92014-12-04 10:41:40 -080022 static inline void GenKey(const GrGeometryProcessor&,
23 const GrBatchTracker&,
24 const GrGLCaps&,
25 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000026
joshualitt87f48d92014-12-04 10:41:40 -080027 virtual void setData(const GrGLProgramDataManager&,
28 const GrGeometryProcessor&,
29 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000030
31private:
joshualittb0a8a372014-09-23 09:50:21 -070032 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000033
joshualitt249af152014-09-15 11:41:13 -070034 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000035};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000036
joshualitteb2a6762014-12-04 11:35:33 -080037GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor,
38 const GrBatchTracker& bt) {
joshualitt87f48d92014-12-04 10:41:40 -080039 const GrConicEffect& ce = processor.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000040 fEdgeType = ce.getEdgeType();
41}
42
joshualittc369e7c2014-10-22 10:56:26 -070043void GrGLConicEffect::emitCode(const EmitArgs& args) {
joshualitt2dd1ae02014-12-03 06:24:10 -080044 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
45 const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
46
joshualitt74077b92014-10-24 11:26:03 -070047 GrGLVertToFrag v(kVec4f_GrSLType);
48 args.fPB->addVarying("ConicCoeffs", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -080049 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000050
joshualitt2dd1ae02014-12-03 06:24:10 -080051 // setup coord outputs
52 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
53 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -070054
joshualitt4973d9d2014-11-08 09:24:25 -080055 // setup position varying
56 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080057 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080058
joshualittc369e7c2014-10-22 10:56:26 -070059 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070060 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000061
62 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -070063 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070064 SkAssertResult(fsBuilder->enableFeature(
65 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -070066 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
67 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070068 fsBuilder->codeAppendf("float dfdx ="
69 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -070070 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070071 fsBuilder->codeAppendf("float dfdy ="
72 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -070073 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070074 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
75 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -070076 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
77 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070078 fsBuilder->codeAppend("func = abs(func);");
79 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
80 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000081 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -070082 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000083 break;
84 }
joshualittb0a8a372014-09-23 09:50:21 -070085 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070086 SkAssertResult(fsBuilder->enableFeature(
87 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -070088 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
89 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070090 fsBuilder->codeAppendf("float dfdx ="
91 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -070092 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070093 fsBuilder->codeAppendf("float dfdy ="
94 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -070095 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070096 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
97 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -070098 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
99 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700100 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
101 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000102 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700103 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000104 break;
105 }
joshualittb0a8a372014-09-23 09:50:21 -0700106 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700107 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
108 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700109 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000110 break;
111 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000112 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000113 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000114 }
115
joshualitt2dd1ae02014-12-03 06:24:10 -0800116 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000117}
118
joshualitt87f48d92014-12-04 10:41:40 -0800119void GrGLConicEffect::GenKey(const GrGeometryProcessor& processor,
120 const GrBatchTracker&,
121 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700122 GrProcessorKeyBuilder* b) {
123 const GrConicEffect& ce = processor.cast<GrConicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700124 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
125 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000126}
127
128//////////////////////////////////////////////////////////////////////////////
129
130GrConicEffect::~GrConicEffect() {}
131
joshualitteb2a6762014-12-04 11:35:33 -0800132void GrConicEffect::getGLProcessorKey(const GrBatchTracker& bt,
133 const GrGLCaps& caps,
134 GrProcessorKeyBuilder* b) const {
135 GrGLConicEffect::GenKey(*this, bt, caps, b);
136}
137
138GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) const {
139 return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000140}
141
joshualitt2e3b3e32014-12-09 13:31:14 -0800142GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
143 : INHERITED(color, coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800144 this->initClassID<GrConicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800145 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
146 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
147 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000148}
149
bsalomon0e08fc12014-10-15 08:19:04 -0700150bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700151 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000152 return (ce.fEdgeType == fEdgeType);
153}
154
155//////////////////////////////////////////////////////////////////////////////
156
joshualittb0a8a372014-09-23 09:50:21 -0700157GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000158
joshualittb0a8a372014-09-23 09:50:21 -0700159GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
160 GrContext*,
161 const GrDrawTargetCaps& caps,
162 GrTexture*[]) {
163 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000164 do {
joshualittb0a8a372014-09-23 09:50:21 -0700165 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
166 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800167 gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700168 } while (NULL == gp);
169 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000170}
171
172//////////////////////////////////////////////////////////////////////////////
173// Quad
174//////////////////////////////////////////////////////////////////////////////
175
joshualitt249af152014-09-15 11:41:13 -0700176class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000177public:
joshualitteb2a6762014-12-04 11:35:33 -0800178 GrGLQuadEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800179 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000180
joshualittc369e7c2014-10-22 10:56:26 -0700181 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000182
joshualitt87f48d92014-12-04 10:41:40 -0800183 static inline void GenKey(const GrGeometryProcessor&,
184 const GrBatchTracker&,
185 const GrGLCaps&,
186 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000187
joshualitt87f48d92014-12-04 10:41:40 -0800188 virtual void setData(const GrGLProgramDataManager&,
189 const GrGeometryProcessor&,
190 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000191
192private:
joshualittb0a8a372014-09-23 09:50:21 -0700193 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000194
joshualitt249af152014-09-15 11:41:13 -0700195 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000196};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000197
joshualitteb2a6762014-12-04 11:35:33 -0800198GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor,
199 const GrBatchTracker& bt) {
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
joshualitteb2a6762014-12-04 11:35:33 -0800279void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt,
280 const GrGLCaps& caps,
281 GrProcessorKeyBuilder* b) const {
282 GrGLQuadEffect::GenKey(*this, bt, caps, b);
283}
284
285GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const {
286 return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000287}
288
joshualitt2e3b3e32014-12-09 13:31:14 -0800289GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
290 : INHERITED(color, coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800291 this->initClassID<GrQuadEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800292 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
293 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
294 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000295}
296
bsalomon0e08fc12014-10-15 08:19:04 -0700297bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700298 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000299 return (ce.fEdgeType == fEdgeType);
300}
301
302//////////////////////////////////////////////////////////////////////////////
303
joshualittb0a8a372014-09-23 09:50:21 -0700304GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000305
joshualittb0a8a372014-09-23 09:50:21 -0700306GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
307 GrContext*,
308 const GrDrawTargetCaps& caps,
309 GrTexture*[]) {
310 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000311 do {
joshualittb0a8a372014-09-23 09:50:21 -0700312 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
313 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800314 gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700315 } while (NULL == gp);
316 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000317}
318
319//////////////////////////////////////////////////////////////////////////////
320// Cubic
321//////////////////////////////////////////////////////////////////////////////
322
joshualitt249af152014-09-15 11:41:13 -0700323class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000324public:
joshualitteb2a6762014-12-04 11:35:33 -0800325 GrGLCubicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800326 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000327
joshualittc369e7c2014-10-22 10:56:26 -0700328 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000329
joshualitt87f48d92014-12-04 10:41:40 -0800330 static inline void GenKey(const GrGeometryProcessor&,
331 const GrBatchTracker&,
332 const GrGLCaps&,
333 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000334
joshualitt87f48d92014-12-04 10:41:40 -0800335 virtual void setData(const GrGLProgramDataManager&,
336 const GrGeometryProcessor&,
337 const GrBatchTracker&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000338
339private:
joshualittb0a8a372014-09-23 09:50:21 -0700340 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000341
joshualitt249af152014-09-15 11:41:13 -0700342 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000343};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000344
joshualitteb2a6762014-12-04 11:35:33 -0800345GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor,
346 const GrBatchTracker&) {
joshualittb0a8a372014-09-23 09:50:21 -0700347 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000348 fEdgeType = ce.getEdgeType();
349}
350
joshualittc369e7c2014-10-22 10:56:26 -0700351void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700352 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800353 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
354
355 GrGLVertToFrag v(kVec4f_GrSLType);
bsalomonc0bd6482014-12-09 10:04:14 -0800356 args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800357 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
358
359 // setup coord outputs
360 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
361 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700362
joshualitt4973d9d2014-11-08 09:24:25 -0800363 // setup position varying
364 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800365 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800366
joshualittc369e7c2014-10-22 10:56:26 -0700367 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700368
bsalomonc0bd6482014-12-09 10:04:14 -0800369 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
370 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
371 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
372 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
373 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
374 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
375 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
376 GrGLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
egdaniel9bd5bbf2014-08-29 11:12:30 -0700377
378 fsBuilder->declAppend(edgeAlpha);
379 fsBuilder->declAppend(dklmdx);
380 fsBuilder->declAppend(dklmdy);
381 fsBuilder->declAppend(dfdx);
382 fsBuilder->declAppend(dfdy);
383 fsBuilder->declAppend(gF);
384 fsBuilder->declAppend(gFM);
385 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000386
387 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700388 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700389 SkAssertResult(fsBuilder->enableFeature(
390 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700391 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
392 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700393 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 -0700394 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
395 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700396 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 -0700397 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
398 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700399 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
400 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
401 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700402 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700403 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
404 fsBuilder->codeAppendf("%s = %s / %s;",
405 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
406 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
407 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000408 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700409 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
410 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
411 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000412 break;
413 }
joshualittb0a8a372014-09-23 09:50:21 -0700414 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700415 SkAssertResult(fsBuilder->enableFeature(
416 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700417 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
418 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700419 fsBuilder->codeAppendf("%s ="
420 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700421 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
422 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700423 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 -0700424 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
425 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700426 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
427 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
428 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700429 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700430 fsBuilder->codeAppendf("%s = %s / %s;",
431 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
432 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
433 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000434 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700435 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
436 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
437 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000438 break;
439 }
joshualittb0a8a372014-09-23 09:50:21 -0700440 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700441 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700442 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700443 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000444 break;
445 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000446 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000447 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000448 }
449
joshualitt2dd1ae02014-12-03 06:24:10 -0800450
451 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000452}
453
joshualitt87f48d92014-12-04 10:41:40 -0800454void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
455 const GrBatchTracker&,
456 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700457 GrProcessorKeyBuilder* b) {
458 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700459 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
460 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000461}
462
463//////////////////////////////////////////////////////////////////////////////
464
465GrCubicEffect::~GrCubicEffect() {}
466
joshualitteb2a6762014-12-04 11:35:33 -0800467void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt,
468 const GrGLCaps& caps,
469 GrProcessorKeyBuilder* b) const {
470 GrGLCubicEffect::GenKey(*this, bt, caps, b);
471}
472
473GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const {
474 return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000475}
476
joshualitt2e3b3e32014-12-09 13:31:14 -0800477GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
478 : INHERITED(color), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800479 this->initClassID<GrCubicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800480 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
481 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
482 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000483}
484
bsalomon0e08fc12014-10-15 08:19:04 -0700485bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700486 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000487 return (ce.fEdgeType == fEdgeType);
488}
489
490//////////////////////////////////////////////////////////////////////////////
491
joshualittb0a8a372014-09-23 09:50:21 -0700492GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000493
joshualittb0a8a372014-09-23 09:50:21 -0700494GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
495 GrContext*,
496 const GrDrawTargetCaps& caps,
497 GrTexture*[]) {
498 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000499 do {
joshualittb0a8a372014-09-23 09:50:21 -0700500 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
501 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800502 gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700503 } while (NULL == gp);
504 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000505}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700506