blob: 9a60b2f1dbc9f29758b74b586f767802abdf2867 [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
joshualitt47bb3822014-10-07 16:43:25 -070010#include "gl/builders/GrGLProgramBuilder.h"
joshualittb0a8a372014-09-23 09:50:21 -070011#include "gl/GrGLProcessor.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000012#include "gl/GrGLSL.h"
joshualitt249af152014-09-15 11:41:13 -070013#include "gl/GrGLGeometryProcessor.h"
joshualittb0a8a372014-09-23 09:50:21 -070014#include "GrTBackendProcessorFactory.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000015
joshualitt249af152014-09-15 11:41:13 -070016class GrGLConicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000017public:
joshualittb0a8a372014-09-23 09:50:21 -070018 GrGLConicEffect(const GrBackendProcessorFactory&, const GrProcessor&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000019
joshualitt47bb3822014-10-07 16:43:25 -070020 virtual void emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -070021 const GrGeometryProcessor& geometryProcessor,
22 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000023 const char* outputColor,
24 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +000025 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000026 const TextureSamplerArray&) SK_OVERRIDE;
27
joshualittb0a8a372014-09-23 09:50:21 -070028 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000029
joshualittb0a8a372014-09-23 09:50:21 -070030 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000031
32private:
joshualittb0a8a372014-09-23 09:50:21 -070033 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000034
joshualitt249af152014-09-15 11:41:13 -070035 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000036};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000037
joshualittb0a8a372014-09-23 09:50:21 -070038GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
39 const GrProcessor& effect)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000040 : INHERITED (factory) {
joshualitt49586be2014-09-16 08:21:41 -070041 const GrConicEffect& ce = effect.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000042 fEdgeType = ce.getEdgeType();
43}
44
joshualitt47bb3822014-10-07 16:43:25 -070045void GrGLConicEffect::emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -070046 const GrGeometryProcessor& geometryProcessor,
47 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000048 const char* outputColor,
49 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +000050 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000051 const TextureSamplerArray& samplers) {
52 const char *vsName, *fsName;
53
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000054 builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000055 &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000056
joshualittb0a8a372014-09-23 09:50:21 -070057 const GrShaderVar& inConicCoeffs = geometryProcessor.cast<GrConicEffect>().inConicCoeffs();
joshualitt47bb3822014-10-07 16:43:25 -070058 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder();
joshualitt249af152014-09-15 11:41:13 -070059 vsBuilder->codeAppendf("%s = %s;", vsName, inConicCoeffs.c_str());
joshualitt30ba4362014-08-21 20:18:45 -070060
joshualitt47bb3822014-10-07 16:43:25 -070061 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -070062 fsBuilder->codeAppend("float edgeAlpha;");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000063
64 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -070065 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070066 SkAssertResult(fsBuilder->enableFeature(
67 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -070068 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
69 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
70 fsBuilder->codeAppendf("float dfdx ="
71 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
72 fsName, fsName, fsName);
73 fsBuilder->codeAppendf("float dfdy ="
74 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
75 fsName, fsName, fsName);
76 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
77 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
78 fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName,
79 fsName, fsName);
80 fsBuilder->codeAppend("func = abs(func);");
81 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
82 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000083 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -070084 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000085 break;
86 }
joshualittb0a8a372014-09-23 09:50:21 -070087 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -070088 SkAssertResult(fsBuilder->enableFeature(
89 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -070090 fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
91 fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
92 fsBuilder->codeAppendf("float dfdx ="
93 "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
94 fsName, fsName, fsName);
95 fsBuilder->codeAppendf("float dfdy ="
96 "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
97 fsName, fsName, fsName);
98 fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
99 fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
100 fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
101 fsName, fsName);
102 fsBuilder->codeAppend("edgeAlpha = func / gFM;");
103 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000104 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700105 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000106 break;
107 }
joshualittb0a8a372014-09-23 09:50:21 -0700108 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700109 fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
110 fsName, fsName);
111 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000112 break;
113 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000114 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000115 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000116 }
117
egdanielb2f94d12014-08-29 10:08:36 -0700118 fsBuilder->codeAppendf("%s = %s;", outputColor,
egdaniel9bd5bbf2014-08-29 11:12:30 -0700119 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000120}
121
joshualittb0a8a372014-09-23 09:50:21 -0700122void GrGLConicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
123 GrProcessorKeyBuilder* b) {
124 const GrConicEffect& ce = processor.cast<GrConicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700125 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
126 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000127}
128
129//////////////////////////////////////////////////////////////////////////////
130
131GrConicEffect::~GrConicEffect() {}
132
joshualittb0a8a372014-09-23 09:50:21 -0700133const GrBackendGeometryProcessorFactory& GrConicEffect::getFactory() const {
134 return GrTBackendGeometryProcessorFactory<GrConicEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000135}
136
joshualittb0a8a372014-09-23 09:50:21 -0700137GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType)
joshualitt249af152014-09-15 11:41:13 -0700138 : fEdgeType(edgeType)
139 , fInConicCoeffs(this->addVertexAttrib(GrShaderVar("inConicCoeffs",
140 kVec4f_GrSLType,
141 GrShaderVar::kAttribute_TypeModifier))) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000142}
143
bsalomon0e08fc12014-10-15 08:19:04 -0700144bool GrConicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700145 const GrConicEffect& ce = other.cast<GrConicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000146 return (ce.fEdgeType == fEdgeType);
147}
148
149//////////////////////////////////////////////////////////////////////////////
150
joshualittb0a8a372014-09-23 09:50:21 -0700151GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000152
joshualittb0a8a372014-09-23 09:50:21 -0700153GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random,
154 GrContext*,
155 const GrDrawTargetCaps& caps,
156 GrTexture*[]) {
157 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000158 do {
joshualittb0a8a372014-09-23 09:50:21 -0700159 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
160 random->nextULessThan(kGrProcessorEdgeTypeCnt));
161 gp = GrConicEffect::Create(edgeType, caps);
162 } while (NULL == gp);
163 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000164}
165
166//////////////////////////////////////////////////////////////////////////////
167// Quad
168//////////////////////////////////////////////////////////////////////////////
169
joshualitt249af152014-09-15 11:41:13 -0700170class GrGLQuadEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000171public:
joshualittb0a8a372014-09-23 09:50:21 -0700172 GrGLQuadEffect(const GrBackendProcessorFactory&, const GrProcessor&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000173
joshualitt47bb3822014-10-07 16:43:25 -0700174 virtual void emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700175 const GrGeometryProcessor& geometryProcessor,
176 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000177 const char* outputColor,
178 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000179 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000180 const TextureSamplerArray&) SK_OVERRIDE;
181
joshualittb0a8a372014-09-23 09:50:21 -0700182 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000183
joshualittb0a8a372014-09-23 09:50:21 -0700184 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000185
186private:
joshualittb0a8a372014-09-23 09:50:21 -0700187 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000188
joshualitt249af152014-09-15 11:41:13 -0700189 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000190};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000191
joshualittb0a8a372014-09-23 09:50:21 -0700192GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
193 const GrProcessor& effect)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000194 : INHERITED (factory) {
joshualitt49586be2014-09-16 08:21:41 -0700195 const GrQuadEffect& ce = effect.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000196 fEdgeType = ce.getEdgeType();
197}
198
joshualitt47bb3822014-10-07 16:43:25 -0700199void GrGLQuadEffect::emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700200 const GrGeometryProcessor& geometryProcessor,
201 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000202 const char* outputColor,
203 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000204 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000205 const TextureSamplerArray& samplers) {
206 const char *vsName, *fsName;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000207 builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000208
joshualitt47bb3822014-10-07 16:43:25 -0700209 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder();
joshualittb0a8a372014-09-23 09:50:21 -0700210 const GrShaderVar& inHairQuadEdge = geometryProcessor.cast<GrQuadEffect>().inHairQuadEdge();
joshualitt249af152014-09-15 11:41:13 -0700211 vsBuilder->codeAppendf("%s = %s;", vsName, inHairQuadEdge.c_str());
joshualitt30ba4362014-08-21 20:18:45 -0700212
joshualitt47bb3822014-10-07 16:43:25 -0700213 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdanielb2f94d12014-08-29 10:08:36 -0700214 fsBuilder->codeAppendf("float edgeAlpha;");
joshualitt30ba4362014-08-21 20:18:45 -0700215
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000216 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700217 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700218 SkAssertResult(fsBuilder->enableFeature(
219 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdanielb2f94d12014-08-29 10:08:36 -0700220 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
221 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
222 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
223 " 2.0 * %s.x * duvdy.x - duvdy.y);",
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000224 fsName, fsName);
egdanielb2f94d12014-08-29 10:08:36 -0700225 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
226 fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
227 fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000228 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700229 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000230 break;
231 }
joshualittb0a8a372014-09-23 09:50:21 -0700232 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700233 SkAssertResult(fsBuilder->enableFeature(
234 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdanielb2f94d12014-08-29 10:08:36 -0700235 fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
236 fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
237 fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
238 " 2.0 * %s.x * duvdy.x - duvdy.y);",
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000239 fsName, fsName);
egdanielb2f94d12014-08-29 10:08:36 -0700240 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
241 fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
242 fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000243 // Add line below for smooth cubic ramp
egdanielb2f94d12014-08-29 10:08:36 -0700244 // fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000245 break;
246 }
joshualittb0a8a372014-09-23 09:50:21 -0700247 case kFillBW_GrProcessorEdgeType: {
egdanielb2f94d12014-08-29 10:08:36 -0700248 fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
249 fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000250 break;
251 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000252 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000253 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000254 }
255
egdanielb2f94d12014-08-29 10:08:36 -0700256 fsBuilder->codeAppendf("%s = %s;", outputColor,
commit-bot@chromium.orga34995e2013-10-23 05:42:03 +0000257 (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000258}
259
joshualittb0a8a372014-09-23 09:50:21 -0700260void GrGLQuadEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
261 GrProcessorKeyBuilder* b) {
262 const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700263 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
264 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000265}
266
267//////////////////////////////////////////////////////////////////////////////
268
269GrQuadEffect::~GrQuadEffect() {}
270
joshualittb0a8a372014-09-23 09:50:21 -0700271const GrBackendGeometryProcessorFactory& GrQuadEffect::getFactory() const {
272 return GrTBackendGeometryProcessorFactory<GrQuadEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000273}
274
joshualittb0a8a372014-09-23 09:50:21 -0700275GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType)
joshualitt249af152014-09-15 11:41:13 -0700276 : fEdgeType(edgeType)
277 , fInHairQuadEdge(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
278 kVec4f_GrSLType,
279 GrShaderVar::kAttribute_TypeModifier))) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000280}
281
bsalomon0e08fc12014-10-15 08:19:04 -0700282bool GrQuadEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700283 const GrQuadEffect& ce = other.cast<GrQuadEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000284 return (ce.fEdgeType == fEdgeType);
285}
286
287//////////////////////////////////////////////////////////////////////////////
288
joshualittb0a8a372014-09-23 09:50:21 -0700289GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000290
joshualittb0a8a372014-09-23 09:50:21 -0700291GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random,
292 GrContext*,
293 const GrDrawTargetCaps& caps,
294 GrTexture*[]) {
295 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000296 do {
joshualittb0a8a372014-09-23 09:50:21 -0700297 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
298 random->nextULessThan(kGrProcessorEdgeTypeCnt));
299 gp = GrQuadEffect::Create(edgeType, caps);
300 } while (NULL == gp);
301 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000302}
303
304//////////////////////////////////////////////////////////////////////////////
305// Cubic
306//////////////////////////////////////////////////////////////////////////////
307
joshualitt249af152014-09-15 11:41:13 -0700308class GrGLCubicEffect : public GrGLGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000309public:
joshualittb0a8a372014-09-23 09:50:21 -0700310 GrGLCubicEffect(const GrBackendProcessorFactory&, const GrProcessor&);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000311
joshualitt47bb3822014-10-07 16:43:25 -0700312 virtual void emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700313 const GrGeometryProcessor& geometryProcessor,
314 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000315 const char* outputColor,
316 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000317 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000318 const TextureSamplerArray&) SK_OVERRIDE;
319
joshualittb0a8a372014-09-23 09:50:21 -0700320 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000321
joshualittb0a8a372014-09-23 09:50:21 -0700322 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000323
324private:
joshualittb0a8a372014-09-23 09:50:21 -0700325 GrPrimitiveEdgeType fEdgeType;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000326
joshualitt249af152014-09-15 11:41:13 -0700327 typedef GrGLGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000328};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000329
joshualittb0a8a372014-09-23 09:50:21 -0700330GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
331 const GrProcessor& processor)
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000332 : INHERITED (factory) {
joshualittb0a8a372014-09-23 09:50:21 -0700333 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000334 fEdgeType = ce.getEdgeType();
335}
336
joshualitt47bb3822014-10-07 16:43:25 -0700337void GrGLCubicEffect::emitCode(GrGLGPBuilder* builder,
joshualittb0a8a372014-09-23 09:50:21 -0700338 const GrGeometryProcessor& geometryProcessor,
339 const GrProcessorKey& key,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000340 const char* outputColor,
341 const char* inputColor,
bsalomon@google.com77af6802013-10-02 13:04:56 +0000342 const TransformedCoordsArray&,
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000343 const TextureSamplerArray& samplers) {
344 const char *vsName, *fsName;
345
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000346 builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
egdaniel6db91282014-09-02 08:02:38 -0700347 &vsName, &fsName, GrGLShaderVar::kHigh_Precision);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000348
joshualitt47bb3822014-10-07 16:43:25 -0700349 GrGLVertexBuilder* vsBuilder = builder->getVertexShaderBuilder();
joshualittb0a8a372014-09-23 09:50:21 -0700350 const GrShaderVar& inCubicCoeffs = geometryProcessor.cast<GrCubicEffect>().inCubicCoeffs();
joshualitt249af152014-09-15 11:41:13 -0700351 vsBuilder->codeAppendf("%s = %s;", vsName, inCubicCoeffs.c_str());
joshualitt30ba4362014-08-21 20:18:45 -0700352
joshualitt47bb3822014-10-07 16:43:25 -0700353 GrGLGPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
egdaniel9bd5bbf2014-08-29 11:12:30 -0700354
355 GrGLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
356 GrGLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
357 GrGLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
358 GrGLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
359 GrGLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
360 GrGLShaderVar gF("gF", kVec2f_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
361 GrGLShaderVar gFM("gFM", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
362 GrGLShaderVar func("func", kFloat_GrSLType, 0, GrGLShaderVar::kHigh_Precision);
363
364 fsBuilder->declAppend(edgeAlpha);
365 fsBuilder->declAppend(dklmdx);
366 fsBuilder->declAppend(dklmdy);
367 fsBuilder->declAppend(dfdx);
368 fsBuilder->declAppend(dfdy);
369 fsBuilder->declAppend(gF);
370 fsBuilder->declAppend(gFM);
371 fsBuilder->declAppend(func);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000372
373 switch (fEdgeType) {
joshualittb0a8a372014-09-23 09:50:21 -0700374 case kHairlineAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700375 SkAssertResult(fsBuilder->enableFeature(
376 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -0700377 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
378 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
379 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
380 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
381 dklmdx.c_str(), fsName, dklmdx.c_str());
382 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
383 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
384 dklmdy.c_str(), fsName, dklmdy.c_str());
385 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
386 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
387 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
388 func.c_str(), fsName, fsName, fsName, fsName, fsName);
389 fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
390 fsBuilder->codeAppendf("%s = %s / %s;",
391 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
392 fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
393 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000394 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700395 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
396 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
397 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000398 break;
399 }
joshualittb0a8a372014-09-23 09:50:21 -0700400 case kFillAA_GrProcessorEdgeType: {
joshualitt30ba4362014-08-21 20:18:45 -0700401 SkAssertResult(fsBuilder->enableFeature(
402 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
egdaniel9bd5bbf2014-08-29 11:12:30 -0700403 fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
404 fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
405 fsBuilder->codeAppendf("%s ="
406 "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
407 dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
408 dklmdx.c_str(), fsName, dklmdx.c_str());
409 fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
410 dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
411 dklmdy.c_str(), fsName, dklmdy.c_str());
412 fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
413 fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
414 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
415 func.c_str(), fsName, fsName, fsName, fsName, fsName);
416 fsBuilder->codeAppendf("%s = %s / %s;",
417 edgeAlpha.c_str(), func.c_str(), gFM.c_str());
418 fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
419 edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000420 // Add line below for smooth cubic ramp
egdaniel9bd5bbf2014-08-29 11:12:30 -0700421 // fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
422 // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
423 // edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000424 break;
425 }
joshualittb0a8a372014-09-23 09:50:21 -0700426 case kFillBW_GrProcessorEdgeType: {
egdaniel9bd5bbf2014-08-29 11:12:30 -0700427 fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
428 edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName);
429 fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000430 break;
431 }
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000432 default:
commit-bot@chromium.org88cb22b2014-04-30 14:17:00 +0000433 SkFAIL("Shouldn't get here");
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000434 }
435
egdanielb2f94d12014-08-29 10:08:36 -0700436 fsBuilder->codeAppendf("%s = %s;", outputColor,
egdaniel9bd5bbf2014-08-29 11:12:30 -0700437 (GrGLSLExpr4(inputColor) * GrGLSLExpr1(edgeAlpha.c_str())).c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000438}
439
joshualittb0a8a372014-09-23 09:50:21 -0700440void GrGLCubicEffect::GenKey(const GrProcessor& processor, const GrGLCaps&,
441 GrProcessorKeyBuilder* b) {
442 const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
bsalomon63e99f72014-07-21 08:03:14 -0700443 uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
444 b->add32(key);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000445}
446
447//////////////////////////////////////////////////////////////////////////////
448
449GrCubicEffect::~GrCubicEffect() {}
450
joshualittb0a8a372014-09-23 09:50:21 -0700451const GrBackendGeometryProcessorFactory& GrCubicEffect::getFactory() const {
452 return GrTBackendGeometryProcessorFactory<GrCubicEffect>::getInstance();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000453}
454
joshualittb0a8a372014-09-23 09:50:21 -0700455GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType)
joshualitt249af152014-09-15 11:41:13 -0700456 : fEdgeType(edgeType)
457 , fInCubicCoeffs(this->addVertexAttrib(GrShaderVar("inCubicCoeffs",
458 kVec4f_GrSLType,
459 GrShaderVar::kAttribute_TypeModifier))) {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000460}
461
bsalomon0e08fc12014-10-15 08:19:04 -0700462bool GrCubicEffect::onIsEqual(const GrGeometryProcessor& other) const {
joshualitt49586be2014-09-16 08:21:41 -0700463 const GrCubicEffect& ce = other.cast<GrCubicEffect>();
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000464 return (ce.fEdgeType == fEdgeType);
465}
466
467//////////////////////////////////////////////////////////////////////////////
468
joshualittb0a8a372014-09-23 09:50:21 -0700469GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000470
joshualittb0a8a372014-09-23 09:50:21 -0700471GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random,
472 GrContext*,
473 const GrDrawTargetCaps& caps,
474 GrTexture*[]) {
475 GrGeometryProcessor* gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000476 do {
joshualittb0a8a372014-09-23 09:50:21 -0700477 GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
478 random->nextULessThan(kGrProcessorEdgeTypeCnt));
479 gp = GrCubicEffect::Create(edgeType, caps);
480 } while (NULL == gp);
481 return gp;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000482}
egdaniel9bd5bbf2014-08-29 11:12:30 -0700483