Added varying struct

TBR=
BUG=skia:

Review URL: https://codereview.chromium.org/671023002
This commit is contained in:
joshualitt 2014-10-24 07:56:04 -07:00 committed by Commit bot
parent 8dae0f364b
commit 852ae80b9c
17 changed files with 308 additions and 264 deletions

View File

@ -23,7 +23,8 @@
*/
class GrGeometryProcessor : public GrProcessor {
public:
GrGeometryProcessor() {}
GrGeometryProcessor()
: fWillUseGeoShader(false) {}
virtual const GrBackendGeometryProcessorFactory& getFactory() const = 0;
@ -37,6 +38,8 @@ public:
const VertexAttribArray& getVertexAttribs() const { return fVertexAttribs; }
bool willUseGeoShader() const { return fWillUseGeoShader; }
/** Returns true if this and other processor conservatively draw identically. It can only return
true when the two prcoessors are of the same subclass (i.e. they return the same object from
from getFactory()).
@ -61,10 +64,13 @@ protected:
return fVertexAttribs.push_back(var);
}
void setWillUseGeoShader() { fWillUseGeoShader = true; }
private:
virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
SkSTArray<kMaxVertexAttribs, GrShaderVar, true> fVertexAttribs;
bool fWillUseGeoShader;
typedef GrProcessor INHERITED;
};

View File

@ -529,38 +529,38 @@ public:
: INHERITED (factory) {}
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const char *vsName, *fsName;
args.fPB->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("QuadEdge", &v);
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("\t\tfloat edgeAlpha;\n");
fsBuilder->codeAppendf("float edgeAlpha;");
// keep the derivative instructions outside the conditional
fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
fsBuilder->codeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
// today we know z and w are in device space. We could use derivatives
fsBuilder->codeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
fsName);
fsBuilder->codeAppendf ("\t\t} else {\n");
fsBuilder->codeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
"\t\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
fsName, fsName);
fsBuilder->codeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
fsName);
fsBuilder->codeAppendf("\t\t\tedgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
fsBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),
v.fsIn());
fsBuilder->codeAppendf ("} else {");
fsBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,"
" 2.0*%s.x*duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(),
v.fsIn());
fsBuilder->codeAppendf("edgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
fsBuilder->codeAppendf("%s = %s;", args.fOutput,
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsName, inQuadEdge.c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
}
static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}

View File

@ -45,17 +45,17 @@ public:
// setup the varying for the Axis aligned rect effect
// xy -> interpolated offset
// zw -> w/2+0.5, h/2+0.5
const char *vsRectName, *fsRectName;
args.fPB->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("Rect", &v);
const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inRect();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsRectName, inRect.c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
// TODO: compute all these offsets, spans, and scales in the VS
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v.fsIn());
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v.fsIn());
fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
@ -69,12 +69,12 @@ public:
// Compute the coverage for the rect's width
fsBuilder->codeAppendf(
"\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", fsRectName,
fsRectName);
"\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", v.fsIn(),
v.fsIn());
// Compute the coverage for the rect's height and merge with the width
fsBuilder->codeAppendf(
"\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
fsRectName, fsRectName);
v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
@ -163,26 +163,24 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
// setup the varying for the center point and the unit vector
// that points down the height of the rect
const char *vsRectEdgeName, *fsRectEdgeName;
args.fPB->addVarying(kVec4f_GrSLType, "RectEdge",
&vsRectEdgeName, &fsRectEdgeName);
GrGLVertToFrag rectEdge(kVec4f_GrSLType);
args.fPB->addVarying("RectEdge", &rectEdge);
const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", vsRectEdgeName, rectEffect.inRectEdge().c_str());
vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRectEdge().c_str());
// setup the varying for width/2+.5 and height/2+.5
const char *vsWidthHeightName, *fsWidthHeightName;
args.fPB->addVarying(kVec2f_GrSLType, "WidthHeight",
&vsWidthHeightName, &fsWidthHeightName);
GrGLVertToFrag widthHeight(kVec2f_GrSLType);
args.fPB->addVarying("WidthHeight", &widthHeight);
vsBuilder->codeAppendf("%s = %s;",
vsWidthHeightName,
widthHeight.vsOut(),
rectEffect.inWidthHeight().c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
// TODO: compute all these offsets, spans, and scales in the VS
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", widthHeight.fsIn());
fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", widthHeight.fsIn());
fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
// For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
// < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
@ -196,19 +194,19 @@ public:
// Compute the coverage for the rect's width
fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
fsBuilder->fragmentPosition(), fsRectEdgeName);
fsBuilder->fragmentPosition(), rectEdge.fsIn());
fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
fsRectEdgeName, fsRectEdgeName);
rectEdge.fsIn(), rectEdge.fsIn());
fsBuilder->codeAppendf(
"\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
fsWidthHeightName);
widthHeight.fsIn());
// Compute the coverage for the rect's height and merge with the width
fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
fsRectEdgeName);
rectEdge.fsIn());
fsBuilder->codeAppendf(
"\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
fsWidthHeightName);
widthHeight.fsIn());
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,

View File

@ -94,21 +94,22 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const CircleEdgeEffect& circleEffect = args.fGP.cast<CircleEdgeEffect>();
const char *vsName, *fsName;
args.fPB->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("CircleEdge", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircleEdge().c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName);
fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
if (circleEffect.isStroked()) {
fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n");
fsBuilder->codeAppendf("float innerAlpha = clamp(d - %s.w, 0.0, 1.0);",
v.fsIn());
fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
}
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
fsBuilder->codeAppendf("%s = %s;\n", args.fOutput,
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
}
@ -206,39 +207,43 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const EllipseEdgeEffect& ellipseEffect = args.fGP.cast<EllipseEdgeEffect>();
const char *vsOffsetName, *fsOffsetName;
const char *vsRadiiName, *fsRadiiName;
args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName);
GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", vsOffsetName,
vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
ellipseEffect.inEllipseOffset().c_str());
args.fPB->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName);
vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inEllipseRadii().c_str());
GrGLVertToFrag ellipseRadii(kVec4f_GrSLType);
args.fPB->addVarying("EllipseRadii", &ellipseRadii);
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
ellipseEffect.inEllipseRadii().c_str());
// for outer curve
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
ellipseRadii.fsIn());
fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
// avoid calling inversesqrt on zero.
fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
// for inner curve
if (ellipseEffect.isStroked()) {
fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
ellipseOffsets.fsIn(), ellipseRadii.fsIn());
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
ellipseRadii.fsIn());
fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
fsBuilder->codeAppendf("%s = %s;", args.fOutput,
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
}
@ -348,57 +353,57 @@ public:
virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
const DIEllipseEdgeEffect& ellipseEffect = args.fGP.cast<DIEllipseEdgeEffect>();
const char *vsOffsetName0, *fsOffsetName0;
args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
&vsOffsetName0, &fsOffsetName0);
GrGLVertToFrag offsets0(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets0", &offsets0);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", vsOffsetName0,
vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
ellipseEffect.inEllipseOffsets0().c_str());
const char *vsOffsetName1, *fsOffsetName1;
args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
&vsOffsetName1, &fsOffsetName1);
vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1,
GrGLVertToFrag offsets1(kVec2f_GrSLType);
args.fPB->addVarying("EllipseOffsets1", &offsets1);
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
ellipseEffect.inEllipseOffsets1().c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
// for outer curve
fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
"\t 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
fsOffsetName0, fsOffsetName0, fsOffsetName0, fsOffsetName0);
fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn());
fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
// avoid calling inversesqrt on zero.
fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
if (kHairline == ellipseEffect.getMode()) {
// can probably do this with one step
fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
} else {
fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
}
// for inner curve
if (kStroke == ellipseEffect.getMode()) {
fsBuilder->codeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
fsBuilder->codeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
fsBuilder->codeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
fsBuilder->codeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
"\t 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
fsOffsetName1, fsOffsetName1, fsOffsetName1, fsOffsetName1);
fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
offsets1.fsIn());
fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
fsBuilder->codeAppendf("%s = %s;", args.fOutput,
(GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
}

View File

@ -37,13 +37,12 @@ GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
}
void GrGLConicEffect::emitCode(const EmitArgs& args) {
const char *vsName, *fsName;
args.fPB->addVarying(kVec4f_GrSLType, "ConicCoeffs", &vsName, &fsName);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("ConicCoeffs", &v);
const GrShaderVar& inConicCoeffs = args.fGP.cast<GrConicEffect>().inConicCoeffs();
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", vsName, inConicCoeffs.c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppend("float edgeAlpha;");
@ -52,18 +51,18 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
case kHairlineAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
fsBuilder->codeAppendf("float dfdx ="
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
fsName, fsName, fsName);
v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("float dfdy ="
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
fsName, fsName, fsName);
v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName,
fsName, fsName);
fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
v.fsIn(), v.fsIn());
fsBuilder->codeAppend("func = abs(func);");
fsBuilder->codeAppend("edgeAlpha = func / gFM;");
fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
@ -74,18 +73,18 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
case kFillAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
fsBuilder->codeAppendf("float dfdx ="
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
fsName, fsName, fsName);
v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("float dfdy ="
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
fsName, fsName, fsName);
v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
fsName, fsName);
fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
v.fsIn(), v.fsIn());
fsBuilder->codeAppend("edgeAlpha = func / gFM;");
fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
// Add line below for smooth cubic ramp
@ -93,8 +92,8 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
break;
}
case kFillBW_GrProcessorEdgeType: {
fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
fsName, fsName);
fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
v.fsIn(), v.fsIn());
fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
break;
}
@ -178,12 +177,12 @@ GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
}
void GrGLQuadEffect::emitCode(const EmitArgs& args) {
const char *vsName, *fsName;
args.fPB->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("HairQuadEdge", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
vsBuilder->codeAppendf("%s = %s;", vsName, inHairQuadEdge.c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("float edgeAlpha;");
@ -192,12 +191,12 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
case kHairlineAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
fsName, fsName);
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
// Add line below for smooth cubic ramp
@ -207,12 +206,12 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
case kFillAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
fsName, fsName);
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
// Add line below for smooth cubic ramp
@ -220,7 +219,7 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
break;
}
case kFillBW_GrProcessorEdgeType: {
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
break;
}
@ -304,14 +303,12 @@ GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
}
void GrGLCubicEffect::emitCode(const EmitArgs& args) {
const char *vsName, *fsName;
args.fPB->addVarying(kVec4f_GrSLType, "CubicCoeffs",
&vsName, &fsName, GrGLShaderVar::kHigh_Precision);
GrGLVertToFrag v(kVec4f_GrSLType);
args.fPB->addVarying("CubicCoeffs", &v, GrGLShaderVar::kHigh_Precision);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
vsBuilder->codeAppendf("%s = %s;", vsName, inCubicCoeffs.c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
@ -337,18 +334,18 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
case kHairlineAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
dklmdx.c_str(), fsName, dklmdx.c_str());
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
dklmdy.c_str(), fsName, dklmdy.c_str());
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
func.c_str(), fsName, fsName, fsName, fsName, fsName);
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
fsBuilder->codeAppendf("%s = %s / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
@ -363,19 +360,19 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
case kFillAA_GrProcessorEdgeType: {
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fsBuilder->codeAppendf("%s ="
"3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
dklmdx.c_str(), fsName, dklmdx.c_str());
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
dklmdy.c_str(), fsName, dklmdy.c_str());
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
func.c_str(), fsName, fsName, fsName, fsName, fsName);
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("%s = %s / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
@ -388,7 +385,7 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
}
case kFillBW_GrProcessorEdgeType: {
fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName);
edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
break;
}

View File

@ -24,23 +24,20 @@ public:
args.fGP.cast<GrCustomCoordsTextureEffect>();
SkASSERT(1 == customCoordsTextureEffect.getVertexAttribs().count());
SkString fsCoordName;
const char* vsVaryingName;
const char* fsVaryingNamePtr;
args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr);
fsCoordName = fsVaryingNamePtr;
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
vsBuilder->codeAppendf("\t%s = %s;\n", vsVaryingName, inTextureCoords.c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\t%s = ", args.fOutput);
fsBuilder->codeAppendf("%s = ", args.fOutput);
fsBuilder->appendTextureLookupAndModulate(args.fInput,
args.fSamplers[0],
fsCoordName.c_str(),
v.fsIn(),
kVec2f_GrSLType);
fsBuilder->codeAppend(";\n");
fsBuilder->codeAppend(";");
}
virtual void setData(const GrGLProgramDataManager&,

View File

@ -514,17 +514,17 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
"params",
&paramName);
const char *vsCoordName, *fsCoordName;
args.fPB->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("Coord", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dce.inCoord().c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
// transforms all points so that we can compare them to our test circle
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
fsCoordName, fsCoordName, paramName, paramName);
fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
v.fsIn(), v.fsIn(), paramName, paramName);
fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn());
fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName);
fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n");
if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) {
@ -718,16 +718,16 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
"interval",
&intervalName);
const char *vsCoordName, *fsCoordName;
args.fPB->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("Coord", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, de.inCoord().c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
// transforms all points so that we can compare them to our test rect
GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
fsCoordName, fsCoordName, intervalName, intervalName);
fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
v.fsIn(), v.fsIn(), intervalName, intervalName);
fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn());
if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) {
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
// numbers, xSub and ySub.

View File

@ -49,14 +49,11 @@ public:
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
SkString fsCoordName;
const char* vsCoordName;
const char* fsCoordNamePtr;
args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
fsCoordName = fsCoordNamePtr;
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@ -65,7 +62,7 @@ public:
fsBuilder->codeAppend("\tvec4 texColor = ");
fsBuilder->appendTextureLookup(args.fSamplers[0],
fsCoordName.c_str(),
v.fsIn(),
kVec2f_GrSLType);
fsBuilder->codeAppend(";\n");
fsBuilder->codeAppend("\tfloat distance = "
@ -75,7 +72,7 @@ public:
// we adjust for the effect of the transformation on the distance by using
// the length of the gradient of the texture coordinates. We use st coordinates
// to ensure we're mapping 1:1 from texel space to pixel space.
fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn());
fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
fsBuilder->codeAppend("\tfloat afwidth;\n");
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
@ -264,14 +261,11 @@ public:
SkAssertResult(fsBuilder->enableFeature(
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
SkString fsCoordName;
const char* vsCoordName;
const char* fsCoordNamePtr;
args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
fsCoordName = fsCoordNamePtr;
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoords().c_str());
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
const char* textureSizeUniName = NULL;
fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@ -280,7 +274,7 @@ public:
fsBuilder->codeAppend("vec4 texColor = ");
fsBuilder->appendTextureLookup(args.fSamplers[0],
fsCoordName.c_str(),
v.fsIn(),
kVec2f_GrSLType);
fsBuilder->codeAppend(";");
fsBuilder->codeAppend("float distance = "
@ -289,7 +283,7 @@ public:
// we adjust for the effect of the transformation on the distance by using
// the length of the gradient of the texture coordinates. We use st coordinates
// to ensure we're mapping 1:1 from texel space to pixel space.
fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str());
fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
fsBuilder->codeAppend("float afwidth;");
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
@ -421,14 +415,11 @@ public:
args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
SkString fsCoordName;
const char* vsCoordName;
const char* fsCoordNamePtr;
args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
fsCoordName = fsCoordNamePtr;
GrGLVertToFrag v(kVec2f_GrSLType);
args.fPB->addVarying("TextureCoords", &v);
GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
const char* textureSizeUniName = NULL;
// width, height, 1/(3*width)
@ -442,7 +433,7 @@ public:
GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
// create LCD offset adjusted by inverse of transform
fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn());
fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
if (isUniformScale) {

View File

@ -346,12 +346,10 @@ void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID)
}
}
void GrGLFragmentShaderBuilder::addVarying(GrSLType type,
const char* name,
const char** fsInName,
GrGLShaderVar::Precision fsPrecision) {
fInputs.push_back().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, name, fsPrecision);
if (fsInName) {
*fsInName = name;
void GrGLFragmentShaderBuilder::addVarying(GrGLVarying* v, GrGLShaderVar::Precision fsPrec) {
v->fFsIn = v->fVsOut;
if (v->fGsOut) {
v->fFsIn = v->fGsOut;
}
fInputs.push_back().set(v->fType, GrGLShaderVar::kVaryingIn_TypeModifier, v->fFsIn, fsPrec);
}

View File

@ -10,6 +10,8 @@
#include "GrGLShaderBuilder.h"
class GrGLVarying;
/*
* This base class encapsulates the functionality which the GP uses to build fragment shaders
*/
@ -91,6 +93,7 @@ public:
virtual const char* fragmentPosition() SK_OVERRIDE;
virtual const char* dstColor() SK_OVERRIDE;
private:
// Private public interface, used by GrGLProgramBuilder to build a fragment shader
void emitCodeToReadDstTexture();
void enableCustomOutput();
@ -102,14 +105,6 @@ public:
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
void bindFragmentShaderLocations(GrGLuint programID);
/*
* An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
*/
void addVarying(GrSLType type,
const char* name,
const char** fsInName,
GrGLShaderVar::Precision fsPrecision = GrGLShaderVar::kDefault_Precision);
// As GLProcessors emit code, there are some conditions we need to verify. We use the below
// state to track this. The reset call is called per processor emitted.
bool hasReadDstColor() const { return fHasReadDstColor; }
@ -119,7 +114,12 @@ public:
fHasReadFragmentPosition = false;
}
private:
/*
* An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
*/
void addVarying(GrGLVarying* v,
GrGLShaderVar::Precision fsPrec = GrGLShaderVar::kDefault_Precision);
/**
* Features that should only be enabled by GrGLFragmentShaderBuilder itself.
*/

