diff options
Diffstat (limited to 'src/effects/gradients')
-rw-r--r-- | src/effects/gradients/SkGradientShader.cpp | 62 | ||||
-rw-r--r-- | src/effects/gradients/SkGradientShaderPriv.h | 1 | ||||
-rw-r--r-- | src/effects/gradients/SkLinearGradient.cpp | 8 | ||||
-rw-r--r-- | src/effects/gradients/SkRadialGradient.cpp | 8 | ||||
-rw-r--r-- | src/effects/gradients/SkSweepGradient.cpp | 9 | ||||
-rw-r--r-- | src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp | 125 |
6 files changed, 125 insertions, 88 deletions
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp index f11d0787b9..8c944bae55 100644 --- a/src/effects/gradients/SkGradientShader.cpp +++ b/src/effects/gradients/SkGradientShader.cpp @@ -1027,61 +1027,61 @@ uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrProcessor& processor) { } void GrGLGradientEffect::emitColor(GrGLSLFPBuilder* builder, + GrGLSLFragmentBuilder* fragBuilder, const GrGradientEffect& ge, const char* gradientTValue, const char* outputColor, const char* inputColor, const TextureSamplerArray& samplers) { - GrGLSLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){ - fsBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n", - builder->getUniformVariable(fColorStartUni).c_str(), - builder->getUniformVariable(fColorEndUni).c_str(), - gradientTValue); + fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n", + builder->getUniformVariable(fColorStartUni).c_str(), + builder->getUniformVariable(fColorEndUni).c_str(), + gradientTValue); // Note that we could skip this step if both colors are known to be opaque. Two // considerations: // The gradient SkShader reporting opaque is more restrictive than necessary in the two pt // case. Make sure the key reflects this optimization (and note that it can use the same // shader as thekBeforeIterp case). This same optimization applies to the 3 color case below. if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { - fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); + fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); } - fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, - (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); + fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, + (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) { - fsBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", - gradientTValue); - fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n", - builder->getUniformVariable(fColorStartUni).c_str()); + fragBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n", + gradientTValue); + fragBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n", + builder->getUniformVariable(fColorStartUni).c_str()); if (!builder->glslCaps()->canUseMinAndAbsTogether()) { // The Tegra3 compiler will sometimes never return if we have // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression. - fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); - fsBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n"); - fsBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", - builder->getUniformVariable(fColorMidUni).c_str()); + fragBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n"); + fragBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n"); + fragBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n", + builder->getUniformVariable(fColorMidUni).c_str()); } else { - fsBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n", - builder->getUniformVariable(fColorMidUni).c_str()); + fragBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n", + builder->getUniformVariable(fColorMidUni).c_str()); } - fsBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n", - builder->getUniformVariable(fColorEndUni).c_str()); + fragBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n", + builder->getUniformVariable(fColorEndUni).c_str()); if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) { - fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); + fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n"); } - fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, - (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); + fragBuilder->codeAppendf("\t%s = %s;\n", outputColor, + (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str()); } else { - fsBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n", - gradientTValue, - builder->getUniformVariable(fFSYUni).c_str()); - fsBuilder->codeAppendf("\t%s = ", outputColor); - fsBuilder->appendTextureLookupAndModulate(inputColor, - samplers[0], - "coord"); - fsBuilder->codeAppend(";\n"); + fragBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n", + gradientTValue, + builder->getUniformVariable(fFSYUni).c_str()); + fragBuilder->codeAppendf("\t%s = ", outputColor); + fragBuilder->appendTextureLookupAndModulate(inputColor, + samplers[0], + "coord"); + fragBuilder->codeAppend(";\n"); } } diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h index 86f63f9529..8af65a47b7 100644 --- a/src/effects/gradients/SkGradientShaderPriv.h +++ b/src/effects/gradients/SkGradientShaderPriv.h @@ -426,6 +426,7 @@ protected: // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using // native GLSL mix), and 4+ color gradients that use the traditional texture lookup. void emitColor(GrGLSLFPBuilder* builder, + GrGLSLFragmentBuilder* fragBuilder, const GrGradientEffect&, const char* gradientTValue, const char* outputColor, diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp index fdc016c0d2..b60ee971f8 100644 --- a/src/effects/gradients/SkLinearGradient.cpp +++ b/src/effects/gradients/SkLinearGradient.cpp @@ -604,9 +604,13 @@ const GrFragmentProcessor* GrLinearGradient::TestCreate(GrProcessorTestData* d) void GrGLLinearGradient::emitCode(EmitArgs& args) { const GrLinearGradient& ge = args.fFp.cast<GrLinearGradient>(); this->emitUniforms(args.fBuilder, ge); - SkString t = args.fBuilder->getFragmentShaderBuilder()->ensureFSCoords2D(args.fCoords, 0); + SkString t = args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0); t.append(".x"); - this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor, + this->emitColor(args.fBuilder, + args.fFragBuilder, + ge, t.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); } diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp index c9ff20fa92..efd41c4a8a 100644 --- a/src/effects/gradients/SkRadialGradient.cpp +++ b/src/effects/gradients/SkRadialGradient.cpp @@ -501,9 +501,13 @@ void GrGLRadialGradient::emitCode(EmitArgs& args) { const GrRadialGradient& ge = args.fFp.cast<GrRadialGradient>(); this->emitUniforms(args.fBuilder, ge); SkString t("length("); - t.append(args.fBuilder->getFragmentShaderBuilder()->ensureFSCoords2D(args.fCoords, 0)); + t.append(args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0)); t.append(")"); - this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor, + this->emitColor(args.fBuilder, + args.fFragBuilder, + ge, t.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); } diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index c41c2a37a6..f2f14c4b58 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -248,8 +248,7 @@ const GrFragmentProcessor* GrSweepGradient::TestCreate(GrProcessorTestData* d) { void GrGLSweepGradient::emitCode(EmitArgs& args) { const GrSweepGradient& ge = args.fFp.cast<GrSweepGradient>(); this->emitUniforms(args.fBuilder, ge); - SkString coords2D = args.fBuilder->getFragmentShaderBuilder() - ->ensureFSCoords2D(args.fCoords, 0); + SkString coords2D = args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0); SkString t; // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int @@ -261,7 +260,11 @@ void GrGLSweepGradient::emitCode(EmitArgs& args) { t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str()); } - this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor, + this->emitColor(args.fBuilder, + args.fFragBuilder, + ge, t.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); } diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp index 653aa016a3..4633bc25e1 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp @@ -242,9 +242,9 @@ void GLEdge2PtConicalEffect::emitCode(EmitArgs& args) { SkASSERT(args.fCoords[0].getType() == args.fCoords[1].getType()); const char* coords2D; SkString bVar; - GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; if (kVec3f_GrSLType == args.fCoords[0].getType()) { - fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n", + fragBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n", args.fCoords[0].c_str(), args.fCoords[0].c_str(), args.fCoords[1].c_str(), args.fCoords[1].c_str()); coords2D = "interpolants.xy"; @@ -256,23 +256,28 @@ void GLEdge2PtConicalEffect::emitCode(EmitArgs& args) { // output will default to transparent black (we simply won't write anything // else to it if invalid, instead of discarding or returning prematurely) - fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); + fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); // c = (x^2)+(y^2) - params[1] - fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", + fragBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(), coords2D, coords2D, p1.c_str()); // linear case: t = -c/b - fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), + fragBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(), cName.c_str(), bVar.c_str()); // if r(t) > 0, then t will be the x coordinate - fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), + fragBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(), p2.c_str(), p0.c_str()); - fsBuilder->codeAppend("\t"); - this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, + fragBuilder->codeAppend("\t"); + this->emitColor(args.fBuilder, + fragBuilder, + ge, + tName.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); - fsBuilder->codeAppend("\t}\n"); + fragBuilder->codeAppend("\t}\n"); } void GLEdge2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman, @@ -511,35 +516,40 @@ void GLFocalOutside2PtConicalEffect::emitCode(EmitArgs& args) { args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1); // if we have a vec3 from being in perspective, convert it to a vec2 first - GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); - SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0); const char* coords2D = coords2DString.c_str(); // t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2) // output will default to transparent black (we simply won't write anything // else to it if invalid, instead of discarding or returning prematurely) - fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); + fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); - fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D); - fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D); - fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str()); + fragBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D); + fragBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D); + fragBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str()); // Must check to see if we flipped the circle order (to make sure start radius < end radius) // If so we must also flip sign on sqrt if (!fIsFlipped) { - fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(), - coords2D, p0.c_str()); + fragBuilder->codeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(), + coords2D, p0.c_str()); } else { - fsBuilder->codeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(), - coords2D, p0.c_str()); + fragBuilder->codeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(), + coords2D, p0.c_str()); } - fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str()); - fsBuilder->codeAppend("\t\t"); - this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, + fragBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str()); + fragBuilder->codeAppend("\t\t"); + this->emitColor(args.fBuilder, + fragBuilder, + ge, + tName.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); - fsBuilder->codeAppend("\t}\n"); + fragBuilder->codeAppend("\t}\n"); } void GLFocalOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman, @@ -713,15 +723,20 @@ void GLFocalInside2PtConicalEffect::emitCode(EmitArgs& args) { GrGLSLShaderVar focal = args.fBuilder->getUniformVariable(fFocalUni); // if we have a vec3 from being in perspective, convert it to a vec2 first - GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); - SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0); const char* coords2D = coords2DString.c_str(); // t = p.x * focalX + length(p) - fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(), + fragBuilder->codeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(), coords2D, focal.c_str(), coords2D); - this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, + this->emitColor(args.fBuilder, + fragBuilder, + ge, + tName.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); } @@ -963,8 +978,8 @@ void GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) { GrGLSLShaderVar params = args.fBuilder->getUniformVariable(fParamUni); // if we have a vec3 from being in perspective, convert it to a vec2 first - GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); - SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0); const char* coords2D = coords2DString.c_str(); // p = coords2D @@ -975,13 +990,18 @@ void GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) { // C = 1 / A // d = dot(e, p) + B // t = d +/- sqrt(d^2 - A * dot(p, p) + C) - fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D); - fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), - params.c_str()); - fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n", - tName.c_str(), params.c_str(), params.c_str()); - - this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, + fragBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D); + fragBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), + params.c_str()); + fragBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n", + tName.c_str(), params.c_str(), params.c_str()); + + this->emitColor(args.fBuilder, + fragBuilder, + ge, + tName.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); } @@ -1193,13 +1213,13 @@ void GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) { GrGLSLShaderVar params = args.fBuilder->getUniformVariable(fParamUni); // if we have a vec3 from being in perspective, convert it to a vec2 first - GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); - SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0); + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0); const char* coords2D = coords2DString.c_str(); // output will default to transparent black (we simply won't write anything // else to it if invalid, instead of discarding or returning prematurely) - fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); + fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor); // p = coords2D // e = center end @@ -1210,25 +1230,30 @@ void GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) { // d = dot(e, p) + B // t = d +/- sqrt(d^2 - A * dot(p, p) + C) - fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D); - fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), - params.c_str()); - fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), - params.c_str()); + fragBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D); + fragBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(), + params.c_str()); + fragBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(), + params.c_str()); // Must check to see if we flipped the circle order (to make sure start radius < end radius) // If so we must also flip sign on sqrt if (!fIsFlipped) { - fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str()); + fragBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str()); } else { - fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str()); + fragBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str()); } - fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str()); - fsBuilder->codeAppend("\t\t"); - this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor, + fragBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str()); + fragBuilder->codeAppend("\t\t"); + this->emitColor(args.fBuilder, + fragBuilder, + ge, + tName.c_str(), + args.fOutputColor, + args.fInputColor, args.fSamplers); - fsBuilder->codeAppend("\t}\n"); + fragBuilder->codeAppend("\t}\n"); } void GLCircleOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman, |