blob: e16601dee111bd682716e691dbd90a52109bfd81 [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
joshualitt9b989322014-12-15 14:16:27 -080015struct ConicBatchTracker {
16 GrGPInput fInputColorType;
17 GrColor fColor;
18 uint8_t fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -080019 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -080020};
21
joshualitt249af152014-09-15 11:41:13 -070022class GrGLConicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000023public:
joshualitteb2a6762014-12-04 11:35:33 -080024 GrGLConicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -080025 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000026
mtklein72c9faa2015-01-09 10:06:39 -080027 void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000028
joshualitt87f48d92014-12-04 10:41:40 -080029 static inline void GenKey(const GrGeometryProcessor&,
30 const GrBatchTracker&,
31 const GrGLCaps&,
32 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000033
joshualitt9b989322014-12-15 14:16:27 -080034 virtual void setData(const GrGLProgramDataManager& pdman,
joshualittee2af952014-12-30 09:04:15 -080035 const GrPrimitiveProcessor& primProc,
joshualitt9b989322014-12-15 14:16:27 -080036 const GrBatchTracker& bt) SK_OVERRIDE {
joshualittee2af952014-12-30 09:04:15 -080037 this->setUniformViewMatrix(pdman, primProc.viewMatrix());
38
joshualitt9b989322014-12-15 14:16:27 -080039 const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
40 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
41 GrGLfloat c[4];
42 GrColorToRGBAFloat(local.fColor, c);
43 pdman.set4fv(fColorUniform, 1, c);
44 fColor = local.fColor;
45 }
46 if (0xff != local.fCoverageScale && fCoverageScale != local.fCoverageScale) {
47 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
48 fCoverageScale = local.fCoverageScale;
49 }
50 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000051
52private:
joshualitt9b989322014-12-15 14:16:27 -080053 GrColor fColor;
54 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -070055 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -080056 UniformHandle fColorUniform;
57 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000058
joshualitt249af152014-09-15 11:41:13 -070059 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000060};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000061
joshualitteb2a6762014-12-04 11:35:33 -080062GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -080063 const GrBatchTracker& bt)
64 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -080065 const GrConicEffect& ce = processor.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000066 fEdgeType = ce.getEdgeType();
67}
68
joshualittc369e7c2014-10-22 10:56:26 -070069void GrGLConicEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -080070 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -080071 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
72 const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
joshualitt9b989322014-12-15 14:16:27 -080073 const ConicBatchTracker& local = args.fBT.cast<ConicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -080074
joshualitt74077b92014-10-24 11:26:03 -070075 GrGLVertToFrag v(kVec4f_GrSLType);
76 args.fPB->addVarying("ConicCoeffs", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -080077 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000078
joshualitt9b989322014-12-15 14:16:27 -080079 // Setup pass through color
80 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
81 &fColorUniform);
82
joshualitt2dd1ae02014-12-03 06:24:10 -080083 // setup coord outputs
84 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
85 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -070086
joshualittee2af952014-12-30 09:04:15 -080087 // setup uniform viewMatrix
88 this->addUniformViewMatrix(pb);
89
joshualitt4973d9d2014-11-08 09:24:25 -080090 // setup position varying
joshualittee2af952014-12-30 09:04:15 -080091 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080092 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080093
joshualittc369e7c2014-10-22 10:56:26 -070094 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070095 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000096
97 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -070098 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070099 SkAssertResult(fsBuilder->enableFeature(
100 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700101 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
102 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700103 fsBuilder->codeAppendf("float dfdx ="
104 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -0700105 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700106 fsBuilder->codeAppendf("float dfdy ="
107 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -0700108 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700109 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
110 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -0700111 fsBuilder->codeAppendf("float func = %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("func = abs(func);");
114 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
115 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000116 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700117 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000118 break;
119 }
joshualittb0a8a372014-09-23 09:50:21 -0700120 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700121 SkAssertResult(fsBuilder->enableFeature(
122 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700123 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
124 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700125 fsBuilder->codeAppendf("float dfdx ="
126 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -0700127 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700128 fsBuilder->codeAppendf("float dfdy ="
129 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -0700130 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700131 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
132 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -0700133 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
134 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700135 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
136 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000137 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700138 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000139 break;
140 }
joshualittb0a8a372014-09-23 09:50:21 -0700141 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700142 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
143 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700144 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000145 break;
146 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000147 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000148 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000149 }
150
joshualitt9b989322014-12-15 14:16:27 -0800151 if (0xff != local.fCoverageScale) {
152 const char* coverageScale;
153 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
154 kFloat_GrSLType,
155 kDefault_GrSLPrecision,
156 "Coverage",
157 &coverageScale);
158 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
159 } else {
160 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
161 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000162}
163
joshualitt87f48d92014-12-04 10:41:40 -0800164void GrGLConicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800165 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800166 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700167 GrProcessorKeyBuilder* b) {
168 const GrConicEffect& ce = processor.cast<GrConicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800169 const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700170 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800171 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
172 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800173 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700174 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000175}
176
177//////////////////////////////////////////////////////////////////////////////
178
179GrConicEffect::~GrConicEffect() {}
180
joshualitteb2a6762014-12-04 11:35:33 -0800181void GrConicEffect::getGLProcessorKey(const GrBatchTracker& bt,
182 const GrGLCaps& caps,
183 GrProcessorKeyBuilder* b) const {
184 GrGLConicEffect::GenKey(*this, bt, caps, b);
185}
186
187GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) const {
188 return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000189}
190
joshualitt8059eb92014-12-29 15:10:07 -0800191GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
192 GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix)
193 : INHERITED(color, viewMatrix, localMatrix)
194 , fCoverageScale(coverage)
195 , fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800196 this->initClassID<GrConicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800197 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
198 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
199 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000200}
201
bsalomon0e08fc12014-10-15 08:19:04 -0700202bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700203 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000204 return (ce.fEdgeType == fEdgeType);
205}
206
joshualitt9b989322014-12-15 14:16:27 -0800207void GrConicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
208 ConicBatchTracker* local = bt->cast<ConicBatchTracker>();
209 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
210 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800211 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800212}
213
joshualitt290c09b2014-12-19 13:45:20 -0800214bool GrConicEffect::onCanMakeEqual(const GrBatchTracker& m,
215 const GrGeometryProcessor& that,
216 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800217 const ConicBatchTracker& mine = m.cast<ConicBatchTracker>();
218 const ConicBatchTracker& theirs = t.cast<ConicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800219 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
220 that, theirs.fUsesLocalCoords) &&
221 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800222 theirs.fInputColorType, theirs.fColor) &&
223 mine.fCoverageScale == theirs.fCoverageScale;
224}
225
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000226//////////////////////////////////////////////////////////////////////////////
227
joshualittb0a8a372014-09-23 09:50:21 -0700228GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000229
joshualittb0a8a372014-09-23 09:50:21 -0700230GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
231 GrContext*,
232 const GrDrawTargetCaps& caps,
233 GrTexture*[]) {
234 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000235 do {
joshualittb0a8a372014-09-23 09:50:21 -0700236 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
237 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt8059eb92014-12-29 15:10:07 -0800238 gp = GrConicEffect::Create(GrRandomColor(random), GrProcessorUnitTest::TestMatrix(random),
239 edgeType, caps,
joshualittd27f73e2014-12-29 07:43:36 -0800240 GrProcessorUnitTest::TestMatrix(random));
joshualittb0a8a372014-09-23 09:50:21 -0700241 } while (NULL == gp);
242 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000243}
244
245//////////////////////////////////////////////////////////////////////////////
246// Quad
247//////////////////////////////////////////////////////////////////////////////
248
joshualitt9b989322014-12-15 14:16:27 -0800249struct QuadBatchTracker {
250 GrGPInput fInputColorType;
251 GrColor fColor;
252 uint8_t fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800253 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800254};
255
joshualitt249af152014-09-15 11:41:13 -0700256class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000257public:
joshualitteb2a6762014-12-04 11:35:33 -0800258 GrGLQuadEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800259 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000260
mtklein72c9faa2015-01-09 10:06:39 -0800261 void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000262
joshualitt87f48d92014-12-04 10:41:40 -0800263 static inline void GenKey(const GrGeometryProcessor&,
264 const GrBatchTracker&,
265 const GrGLCaps&,
266 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000267
joshualitt9b989322014-12-15 14:16:27 -0800268 virtual void setData(const GrGLProgramDataManager& pdman,
joshualittee2af952014-12-30 09:04:15 -0800269 const GrPrimitiveProcessor& primProc,
joshualitt9b989322014-12-15 14:16:27 -0800270 const GrBatchTracker& bt) SK_OVERRIDE {
joshualittee2af952014-12-30 09:04:15 -0800271 this->setUniformViewMatrix(pdman, primProc.viewMatrix());
272
joshualitt9b989322014-12-15 14:16:27 -0800273 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
274 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
275 GrGLfloat c[4];
276 GrColorToRGBAFloat(local.fColor, c);
277 pdman.set4fv(fColorUniform, 1, c);
278 fColor = local.fColor;
279 }
280 if (0xff != local.fCoverageScale && local.fCoverageScale != fCoverageScale) {
281 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
282 fCoverageScale = local.fCoverageScale;
283 }
284 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000285
286private:
joshualitt9b989322014-12-15 14:16:27 -0800287 GrColor fColor;
288 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -0700289 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800290 UniformHandle fColorUniform;
291 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000292
joshualitt249af152014-09-15 11:41:13 -0700293 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000294};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000295
joshualitteb2a6762014-12-04 11:35:33 -0800296GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800297 const GrBatchTracker& bt)
298 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -0800299 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000300 fEdgeType = ce.getEdgeType();
301}
302
joshualittc369e7c2014-10-22 10:56:26 -0700303void GrGLQuadEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -0800304 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -0800305 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
306 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800307 const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800308
joshualitt74077b92014-10-24 11:26:03 -0700309 GrGLVertToFrag v(kVec4f_GrSLType);
310 args.fPB->addVarying("HairQuadEdge", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -0800311 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000312
joshualitt9b989322014-12-15 14:16:27 -0800313 // Setup pass through color
314 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
315 &fColorUniform);
316
joshualitt2dd1ae02014-12-03 06:24:10 -0800317 // setup coord outputs
318 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
319 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700320
joshualittee2af952014-12-30 09:04:15 -0800321 // setup uniform viewMatrix
322 this->addUniformViewMatrix(pb);
323
joshualitt4973d9d2014-11-08 09:24:25 -0800324 // setup position varying
joshualittee2af952014-12-30 09:04:15 -0800325 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800326 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800327
joshualittc369e7c2014-10-22 10:56:26 -0700328 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700329 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700330
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000331 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700332 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700333 SkAssertResult(fsBuilder->enableFeature(
334 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700335 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
336 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700337 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
338 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700339 v.fsIn(), v.fsIn());
340 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700341 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
342 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000343 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700344 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000345 break;
346 }
joshualittb0a8a372014-09-23 09:50:21 -0700347 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700348 SkAssertResult(fsBuilder->enableFeature(
349 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700350 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
351 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700352 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
353 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700354 v.fsIn(), v.fsIn());
355 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700356 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
357 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000358 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700359 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000360 break;
361 }
joshualittb0a8a372014-09-23 09:50:21 -0700362 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700363 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700364 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000365 break;
366 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000367 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000368 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000369 }
370
joshualitt9b989322014-12-15 14:16:27 -0800371 if (0xff != local.fCoverageScale) {
372 const char* coverageScale;
373 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
374 kFloat_GrSLType,
375 kDefault_GrSLPrecision,
376 "Coverage",
377 &coverageScale);
378 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
379 } else {
380 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
381 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000382}
383
joshualitt87f48d92014-12-04 10:41:40 -0800384void GrGLQuadEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800385 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800386 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700387 GrProcessorKeyBuilder* b) {
388 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800389 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700390 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800391 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
392 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800393 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700394 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000395}
396
397//////////////////////////////////////////////////////////////////////////////
398
399GrQuadEffect::~GrQuadEffect() {}
400
joshualitteb2a6762014-12-04 11:35:33 -0800401void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt,
402 const GrGLCaps& caps,
403 GrProcessorKeyBuilder* b) const {
404 GrGLQuadEffect::GenKey(*this, bt, caps, b);
405}
406
407GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const {
408 return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000409}
410
joshualitt8059eb92014-12-29 15:10:07 -0800411GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
412 GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix)
413 : INHERITED(color, viewMatrix, localMatrix)
414 , fCoverageScale(coverage)
415 , fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800416 this->initClassID<GrQuadEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800417 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
418 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
419 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000420}
421
bsalomon0e08fc12014-10-15 08:19:04 -0700422bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700423 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000424 return (ce.fEdgeType == fEdgeType);
425}
426
joshualitt9b989322014-12-15 14:16:27 -0800427void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
428 QuadBatchTracker* local = bt->cast<QuadBatchTracker>();
429 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
430 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800431 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800432}
433
joshualitt290c09b2014-12-19 13:45:20 -0800434bool GrQuadEffect::onCanMakeEqual(const GrBatchTracker& m,
435 const GrGeometryProcessor& that,
436 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800437 const QuadBatchTracker& mine = m.cast<QuadBatchTracker>();
438 const QuadBatchTracker& theirs = t.cast<QuadBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800439 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
440 that, theirs.fUsesLocalCoords) &&
441 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800442 theirs.fInputColorType, theirs.fColor) &&
443 mine.fCoverageScale == theirs.fCoverageScale;
444}
445
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000446//////////////////////////////////////////////////////////////////////////////
447
joshualittb0a8a372014-09-23 09:50:21 -0700448GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000449
joshualittb0a8a372014-09-23 09:50:21 -0700450GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
451 GrContext*,
452 const GrDrawTargetCaps& caps,
453 GrTexture*[]) {
454 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000455 do {
joshualittb0a8a372014-09-23 09:50:21 -0700456 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
457 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt8059eb92014-12-29 15:10:07 -0800458 gp = GrQuadEffect::Create(GrRandomColor(random),
459 GrProcessorUnitTest::TestMatrix(random),
460 edgeType, caps,
joshualittd27f73e2014-12-29 07:43:36 -0800461 GrProcessorUnitTest::TestMatrix(random));
joshualittb0a8a372014-09-23 09:50:21 -0700462 } while (NULL == gp);
463 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000464}
465
466//////////////////////////////////////////////////////////////////////////////
467// Cubic
468//////////////////////////////////////////////////////////////////////////////
469
joshualitt9b989322014-12-15 14:16:27 -0800470struct CubicBatchTracker {
471 GrGPInput fInputColorType;
472 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800473 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800474};
475
joshualitt249af152014-09-15 11:41:13 -0700476class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000477public:
joshualitteb2a6762014-12-04 11:35:33 -0800478 GrGLCubicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800479 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000480
mtklein72c9faa2015-01-09 10:06:39 -0800481 void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000482
joshualitt87f48d92014-12-04 10:41:40 -0800483 static inline void GenKey(const GrGeometryProcessor&,
484 const GrBatchTracker&,
485 const GrGLCaps&,
486 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000487
joshualitt9b989322014-12-15 14:16:27 -0800488 virtual void setData(const GrGLProgramDataManager& pdman,
joshualittee2af952014-12-30 09:04:15 -0800489 const GrPrimitiveProcessor& primProc,
joshualitt9b989322014-12-15 14:16:27 -0800490 const GrBatchTracker& bt) SK_OVERRIDE {
joshualittee2af952014-12-30 09:04:15 -0800491 this->setUniformViewMatrix(pdman, primProc.viewMatrix());
492
joshualitt9b989322014-12-15 14:16:27 -0800493 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
494 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
495 GrGLfloat c[4];
496 GrColorToRGBAFloat(local.fColor, c);
497 pdman.set4fv(fColorUniform, 1, c);
498 fColor = local.fColor;
499 }
500 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000501
502private:
joshualitt9b989322014-12-15 14:16:27 -0800503 GrColor fColor;
joshualittb0a8a372014-09-23 09:50:21 -0700504 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800505 UniformHandle fColorUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000506
joshualitt249af152014-09-15 11:41:13 -0700507 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000508};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000509
joshualitteb2a6762014-12-04 11:35:33 -0800510GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800511 const GrBatchTracker&)
512 : fColor(GrColor_ILLEGAL) {
joshualittb0a8a372014-09-23 09:50:21 -0700513 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000514 fEdgeType = ce.getEdgeType();
515}
516
joshualittc369e7c2014-10-22 10:56:26 -0700517void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700518 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800519 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800520 const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800521
522 GrGLVertToFrag v(kVec4f_GrSLType);
bsalomonc0bd6482014-12-09 10:04:14 -0800523 args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800524 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
525
joshualitt9b989322014-12-15 14:16:27 -0800526 // Setup pass through color
527 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
528 &fColorUniform);
529
joshualitt2dd1ae02014-12-03 06:24:10 -0800530 // setup coord outputs
531 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
532 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700533
joshualittee2af952014-12-30 09:04:15 -0800534 // setup uniform viewMatrix
535 this->addUniformViewMatrix(args.fPB);
536
joshualitt4973d9d2014-11-08 09:24:25 -0800537 // setup position varying
joshualittee2af952014-12-30 09:04:15 -0800538 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), this->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800539 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800540
joshualittc369e7c2014-10-22 10:56:26 -0700541 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700542
bsalomonc0bd6482014-12-09 10:04:14 -0800543 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
544 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
545 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
546 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
547 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
548 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
549 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
550 GrGLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
egdaniel9bd5bbf2014-08-29 11:12:30 -0700551
552 fsBuilder->declAppend(edgeAlpha);
553 fsBuilder->declAppend(dklmdx);
554 fsBuilder->declAppend(dklmdy);
555 fsBuilder->declAppend(dfdx);
556 fsBuilder->declAppend(dfdy);
557 fsBuilder->declAppend(gF);
558 fsBuilder->declAppend(gFM);
559 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000560
561 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700562 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700563 SkAssertResult(fsBuilder->enableFeature(
564 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700565 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
566 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700567 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 -0700568 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
569 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700570 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 -0700571 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
572 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700573 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
574 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
575 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700576 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700577 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
578 fsBuilder->codeAppendf("%s = %s / %s;",
579 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
580 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
581 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000582 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700583 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
584 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
585 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000586 break;
587 }
joshualittb0a8a372014-09-23 09:50:21 -0700588 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700589 SkAssertResult(fsBuilder->enableFeature(
590 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700591 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
592 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700593 fsBuilder->codeAppendf("%s ="
594 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700595 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
596 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700597 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 -0700598 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
599 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700600 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
601 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
602 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700603 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700604 fsBuilder->codeAppendf("%s = %s / %s;",
605 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
606 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
607 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000608 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700609 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
610 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
611 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000612 break;
613 }
joshualittb0a8a372014-09-23 09:50:21 -0700614 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700615 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700616 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700617 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000618 break;
619 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000620 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000621 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000622 }
623
joshualitt2dd1ae02014-12-03 06:24:10 -0800624
625 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000626}
627
joshualitt87f48d92014-12-04 10:41:40 -0800628void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800629 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800630 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700631 GrProcessorKeyBuilder* b) {
632 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800633 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700634 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800635 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x8;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800636 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700637 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000638}
639
640//////////////////////////////////////////////////////////////////////////////
641
642GrCubicEffect::~GrCubicEffect() {}
643
joshualitteb2a6762014-12-04 11:35:33 -0800644void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt,
645 const GrGLCaps& caps,
646 GrProcessorKeyBuilder* b) const {
647 GrGLCubicEffect::GenKey(*this, bt, caps, b);
648}
649
650GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const {
651 return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000652}
653
joshualitt8059eb92014-12-29 15:10:07 -0800654GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix,
655 GrPrimitiveEdgeType edgeType)
656 : INHERITED(color, viewMatrix), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800657 this->initClassID<GrCubicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800658 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
659 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
660 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000661}
662
bsalomon0e08fc12014-10-15 08:19:04 -0700663bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700664 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000665 return (ce.fEdgeType == fEdgeType);
666}
667
joshualitt9b989322014-12-15 14:16:27 -0800668void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
669 CubicBatchTracker* local = bt->cast<CubicBatchTracker>();
670 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800671 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800672}
673
joshualitt290c09b2014-12-19 13:45:20 -0800674bool GrCubicEffect::onCanMakeEqual(const GrBatchTracker& m,
675 const GrGeometryProcessor& that,
676 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800677 const CubicBatchTracker& mine = m.cast<CubicBatchTracker>();
678 const CubicBatchTracker& theirs = t.cast<CubicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800679 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
680 that, theirs.fUsesLocalCoords) &&
681 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800682 theirs.fInputColorType, theirs.fColor);
683}
684
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000685//////////////////////////////////////////////////////////////////////////////
686
joshualittb0a8a372014-09-23 09:50:21 -0700687GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000688
joshualittb0a8a372014-09-23 09:50:21 -0700689GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
690 GrContext*,
691 const GrDrawTargetCaps& caps,
692 GrTexture*[]) {
693 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000694 do {
joshualittb0a8a372014-09-23 09:50:21 -0700695 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
696 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt8059eb92014-12-29 15:10:07 -0800697 gp = GrCubicEffect::Create(GrRandomColor(random),
698 GrProcessorUnitTest::TestMatrix(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700699 } while (NULL == gp);
700 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000701}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700702