View File

@ -15,26 +15,27 @@ GrGLGeometryBuilder::GrGLGeometryBuilder(GrGLProgramBuilder* program)
}
void GrGLGeometryBuilder::addVarying(GrSLType type,
const char* name,
const char** gsOutName) {
void GrGLGeometryBuilder::addVarying(const char* name, GrGLVarying* v) {
// if we have a GS take each varying in as an array
// and output as non-array.
fInputs.push_back();
fInputs.back().setType(type);
fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
fInputs.back().setUnsizedArray();
*fInputs.back().accessName() = name;
fOutputs.push_back();
fOutputs.back().setType(type);
fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
if (gsOutName) {
*gsOutName = fOutputs.back().getName().c_str();
if (v->vsVarying()) {
fInputs.push_back();
fInputs.back().setType(v->fType);
fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
fInputs.back().setUnsizedArray();
*fInputs.back().accessName() = v->fVsOut;
v->fGsIn = v->fVsOut;
}
if (v->fsVarying()) {
fOutputs.push_back();
fOutputs.back().setType(v->fType);
fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
v->fGsOut = fOutputs.back().getName().c_str();
}
}
bool GrGLGeometryBuilder::compileAndAttachShaders(GrGLuint programId,
SkTDArray<GrGLuint>* shaderIds) const {
const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();

View File

@ -10,18 +10,22 @@
#include "GrGLShaderBuilder.h"
class GrGLVarying;
class GrGLGeometryBuilder : public GrGLShaderBuilder {
public:
GrGLGeometryBuilder(GrGLProgramBuilder* program);
private:
/*
* an internal call for GrGLFullProgramBuilder to add varyings
*/
void addVarying(GrSLType type,
const char* name,
const char** gsOutName);
void addVarying(const char* name, GrGLVarying*);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
friend class GrGLProgramBuilder;
typedef GrGLShaderBuilder INHERITED;
};

View File

@ -55,7 +55,6 @@ GrGLNvprProgramBuilder::addSeparableVarying(GrSLType type,
const char* name,
const char** vsOutName,
const char** fsInName) {
addVarying(type, name, vsOutName, fsInName);
SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
varying.fVariable = fFS.fInputs.back();
return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);

View File

@ -126,13 +126,19 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
, fUniforms(kVarsPerBlock) {
}
void GrGLProgramBuilder::addVarying(GrSLType type,
const char* name,
const char** vsOutName,
const char** fsInName,
void GrGLProgramBuilder::addVarying(const char* name,
GrGLVarying* varying,
GrGLShaderVar::Precision fsPrecision) {
SkString* fsInputName = fVS.addVarying(type, name, vsOutName);
fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
SkASSERT(varying);
if (varying->vsVarying()) {
fVS.addVarying(name, varying);
}
if (fOptState.hasGeometryProcessor() && fOptState.getGeometryProcessor()->willUseGeoShader()) {
fGS.addVarying(name, varying);
}
if (varying->fsVarying()) {
fFS.addVarying(varying);
}
}
void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
@ -362,9 +368,8 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
suffixedVaryingName.appendf("_%i", t);
varyingName = suffixedVaryingName.c_str();
}
const char* vsVaryingName;
const char* fsVaryingName;
this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
GrGLVertToFrag v(varyingType);
this->addVarying(varyingName, &v);
const GrGLShaderVar& coords =
kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
@ -375,13 +380,13 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
if (kVec2f_GrSLType == varyingType) {
fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
vsVaryingName, uniName, coords.c_str());
v.vsOut(), uniName, coords.c_str());
} else {
fVS.codeAppendf("%s = %s * vec3(%s, 1);",
vsVaryingName, uniName, coords.c_str());
v.vsOut(), uniName, coords.c_str());
}
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
(SkString(fsVaryingName), varyingType));
(SkString(v.fsIn()), varyingType));
}
}

