Added varying struct
TBR= BUG=skia: Review URL: https://codereview.chromium.org/671023002
This commit is contained in:
parent
8dae0f364b
commit
852ae80b9c
@ -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;
|
||||
};
|
||||
|
@ -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*) {}
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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&,
|
||||
|
@ -514,17 +514,17 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
|
||||
"params",
|
||||
¶mName);
|
||||
|
||||
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.
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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++;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user