blob: c90067d4a4142a82701dd75d86f53d4076c8743b [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
joshualittd27f73e2014-12-29 07:43:36 -0800186GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType,
187 const SkMatrix& localMatrix)
188 : INHERITED(color, false, localMatrix), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800189 this->initClassID<GrConicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800190 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
191 fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs",
192 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000193}
194
bsalomon0e08fc12014-10-15 08:19:04 -0700195bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700196 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000197 return (ce.fEdgeType == fEdgeType);
198}
199
joshualitt9b989322014-12-15 14:16:27 -0800200void GrConicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
201 ConicBatchTracker* local = bt->cast<ConicBatchTracker>();
202 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
203 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800204 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800205}
206
joshualitt290c09b2014-12-19 13:45:20 -0800207bool GrConicEffect::onCanMakeEqual(const GrBatchTracker& m,
208 const GrGeometryProcessor& that,
209 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800210 const ConicBatchTracker& mine = m.cast<ConicBatchTracker>();
211 const ConicBatchTracker& theirs = t.cast<ConicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800212 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
213 that, theirs.fUsesLocalCoords) &&
214 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800215 theirs.fInputColorType, theirs.fColor) &&
216 mine.fCoverageScale == theirs.fCoverageScale;
217}
218
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000219//////////////////////////////////////////////////////////////////////////////
220
joshualittb0a8a372014-09-23 09:50:21 -0700221GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000222
joshualittb0a8a372014-09-23 09:50:21 -0700223GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
224 GrContext*,
225 const GrDrawTargetCaps& caps,
226 GrTexture*[]) {
227 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000228 do {
joshualittb0a8a372014-09-23 09:50:21 -0700229 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
230 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualittd27f73e2014-12-29 07:43:36 -0800231 gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps,
232 GrProcessorUnitTest::TestMatrix(random));
joshualittb0a8a372014-09-23 09:50:21 -0700233 } while (NULL == gp);
234 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000235}
236
237//////////////////////////////////////////////////////////////////////////////
238// Quad
239//////////////////////////////////////////////////////////////////////////////
240
joshualitt9b989322014-12-15 14:16:27 -0800241struct QuadBatchTracker {
242 GrGPInput fInputColorType;
243 GrColor fColor;
244 uint8_t fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800245 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800246};
247
joshualitt249af152014-09-15 11:41:13 -0700248class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000249public:
joshualitteb2a6762014-12-04 11:35:33 -0800250 GrGLQuadEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800251 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000252
joshualittc369e7c2014-10-22 10:56:26 -0700253 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000254
joshualitt87f48d92014-12-04 10:41:40 -0800255 static inline void GenKey(const GrGeometryProcessor&,
256 const GrBatchTracker&,
257 const GrGLCaps&,
258 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000259
joshualitt9b989322014-12-15 14:16:27 -0800260 virtual void setData(const GrGLProgramDataManager& pdman,
261 const GrPrimitiveProcessor&,
262 const GrBatchTracker& bt) SK_OVERRIDE {
263 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
264 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
265 GrGLfloat c[4];
266 GrColorToRGBAFloat(local.fColor, c);
267 pdman.set4fv(fColorUniform, 1, c);
268 fColor = local.fColor;
269 }
270 if (0xff != local.fCoverageScale && local.fCoverageScale != fCoverageScale) {
271 pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(local.fCoverageScale));
272 fCoverageScale = local.fCoverageScale;
273 }
274 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000275
276private:
joshualitt9b989322014-12-15 14:16:27 -0800277 GrColor fColor;
278 uint8_t fCoverageScale;
joshualittb0a8a372014-09-23 09:50:21 -0700279 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800280 UniformHandle fColorUniform;
281 UniformHandle fCoverageScaleUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000282
joshualitt249af152014-09-15 11:41:13 -0700283 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000284};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000285
joshualitteb2a6762014-12-04 11:35:33 -0800286GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800287 const GrBatchTracker& bt)
288 : fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
joshualitt87f48d92014-12-04 10:41:40 -0800289 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000290 fEdgeType = ce.getEdgeType();
291}
292
joshualittc369e7c2014-10-22 10:56:26 -0700293void GrGLQuadEffect::emitCode(const EmitArgs& args) {
joshualitt9b989322014-12-15 14:16:27 -0800294 GrGLGPBuilder* pb = args.fPB;
joshualitt2dd1ae02014-12-03 06:24:10 -0800295 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
296 const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800297 const QuadBatchTracker& local = args.fBT.cast<QuadBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800298
joshualitt74077b92014-10-24 11:26:03 -0700299 GrGLVertToFrag v(kVec4f_GrSLType);
300 args.fPB->addVarying("HairQuadEdge", &v);
joshualitt2dd1ae02014-12-03 06:24:10 -0800301 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000302
joshualitt9b989322014-12-15 14:16:27 -0800303 // Setup pass through color
304 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
305 &fColorUniform);
306
joshualitt2dd1ae02014-12-03 06:24:10 -0800307 // setup coord outputs
308 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
309 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700310
joshualitt4973d9d2014-11-08 09:24:25 -0800311 // setup position varying
312 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800313 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800314
joshualittc369e7c2014-10-22 10:56:26 -0700315 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700316 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700317
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000318 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700319 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700320 SkAssertResult(fsBuilder->enableFeature(
321 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700322 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
323 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700324 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
325 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700326 v.fsIn(), v.fsIn());
327 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700328 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
329 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000330 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700331 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000332 break;
333 }
joshualittb0a8a372014-09-23 09:50:21 -0700334 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700335 SkAssertResult(fsBuilder->enableFeature(
336 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700337 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
338 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700339 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
340 " 2.0 * %s.x * duvdy.x - duvdy.y);",
joshualitt74077b92014-10-24 11:26:03 -0700341 v.fsIn(), v.fsIn());
342 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700343 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
344 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000345 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700346 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000347 break;
348 }
joshualittb0a8a372014-09-23 09:50:21 -0700349 case kFillBW_GrProcessorEdgeType: {
joshualitt74077b92014-10-24 11:26:03 -0700350 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
egdanielb2f94d12014-08-29 10:08:36 -0700351 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000352 break;
353 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000354 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000355 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000356 }
357
joshualitt9b989322014-12-15 14:16:27 -0800358 if (0xff != local.fCoverageScale) {
359 const char* coverageScale;
360 fCoverageScaleUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
361 kFloat_GrSLType,
362 kDefault_GrSLPrecision,
363 "Coverage",
364 &coverageScale);
365 fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
366 } else {
367 fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
368 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000369}
370
joshualitt87f48d92014-12-04 10:41:40 -0800371void GrGLQuadEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800372 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800373 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700374 GrProcessorKeyBuilder* b) {
375 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800376 const QuadBatchTracker& local = bt.cast<QuadBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700377 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800378 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x0;
379 key |= 0xff != local.fCoverageScale ? 0x8 : 0x0;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800380 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700381 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000382}
383
384//////////////////////////////////////////////////////////////////////////////
385
386GrQuadEffect::~GrQuadEffect() {}
387
joshualitteb2a6762014-12-04 11:35:33 -0800388void GrQuadEffect::getGLProcessorKey(const GrBatchTracker& bt,
389 const GrGLCaps& caps,
390 GrProcessorKeyBuilder* b) const {
391 GrGLQuadEffect::GenKey(*this, bt, caps, b);
392}
393
394GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) const {
395 return SkNEW_ARGS(GrGLQuadEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000396}
397
joshualittd27f73e2014-12-29 07:43:36 -0800398GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType,
399 const SkMatrix& localMatrix)
400 : INHERITED(color, false, localMatrix), fCoverageScale(coverage), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800401 this->initClassID<GrQuadEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800402 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
403 fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge",
404 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000405}
406
bsalomon0e08fc12014-10-15 08:19:04 -0700407bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700408 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000409 return (ce.fEdgeType == fEdgeType);
410}
411
joshualitt9b989322014-12-15 14:16:27 -0800412void GrQuadEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
413 QuadBatchTracker* local = bt->cast<QuadBatchTracker>();
414 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
415 local->fCoverageScale = fCoverageScale;
joshualitt290c09b2014-12-19 13:45:20 -0800416 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800417}
418
joshualitt290c09b2014-12-19 13:45:20 -0800419bool GrQuadEffect::onCanMakeEqual(const GrBatchTracker& m,
420 const GrGeometryProcessor& that,
421 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800422 const QuadBatchTracker& mine = m.cast<QuadBatchTracker>();
423 const QuadBatchTracker& theirs = t.cast<QuadBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800424 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
425 that, theirs.fUsesLocalCoords) &&
426 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800427 theirs.fInputColorType, theirs.fColor) &&
428 mine.fCoverageScale == theirs.fCoverageScale;
429}
430
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000431//////////////////////////////////////////////////////////////////////////////
432
joshualittb0a8a372014-09-23 09:50:21 -0700433GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000434
joshualittb0a8a372014-09-23 09:50:21 -0700435GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
436 GrContext*,
437 const GrDrawTargetCaps& caps,
438 GrTexture*[]) {
439 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000440 do {
joshualittb0a8a372014-09-23 09:50:21 -0700441 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
442 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualittd27f73e2014-12-29 07:43:36 -0800443 gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps,
444 GrProcessorUnitTest::TestMatrix(random));
joshualittb0a8a372014-09-23 09:50:21 -0700445 } while (NULL == gp);
446 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000447}
448
449//////////////////////////////////////////////////////////////////////////////
450// Cubic
451//////////////////////////////////////////////////////////////////////////////
452
joshualitt9b989322014-12-15 14:16:27 -0800453struct CubicBatchTracker {
454 GrGPInput fInputColorType;
455 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800456 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800457};
458
joshualitt249af152014-09-15 11:41:13 -0700459class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000460public:
joshualitteb2a6762014-12-04 11:35:33 -0800461 GrGLCubicEffect(const GrGeometryProcessor&,
joshualitt87f48d92014-12-04 10:41:40 -0800462 const GrBatchTracker&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000463
joshualittc369e7c2014-10-22 10:56:26 -0700464 virtual void emitCode(const EmitArgs&) SK_OVERRIDE;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000465
joshualitt87f48d92014-12-04 10:41:40 -0800466 static inline void GenKey(const GrGeometryProcessor&,
467 const GrBatchTracker&,
468 const GrGLCaps&,
469 GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000470
joshualitt9b989322014-12-15 14:16:27 -0800471 virtual void setData(const GrGLProgramDataManager& pdman,
472 const GrPrimitiveProcessor&,
473 const GrBatchTracker& bt) SK_OVERRIDE {
474 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
475 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
476 GrGLfloat c[4];
477 GrColorToRGBAFloat(local.fColor, c);
478 pdman.set4fv(fColorUniform, 1, c);
479 fColor = local.fColor;
480 }
481 }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000482
483private:
joshualitt9b989322014-12-15 14:16:27 -0800484 GrColor fColor;
joshualittb0a8a372014-09-23 09:50:21 -0700485 GrPrimitiveEdgeType fEdgeType;
joshualitt9b989322014-12-15 14:16:27 -0800486 UniformHandle fColorUniform;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000487
joshualitt249af152014-09-15 11:41:13 -0700488 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000489};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000490
joshualitteb2a6762014-12-04 11:35:33 -0800491GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800492 const GrBatchTracker&)
493 : fColor(GrColor_ILLEGAL) {
joshualittb0a8a372014-09-23 09:50:21 -0700494 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000495 fEdgeType = ce.getEdgeType();
496}
497
joshualittc369e7c2014-10-22 10:56:26 -0700498void GrGLCubicEffect::emitCode(const EmitArgs& args) {
joshualittc369e7c2014-10-22 10:56:26 -0700499 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
joshualitt2dd1ae02014-12-03 06:24:10 -0800500 const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800501 const CubicBatchTracker& local = args.fBT.cast<CubicBatchTracker>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800502
503 GrGLVertToFrag v(kVec4f_GrSLType);
bsalomonc0bd6482014-12-09 10:04:14 -0800504 args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
joshualitt2dd1ae02014-12-03 06:24:10 -0800505 vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
506
joshualitt9b989322014-12-15 14:16:27 -0800507 // Setup pass through color
508 this->setupColorPassThrough(args.fPB, local.fInputColorType, args.fOutputColor, NULL,
509 &fColorUniform);
510
joshualitt2dd1ae02014-12-03 06:24:10 -0800511 // setup coord outputs
512 vsBuilder->codeAppendf("%s = %s;", vsBuilder->positionCoords(), gp.inPosition()->fName);
513 vsBuilder->codeAppendf("%s = %s;", vsBuilder->localCoords(), gp.inPosition()->fName);
joshualitt30ba4362014-08-21 20:18:45 -0700514
joshualitt4973d9d2014-11-08 09:24:25 -0800515 // setup position varying
516 vsBuilder->codeAppendf("%s = %s * vec3(%s, 1);", vsBuilder->glPosition(), vsBuilder->uViewM(),
joshualitt2dd1ae02014-12-03 06:24:10 -0800517 gp.inPosition()->fName);
joshualitt4973d9d2014-11-08 09:24:25 -0800518
joshualittc369e7c2014-10-22 10:56:26 -0700519 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700520
bsalomonc0bd6482014-12-09 10:04:14 -0800521 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
522 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
523 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
524 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
525 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
526 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
527 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
528 GrGLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
egdaniel9bd5bbf2014-08-29 11:12:30 -0700529
530 fsBuilder->declAppend(edgeAlpha);
531 fsBuilder->declAppend(dklmdx);
532 fsBuilder->declAppend(dklmdy);
533 fsBuilder->declAppend(dfdx);
534 fsBuilder->declAppend(dfdy);
535 fsBuilder->declAppend(gF);
536 fsBuilder->declAppend(gFM);
537 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000538
539 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700540 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700541 SkAssertResult(fsBuilder->enableFeature(
542 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700543 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
544 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700545 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 -0700546 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
547 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700548 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 -0700549 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
550 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700551 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
552 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
553 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700554 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700555 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
556 fsBuilder->codeAppendf("%s = %s / %s;",
557 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
558 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
559 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000560 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700561 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
562 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
563 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000564 break;
565 }
joshualittb0a8a372014-09-23 09:50:21 -0700566 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700567 SkAssertResult(fsBuilder->enableFeature(
568 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
joshualitt74077b92014-10-24 11:26:03 -0700569 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
570 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700571 fsBuilder->codeAppendf("%s ="
572 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
joshualitt74077b92014-10-24 11:26:03 -0700573 dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
574 dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700575 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 -0700576 dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
577 dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700578 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
579 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
580 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700581 func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700582 fsBuilder->codeAppendf("%s = %s / %s;",
583 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
584 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
585 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000586 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700587 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
588 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
589 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000590 break;
591 }
joshualittb0a8a372014-09-23 09:50:21 -0700592 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700593 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
joshualitt74077b92014-10-24 11:26:03 -0700594 edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
egdaniel9bd5bbf2014-08-29 11:12:30 -0700595 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000596 break;
597 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000598 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000599 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000600 }
601
joshualitt2dd1ae02014-12-03 06:24:10 -0800602
603 fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000604}
605
joshualitt87f48d92014-12-04 10:41:40 -0800606void GrGLCubicEffect::GenKey(const GrGeometryProcessor& processor,
joshualitt9b989322014-12-15 14:16:27 -0800607 const GrBatchTracker& bt,
joshualitt87f48d92014-12-04 10:41:40 -0800608 const GrGLCaps&,
joshualittb0a8a372014-09-23 09:50:21 -0700609 GrProcessorKeyBuilder* b) {
610 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
joshualitt9b989322014-12-15 14:16:27 -0800611 const CubicBatchTracker& local = bt.cast<CubicBatchTracker>();
bsalomon63e99f72014-07-21 08:03:14 -0700612 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
joshualitt9b989322014-12-15 14:16:27 -0800613 key |= kUniform_GrGPInput == local.fInputColorType ? 0x4 : 0x8;
joshualitt8fc6c2d2014-12-22 15:27:05 -0800614 key |= local.fUsesLocalCoords && processor.localMatrix().hasPerspective() ? 0x10 : 0x0;
bsalomon63e99f72014-07-21 08:03:14 -0700615 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000616}
617
618//////////////////////////////////////////////////////////////////////////////
619
620GrCubicEffect::~GrCubicEffect() {}
621
joshualitteb2a6762014-12-04 11:35:33 -0800622void GrCubicEffect::getGLProcessorKey(const GrBatchTracker& bt,
623 const GrGLCaps& caps,
624 GrProcessorKeyBuilder* b) const {
625 GrGLCubicEffect::GenKey(*this, bt, caps, b);
626}
627
628GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) const {
629 return SkNEW_ARGS(GrGLCubicEffect, (*this, bt));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000630}
631
joshualitt2e3b3e32014-12-09 13:31:14 -0800632GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType)
633 : INHERITED(color), fEdgeType(edgeType) {
joshualitteb2a6762014-12-04 11:35:33 -0800634 this->initClassID<GrCubicEffect>();
joshualitt2dd1ae02014-12-03 06:24:10 -0800635 fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType));
636 fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs",
637 kVec4f_GrVertexAttribType));
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000638}
639
bsalomon0e08fc12014-10-15 08:19:04 -0700640bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700641 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000642 return (ce.fEdgeType == fEdgeType);
643}
644
joshualitt9b989322014-12-15 14:16:27 -0800645void GrCubicEffect::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
646 CubicBatchTracker* local = bt->cast<CubicBatchTracker>();
647 local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false);
joshualitt290c09b2014-12-19 13:45:20 -0800648 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800649}
650
joshualitt290c09b2014-12-19 13:45:20 -0800651bool GrCubicEffect::onCanMakeEqual(const GrBatchTracker& m,
652 const GrGeometryProcessor& that,
653 const GrBatchTracker& t) const {
joshualitt9b989322014-12-15 14:16:27 -0800654 const CubicBatchTracker& mine = m.cast<CubicBatchTracker>();
655 const CubicBatchTracker& theirs = t.cast<CubicBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800656 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
657 that, theirs.fUsesLocalCoords) &&
658 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800659 theirs.fInputColorType, theirs.fColor);
660}
661
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000662//////////////////////////////////////////////////////////////////////////////
663
joshualittb0a8a372014-09-23 09:50:21 -0700664GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000665
joshualittb0a8a372014-09-23 09:50:21 -0700666GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
667 GrContext*,
668 const GrDrawTargetCaps& caps,
669 GrTexture*[]) {
670 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000671 do {
joshualittb0a8a372014-09-23 09:50:21 -0700672 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
673 random->nextULessThan(kGrProcessorEdgeTypeCnt));
joshualitt2e3b3e32014-12-09 13:31:14 -0800674 gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps);
joshualittb0a8a372014-09-23 09:50:21 -0700675 } while (NULL == gp);
676 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000677}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700678