blob: 2a4ef3692f5eb42f83e7a93185fe318c56f7965a [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
joshualittc369e7c2014-10-22 10:56:26 -070027 virtual 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,
35 const GrPrimitiveProcessor&,
36 const GrBatchTracker& bt) SK_OVERRIDE {
37 const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
38 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
39 GrGLfloat c[4];
40 GrColorToRGBAFloat(local.fColor, c);
41 pdman.set4fv(fColorUniform, 1, c);
42 fColor = local.fColor;
43 }
44 if (0xff != local.fCoverageScale && fCoverageScale != local.fCoverageScale) {
45 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
46 fCoverageScale = local.fCoverageScale;
47 }
48 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000049
50private:
joshualitt9b989322014-12-15 14:16:27 -080051 GrColor fColor;
52 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -070053 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -080054 UniformHandle fColorUniform;
55 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000056
joshualitt249af152014-09-15 11:41:13 -070057 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000058};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000059
joshualitteb2a6762014-12-04 11:35:33 -080060GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -080061 const GrBatchTracker& bt)
62 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -080063 const GrConicEffect& ce = processor.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000064 fEdgeType = ce.getEdgeType();
65}
66
joshualittc369e7c2014-10-22 10:56:26 -070067void GrGLConicEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -080068 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -080069 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
70 const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
joshualitt9b989322014-12-15 14:16:27 -080071 const ConicBatchTracker& local = args.fBT.cast<ConicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -080072
joshualitt74077b92014-10-24 11:26:03 -070073 GrGLVertToFrag v(kVec4f_GrSLType);
74 args.fPB->addVarying("ConicCoeffs", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -080075 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000076
joshualitt9b989322014-12-15 14:16:27 -080077 // Setup pass through color
78 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
79 &fColorUniform);
80
joshualitt2dd1ae02014-12-03 06:24:10 -080081 // setup coord outputs
82 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
83 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -070084
joshualitt4973d9d2014-11-08 09:24:25 -080085 // setup position varying
86 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -080087 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -080088
joshualittc369e7c2014-10-22 10:56:26 -070089 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070090 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000091
92 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -070093 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070094 SkAssertResult(fsBuilder->enableFeature(
95 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -070096 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
97 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -070098 fsBuilder->codeAppendf("float dfdx ="
99 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -0700100 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700101 fsBuilder->codeAppendf("float dfdy ="
102 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -0700103 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700104 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
105 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -0700106 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
107 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700108 fsBuilder->codeAppend("func = abs(func);");
109 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
110 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000111 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700112 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000113 break;
114 }
joshualittb0a8a372014-09-23 09:50:21 -0700115 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700116 SkAssertResult(fsBuilder->enableFeature(
117 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700118 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
119 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700120 fsBuilder->codeAppendf("float dfdx ="
121 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
joshualitt74077b92014-10-24 11:26:03 -0700122 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700123 fsBuilder->codeAppendf("float dfdy ="
124 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
joshualitt74077b92014-10-24 11:26:03 -0700125 v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700126 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
127 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
joshualitt74077b92014-10-24 11:26:03 -0700128 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
129 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700130 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
131 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000132 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700133 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000134 break;
135 }
joshualittb0a8a372014-09-23 09:50:21 -0700136 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700137 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
138 v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700139 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000140 break;
141 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000142 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000143 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000144 }
145
joshualitt9b989322014-12-15 14:16:27 -0800146 if (0xff != local.fCoverageScale) {
147 const char* coverageScale;
148 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
149 kFloat_GrSLType,
150 kDefault_GrSLPrecision,
151 "Coverage",
152 &coverageScale);
153 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
154 } else {
155 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
156 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000157}
158
joshualitt87f48d92014-12-04 10:41:40 -0800159void GrGLConicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800160 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800161 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700162 GrProcessorKeyBuilder* b) {
163 const GrConicEffect& ce = processor.cast<GrConicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800164 const ConicBatchTracker& local = bt.cast<ConicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700165 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800166 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
167 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700168 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000169}
170
171//////////////////////////////////////////////////////////////////////////////
172
173GrConicEffect::~GrConicEffect() {}
174
joshualitteb2a6762014-12-04 11:35:33 -0800175void GrConicEffect::getGLProcessorKey(const GrBatchTracker& bt,
176 const GrGLCaps& caps,
177 GrProcessorKeyBuilder* b) const {
178 GrGLConicEffect::GenKey(*this, bt, caps, b);
179}
180
181GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) const {
182 return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000183}
184
joshualitt2e3b3e32014-12-09 13:31:14 -0800185GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
joshualitt9b989322014-12-15 14:16:27 -0800186 : INHERITED(color, false), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800187 this->initClassID<GrConicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800188 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
189 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
190 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000191}
192
bsalomon0e08fc12014-10-15 08:19:04 -0700193bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700194 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000195 return (ce.fEdgeType == fEdgeType);
196}
197
joshualitt9b989322014-12-15 14:16:27 -0800198void GrConicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
199 ConicBatchTracker* local = bt->cast<ConicBatchTracker>();
200 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
201 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800202 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800203}
204
joshualitt290c09b2014-12-19 13:45:20 -0800205bool GrConicEffect::onCanMakeEqual(const GrBatchTracker& m,
206 const GrGeometryProcessor& that,
207 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800208 const ConicBatchTracker& mine = m.cast<ConicBatchTracker>();
209 const ConicBatchTracker& theirs = t.cast<ConicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800210 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
211 that, theirs.fUsesLocalCoords) &&
212 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800213 theirs.fInputColorType, theirs.fColor) &&
214 mine.fCoverageScale == theirs.fCoverageScale;
215}
216
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000217//////////////////////////////////////////////////////////////////////////////
218
joshualittb0a8a372014-09-23 09:50:21 -0700219GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000220
joshualittb0a8a372014-09-23 09:50:21 -0700221GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
222 GrContext*,
223 const GrDrawTargetCaps& caps,
224 GrTexture*[]) {
225 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000226 do {
joshualittb0a8a372014-09-23 09:50:21 -0700227 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
228 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800229 gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700230 } while (NULL == gp);
231 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000232}
233
234//////////////////////////////////////////////////////////////////////////////
235// Quad
236//////////////////////////////////////////////////////////////////////////////
237
joshualitt9b989322014-12-15 14:16:27 -0800238struct QuadBatchTracker {
239 GrGPInput fInputColorType;
240 GrColor fColor;
241 uint8_t fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800242 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800243};
244
joshualitt249af152014-09-15 11:41:13 -0700245class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000246public:
joshualitteb2a6762014-12-04 11:35:33 -0800247 GrGLQuadEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800248 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000249
joshualittc369e7c2014-10-22 10:56:26 -0700250 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000251
joshualitt87f48d92014-12-04 10:41:40 -0800252 static inline void GenKey(const GrGeometryProcessor&,
253 const GrBatchTracker&,
254 const GrGLCaps&,
255 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000256
joshualitt9b989322014-12-15 14:16:27 -0800257 virtual void setData(const GrGLProgramDataManager& pdman,
258 const GrPrimitiveProcessor&,
259 const GrBatchTracker& bt) SK_OVERRIDE {
260 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
261 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
262 GrGLfloat c[4];
263 GrColorToRGBAFloat(local.fColor, c);
264 pdman.set4fv(fColorUniform, 1, c);
265 fColor = local.fColor;
266 }
267 if (0xff != local.fCoverageScale && local.fCoverageScale != fCoverageScale) {
268 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
269 fCoverageScale = local.fCoverageScale;
270 }
271 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000272
273private:
joshualitt9b989322014-12-15 14:16:27 -0800274 GrColor fColor;
275 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -0700276 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800277 UniformHandle fColorUniform;
278 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000279
joshualitt249af152014-09-15 11:41:13 -0700280 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000281};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000282
joshualitteb2a6762014-12-04 11:35:33 -0800283GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800284 const GrBatchTracker& bt)
285 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -0800286 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000287 fEdgeType = ce.getEdgeType();
288}
289
joshualittc369e7c2014-10-22 10:56:26 -0700290void GrGLQuadEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -0800291 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -0800292 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
293 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800294 const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800295
joshualitt74077b92014-10-24 11:26:03 -0700296 GrGLVertToFrag v(kVec4f_GrSLType);
297 args.fPB->addVarying("HairQuadEdge", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -0800298 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000299
joshualitt9b989322014-12-15 14:16:27 -0800300 // Setup pass through color
301 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
302 &fColorUniform);
303
joshualitt2dd1ae02014-12-03 06:24:10 -0800304 // setup coord outputs
305 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
306 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700307
joshualitt4973d9d2014-11-08 09:24:25 -0800308 // setup position varying
309 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800310 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800311
joshualittc369e7c2014-10-22 10:56:26 -0700312 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700313 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700314
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000315 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700316 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700317 SkAssertResult(fsBuilder->enableFeature(
318 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700319 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
320 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700321 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
322 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700323 v.fsIn(), v.fsIn());
324 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700325 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
326 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000327 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700328 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000329 break;
330 }
joshualittb0a8a372014-09-23 09:50:21 -0700331 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700332 SkAssertResult(fsBuilder->enableFeature(
333 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700334 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
335 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700336 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
337 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700338 v.fsIn(), v.fsIn());
339 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700340 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
341 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000342 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700343 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000344 break;
345 }
joshualittb0a8a372014-09-23 09:50:21 -0700346 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700347 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700348 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000349 break;
350 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000351 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000352 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000353 }
354
joshualitt9b989322014-12-15 14:16:27 -0800355 if (0xff != local.fCoverageScale) {
356 const char* coverageScale;
357 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
358 kFloat_GrSLType,
359 kDefault_GrSLPrecision,
360 "Coverage",
361 &coverageScale);
362 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
363 } else {
364 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
365 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000366}
367
joshualitt87f48d92014-12-04 10:41:40 -0800368void GrGLQuadEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800369 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800370 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700371 GrProcessorKeyBuilder* b) {
372 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800373 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700374 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800375 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
376 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700377 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000378}
379
380//////////////////////////////////////////////////////////////////////////////
381
382GrQuadEffect::~GrQuadEffect() {}
383
joshualitteb2a6762014-12-04 11:35:33 -0800384void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt,
385 const GrGLCaps& caps,
386 GrProcessorKeyBuilder* b) const {
387 GrGLQuadEffect::GenKey(*this, bt, caps, b);
388}
389
390GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const {
391 return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000392}
393
joshualitt2e3b3e32014-12-09 13:31:14 -0800394GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
joshualitt9b989322014-12-15 14:16:27 -0800395 : INHERITED(color, false), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800396 this->initClassID<GrQuadEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800397 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
398 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
399 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000400}
401
bsalomon0e08fc12014-10-15 08:19:04 -0700402bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700403 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000404 return (ce.fEdgeType == fEdgeType);
405}
406
joshualitt9b989322014-12-15 14:16:27 -0800407void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
408 QuadBatchTracker* local = bt->cast<QuadBatchTracker>();
409 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
410 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800411 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800412}
413
joshualitt290c09b2014-12-19 13:45:20 -0800414bool GrQuadEffect::onCanMakeEqual(const GrBatchTracker& m,
415 const GrGeometryProcessor& that,
416 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800417 const QuadBatchTracker& mine = m.cast<QuadBatchTracker>();
418 const QuadBatchTracker& theirs = t.cast<QuadBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800419 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
420 that, theirs.fUsesLocalCoords) &&
421 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800422 theirs.fInputColorType, theirs.fColor) &&
423 mine.fCoverageScale == theirs.fCoverageScale;
424}
425
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000426//////////////////////////////////////////////////////////////////////////////
427
joshualittb0a8a372014-09-23 09:50:21 -0700428GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000429
joshualittb0a8a372014-09-23 09:50:21 -0700430GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
431 GrContext*,
432 const GrDrawTargetCaps& caps,
433 GrTexture*[]) {
434 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000435 do {
joshualittb0a8a372014-09-23 09:50:21 -0700436 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
437 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800438 gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700439 } while (NULL == gp);
440 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000441}
442
443//////////////////////////////////////////////////////////////////////////////
444// Cubic
445//////////////////////////////////////////////////////////////////////////////
446
joshualitt9b989322014-12-15 14:16:27 -0800447struct CubicBatchTracker {
448 GrGPInput fInputColorType;
449 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800450 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800451};
452
joshualitt249af152014-09-15 11:41:13 -0700453class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000454public:
joshualitteb2a6762014-12-04 11:35:33 -0800455 GrGLCubicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800456 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000457
joshualittc369e7c2014-10-22 10:56:26 -0700458 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000459
joshualitt87f48d92014-12-04 10:41:40 -0800460 static inline void GenKey(const GrGeometryProcessor&,
461 const GrBatchTracker&,
462 const GrGLCaps&,
463 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000464
joshualitt9b989322014-12-15 14:16:27 -0800465 virtual void setData(const GrGLProgramDataManager& pdman,
466 const GrPrimitiveProcessor&,
467 const GrBatchTracker& bt) SK_OVERRIDE {
468 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
469 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
470 GrGLfloat c[4];
471 GrColorToRGBAFloat(local.fColor, c);
472 pdman.set4fv(fColorUniform, 1, c);
473 fColor = local.fColor;
474 }
475 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000476
477private:
joshualitt9b989322014-12-15 14:16:27 -0800478 GrColor fColor;
joshualittb0a8a372014-09-23 09:50:21 -0700479 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800480 UniformHandle fColorUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000481
joshualitt249af152014-09-15 11:41:13 -0700482 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000483};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000484
joshualitteb2a6762014-12-04 11:35:33 -0800485GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800486 const GrBatchTracker&)
487 : fColor(GrColor_ILLEGAL) {
joshualittb0a8a372014-09-23 09:50:21 -0700488 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000489 fEdgeType = ce.getEdgeType();
490}
491
joshualittc369e7c2014-10-22 10:56:26 -0700492void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700493 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800494 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800495 const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800496
497 GrGLVertToFrag v(kVec4f_GrSLType);
bsalomonc0bd6482014-12-09 10:04:14 -0800498 args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800499 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
500
joshualitt9b989322014-12-15 14:16:27 -0800501 // Setup pass through color
502 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
503 &fColorUniform);
504
joshualitt2dd1ae02014-12-03 06:24:10 -0800505 // setup coord outputs
506 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
507 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700508
joshualitt4973d9d2014-11-08 09:24:25 -0800509 // setup position varying
510 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800511 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800512
joshualittc369e7c2014-10-22 10:56:26 -0700513 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700514
bsalomonc0bd6482014-12-09 10:04:14 -0800515 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
516 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
517 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
518 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
519 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
520 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
521 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
522 GrGLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
egdaniel9bd5bbf2014-08-29 11:12:30 -0700523
524 fsBuilder->declAppend(edgeAlpha);
525 fsBuilder->declAppend(dklmdx);
526 fsBuilder->declAppend(dklmdy);
527 fsBuilder->declAppend(dfdx);
528 fsBuilder->declAppend(dfdy);
529 fsBuilder->declAppend(gF);
530 fsBuilder->declAppend(gFM);
531 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000532
533 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700534 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700535 SkAssertResult(fsBuilder->enableFeature(
536 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700537 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
538 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700539 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 -0700540 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
541 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700542 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 -0700543 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
544 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700545 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
546 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
547 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700548 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700549 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
550 fsBuilder->codeAppendf("%s = %s / %s;",
551 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
552 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
553 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000554 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700555 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
556 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
557 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000558 break;
559 }
joshualittb0a8a372014-09-23 09:50:21 -0700560 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700561 SkAssertResult(fsBuilder->enableFeature(
562 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700563 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
564 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700565 fsBuilder->codeAppendf("%s ="
566 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700567 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
568 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700569 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 -0700570 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
571 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700572 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
573 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
574 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700575 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700576 fsBuilder->codeAppendf("%s = %s / %s;",
577 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
578 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
579 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000580 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700581 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
582 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
583 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000584 break;
585 }
joshualittb0a8a372014-09-23 09:50:21 -0700586 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700587 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700588 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700589 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000590 break;
591 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000592 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000593 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000594 }
595
joshualitt2dd1ae02014-12-03 06:24:10 -0800596
597 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000598}
599
joshualitt87f48d92014-12-04 10:41:40 -0800600void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800601 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800602 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700603 GrProcessorKeyBuilder* b) {
604 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800605 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700606 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800607 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x8;
bsalomon63e99f72014-07-21 08:03:14 -0700608 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000609}
610
611//////////////////////////////////////////////////////////////////////////////
612
613GrCubicEffect::~GrCubicEffect() {}
614
joshualitteb2a6762014-12-04 11:35:33 -0800615void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt,
616 const GrGLCaps& caps,
617 GrProcessorKeyBuilder* b) const {
618 GrGLCubicEffect::GenKey(*this, bt, caps, b);
619}
620
621GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const {
622 return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000623}
624
joshualitt2e3b3e32014-12-09 13:31:14 -0800625GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
626 : INHERITED(color), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800627 this->initClassID<GrCubicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800628 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
629 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
630 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000631}
632
bsalomon0e08fc12014-10-15 08:19:04 -0700633bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700634 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000635 return (ce.fEdgeType == fEdgeType);
636}
637
joshualitt9b989322014-12-15 14:16:27 -0800638void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
639 CubicBatchTracker* local = bt->cast<CubicBatchTracker>();
640 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800641 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800642}
643
joshualitt290c09b2014-12-19 13:45:20 -0800644bool GrCubicEffect::onCanMakeEqual(const GrBatchTracker& m,
645 const GrGeometryProcessor& that,
646 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800647 const CubicBatchTracker& mine = m.cast<CubicBatchTracker>();
648 const CubicBatchTracker& theirs = t.cast<CubicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800649 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
650 that, theirs.fUsesLocalCoords) &&
651 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800652 theirs.fInputColorType, theirs.fColor);
653}
654
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000655//////////////////////////////////////////////////////////////////////////////
656
joshualittb0a8a372014-09-23 09:50:21 -0700657GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000658
joshualittb0a8a372014-09-23 09:50:21 -0700659GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
660 GrContext*,
661 const GrDrawTargetCaps& caps,
662 GrTexture*[]) {
663 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000664 do {
joshualittb0a8a372014-09-23 09:50:21 -0700665 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
666 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800667 gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700668 } while (NULL == gp);
669 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000670}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700671