| Index: src/gpu/effects/GrDistanceFieldGeoProc.cpp
|
| diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
|
| index 3cd981293cd906e9a62b4e244b3fe5c821858c9d..159f1849b92c7c6331e5db67309465997e8287ad 100644
|
| --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
|
| +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
|
| @@ -35,14 +35,14 @@ public:
|
| const GrDistanceFieldA8TextGeoProc& dfTexEffect =
|
| args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
|
| GrGLSLGPBuilder* pb = args.fPB;
|
| - GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
| + SkAssertResult(fragBuilder->enableFeature(
|
| GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
|
|
| - GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
| + GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
|
|
| // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| + vertBuilder->emitAttributes(dfTexEffect);
|
|
|
| #ifdef SK_GAMMA_APPLY_TO_A8
|
| // adjust based on gamma
|
| @@ -58,24 +58,32 @@ public:
|
| if (dfTexEffect.hasVertexColor()) {
|
| pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
|
| } else {
|
| - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
| + this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
| }
|
| }
|
|
|
| // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
| + this->setupPosition(pb,
|
| + vertBuilder,
|
| + gpArgs,
|
| + dfTexEffect.inPosition()->fName,
|
| + dfTexEffect.viewMatrix(),
|
| &fViewMatrixUniform);
|
|
|
| // emit transforms
|
| - this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - args.fTransformsIn, args.fTransformsOut);
|
| + this->emitTransforms(pb,
|
| + vertBuilder,
|
| + gpArgs->fPositionVar,
|
| + dfTexEffect.inPosition()->fName,
|
| + args.fTransformsIn,
|
| + args.fTransformsOut);
|
|
|
| // add varyings
|
| GrGLSLVertToFrag recipScale(kFloat_GrSLType);
|
| GrGLSLVertToFrag st(kVec2f_GrSLType);
|
| bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
|
| pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| + vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
|
|
| // compute numbers to be hardcoded to convert texture coordinates from int to float
|
| SkASSERT(dfTexEffect.numTextures() == 1);
|
| @@ -86,29 +94,29 @@ public:
|
|
|
| GrGLSLVertToFrag uv(kVec2f_GrSLType);
|
| pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
| - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
| - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
| - dfTexEffect.inTextureCoords()->fName);
|
| + vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
| + GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
| + GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
| + dfTexEffect.inTextureCoords()->fName);
|
|
|
| // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| - kHigh_GrSLPrecision));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| -
|
| - fsBuilder->codeAppend("\tfloat texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0],
|
| - "uv",
|
| - kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(".r;\n");
|
| - fsBuilder->codeAppend("\tfloat distance = "
|
| + fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| + kHigh_GrSLPrecision));
|
| + fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| +
|
| + fragBuilder->codeAppend("\tfloat texColor = ");
|
| + fragBuilder->appendTextureLookup(args.fSamplers[0],
|
| + "uv",
|
| + kVec2f_GrSLType);
|
| + fragBuilder->codeAppend(".r;\n");
|
| + fragBuilder->codeAppend("\tfloat distance = "
|
| SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
| #ifdef SK_GAMMA_APPLY_TO_A8
|
| // adjust width based on gamma
|
| - fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
| + fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
| #endif
|
|
|
| - fsBuilder->codeAppend("float afwidth;");
|
| + fragBuilder->codeAppend("float afwidth;");
|
| if (isSimilarity) {
|
| // For uniform scale, 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
|
| @@ -116,33 +124,33 @@ public:
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| // we use y to work around a Mali400 bug in the x direction
|
| - fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
|
| - st.fsIn());
|
| + fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
|
| + st.fsIn());
|
| } else {
|
| // For general transforms, to determine the amount of correction we multiply a unit
|
| // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| + fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| // the length of the gradient may be 0, so we need to check for this
|
| // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| -
|
| - fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
|
| - fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| + fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| + fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| + fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| + fragBuilder->codeAppend("} else {");
|
| + fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| + fragBuilder->codeAppend("}");
|
| +
|
| + fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
|
| + fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
|
| + fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| + fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| + fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| }
|
| - fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
| + fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
|
|
| - fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| + fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| }
|
|
|
| void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
| @@ -286,14 +294,14 @@ public:
|
| const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
|
|
|
| GrGLSLGPBuilder* pb = args.fPB;
|
| - GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
| + SkAssertResult(fragBuilder->enableFeature(
|
| GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
|
|
| - GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
| + GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
|
|
| // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| + vertBuilder->emitAttributes(dfTexEffect);
|
|
|
| GrGLSLVertToFrag v(kVec2f_GrSLType);
|
| pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
|
| @@ -303,18 +311,26 @@ public:
|
| if (dfTexEffect.hasVertexColor()) {
|
| pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
|
| } else {
|
| - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
| + this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
| }
|
| }
|
| - vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| + vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
|
|
| // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
| + this->setupPosition(pb,
|
| + vertBuilder,
|
| + gpArgs,
|
| + dfTexEffect.inPosition()->fName,
|
| + dfTexEffect.viewMatrix(),
|
| &fViewMatrixUniform);
|
|
|
| // emit transforms
|
| - this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - args.fTransformsIn, args.fTransformsOut);
|
| + this->emitTransforms(pb,
|
| + vertBuilder,
|
| + gpArgs->fPositionVar,
|
| + dfTexEffect.inPosition()->fName,
|
| + args.fTransformsIn,
|
| + args.fTransformsOut);
|
|
|
| const char* textureSizeUniName = nullptr;
|
| fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
| @@ -322,54 +338,54 @@ public:
|
| "TextureSize", &textureSizeUniName);
|
|
|
| // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| - kHigh_GrSLPrecision));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
|
| -
|
| - fsBuilder->codeAppend("float texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0],
|
| - "uv",
|
| - kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(".r;");
|
| - fsBuilder->codeAppend("float distance = "
|
| + fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| + kHigh_GrSLPrecision));
|
| + fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
|
| +
|
| + fragBuilder->codeAppend("float texColor = ");
|
| + fragBuilder->appendTextureLookup(args.fSamplers[0],
|
| + "uv",
|
| + kVec2f_GrSLType);
|
| + fragBuilder->codeAppend(".r;");
|
| + fragBuilder->codeAppend("float distance = "
|
| SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
|
|
| - fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| - kHigh_GrSLPrecision));
|
| - fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
|
| - fsBuilder->codeAppend("float afwidth;");
|
| + fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| + kHigh_GrSLPrecision));
|
| + fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
|
| + fragBuilder->codeAppend("float afwidth;");
|
| if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
|
| // For uniform scale, 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.
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
|
| + fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
|
| } else {
|
| // For general transforms, to determine the amount of correction we multiply a unit
|
| // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| + fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
| // the length of the gradient may be 0, so we need to check for this
|
| // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| -
|
| - fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| - fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| + fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| + fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| + fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| + fragBuilder->codeAppend("} else {");
|
| + fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| + fragBuilder->codeAppend("}");
|
| +
|
| + fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| + fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| + fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| + fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| + fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| }
|
| - fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
| + fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
|
|
| - fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| + fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
| }
|
|
|
| void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
| @@ -502,30 +518,40 @@ public:
|
| args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
|
| GrGLSLGPBuilder* pb = args.fPB;
|
|
|
| - GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
| + GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
|
|
| // emit attributes
|
| - vsBuilder->emitAttributes(dfTexEffect);
|
| + vertBuilder->emitAttributes(dfTexEffect);
|
| +
|
| + GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
|
|
| // setup pass through color
|
| if (!dfTexEffect.colorIgnored()) {
|
| - this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
| + this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
| }
|
|
|
| // Setup position
|
| - this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
| + this->setupPosition(pb,
|
| + vertBuilder,
|
| + gpArgs,
|
| + dfTexEffect.inPosition()->fName,
|
| + dfTexEffect.viewMatrix(),
|
| &fViewMatrixUniform);
|
|
|
| // emit transforms
|
| - this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
| - args.fTransformsIn, args.fTransformsOut);
|
| + this->emitTransforms(pb,
|
| + vertBuilder,
|
| + gpArgs->fPositionVar,
|
| + dfTexEffect.inPosition()->fName,
|
| + args.fTransformsIn,
|
| + args.fTransformsOut);
|
|
|
| // set up varyings
|
| bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
|
| GrGLSLVertToFrag recipScale(kFloat_GrSLType);
|
| GrGLSLVertToFrag st(kVec2f_GrSLType);
|
| pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
| + vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
|
|
| // compute numbers to be hardcoded to convert texture coordinates from int to float
|
| SkASSERT(dfTexEffect.numTextures() == 1);
|
| @@ -536,62 +562,61 @@ public:
|
|
|
| GrGLSLVertToFrag uv(kVec2f_GrSLType);
|
| pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
| - vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
| - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
| - GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
| - dfTexEffect.inTextureCoords()->fName);
|
| + vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
| + GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
| + GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
| + dfTexEffect.inTextureCoords()->fName);
|
|
|
| // add frag shader code
|
| - GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
|
|
| - SkAssertResult(fsBuilder->enableFeature(
|
| + SkAssertResult(fragBuilder->enableFeature(
|
| GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
|
|
| // create LCD offset adjusted by inverse of transform
|
| // Use highp to work around aliasing issues
|
| - fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| - kHigh_GrSLPrecision));
|
| - fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| - fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| - kHigh_GrSLPrecision));
|
| + fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| + kHigh_GrSLPrecision));
|
| + fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
| + fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
| + kHigh_GrSLPrecision));
|
|
|
| SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
|
| if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
|
| - fsBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
| + fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
| } else {
|
| - fsBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
| + fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
| }
|
| if (isUniformScale) {
|
| - fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
|
| - fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
|
| + fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
|
| + fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
|
| } else {
|
| - fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
|
| + fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
|
|
|
| - fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| - fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| - fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
|
| + fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
| + fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
| + fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
|
| }
|
|
|
| // green is distance to uv center
|
| - fsBuilder->codeAppend("\tvec4 texColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tvec3 distance;\n");
|
| - fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
|
| + fragBuilder->codeAppend("\tvec4 texColor = ");
|
| + fragBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
|
| + fragBuilder->codeAppend(";\n");
|
| + fragBuilder->codeAppend("\tvec3 distance;\n");
|
| + fragBuilder->codeAppend("\tdistance.y = texColor.r;\n");
|
| // red is distance to left offset
|
| - fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
|
| - fsBuilder->codeAppend("\ttexColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
|
| + fragBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
|
| + fragBuilder->codeAppend("\ttexColor = ");
|
| + fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| + fragBuilder->codeAppend(";\n");
|
| + fragBuilder->codeAppend("\tdistance.x = texColor.r;\n");
|
| // blue is distance to right offset
|
| - fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
|
| - fsBuilder->codeAppend("\ttexColor = ");
|
| - fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| - fsBuilder->codeAppend(";\n");
|
| - fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
|
| + fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
|
| + fragBuilder->codeAppend("\ttexColor = ");
|
| + fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
| + fragBuilder->codeAppend(";\n");
|
| + fragBuilder->codeAppend("\tdistance.z = texColor.r;\n");
|
|
|
| - fsBuilder->codeAppend("\tdistance = "
|
| + fragBuilder->codeAppend("\tdistance = "
|
| "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
|
|
|
| // adjust width based on gamma
|
| @@ -599,46 +624,46 @@ public:
|
| fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
| kVec3f_GrSLType, kDefault_GrSLPrecision,
|
| "DistanceAdjust", &distanceAdjustUniName);
|
| - fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
| + fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
|
|
| // To be strictly correct, we should compute the anti-aliasing factor separately
|
| // for each color component. However, this is only important when using perspective
|
| // transformations, and even then using a single factor seems like a reasonable
|
| // trade-off between quality and speed.
|
| - fsBuilder->codeAppend("float afwidth;");
|
| + fragBuilder->codeAppend("float afwidth;");
|
| if (isUniformScale) {
|
| // For uniform scale, 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.
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
|
| + fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
|
| } else {
|
| // For general transforms, to determine the amount of correction we multiply a unit
|
| // vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
| // (which is the inverse transform for this fragment) and take the length of the result.
|
| - fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
|
| + fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
|
| // the length of the gradient may be 0, so we need to check for this
|
| // this also compensates for the Adreno, which likes to drop tiles on division by 0
|
| - fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| - fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| - fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| - fsBuilder->codeAppend("} else {");
|
| - fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| - fsBuilder->codeAppend("}");
|
| - fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| - fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
| + fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
| + fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
| + fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
| + fragBuilder->codeAppend("} else {");
|
| + fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
| + fragBuilder->codeAppend("}");
|
| + fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
| + fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
|
|
| // this gives us a smooth step across approximately one fragment
|
| - fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| + fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
| }
|
|
|
| - fsBuilder->codeAppend(
|
| + fragBuilder->codeAppend(
|
| "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
|
| // set alpha to be max of rgb coverage
|
| - fsBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
|
| + fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
|
|
|
| - fsBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
|
| + fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
|
| }
|
|
|
| void setData(const GrGLSLProgramDataManager& pdman,
|
|
|