blob: 0ba7beeb88491e2a07ff7c7f66bc579544f7d1e3 [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;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800168 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700169 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000170}
171
172//////////////////////////////////////////////////////////////////////////////
173
174GrConicEffect::~GrConicEffect() {}
175
joshualitteb2a6762014-12-04 11:35:33 -0800176void GrConicEffect::getGLProcessorKey(const GrBatchTracker& bt,
177 const GrGLCaps& caps,
178 GrProcessorKeyBuilder* b) const {
179 GrGLConicEffect::GenKey(*this, bt, caps, b);
180}
181
182GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) const {
183 return SkNEW_ARGS(GrGLConicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000184}
185
joshualitt2e3b3e32014-12-09 13:31:14 -0800186GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
joshualitt9b989322014-12-15 14:16:27 -0800187 : INHERITED(color, false), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800188 this->initClassID<GrConicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800189 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
190 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
191 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000192}
193
bsalomon0e08fc12014-10-15 08:19:04 -0700194bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700195 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000196 return (ce.fEdgeType == fEdgeType);
197}
198
joshualitt9b989322014-12-15 14:16:27 -0800199void GrConicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
200 ConicBatchTracker* local = bt->cast<ConicBatchTracker>();
201 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
202 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800203 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800204}
205
joshualitt290c09b2014-12-19 13:45:20 -0800206bool GrConicEffect::onCanMakeEqual(const GrBatchTracker& m,
207 const GrGeometryProcessor& that,
208 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800209 const ConicBatchTracker& mine = m.cast<ConicBatchTracker>();
210 const ConicBatchTracker& theirs = t.cast<ConicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800211 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
212 that, theirs.fUsesLocalCoords) &&
213 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800214 theirs.fInputColorType, theirs.fColor) &&
215 mine.fCoverageScale == theirs.fCoverageScale;
216}
217
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000218//////////////////////////////////////////////////////////////////////////////
219
joshualittb0a8a372014-09-23 09:50:21 -0700220GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000221
joshualittb0a8a372014-09-23 09:50:21 -0700222GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
223 GrContext*,
224 const GrDrawTargetCaps& caps,
225 GrTexture*[]) {
226 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000227 do {
joshualittb0a8a372014-09-23 09:50:21 -0700228 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
229 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800230 gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700231 } while (NULL == gp);
232 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000233}
234
235//////////////////////////////////////////////////////////////////////////////
236// Quad
237//////////////////////////////////////////////////////////////////////////////
238
joshualitt9b989322014-12-15 14:16:27 -0800239struct QuadBatchTracker {
240 GrGPInput fInputColorType;
241 GrColor fColor;
242 uint8_t fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800243 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800244};
245
joshualitt249af152014-09-15 11:41:13 -0700246class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000247public:
joshualitteb2a6762014-12-04 11:35:33 -0800248 GrGLQuadEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800249 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000250
joshualittc369e7c2014-10-22 10:56:26 -0700251 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000252
joshualitt87f48d92014-12-04 10:41:40 -0800253 static inline void GenKey(const GrGeometryProcessor&,
254 const GrBatchTracker&,
255 const GrGLCaps&,
256 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000257
joshualitt9b989322014-12-15 14:16:27 -0800258 virtual void setData(const GrGLProgramDataManager& pdman,
259 const GrPrimitiveProcessor&,
260 const GrBatchTracker& bt) SK_OVERRIDE {
261 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
262 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
263 GrGLfloat c[4];
264 GrColorToRGBAFloat(local.fColor, c);
265 pdman.set4fv(fColorUniform, 1, c);
266 fColor = local.fColor;
267 }
268 if (0xff != local.fCoverageScale && local.fCoverageScale != fCoverageScale) {
269 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
270 fCoverageScale = local.fCoverageScale;
271 }
272 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000273
274private:
joshualitt9b989322014-12-15 14:16:27 -0800275 GrColor fColor;
276 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -0700277 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800278 UniformHandle fColorUniform;
279 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000280
joshualitt249af152014-09-15 11:41:13 -0700281 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000282};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000283
joshualitteb2a6762014-12-04 11:35:33 -0800284GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800285 const GrBatchTracker& bt)
286 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -0800287 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000288 fEdgeType = ce.getEdgeType();
289}
290
joshualittc369e7c2014-10-22 10:56:26 -0700291void GrGLQuadEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -0800292 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -0800293 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
294 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800295 const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800296
joshualitt74077b92014-10-24 11:26:03 -0700297 GrGLVertToFrag v(kVec4f_GrSLType);
298 args.fPB->addVarying("HairQuadEdge", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -0800299 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000300
joshualitt9b989322014-12-15 14:16:27 -0800301 // Setup pass through color
302 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
303 &fColorUniform);
304
joshualitt2dd1ae02014-12-03 06:24:10 -0800305 // setup coord outputs
306 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
307 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700308
joshualitt4973d9d2014-11-08 09:24:25 -0800309 // setup position varying
310 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800311 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800312
joshualittc369e7c2014-10-22 10:56:26 -0700313 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700314 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700315
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000316 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700317 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700318 SkAssertResult(fsBuilder->enableFeature(
319 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700320 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
321 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700322 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
323 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700324 v.fsIn(), v.fsIn());
325 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700326 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
327 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000328 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700329 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000330 break;
331 }
joshualittb0a8a372014-09-23 09:50:21 -0700332 case kFillAA_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 = edgeAlpha / sqrt(dot(gF, gF));");
342 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.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 kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700348 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700349 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000350 break;
351 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000352 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000353 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000354 }
355
joshualitt9b989322014-12-15 14:16:27 -0800356 if (0xff != local.fCoverageScale) {
357 const char* coverageScale;
358 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
359 kFloat_GrSLType,
360 kDefault_GrSLPrecision,
361 "Coverage",
362 &coverageScale);
363 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
364 } else {
365 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
366 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000367}
368
joshualitt87f48d92014-12-04 10:41:40 -0800369void GrGLQuadEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800370 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800371 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700372 GrProcessorKeyBuilder* b) {
373 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800374 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700375 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800376 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
377 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800378 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700379 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000380}
381
382//////////////////////////////////////////////////////////////////////////////
383
384GrQuadEffect::~GrQuadEffect() {}
385
joshualitteb2a6762014-12-04 11:35:33 -0800386void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt,
387 const GrGLCaps& caps,
388 GrProcessorKeyBuilder* b) const {
389 GrGLQuadEffect::GenKey(*this, bt, caps, b);
390}
391
392GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const {
393 return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000394}
395
joshualitt2e3b3e32014-12-09 13:31:14 -0800396GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType)
joshualitt9b989322014-12-15 14:16:27 -0800397 : INHERITED(color, false), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800398 this->initClassID<GrQuadEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800399 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
400 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
401 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000402}
403
bsalomon0e08fc12014-10-15 08:19:04 -0700404bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700405 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000406 return (ce.fEdgeType == fEdgeType);
407}
408
joshualitt9b989322014-12-15 14:16:27 -0800409void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
410 QuadBatchTracker* local = bt->cast<QuadBatchTracker>();
411 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
412 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800413 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800414}
415
joshualitt290c09b2014-12-19 13:45:20 -0800416bool GrQuadEffect::onCanMakeEqual(const GrBatchTracker& m,
417 const GrGeometryProcessor& that,
418 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800419 const QuadBatchTracker& mine = m.cast<QuadBatchTracker>();
420 const QuadBatchTracker& theirs = t.cast<QuadBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800421 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
422 that, theirs.fUsesLocalCoords) &&
423 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800424 theirs.fInputColorType, theirs.fColor) &&
425 mine.fCoverageScale == theirs.fCoverageScale;
426}
427
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000428//////////////////////////////////////////////////////////////////////////////
429
joshualittb0a8a372014-09-23 09:50:21 -0700430GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000431
joshualittb0a8a372014-09-23 09:50:21 -0700432GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
433 GrContext*,
434 const GrDrawTargetCaps& caps,
435 GrTexture*[]) {
436 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000437 do {
joshualittb0a8a372014-09-23 09:50:21 -0700438 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
439 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800440 gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700441 } while (NULL == gp);
442 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000443}
444
445//////////////////////////////////////////////////////////////////////////////
446// Cubic
447//////////////////////////////////////////////////////////////////////////////
448
joshualitt9b989322014-12-15 14:16:27 -0800449struct CubicBatchTracker {
450 GrGPInput fInputColorType;
451 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800452 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800453};
454
joshualitt249af152014-09-15 11:41:13 -0700455class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000456public:
joshualitteb2a6762014-12-04 11:35:33 -0800457 GrGLCubicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800458 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000459
joshualittc369e7c2014-10-22 10:56:26 -0700460 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000461
joshualitt87f48d92014-12-04 10:41:40 -0800462 static inline void GenKey(const GrGeometryProcessor&,
463 const GrBatchTracker&,
464 const GrGLCaps&,
465 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000466
joshualitt9b989322014-12-15 14:16:27 -0800467 virtual void setData(const GrGLProgramDataManager& pdman,
468 const GrPrimitiveProcessor&,
469 const GrBatchTracker& bt) SK_OVERRIDE {
470 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
471 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
472 GrGLfloat c[4];
473 GrColorToRGBAFloat(local.fColor, c);
474 pdman.set4fv(fColorUniform, 1, c);
475 fColor = local.fColor;
476 }
477 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000478
479private:
joshualitt9b989322014-12-15 14:16:27 -0800480 GrColor fColor;
joshualittb0a8a372014-09-23 09:50:21 -0700481 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800482 UniformHandle fColorUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000483
joshualitt249af152014-09-15 11:41:13 -0700484 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000485};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000486
joshualitteb2a6762014-12-04 11:35:33 -0800487GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800488 const GrBatchTracker&)
489 : fColor(GrColor_ILLEGAL) {
joshualittb0a8a372014-09-23 09:50:21 -0700490 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000491 fEdgeType = ce.getEdgeType();
492}
493
joshualittc369e7c2014-10-22 10:56:26 -0700494void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700495 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800496 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800497 const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800498
499 GrGLVertToFrag v(kVec4f_GrSLType);
bsalomonc0bd6482014-12-09 10:04:14 -0800500 args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800501 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
502
joshualitt9b989322014-12-15 14:16:27 -0800503 // Setup pass through color
504 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
505 &fColorUniform);
506
joshualitt2dd1ae02014-12-03 06:24:10 -0800507 // setup coord outputs
508 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
509 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700510
joshualitt4973d9d2014-11-08 09:24:25 -0800511 // setup position varying
512 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800513 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800514
joshualittc369e7c2014-10-22 10:56:26 -0700515 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700516
bsalomonc0bd6482014-12-09 10:04:14 -0800517 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
518 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
519 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
520 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
521 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
522 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
523 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
524 GrGLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
egdaniel9bd5bbf2014-08-29 11:12:30 -0700525
526 fsBuilder->declAppend(edgeAlpha);
527 fsBuilder->declAppend(dklmdx);
528 fsBuilder->declAppend(dklmdy);
529 fsBuilder->declAppend(dfdx);
530 fsBuilder->declAppend(dfdy);
531 fsBuilder->declAppend(gF);
532 fsBuilder->declAppend(gFM);
533 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000534
535 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700536 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700537 SkAssertResult(fsBuilder->enableFeature(
538 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700539 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
540 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700541 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 -0700542 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
543 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700544 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 -0700545 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
546 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700547 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
548 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
549 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700550 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700551 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
552 fsBuilder->codeAppendf("%s = %s / %s;",
553 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
554 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
555 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000556 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700557 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
558 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
559 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000560 break;
561 }
joshualittb0a8a372014-09-23 09:50:21 -0700562 case kFillAA_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 ="
568 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700569 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
570 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700571 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 -0700572 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
573 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700574 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
575 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
576 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700577 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700578 fsBuilder->codeAppendf("%s = %s / %s;",
579 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
580 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.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 kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700589 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700590 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700591 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000592 break;
593 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000594 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000595 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000596 }
597
joshualitt2dd1ae02014-12-03 06:24:10 -0800598
599 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000600}
601
joshualitt87f48d92014-12-04 10:41:40 -0800602void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800603 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800604 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700605 GrProcessorKeyBuilder* b) {
606 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800607 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700608 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800609 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x8;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800610 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700611 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000612}
613
614//////////////////////////////////////////////////////////////////////////////
615
616GrCubicEffect::~GrCubicEffect() {}
617
joshualitteb2a6762014-12-04 11:35:33 -0800618void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt,
619 const GrGLCaps& caps,
620 GrProcessorKeyBuilder* b) const {
621 GrGLCubicEffect::GenKey(*this, bt, caps, b);
622}
623
624GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const {
625 return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000626}
627
joshualitt2e3b3e32014-12-09 13:31:14 -0800628GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
629 : INHERITED(color), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800630 this->initClassID<GrCubicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800631 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
632 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
633 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000634}
635
bsalomon0e08fc12014-10-15 08:19:04 -0700636bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700637 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000638 return (ce.fEdgeType == fEdgeType);
639}
640
joshualitt9b989322014-12-15 14:16:27 -0800641void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
642 CubicBatchTracker* local = bt->cast<CubicBatchTracker>();
643 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800644 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800645}
646
joshualitt290c09b2014-12-19 13:45:20 -0800647bool GrCubicEffect::onCanMakeEqual(const GrBatchTracker& m,
648 const GrGeometryProcessor& that,
649 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800650 const CubicBatchTracker& mine = m.cast<CubicBatchTracker>();
651 const CubicBatchTracker& theirs = t.cast<CubicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800652 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
653 that, theirs.fUsesLocalCoords) &&
654 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800655 theirs.fInputColorType, theirs.fColor);
656}
657
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000658//////////////////////////////////////////////////////////////////////////////
659
joshualittb0a8a372014-09-23 09:50:21 -0700660GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000661
joshualittb0a8a372014-09-23 09:50:21 -0700662GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
663 GrContext*,
664 const GrDrawTargetCaps& caps,
665 GrTexture*[]) {
666 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000667 do {
joshualittb0a8a372014-09-23 09:50:21 -0700668 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
669 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800670 gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700671 } while (NULL == gp);
672 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000673}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700674