View File

@ -69,13 +69,63 @@ public:
*/
};
// TODO move this into GrGLGPBuilder and move them both out of this file
class GrGLVarying {
public:
bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
kVertToGeo_Varying == fVarying; }
bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
kGeoToFrag_Varying == fVarying; }
const char* vsOut() const { return fVsOut; }
const char* gsIn() const { return fGsIn; }
const char* gsOut() const { return fGsOut; }
const char* fsIn() const { return fFsIn; }
protected:
enum Varying {
kVertToFrag_Varying,
kVertToGeo_Varying,
kGeoToFrag_Varying,
};
GrGLVarying(GrSLType type, Varying varying)
: fVarying(varying), fType(type), fVsOut(NULL), fGsIn(NULL), fGsOut(NULL),
fFsIn(NULL) {}
Varying fVarying;
private:
GrSLType fType;
const char* fVsOut;
const char* fGsIn;
const char* fGsOut;
const char* fFsIn;
friend class GrGLVertexBuilder;
friend class GrGLGeometryBuilder;
friend class GrGLFragmentShaderBuilder;
};
struct GrGLVertToFrag : public GrGLVarying {
GrGLVertToFrag(GrSLType type)
: GrGLVarying(type, kVertToFrag_Varying) {}
};
struct GrGLVertToGeo : public GrGLVarying {
GrGLVertToGeo(GrSLType type)
: GrGLVarying(type, kVertToGeo_Varying) {}
};
struct GrGLGeoToFrag : public GrGLVarying {
GrGLGeoToFrag(GrSLType type)
: GrGLVarying(type, kGeoToFrag_Varying) {}
};
/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */
class GrGLGPBuilder : public virtual GrGLUniformBuilder {
public:
virtual void addVarying(GrSLType type,
const char* name,
const char** vsOutName = NULL,
const char** fsInName = NULL,
virtual void addVarying(const char* name,
GrGLVarying*,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) = 0;
// TODO rename getFragmentBuilder
@ -152,10 +202,8 @@ public:
virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
virtual void addVarying(
GrSLType type,
const char* name,
const char** vsOutName = NULL,
const char** fsInName = NULL,
GrGLVarying*,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
// Handles for program uniforms (other than per-effect uniforms)

View File

@ -23,17 +23,12 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
, fEffectAttribOffset(0) {
}
SkString* GrGLVertexBuilder::addVarying(GrSLType type, const char* name,
const char** vsOutName) {
void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
fOutputs.push_back();
fOutputs.back().setType(type);
fOutputs.back().setType(v->fType);
fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name);
if (vsOutName) {
*vsOutName = fOutputs.back().getName().c_str();
}
return fOutputs.back().accessName();
v->fVsOut = fOutputs.back().getName().c_str();
}
void GrGLVertexBuilder::setupLocalCoords() {
@ -63,15 +58,15 @@ void GrGLVertexBuilder::transformGLToSkiaCoords() {
}
void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out) {
GrGLVertToFrag v(kVec4f_GrSLType);
fProgramBuilder->addVarying(inName, &v);
SkString name(inName);
const char *vsName, *fsName;
fProgramBuilder->addVarying(kVec4f_GrSLType, name.c_str(), &vsName, &fsName);
name.prepend("in");
this->addAttribute(GrShaderVar(name.c_str(),
kVec4f_GrSLType,
GrShaderVar::kAttribute_TypeModifier));
this->codeAppendf("%s = %s;", vsName, name.c_str());
*out = fsName;
this->codeAppendf("%s = %s;", v.vsOut(), name.c_str());
*out = v.fsIn();
fEffectAttribOffset++;
}

View File

@ -10,10 +10,8 @@
#include "GrGLShaderBuilder.h"
class GrGLProgramBuilder;
class GrGLVarying;
// TODO we only actually ever need to return a GrGLShaderBuilder for this guy, none of the below
// functions need to be part of VertexShaderBuilder's public interface
class GrGLVertexBuilder : public GrGLShaderBuilder {
public:
GrGLVertexBuilder(GrGLProgramBuilder* program);
@ -33,10 +31,11 @@ public:
*/
const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
private:
/*
* Internal call for GrGLProgramBuilder.addVarying
*/
SkString* addVarying(GrSLType type, const char* name, const char** vsOutName);
void addVarying(const char* name, GrGLVarying*);
/*
* private helpers for compilation by GrGLProgramBuilder
@ -49,7 +48,6 @@ public:
void bindVertexAttributes(GrGLuint programID);
bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
private:
// an internal call which checks for uniquness of a var before adding it to the list of inputs
bool addAttribute(const GrShaderVar& var);
struct AttributePair {
@ -64,6 +62,8 @@ private:
GrGLShaderVar* fLocalCoordsVar;
int fEffectAttribOffset;
friend class GrGLProgramBuilder;
typedef GrGLShaderBuilder INHERITED;
};