本文整理汇总了C++中GrGLSLVaryingHandler类的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLVaryingHandler类的具体用法?C++ GrGLSLVaryingHandler怎么用?C++ GrGLSLVaryingHandler使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了GrGLSLVaryingHandler类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const MSAAQuadProcessor& qp = args.fGP.cast<MSAAQuadProcessor>();
GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(qp);
varyingHandler->addPassThroughAttribute(qp.inColor(), args.fOutputColor);
GrGLSLVertToFrag uv(kVec2f_GrSLType);
varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qp.inUV()->fName);
// Setup position
this->setupPosition(vsBuilder, uniformHandler, gpArgs, qp.inPosition()->fName,
qp.viewMatrix(), &fViewMatrixUniform);
// emit transforms
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
qp.inPosition()->fName, SkMatrix::I(), args.fTransformsIn,
args.fTransformsOut);
GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn(), uv.fsIn(),
uv.fsIn());
fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputCoverage);
}
示例2: 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);
}
示例3: 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);
}
}
示例4: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(qe);
GrGLSLVertToFrag v(kVec4f_GrSLType);
varyingHandler->addVarying("QuadEdge", &v);
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Setup pass through color
if (!qe.colorIgnored()) {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
// Setup position
this->setupPosition(vertBuilder, gpArgs, qe.inPosition()->fName);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
qe.inPosition()->fName,
qe.localMatrix(),
args.fTransformsIn,
args.fTransformsOut);
SkAssertResult(fragBuilder->enableFeature(
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
fragBuilder->codeAppendf("float edgeAlpha;");
// keep the derivative instructions outside the conditional
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
fragBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
// today we know z and w are in device space. We could use derivatives
fragBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),
v.fsIn());
fragBuilder->codeAppendf ("} else {");
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->codeAppendf("edgeAlpha = "
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
}
示例5: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
const GrPipelineDynamicStateTestProcessor& mp =
args.fGP.cast<GrPipelineDynamicStateTestProcessor>();
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
varyingHandler->emitAttributes(mp);
varyingHandler->addPassThroughAttribute(&mp.fColor, args.fOutputColor);
GrGLSLVertexBuilder* v = args.fVertBuilder;
v->codeAppendf("vec2 vertex = %s;", mp.fVertex.fName);
gpArgs->fPositionVar.set(kVec2f_GrSLType, "vertex");
GrGLSLPPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
}
示例6: 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);
}
示例7: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(gp);
// Setup pass through color
if (!gp.colorIgnored()) {
if (gp.hasVertexColor()) {
varyingHandler->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
}
// Setup position
this->setupPosition(vertBuilder,
uniformHandler,
gpArgs,
gp.inPosition()->fName,
gp.viewMatrix(),
&fViewMatrixUniform);
if (gp.hasExplicitLocalCoords()) {
// emit transforms with explicit local coords
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
gp.inLocalCoords()->fName,
gp.localMatrix(),
args.fTransformsIn,
args.fTransformsOut);
} else if(gp.hasTransformedLocalCoords()) {
// transforms have already been applied to vertex attributes on the cpu
this->emitTransforms(vertBuilder,
varyingHandler,
gp.inLocalCoords()->fName,
args.fTransformsIn,
args.fTransformsOut);
} else {
// emit transforms with position
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gpArgs->fPositionVar,
gp.inPosition()->fName,
gp.localMatrix(),
args.fTransformsIn,
args.fTransformsOut);
}
// Setup coverage as pass through
if (!gp.coverageWillBeIgnored()) {
if (gp.hasVertexCoverage()) {
fragBuilder->codeAppendf("float alpha = 1.0;");
varyingHandler->addPassThroughAttribute(gp.inCoverage(), "alpha");
fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
} else if (gp.coverage() == 0xff) {
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
} else {
const char* fragCoverage;
fCoverageUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType,
kDefault_GrSLPrecision,
"Coverage",
&fragCoverage);
fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage);
}
}
}
示例8: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const auto& proc = args.fGP.cast<Processor>();
bool useHWDerivatives = (proc.fFlags & Flags::kUseHWDerivatives);
bool hasPerspective = (proc.fFlags & Flags::kHasPerspective);
bool hasLocalCoords = (proc.fFlags & Flags::kHasLocalCoords);
SkASSERT(useHWDerivatives == hasPerspective);
SkASSERT(proc.vertexStride() == sizeof(MSAAVertex));
// Emit the vertex shader.
GrGLSLVertexBuilder* v = args.fVertBuilder;
GrGLSLVaryingHandler* varyings = args.fVaryingHandler;
varyings->emitAttributes(proc);
varyings->addPassThroughAttribute(*proc.fColorAttrib, args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// Unpack vertex attribs.
v->codeAppendf("float2 corner = corner_and_radius_outsets.xy;");
v->codeAppendf("float2 radius_outset = corner_and_radius_outsets.zw;");
// Identify our radii.
v->codeAppend("float2 radii;");
v->codeAppend("radii.x = dot(radii_selector, radii_x);");
v->codeAppend("radii.y = dot(radii_selector, radii_y);");
v->codeAppendf("bool is_arc_section = (radii.x > 0);");
v->codeAppendf("radii = abs(radii);");
// Find our vertex position, adjusted for radii. Our rect is drawn in normalized
// [-1,-1,+1,+1] space.
v->codeAppend("float2 vertexpos = corner + radius_outset * radii;");
// Emit transforms.
GrShaderVar localCoord("", kFloat2_GrSLType);
if (hasLocalCoords) {
v->codeAppend("float2 localcoord = (local_rect.xy * (1 - vertexpos) + "
"local_rect.zw * (1 + vertexpos)) * .5;");
localCoord.set(kFloat2_GrSLType, "localcoord");
}
this->emitTransforms(v, varyings, args.fUniformHandler, localCoord,
args.fFPCoordTransformHandler);
// Transform to device space.
if (!hasPerspective) {
v->codeAppend("float2x2 skewmatrix = float2x2(skew.xy, skew.zw);");
v->codeAppend("float2 devcoord = vertexpos * skewmatrix + translate;");
gpArgs->fPositionVar.set(kFloat2_GrSLType, "devcoord");
} else {
v->codeAppend("float3x3 persp_matrix = float3x3(persp_x, persp_y, persp_z);");
v->codeAppend("float3 devcoord = float3(vertexpos, 1) * persp_matrix;");
gpArgs->fPositionVar.set(kFloat3_GrSLType, "devcoord");
}
// Determine normalized arc coordinates for the implicit function.
GrGLSLVarying arcCoord((useHWDerivatives) ? kFloat2_GrSLType : kFloat4_GrSLType);
varyings->addVarying("arccoord", &arcCoord);
v->codeAppendf("if (is_arc_section) {");
v->codeAppendf( "%s.xy = 1 - abs(radius_outset);", arcCoord.vsOut());
if (!useHWDerivatives) {
// The gradient is order-1: Interpolate it across arccoord.zw.
// This doesn't work with perspective.
SkASSERT(!hasPerspective);
v->codeAppendf("float2x2 derivatives = inverse(skewmatrix);");
v->codeAppendf("%s.zw = derivatives * (%s.xy/radii * corner * 2);",
arcCoord.vsOut(), arcCoord.vsOut());
}
v->codeAppendf("} else {");
if (useHWDerivatives) {
v->codeAppendf("%s = float2(0);", arcCoord.vsOut());
} else {
v->codeAppendf("%s = float4(0);", arcCoord.vsOut());
}
v->codeAppendf("}");
// Emit the fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
f->codeAppendf("%s = half4(1);", args.fOutputCoverage);
// If x,y == 0, then we are drawing a triangle that does not track an arc.
f->codeAppendf("if (float2(0) != %s.xy) {", arcCoord.fsIn());
f->codeAppendf( "float fn = dot(%s.xy, %s.xy) - 1;", arcCoord.fsIn(), arcCoord.fsIn());
if (GrAAType::kMSAA == proc.fAAType) {
using ScopeFlags = GrGLSLFPFragmentBuilder::ScopeFlags;
if (!useHWDerivatives) {
f->codeAppendf("float2 grad = %s.zw;", arcCoord.fsIn());
f->applyFnToMultisampleMask("fn", "grad", ScopeFlags::kInsidePerPrimitiveBranch);
} else {
f->applyFnToMultisampleMask("fn", nullptr, ScopeFlags::kInsidePerPrimitiveBranch);
}
} else {
f->codeAppendf("if (fn > 0) {");
f->codeAppendf( "%s = half4(0);", args.fOutputCoverage);
f->codeAppendf("}");
}
f->codeAppendf("}");
}
示例9: 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);
GrGLSLVertToFrag v(kVec4f_GrSLType);
varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
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);
// 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 dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
GrShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
fragBuilder->declAppend(edgeAlpha);
fragBuilder->declAppend(dklmdx);
fragBuilder->declAppend(dklmdy);
fragBuilder->declAppend(dfdx);
fragBuilder->declAppend(dfdy);
fragBuilder->declAppend(gF);
fragBuilder->declAppend(gFM);
fragBuilder->declAppend(func);
switch (fEdgeType) {
case kHairlineAA_GrProcessorEdgeType: {
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
gFM.c_str(), gF.c_str(), gF.c_str());
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 / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.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 = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
fragBuilder->codeAppendf("%s ="
"3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
gFM.c_str(), gF.c_str(), gF.c_str());
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 / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
//.........这里部分代码省略.........
示例10: 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());
//.........这里部分代码省略.........
示例11: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(gp);
// Setup pass through color
if (gp.hasVertexColor()) {
GrGLSLVarying varying(kHalf4_GrSLType);
varyingHandler->addVarying("color", &varying);
// There are several optional steps to process the color. Start with the attribute:
vertBuilder->codeAppendf("half4 color = %s;", gp.inColor()->fName);
// Linearize
if (gp.linearizeColor()) {
SkString srgbFuncName;
static const GrShaderVar gSrgbArgs[] = {
GrShaderVar("x", kHalf_GrSLType),
};
vertBuilder->emitFunction(kHalf_GrSLType,
"srgb_to_linear",
SK_ARRAY_COUNT(gSrgbArgs),
gSrgbArgs,
"return (x <= 0.04045) ? (x / 12.92) "
": pow((x + 0.055) / 1.055, 2.4);",
&srgbFuncName);
vertBuilder->codeAppendf("color = half4(%s(%s.r), %s(%s.g), %s(%s.b), %s.a);",
srgbFuncName.c_str(), gp.inColor()->fName,
srgbFuncName.c_str(), gp.inColor()->fName,
srgbFuncName.c_str(), gp.inColor()->fName,
gp.inColor()->fName);
}
// For SkColor, do a red/blue swap and premul
if (gp.fFlags & kColorAttributeIsSkColor_GPFlag) {
vertBuilder->codeAppend("color = half4(color.a * color.bgr, color.a);");
}
// Do color-correction to destination gamut
if (gp.linearizeColor()) {
fColorSpaceHelper.emitCode(uniformHandler, gp.fColorSpaceXform.get(),
kVertex_GrShaderFlag);
if (fColorSpaceHelper.isValid()) {
SkString xformedColor;
vertBuilder->appendColorGamutXform(&xformedColor, "color",
&fColorSpaceHelper);
vertBuilder->codeAppendf("color = %s;", xformedColor.c_str());
}
}
vertBuilder->codeAppendf("%s = color;\n", varying.vsOut());
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
// Setup position
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
gp.inPosition()->fName,
gp.viewMatrix(),
&fViewMatrixUniform);
if (gp.hasExplicitLocalCoords()) {
// emit transforms with explicit local coords
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gp.inLocalCoords()->asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
} else {
// emit transforms with position
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
gp.inPosition()->asShaderVar(),
gp.localMatrix(),
args.fFPCoordTransformHandler);
}
// Setup coverage as pass through
if (gp.hasVertexCoverage()) {
fragBuilder->codeAppendf("half alpha = 1.0;");
varyingHandler->addPassThroughAttribute(gp.inCoverage(), "alpha");
fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
} else if (gp.coverage() == 0xff) {
fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
} else {
const char* fragCoverage;
fCoverageUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
kHalf_GrSLType,
"Coverage",
&fragCoverage);
//.........这里部分代码省略.........
示例12: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldPathGeoProc& dfPathEffect =
args.fGP.cast<GrDistanceFieldPathGeoProc>();
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// emit attributes
varyingHandler->emitAttributes(dfPathEffect);
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);
GrGLSLVarying st(kFloat2_GrSLType);
append_index_uv_varyings(args, dfPathEffect.inTextureCoords()->fName, atlasSizeInvName, &uv,
&texIdx, &st);
// setup pass through color
varyingHandler->addPassThroughAttribute(dfPathEffect.inColor(), args.fOutputColor);
if (dfPathEffect.matrix().hasPerspective()) {
// Setup position
this->writeOutputPosition(vertBuilder,
uniformHandler,
gpArgs,
dfPathEffect.inPosition()->fName,
dfPathEffect.matrix(),
&fMatrixUniform);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
dfPathEffect.inPosition()->asShaderVar(),
args.fFPCoordTransformHandler);
} else {
// Setup position
this->writeOutputPosition(vertBuilder, gpArgs, dfPathEffect.inPosition()->fName);
// emit transforms
this->emitTransforms(vertBuilder,
varyingHandler,
uniformHandler,
dfPathEffect.inPosition()->asShaderVar(),
dfPathEffect.matrix(),
args.fFPCoordTransformHandler);
}
// Use highp to work around aliasing issues
fragBuilder->codeAppendf("float2 uv = %s;", uv.fsIn());
fragBuilder->codeAppend("half4 texColor;");
append_multitexture_lookup(args, dfPathEffect.numTextureSamplers(), texIdx, "uv",
"texColor");
fragBuilder->codeAppend("half distance = "
SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ");");
fragBuilder->codeAppend("half afwidth;");
bool isUniformScale = (dfPathEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfPathEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
bool isGammaCorrect =
SkToBool(dfPathEffect.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->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*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("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
st.fsIn());
#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->codeAppendf("half st_grad_len = length(dFdx(%s));", 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 = length(dFdy(%s));", st.fsIn());
#endif
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
//.........这里部分代码省略.........
示例13: 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 {");
//.........这里部分代码省略.........
示例14: 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;",
//.........这里部分代码省略.........
示例15: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
GrGLSLFragmentBuilder* 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(GrGLSLUniformHandler::kFragment_Visibility,
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);
}