本文整理汇总了C++中GrGLSLUniformHandler::addUniform方法的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLUniformHandler::addUniform方法的具体用法?C++ GrGLSLUniformHandler::addUniform怎么用?C++ GrGLSLUniformHandler::addUniform使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrGLSLUniformHandler
的用法示例。
在下文中一共展示了GrGLSLUniformHandler::addUniform方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: emitCode
void emitCode(EmitArgs& args) override {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fMatrixHandle = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kMat44f_GrSLType, kDefault_GrSLPrecision,
"ColorMatrix");
fVectorHandle = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"ColorMatrixVector");
if (nullptr == args.fInputColor) {
// could optimize this case, but we aren't for now.
args.fInputColor = "vec4(1)";
}
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
// transparent black.
fragBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n",
args.fInputColor);
fragBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
args.fOutputColor,
uniformHandler->getUniformCStr(fMatrixHandle),
args.fInputColor,
uniformHandler->getUniformCStr(fVectorHandle));
fragBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n",
args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
}
示例2: emitCode
void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
if (!args.fXP.willReadDstColor()) {
this->emitOutputsForBlendState(args);
return;
}
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
const char* dstColor = fragBuilder->dstColor();
if (args.fXP.getDstTexture()) {
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
if (args.fInputCoverage) {
// We don't think any shaders actually output negative coverage, but just as a safety
// check for floating point precision errors we compare with <= here
fragBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
" discard;"
"}", args.fInputCoverage);
}
const char* dstTopLeftName;
const char* dstCoordScaleName;
fDstTopLeftUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstTextureUpperLeft",
&dstTopLeftName);
fDstScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstTextureCoordScale",
&dstCoordScaleName);
const char* fragPos = fragBuilder->fragmentPosition();
fragBuilder->codeAppend("// Read color from copy of the destination.\n");
fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
fragPos, dstTopLeftName, dstCoordScaleName);
if (!topDown) {
fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
}
fragBuilder->codeAppendf("vec4 %s = ", dstColor);
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
fragBuilder->codeAppend(";");
}
this->emitBlendCodeForDstRead(fragBuilder,
uniformHandler,
args.fInputColor,
args.fInputCoverage,
dstColor,
args.fOutputPrimary,
args.fOutputSecondary,
args.fXP);
}
示例3: emitCode
void GrGLConvolutionEffect::emitCode(EmitArgs& args) {
const GrConvolutionEffect& ce = args.fFp.cast<GrConvolutionEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
if (ce.useBounds()) {
fBoundsUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
}
int width = Gr1DKernelEffect::WidthFromRadius(ce.radius());
fKernelUni = uniformHandler->addUniformArray(GrGLSLUniformHandler::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision,
"Kernel", width);
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->codeAppendf("%s = vec4(0, 0, 0, 0);", args.fOutputColor);
const GrGLSLShaderVar& kernel = uniformHandler->getUniformVariable(fKernelUni);
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
fragBuilder->codeAppendf("vec2 coord = %s - %d.0 * %s;", coords2D.c_str(), ce.radius(), imgInc);
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
for (int i = 0; i < width; i++) {
SkString index;
SkString kernelIndex;
index.appendS32(i);
kernel.appendArrayAccess(index.c_str(), &kernelIndex);
if (ce.useBounds()) {
// We used to compute a bool indicating whether we're in bounds or not, cast it to a
// float, and then mul weight*texture_sample by the float. However, the Adreno 430 seems
// to have a bug that caused corruption.
const char* bounds = uniformHandler->getUniformCStr(fBoundsUni);
const char* component = ce.direction() == Gr1DKernelEffect::kY_Direction ? "y" : "x";
fragBuilder->codeAppendf("if (coord.%s >= %s.x && coord.%s <= %s.y) {",
component, bounds, component, bounds);
}
fragBuilder->codeAppendf("\t\t%s += ", args.fOutputColor);
fragBuilder->appendTextureLookup(args.fSamplers[0], "coord");
fragBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
if (ce.useBounds()) {
fragBuilder->codeAppend("}");
}
fragBuilder->codeAppendf("\t\tcoord += %s;\n", imgInc);
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}
示例4: max
void GrColorCubeEffect::GLSLProcessor::emitCode(EmitArgs& args) {
if (nullptr == args.fInputColor) {
args.fInputColor = "vec4(1)";
}
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fColorCubeSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"Size");
const char* colorCubeSizeUni = uniformHandler->getUniformCStr(fColorCubeSizeUni);
fColorCubeInvSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"InvSize");
const char* colorCubeInvSizeUni = uniformHandler->getUniformCStr(fColorCubeInvSizeUni);
const char* nonZeroAlpha = "nonZeroAlpha";
const char* unPMColor = "unPMColor";
const char* cubeIdx = "cubeIdx";
const char* cCoords1 = "cCoords1";
const char* cCoords2 = "cCoords2";
// Note: if implemented using texture3D in OpenGL ES older than OpenGL ES 3.0,
// the shader might need "#extension GL_OES_texture_3D : enable".
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Unpremultiply color
fragBuilder->codeAppendf("\tfloat %s = max(%s.a, 0.00001);\n", nonZeroAlpha, args.fInputColor);
fragBuilder->codeAppendf("\tvec4 %s = vec4(%s.rgb / %s, %s);\n",
unPMColor, args.fInputColor, nonZeroAlpha, nonZeroAlpha);
// Fit input color into the cube.
fragBuilder->codeAppendf(
"vec3 %s = vec3(%s.rg * vec2((%s - 1.0) * %s) + vec2(0.5 * %s), %s.b * (%s - 1.0));\n",
cubeIdx, unPMColor, colorCubeSizeUni, colorCubeInvSizeUni, colorCubeInvSizeUni,
unPMColor, colorCubeSizeUni);
// Compute y coord for for texture fetches.
fragBuilder->codeAppendf("vec2 %s = vec2(%s.r, (floor(%s.b) + %s.g) * %s);\n",
cCoords1, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
fragBuilder->codeAppendf("vec2 %s = vec2(%s.r, (ceil(%s.b) + %s.g) * %s);\n",
cCoords2, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
// Apply the cube.
fragBuilder->codeAppendf("%s = vec4(mix(", args.fOutputColor);
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords1);
fragBuilder->codeAppend(".bgr, ");
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords2);
// Premultiply color by alpha. Note that the input alpha is not modified by this shader.
fragBuilder->codeAppendf(".bgr, fract(%s.b)) * vec3(%s), %s.a);\n",
cubeIdx, nonZeroAlpha, args.fInputColor);
}
示例5: emitCode
void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fOffsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Offset");
fInvZoomVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvZoom");
fInvInsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvInset");
fBoundsVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
fragBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
uniformHandler->getUniformCStr(fOffsetVar),
coords2D.c_str(),
uniformHandler->getUniformCStr(fInvZoomVar));
const char* bounds = uniformHandler->getUniformCStr(fBoundsVar);
fragBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds);
fragBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n");
fragBuilder->codeAppendf("\t\tdelta = delta * %s;\n",
uniformHandler->getUniformCStr(fInvInsetVar));
fragBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
fragBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
fragBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
fragBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
fragBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
fragBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
fragBuilder->codeAppend("\t\t} else {\n");
fragBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
fragBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
fragBuilder->codeAppend("\t\t}\n");
fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
fragBuilder->codeAppend("\t\tvec4 output_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord");
fragBuilder->codeAppend(";\n");
fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}
示例6: onEmitCode
void onEmitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// add uniform
const char* xformUniName = nullptr;
fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat22f_GrSLType,
kDefault_GrSLPrecision, "Xform", &xformUniName);
SkString dstNormalColorName("dstNormalColor");
this->emitChild(0, nullptr, &dstNormalColorName, args);
fragBuilder->codeAppendf("vec3 normal = normalize(%s.rgb - vec3(0.5));",
dstNormalColorName.c_str());
// If there's no x & y components, return (0, 0, +/- 1) instead to avoid division by 0
fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {");
fragBuilder->codeAppendf(" %s = normalize(vec4(0.0, 0.0, normal.z, 0.0));",
args.fOutputColor);
// Else, Normalizing the transformed X and Y, while keeping constant both Z and the
// vector's angle in the XY plane. This maintains the "slope" for the surface while
// appropriately rotating the normal regardless of any anisotropic scaling that occurs.
// Here, we call 'scaling factor' the number that must divide the transformed X and Y so
// that the normal's length remains equal to 1.
fragBuilder->codeAppend( "} else {");
fragBuilder->codeAppendf(" vec2 transformed = %s * normal.xy;",
xformUniName);
fragBuilder->codeAppend( " float scalingFactorSquared = "
"( (transformed.x * transformed.x) "
"+ (transformed.y * transformed.y) )"
"/(1.0 - (normal.z * normal.z));");
fragBuilder->codeAppendf(" %s = vec4(transformed*inversesqrt(scalingFactorSquared),"
"normal.z, 0.0);",
args.fOutputColor);
fragBuilder->codeAppend( "}");
}
示例7: emitCode
void GrGLAlphaThresholdFragmentProcessor::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"inner_threshold");
fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"outer_threshold");
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
fragBuilder->codeAppendf("vec2 coord = %s;", coords2D.c_str());
fragBuilder->codeAppendf("vec2 mask_coord = %s;", maskCoords2D.c_str());
fragBuilder->codeAppend("vec4 input_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord");
fragBuilder->codeAppend(";");
fragBuilder->codeAppend("vec4 mask_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord");
fragBuilder->codeAppend(";");
fragBuilder->codeAppendf("float inner_thresh = %s;",
uniformHandler->getUniformCStr(fInnerThresholdVar));
fragBuilder->codeAppendf("float outer_thresh = %s;",
uniformHandler->getUniformCStr(fOuterThresholdVar));
fragBuilder->codeAppend("float mask = mask_color.a;");
fragBuilder->codeAppend("vec4 color = input_color;");
fragBuilder->codeAppend("if (mask < 0.5) {"
"if (color.a > outer_thresh) {"
"float scale = outer_thresh / color.a;"
"color.rgb *= scale;"
"color.a = outer_thresh;"
"}"
"} else if (color.a < inner_thresh) {"
"float scale = inner_thresh / max(0.001, color.a);"
"color.rgb *= scale;"
"color.a = inner_thresh;"
"}");
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor,
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
}
示例8: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const GrBitmapTextGeoProc& btgp = args.fGP.cast<GrBitmapTextGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(btgp);
const char* atlasSizeInvName;
fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
kFloat2_GrSLType,
kHigh_GrSLPrecision,
"AtlasSizeInv",
&atlasSizeInvName);
GrGLSLVarying uv(kFloat2_GrSLType);
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
append_index_uv_varyings(args, btgp.inTextureCoords().name(), atlasSizeInvName, &uv,
&texIdx, nullptr);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
if (btgp.hasVertexColor()) {
varyingHandler->addPassThroughAttribute(btgp.inColor(), args.fOutputColor);
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
// Setup position
gpArgs->fPositionVar = btgp.inPosition().asShaderVar();
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
btgp.inPosition().asShaderVar(),
btgp.localMatrix(),
args.fFPCoordTransformHandler);
fragBuilder->codeAppend("half4 texColor;");
append_multitexture_lookup(args, btgp.numTextureSamplers(),
texIdx, uv.fsIn(), "texColor");
if (btgp.maskFormat() == kARGB_GrMaskFormat) {
// modulate by color
fragBuilder->codeAppendf("%s = %s * texColor;", args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
} else {
fragBuilder->codeAppendf("%s = texColor;", args.fOutputCoverage);
}
}
示例9: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const PLSFinishEffect& fe = args.fGP.cast<PLSFinishEffect>();
GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fUseEvenOdd = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kLow_GrSLPrecision,
"useEvenOdd");
const char* useEvenOdd = uniformHandler->getUniformCStr(fUseEvenOdd);
varyingHandler->emitAttributes(fe);
this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName);
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
fe.inPosition()->fName, fe.localMatrix(), args.fTransformsIn,
args.fTransformsOut);
GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
SkAssertResult(fsBuilder->enableFeature(
GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
fsBuilder->codeAppend("float coverage;");
fsBuilder->codeAppendf("if (%s != 0.0) {", useEvenOdd);
fsBuilder->codeAppend("coverage = float(abs(pls.windings[0]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[1]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[2]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[3]) % 2) * 0.25;");
fsBuilder->codeAppend("} else {");
fsBuilder->codeAppend("coverage = pls.windings[0] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[1] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[2] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[3] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("}");
if (!fe.colorIgnored()) {
this->setupUniformColor(fsBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
fsBuilder->codeAppendf("%s = vec4(coverage);", args.fOutputCoverage);
fsBuilder->codeAppendf("%s = vec4(1.0, 0.0, 1.0, 1.0);", args.fOutputColor);
}
示例10: emitCode
void GrGLBicubicEffect::emitCode(EmitArgs& args) {
const GrTextureDomain& domain = args.fFp.cast<GrBicubicEffect>().domain();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fCoefficientsUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kMat44f_GrSLType, kDefault_GrSLPrecision,
"Coefficients");
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
const char* coeff = uniformHandler->getUniformCStr(fCoefficientsUni);
SkString cubicBlendName;
static const GrGLSLShaderVar gCubicBlendArgs[] = {
GrGLSLShaderVar("coefficients", kMat44f_GrSLType),
GrGLSLShaderVar("t", kFloat_GrSLType),
GrGLSLShaderVar("c0", kVec4f_GrSLType),
GrGLSLShaderVar("c1", kVec4f_GrSLType),
GrGLSLShaderVar("c2", kVec4f_GrSLType),
GrGLSLShaderVar("c3", kVec4f_GrSLType),
};
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->emitFunction(kVec4f_GrSLType,
"cubicBlend",
SK_ARRAY_COUNT(gCubicBlendArgs),
gCubicBlendArgs,
"\tvec4 ts = vec4(1.0, t, t * t, t * t * t);\n"
"\tvec4 c = coefficients * ts;\n"
"\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n",
&cubicBlendName);
fragBuilder->codeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
// We unnormalize the coord in order to determine our fractional offset (f) within the texel
// We then snap coord to a texel center and renormalize. The snap prevents cases where the
// starting coords are near a texel boundary and accumulations of imgInc would cause us to skip/
// double hit a texel.
fragBuilder->codeAppendf("\tcoord /= %s;\n", imgInc);
fragBuilder->codeAppend("\tvec2 f = fract(coord);\n");
fragBuilder->codeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
fragBuilder->codeAppend("\tvec4 rowColors[4];\n");
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
SkString coord;
coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1);
SkString sampleVar;
sampleVar.printf("rowColors[%d]", x);
fDomain.sampleTexture(fragBuilder,
args.fUniformHandler,
args.fGLSLCaps,
domain,
sampleVar.c_str(),
coord,
args.fTexSamplers[0]);
}
fragBuilder->codeAppendf(
"\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n",
y, cubicBlendName.c_str(), coeff);
}
SkString bicubicColor;
bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff);
fragBuilder->codeAppendf("\t%s = %s;\n",
args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str()) *
GrGLSLExpr4(args.fInputColor)).c_str());
}
示例11: onEmitCode
void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(gp);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
if (!gp.colorIgnored()) {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
}
// Setup position
this->setupPosition(vertBuilder,
uniformHandler,
gpArgs,
gp.inPosition()->fName,
gp.viewMatrix(),
&fViewMatrixUniform);
// Setup KLM
const char* devkLMMatrixName;
fDevKLMUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, kMat33f_GrSLType,
kHigh_GrSLPrecision, "KLM", &devkLMMatrixName);
GrGLSLVertToFrag v(kVec3f_GrSLType);
varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s * vec3(%s, 1);",
v.vsOut(), devkLMMatrixName, gpArgs->fPositionVar.c_str());
GrGLSLVertToFrag gradCoeffs(kVec4f_GrSLType);
if (kFillAA_GrProcessorEdgeType == fEdgeType || kHairlineAA_GrProcessorEdgeType == fEdgeType) {
varyingHandler->addVarying("GradCoeffs", &gradCoeffs, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("highp float k = %s[0], l = %s[1], m = %s[2];",
v.vsOut(), v.vsOut(), v.vsOut());
vertBuilder->codeAppendf("highp vec2 gk = vec2(%s[0][0], %s[1][0]), "
"gl = vec2(%s[0][1], %s[1][1]), "
"gm = vec2(%s[0][2], %s[1][2]);",
devkLMMatrixName, devkLMMatrixName, devkLMMatrixName,
devkLMMatrixName, devkLMMatrixName, devkLMMatrixName);
vertBuilder->codeAppendf("%s = vec4(3 * k * gk, -m * gl - l * gm);",
gradCoeffs.vsOut());
}
// emit transforms with position
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
gp.inPosition()->fName,
args.fFPCoordTransformHandler);
GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
fragBuilder->declAppend(edgeAlpha);
fragBuilder->declAppend(gF);
fragBuilder->declAppend(func);
switch (fEdgeType) {
case kHairlineAA_GrProcessorEdgeType: {
fragBuilder->codeAppendf("%s = %s.x * %s.xy + %s.zw;",
gF.c_str(), v.fsIn(), gradCoeffs.fsIn(), gradCoeffs.fsIn());
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
func.c_str(), v.fsIn(), v.fsIn(),
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
fragBuilder->codeAppendf("%s = %s * inversesqrt(dot(%s, %s));",
edgeAlpha.c_str(), func.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
// edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
// edgeAlpha.c_str());
break;
}
case kFillAA_GrProcessorEdgeType: {
fragBuilder->codeAppendf("%s = %s.x * %s.xy + %s.zw;",
gF.c_str(), v.fsIn(), gradCoeffs.fsIn(), gradCoeffs.fsIn());
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
func.c_str(),
v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = %s * inversesqrt(dot(%s, %s));",
edgeAlpha.c_str(), func.c_str(), gF.c_str(), gF.c_str());
fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
// edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
// edgeAlpha.c_str());
break;
}
case kFillBW_GrProcessorEdgeType: {
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
//.........这里部分代码省略.........
示例12: emitCode
void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) {
const GrMatrixConvolutionEffect& mce = args.fFp.cast<GrMatrixConvolutionEffect>();
const GrTextureDomain& domain = mce.domain();
int kWidth = mce.kernelSize().width();
int kHeight = mce.kernelSize().height();
int arrayCount = (kWidth * kHeight + 3) / 4;
SkASSERT(4 * arrayCount >= kWidth * kHeight);
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"ImageIncrement");
fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, kHalf4_GrSLType,
"Kernel",
arrayCount);
fKernelOffsetUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"KernelOffset");
fGainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Gain");
fBiasUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Bias");
const char* kernelOffset = uniformHandler->getUniformCStr(fKernelOffsetUni);
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
const char* kernel = uniformHandler->getUniformCStr(fKernelUni);
const char* gain = uniformHandler->getUniformCStr(fGainUni);
const char* bias = uniformHandler->getUniformCStr(fBiasUni);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppend("half4 sum = half4(0, 0, 0, 0);");
fragBuilder->codeAppendf("float2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc);
fragBuilder->codeAppend("half4 c;");
const char* kVecSuffix[4] = { ".x", ".y", ".z", ".w" };
for (int y = 0; y < kHeight; y++) {
for (int x = 0; x < kWidth; x++) {
GrGLSLShaderBuilder::ShaderBlock block(fragBuilder);
int offset = y*kWidth + x;
fragBuilder->codeAppendf("half k = %s[%d]%s;", kernel, offset / 4,
kVecSuffix[offset & 0x3]);
SkString coord;
coord.printf("coord + half2(%d, %d) * %s", x, y, imgInc);
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fShaderCaps,
domain,
"c",
coord,
args.fTexSamplers[0]);
if (!mce.convolveAlpha()) {
fragBuilder->codeAppend("c.rgb /= c.a;");
fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);");
}
fragBuilder->codeAppend("sum += c * k;");
}
}
if (mce.convolveAlpha()) {
fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.a = clamp(%s.a, 0, 1);", args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
args.fOutputColor, args.fOutputColor, args.fOutputColor);
} else {
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fShaderCaps,
domain,
"c",
coords2D,
args.fTexSamplers[0]);
fragBuilder->codeAppendf("%s.a = c.a;", args.fOutputColor);
fragBuilder->codeAppendf("%s.rgb = clamp(sum.rgb * %s + %s, 0, 1);", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.fOutputColor, args.fOutputColor);
}
fragBuilder->codeAppendf("%s *= %s;\n", args.fOutputColor, args.fInputColor);
}
示例13: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(dfTexEffect);
const char* atlasSizeInvName;
fAtlasSizeInvUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
kFloat2_GrSLType,
kHigh_GrSLPrecision,
"AtlasSizeInv",
&atlasSizeInvName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
// Setup position
gpArgs->fPositionVar = dfTexEffect.inPosition()->asShaderVar();
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
dfTexEffect.inPosition()->asShaderVar(),
dfTexEffect.localMatrix(),
args.fFPCoordTransformHandler);
// set up varyings
GrGLSLVarying uv(kFloat2_GrSLType);
GrSLType texIdxType = args.fShaderCaps->integerSupport() ? kInt_GrSLType : kFloat_GrSLType;
GrGLSLVarying texIdx(texIdxType);
GrGLSLVarying st(kFloat2_GrSLType);
append_index_uv_varyings(args, dfTexEffect.inTextureCoords()->fName, atlasSizeInvName,
&uv, &texIdx, &st);
GrGLSLVarying delta(kFloat_GrSLType);
varyingHandler->addVarying("Delta", &delta);
if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
vertBuilder->codeAppendf("%s = -%s.x/3.0;", delta.vsOut(), atlasSizeInvName);
} else {
vertBuilder->codeAppendf("%s = %s.x/3.0;", delta.vsOut(), atlasSizeInvName);
}
// add frag shader code
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
bool isGammaCorrect =
SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag);
// create LCD offset adjusted by inverse of transform
// Use highp to work around aliasing issues
fragBuilder->codeAppendf("float2 uv = %s;\n", uv.fsIn());
if (isUniformScale) {
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half st_grad_len = abs(dFdx(%s.x));", st.fsIn());
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppendf("half st_grad_len = abs(dFdy(%s.y));", st.fsIn());
#endif
fragBuilder->codeAppendf("half2 offset = half2(st_grad_len*%s, 0.0);", delta.fsIn());
} else if (isSimilarity) {
// For a similarity matrix with rotation, the gradient will not be aligned
// with the texel coordinate axes, so we need to calculate it.
#ifdef SK_VULKAN
fragBuilder->codeAppendf("half2 st_grad = dFdx(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 offset = %s*st_grad;", delta.fsIn());
#else
// We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
// get the gradient in the x direction.
fragBuilder->codeAppendf("half2 st_grad = dFdy(%s);", st.fsIn());
fragBuilder->codeAppendf("half2 offset = %s*half2(st_grad.y, -st_grad.x);",
delta.fsIn());
#endif
fragBuilder->codeAppend("half st_grad_len = length(st_grad);");
} else {
fragBuilder->codeAppendf("half2 st = %s;\n", st.fsIn());
fragBuilder->codeAppend("half2 Jdx = dFdx(st);");
fragBuilder->codeAppend("half2 Jdy = dFdy(st);");
fragBuilder->codeAppendf("half2 offset = %s*Jdx;", delta.fsIn());
}
// sample the texture by index
fragBuilder->codeAppend("half4 texColor;");
append_multitexture_lookup(args, dfTexEffect.numTextureSamplers(),
texIdx, "uv", "texColor");
// green is distance to uv center
fragBuilder->codeAppend("half3 distance;");
fragBuilder->codeAppend("distance.y = texColor.r;");
// red is distance to left offset
//.........这里部分代码省略.........
示例14: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldA8TextGeoProc& dfTexEffect =
args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkAssertResult(fragBuilder->enableFeature(
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(dfTexEffect);
#ifdef SK_GAMMA_APPLY_TO_A8
// adjust based on gamma
const char* distanceAdjustUniName = nullptr;
// width, height, 1/(3*width)
fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"DistanceAdjust", &distanceAdjustUniName);
#endif
// Setup pass through color
if (!dfTexEffect.colorIgnored()) {
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
}
// Setup position
this->setupPosition(vertBuilder,
uniformHandler,
gpArgs,
dfTexEffect.inPosition()->fName,
dfTexEffect.viewMatrix(),
&fViewMatrixUniform);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
dfTexEffect.inPosition()->fName,
args.fTransformsIn,
args.fTransformsOut);
// add varyings
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
GrGLSLVertToFrag uv(kVec2f_GrSLType);
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);
// compute numbers to be hardcoded to convert texture coordinates from float to int
SkASSERT(dfTexEffect.numTextures() == 1);
GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
GrGLSLVertToFrag st(kVec2f_GrSLType);
varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(),
atlas->width(), atlas->height(),
dfTexEffect.inTextureCoords()->fName);
// Use highp to work around aliasing issues
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
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
fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
#endif
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 t coordinate in the y direction.
// We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
// this gives us a smooth step across approximately one fragment
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
st.fsIn());
} else if (isSimilarity) {
// For similarity transform, we adjust 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.
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
// this gives us a smooth step across approximately one fragment
fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st.fsIn());
//.........这里部分代码省略.........
示例15: onEmitCode
void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(gp);
GrGLSLVertToFrag v(kVec4f_GrSLType);
varyingHandler->addVarying("HairQuadEdge", &v);
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
// Setup position
this->setupPosition(vertBuilder,
uniformHandler,
gpArgs,
gp.inPosition()->fName,
gp.viewMatrix(),
&fViewMatrixUniform);
// emit transforms with position
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
gp.inPosition()->fName,
gp.localMatrix(),
args.fFPCoordTransformHandler);
fragBuilder->codeAppendf("float edgeAlpha;");
switch (fEdgeType) {
case kHairlineAA_GrProcessorEdgeType: {
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case kFillAA_GrProcessorEdgeType: {
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
" 2.0 * %s.x * duvdy.x - duvdy.y);",
v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
fragBuilder->codeAppend("edgeAlpha = clamp(0.5 - edgeAlpha, 0.0, 1.0);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
}
case kFillBW_GrProcessorEdgeType: {
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
break;
}
default:
SkFAIL("Shouldn't get here");
}
if (0xff != gp.coverageScale()) {
const char* coverageScale;
fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType,
kDefault_GrSLPrecision,
"Coverage",
&coverageScale);
fragBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
} else {
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
}