diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 40 | ||||
-rw-r--r-- | src/gpu/GrAARectRenderer.cpp | 44 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 125 | ||||
-rw-r--r-- | src/gpu/effects/GrBezierEffect.cpp | 97 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomCoordsTextureEffect.cpp | 15 | ||||
-rw-r--r-- | src/gpu/effects/GrDashingEffect.cpp | 20 | ||||
-rwxr-xr-x | src/gpu/effects/GrDistanceFieldTextureEffect.cpp | 37 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 12 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 18 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp | 31 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLGeometryShaderBuilder.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp | 1 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 29 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 62 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 19 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 10 |
16 files changed, 304 insertions, 266 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index ef4a17107e..eecc72270c 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -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("\t%s = %s;\n", args.fOutput, + 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("%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*) {} diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index e5d1593bc0..18bba5a1b8 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -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, diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 8c3b99c6e3..72a01813b4 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -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->codeAppend("\tfloat grad_dot = dot(grad, grad);\n"); + 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("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()); } diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 661923d769..196168c06a 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -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; } diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp index 84f6b43295..afa0754603 100644 --- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp +++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp @@ -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&, diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 4f6eef1546..e15ffbed7c 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -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. diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index ca38e849eb..e90ebfbf75 100755 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -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) { diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index 76558d8875..ff3989bf63 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -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); } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 1637d25612..67dfbe3559 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -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. */ diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp index 8a3b1f4a6e..af95f564cf 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp @@ -15,25 +15,26 @@ 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 { diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h index aa27f23f03..88fa298823 100644 --- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h @@ -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; }; diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp index a20b0d6b0d..86b1d7f167 100644 --- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp @@ -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); diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index a628febb69..4a95f33ecc 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -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)); } } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 2afdd099f4..9d8e7e0ac9 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -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) diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index 76026b7a25..1fa946793c 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -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++; } diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h index 6e1495a746..31b4ad4cd9 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h @@ -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; }; |