本文整理汇总了C++中GrGLSLPPFragmentBuilder::codeAppend方法的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLPPFragmentBuilder::codeAppend方法的具体用法?C++ GrGLSLPPFragmentBuilder::codeAppend怎么用?C++ GrGLSLPPFragmentBuilder::codeAppend使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrGLSLPPFragmentBuilder
的用法示例。
在下文中一共展示了GrGLSLPPFragmentBuilder::codeAppend方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const GrRRectShadowGeoProc& rsgp = args.fGP.cast<GrRRectShadowGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// emit attributes
varyingHandler->emitAttributes(rsgp);
fragBuilder->codeAppend("vec4 shadowParams;");
varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
// setup pass through color
varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
// Setup position
this->setupPosition(vertBuilder, gpArgs, rsgp.inPosition()->fName);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
rsgp.inPosition()->fName,
args.fFPCoordTransformHandler);
fragBuilder->codeAppend("float d = length(shadowParams.xy);");
fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);");
fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
fragBuilder->codeAppendf("%s = vec4(factor);",
args.fOutputCoverage);
}
示例2: 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);
GrGLSLPPFragmentBuilder* 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);
}
示例3: 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);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// 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);
// set up varyings
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
GrGLSLVertToFrag uv(kVec2f_GrSLType);
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);
// add frag shader code
SkAssertResult(fragBuilder->enableFeature(
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
// create LCD offset adjusted by inverse of transform
// 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(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
kHigh_GrSLPrecision));
SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
} else {
fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
}
if (isUniformScale) {
fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.fsIn());
fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0);");
} 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.
// We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
// get the gradient in the x direction.
fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn());
fragBuilder->codeAppend("float st_grad_len = length(st_grad);");
fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_grad.x);");
} else {
fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
}
// green is distance to uv center
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
//.........这里部分代码省略.........
示例4: 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);
}
}
示例5: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(cte);
// compute numbers to be hardcoded to convert texture coordinates from int to float
SkASSERT(cte.numTextures() == 1);
SkDEBUGCODE(GrTexture* atlas = cte.textureAccess(0).getTexture());
SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
GrGLSLVertToFrag v(kVec2f_GrSLType);
varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", v.vsOut(),
cte.inTextureCoords()->fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
if (!cte.colorIgnored()) {
if (cte.hasVertexColor()) {
varyingHandler->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
}
// Setup position
this->setupPosition(vertBuilder, gpArgs, cte.inPosition()->fName);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
cte.inPosition()->fName,
cte.localMatrix(),
args.fTransformsIn,
args.fTransformsOut);
if (cte.maskFormat() == kARGB_GrMaskFormat) {
fragBuilder->codeAppendf("%s = ", args.fOutputColor);
fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
args.fTexSamplers[0],
v.fsIn(),
kVec2f_GrSLType);
fragBuilder->codeAppend(";");
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
} else {
fragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
fragBuilder->appendTextureLookup(args.fTexSamplers[0], v.fsIn(), kVec2f_GrSLType);
fragBuilder->codeAppend(";");
if (cte.maskFormat() == kA565_GrMaskFormat) {
// set alpha to be max of rgb coverage
fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
args.fOutputCoverage, args.fOutputCoverage,
args.fOutputCoverage, args.fOutputCoverage);
}
}
}
示例6: onEmitCode
void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
using InstanceAttribs = GrCCPRPathProcessor::InstanceAttribs;
const GrCCPRPathProcessor& proc = args.fGP.cast<GrCCPRPathProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
const char* atlasAdjust;
fAtlasAdjustUniform = uniHandler->addUniform(
kVertex_GrShaderFlag,
kVec2f_GrSLType, kHigh_GrSLPrecision, "atlas_adjust", &atlasAdjust);
varyingHandler->emitAttributes(proc);
GrGLSLVertToFrag texcoord(kVec2f_GrSLType);
GrGLSLVertToFrag color(kVec4f_GrSLType);
varyingHandler->addVarying("texcoord", &texcoord, kHigh_GrSLPrecision);
varyingHandler->addFlatPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor),
args.fOutputColor, kLow_GrSLPrecision);
// Vertex shader.
GrGLSLVertexBuilder* v = args.fVertBuilder;
// Find the intersections of (bloated) devBounds and devBounds45 in order to come up with an
// octagon that circumscribes the (bloated) path. A vertex is the intersection of two lines:
// one edge from the path's bounding box and one edge from its 45-degree bounding box.
v->codeAppendf("highp mat2 N = mat2(%s);", proc.getEdgeNormsAttrib().fName);
// N[0] is the normal for the edge we are intersecting from the regular bounding box, pointing
// out of the octagon.
v->codeAppendf("highp vec2 refpt = (min(N[0].x, N[0].y) < 0) ? %s.xy : %s.zw;",
proc.getInstanceAttrib(InstanceAttribs::kDevBounds).fName,
proc.getInstanceAttrib(InstanceAttribs::kDevBounds).fName);
v->codeAppendf("refpt += N[0] * %f;", kAABloatRadius); // bloat for AA.
// N[1] is the normal for the edge we are intersecting from the 45-degree bounding box, pointing
// out of the octagon.
v->codeAppendf("highp vec2 refpt45 = (N[1].x < 0) ? %s.xy : %s.zw;",
proc.getInstanceAttrib(InstanceAttribs::kDevBounds45).fName,
proc.getInstanceAttrib(InstanceAttribs::kDevBounds45).fName);
v->codeAppendf("refpt45 *= mat2(.5,.5,-.5,.5);"); // transform back to device space.
v->codeAppendf("refpt45 += N[1] * %f;", kAABloatRadius); // bloat for AA.
v->codeAppend ("highp vec2 K = vec2(dot(N[0], refpt), dot(N[1], refpt45));");
v->codeAppendf("highp vec2 octocoord = K * inverse(N);");
gpArgs->fPositionVar.set(kVec2f_GrSLType, "octocoord");
// Convert to atlas coordinates in order to do our texture lookup.
v->codeAppendf("highp vec2 atlascoord = octocoord + vec2(%s);",
proc.getInstanceAttrib(InstanceAttribs::kAtlasOffset).fName);
if (kTopLeft_GrSurfaceOrigin == proc.atlas()->origin()) {
v->codeAppendf("%s = atlascoord * %s;", texcoord.vsOut(), atlasAdjust);
} else {
SkASSERT(kBottomLeft_GrSurfaceOrigin == proc.atlas()->origin());
v->codeAppendf("%s = vec2(atlascoord.x * %s.x, 1 - atlascoord.y * %s.y);",
texcoord.vsOut(), atlasAdjust, atlasAdjust);
}
// Convert to (local) path cordinates.
v->codeAppendf("highp vec2 pathcoord = inverse(mat2(%s)) * (octocoord - %s);",
proc.getInstanceAttrib(InstanceAttribs::kViewMatrix).fName,
proc.getInstanceAttrib(InstanceAttribs::kViewTranslate).fName);
this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, "pathcoord",
args.fFPCoordTransformHandler);
// Fragment shader.
GrGLSLPPFragmentBuilder* f = args.fFragBuilder;
f->codeAppend ("mediump float coverage_count = ");
f->appendTextureLookup(args.fTexSamplers[0], texcoord.fsIn(), kVec2f_GrSLType);
f->codeAppend (".a;");
if (SkPath::kWinding_FillType == proc.fillType()) {
f->codeAppendf("%s = vec4(min(abs(coverage_count), 1));", args.fOutputCoverage);
} else {
SkASSERT(SkPath::kEvenOdd_FillType == proc.fillType());
f->codeAppend ("mediump float t = mod(abs(coverage_count), 2);");
f->codeAppendf("%s = vec4(1 - abs(t - 1));", args.fOutputCoverage);
}
}
示例7: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
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);
GrGLSLVertToFrag v(kVec2f_GrSLType);
varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
// setup pass through color
if (!dfTexEffect.colorIgnored()) {
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
}
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
// 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.fFPCoordTransformHandler);
const char* textureSizeUniName = nullptr;
fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"TextureSize", &textureSizeUniName);
// Use highp to work around aliasing issues
fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
fragBuilder->codeAppend("float texColor = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0],
"uv",
kVec2f_GrSLType);
fragBuilder->codeAppend(".r;");
fragBuilder->codeAppend("float distance = "
SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
fragBuilder->codeAppend("float afwidth;");
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
bool isGammaCorrect =
SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectFlag);
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.
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));");
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
#endif
} 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.
// this gives us a smooth step across approximately one fragment
#ifdef SK_VULKAN
fragBuilder->codeAppend("float st_grad_len = length(dFdx(st));");
#else
// We use the y gradient because there is a bug in the Mali 400 in the x direction.
fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));");
#endif
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
} 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.
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
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 {");
//.........这里部分代码省略.........
示例8: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
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);
GrGLSLVertToFrag v(kVec2f_GrSLType);
varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
// setup pass through color
if (!dfTexEffect.colorIgnored()) {
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
}
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
// 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);
const char* textureSizeUniName = nullptr;
fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"TextureSize", &textureSizeUniName);
// Use highp to work around aliasing issues
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
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 ");");
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
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
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.
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
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
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
}
fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}