本文整理汇总了C++中GrGLSLFragmentBuilder::codeAppend方法的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLFragmentBuilder::codeAppend方法的具体用法?C++ GrGLSLFragmentBuilder::codeAppend怎么用?C++ GrGLSLFragmentBuilder::codeAppend使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrGLSLFragmentBuilder
的用法示例。
在下文中一共展示了GrGLSLFragmentBuilder::codeAppend方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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());
}
示例2: emitCode
void emitCode(EmitArgs& args) override {
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("vec2 c = %s;",
fragBuilder->ensureFSCoords2D(args.fCoords, 0).c_str());
fragBuilder->codeAppend("vec2 r = mod(c, vec2(20.0));");
fragBuilder->codeAppend("vec4 color = vec4(0.5*sin(c.x / 15.0) + 0.5,"
"0.5*cos((c.x + c.y) / 15.0) + 0.5,"
"(r.x + r.y) / 20.0,"
"distance(r, vec2(15.0)) / 20.0 + 0.2);");
fragBuilder->codeAppendf("color.rgb *= color.a;"
"%s = color * %s;",
args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
}
示例3: emitCode
virtual void emitCode(EmitArgs& args) override {
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("\t%s = ", args.fOutputColor);
fragBuilder->appendTextureLookupAndModulate(args.fInputColor,
args.fSamplers[0],
args.fCoords[0].c_str(),
args.fCoords[0].getType());
fragBuilder->codeAppend(";\n");
}
示例4: emitCode
void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
const GrConvexPolyEffect& cpe = args.fFp.cast<GrConvexPolyEffect>();
const char *edgeArrayName;
fEdgeUniform = args.fUniformHandler->addUniformArray(GrGLSLUniformHandler::kFragment_Visibility,
kVec3f_GrSLType,
kDefault_GrSLPrecision,
"edges",
cpe.getEdgeCount(),
&edgeArrayName);
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
fragBuilder->codeAppend("\t\tfloat edge;\n");
const char* fragmentPos = fragBuilder->fragmentPosition();
for (int i = 0; i < cpe.getEdgeCount(); ++i) {
fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
edgeArrayName, i, fragmentPos, fragmentPos);
if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
fragBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
} else {
fragBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
}
fragBuilder->codeAppend("\t\talpha *= edge;\n");
}
if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
fragBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
}
fragBuilder->codeAppendf("\t%s = %s;\n", args.fOutputColor,
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
}
示例5: 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);
}
示例6: emitCode
virtual void emitCode(EmitArgs& args) override {
const GrConfigConversionEffect& cce = args.fFp.cast<GrConfigConversionEffect>();
const GrSwizzle& swizzle = cce.swizzle();
GrConfigConversionEffect::PMConversion pmConversion = cce.pmConversion();
// Using highp for GLES here in order to avoid some precision issues on specific GPUs.
GrGLSLShaderVar tmpVar("tmpColor", kVec4f_GrSLType, 0, kHigh_GrSLPrecision);
SkString tmpDecl;
tmpVar.appendDecl(args.fGLSLCaps, &tmpDecl);
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("%s;", tmpDecl.c_str());
fragBuilder->codeAppendf("%s = ", tmpVar.c_str());
fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
args.fCoords[0].getType());
fragBuilder->codeAppend(";");
if (GrConfigConversionEffect::kNone_PMConversion == pmConversion) {
SkASSERT(GrSwizzle::RGBA() != swizzle);
fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
swizzle.c_str());
} else {
switch (pmConversion) {
case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
fragBuilder->codeAppendf(
"%s = vec4(ceil(%s.rgb * %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
break;
case GrConfigConversionEffect::kMulByAlpha_RoundDown_PMConversion:
// Add a compensation(0.001) here to avoid the side effect of the floor operation.
// In Intel GPUs, the integer value converted from floor(%s.r * 255.0) / 255.0
// is less than the integer value converted from %s.r by 1 when the %s.r is
// converted from the integer value 2^n, such as 1, 2, 4, 8, etc.
fragBuilder->codeAppendf(
"%s = vec4(floor(%s.rgb * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str());
break;
case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
fragBuilder->codeAppendf(
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
tmpVar.c_str());
break;
case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
fragBuilder->codeAppendf(
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.rgb / %s.a * 255.0) / 255.0, %s.a);",
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(),
tmpVar.c_str());
break;
default:
SkFAIL("Unknown conversion op.");
break;
}
fragBuilder->codeAppendf("%s = %s.%s;", args.fOutputColor, tmpVar.c_str(),
swizzle.c_str());
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}
示例7: 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);
GrGLSLFragmentBuilder* 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 = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
GrGLSLVertToFrag st(kVec2f_GrSLType);
varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
// compute numbers to be hardcoded to convert texture coordinates from int to float
SkASSERT(dfTexEffect.numTextures() == 1);
GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
SkScalar recipWidth = 1.0f / atlas->width();
SkScalar recipHeight = 1.0f / atlas->height();
GrGLSLVertToFrag uv(kVec2f_GrSLType);
varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
dfTexEffect.inTextureCoords()->fName);
// add frag shader code
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 dy = abs(dFdy(%s.y));", st.fsIn());
fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
} 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
fragBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
fragBuilder->codeAppend("\ttexColor = ");
fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
fragBuilder->codeAppend(";\n");
fragBuilder->codeAppend("\tdistance.x = texColor.r;\n");
// blue is distance to right offset
fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
//.........这里部分代码省略.........
示例8: emitCode
void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fOffsetVar = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Offset");
fInvZoomVar = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvZoom");
fInvInsetVar = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvInset");
fBoundsVar = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
GrGLSLFragmentBuilder* 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.fSamplers[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());
}
示例9: emitCode
void GrGLDisplacementMapEffect::emitCode(EmitArgs& args) {
const GrTextureDomain& domain = args.fFp.cast<GrDisplacementMapEffect>().domain();
fScaleUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision, "Scale");
const char* scaleUni = args.fBuilder->getUniformCStr(fScaleUni);
const char* dColor = "dColor";
const char* cCoords = "cCoords";
const char* nearZero = "1e-6"; // Since 6.10352e−5 is the smallest half float, use
// a number smaller than that to approximate 0, but
// leave room for 32-bit float GPU rounding errors.
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
args.fCoords[0].getType());
fragBuilder->codeAppend(";\n");
// Unpremultiply the displacement
fragBuilder->codeAppendf(
"\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb / %s.a, 0.0, 1.0);",
dColor, dColor, nearZero, dColor, dColor);
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
fragBuilder->codeAppendf("\t\tvec2 %s = %s + %s*(%s.",
cCoords, coords2D.c_str(), scaleUni, dColor);
switch (fXChannelSelector) {
case SkDisplacementMapEffect::kR_ChannelSelectorType:
fragBuilder->codeAppend("r");
break;
case SkDisplacementMapEffect::kG_ChannelSelectorType:
fragBuilder->codeAppend("g");
break;
case SkDisplacementMapEffect::kB_ChannelSelectorType:
fragBuilder->codeAppend("b");
break;
case SkDisplacementMapEffect::kA_ChannelSelectorType:
fragBuilder->codeAppend("a");
break;
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
default:
SkDEBUGFAIL("Unknown X channel selector");
}
switch (fYChannelSelector) {
case SkDisplacementMapEffect::kR_ChannelSelectorType:
fragBuilder->codeAppend("r");
break;
case SkDisplacementMapEffect::kG_ChannelSelectorType:
fragBuilder->codeAppend("g");
break;
case SkDisplacementMapEffect::kB_ChannelSelectorType:
fragBuilder->codeAppend("b");
break;
case SkDisplacementMapEffect::kA_ChannelSelectorType:
fragBuilder->codeAppend("a");
break;
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
default:
SkDEBUGFAIL("Unknown Y channel selector");
}
fragBuilder->codeAppend("-vec2(0.5));\t\t");
fGLDomain.sampleTexture(fragBuilder,
args.fGLSLCaps,
domain,
args.fOutputColor,
SkString(cCoords),
args.fSamplers[1]);
fragBuilder->codeAppend(";\n");
}
示例10: internalEmitChild
void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
const char* outputColor, EmitArgs& args) {
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
/*
* We now want to find the subset of coords and samplers that belong to the child and its
* descendants and put that into childCoords and childSamplers. To do so, we'll do a forwards
* linear search.
*
* Explanation:
* Each GrFragmentProcessor has a copy of all the transforms and textures of itself and
* all procs in its subtree. For example, suppose we have frag proc A, who has two children B
* and D. B has a child C, and D has two children E and F. Each frag proc's transforms array
* contains its own transforms, followed by the transforms of all its descendants (i.e. preorder
* traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms respectively.
*
* (A)
* [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2]
* / \
* / \
* (B) (D)
* [b1,b2,c1] [d1,e1,e2,e3,f1,f2]
* / / \
* / / \
* (C) (E) (F)
* [c1] [e1,e2,e3] [f1,f2]
*
* So if we're inside proc A's emitCode, and A is about to call emitCode on proc D, we want the
* EmitArgs that's passed onto D to only contain its and its descendants' coords. The
* EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want
* to extract the subset [d1,e1,e2,e3,f1,f2] to pass on to D. We can do this with a linear
* search since we know that A has 1 transform (using A.numTransformsExclChildren()), and B's
* subtree has 3 transforms (using B.numTransforms()), so we know the start of D's transforms is
* 4 after the start of A's transforms.
* Textures work the same way as transforms.
*/
int firstCoordAt = args.fFp.numTransformsExclChildren();
int firstSamplerAt = args.fFp.numTexturesExclChildren();
for (int i = 0; i < childIndex; ++i) {
firstCoordAt += args.fFp.childProcessor(i).numTransforms();
firstSamplerAt += args.fFp.childProcessor(i).numTextures();
}
GrGLSLTransformedCoordsArray childCoords;
TextureSamplerArray childSamplers;
if (childProc.numTransforms() > 0) {
childCoords.push_back_n(childProc.numTransforms(), &args.fCoords[firstCoordAt]);
}
if (childProc.numTextures() > 0) {
childSamplers.push_back_n(childProc.numTextures(), &args.fSamplers[firstSamplerAt]);
}
// emit the code for the child in its own scope
fragBuilder->codeAppend("{\n");
fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
fragBuilder->getMangleString().c_str(), childProc.name());
EmitArgs childArgs(args.fBuilder,
fragBuilder,
args.fGLSLCaps,
childProc,
outputColor,
inputColor,
childCoords,
childSamplers);
this->childProcessor(childIndex)->emitCode(childArgs);
fragBuilder->codeAppend("}\n");
fragBuilder->onAfterChildProcEmitCode();
}
示例11: 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),
};
GrGLSLFragmentBuilder* 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.fSamplers[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());
}
示例12: emitCode
void GrGLMorphologyEffect::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fPixelSizeUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision,
"PixelSize");
const char* pixelSizeInc = uniformHandler->getUniformCStr(fPixelSizeUni);
fRangeUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Range");
const char* range = uniformHandler->getUniformCStr(fRangeUni);
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
const char* func;
switch (fType) {
case GrMorphologyEffect::kErode_MorphologyType:
fragBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", args.fOutputColor);
func = "min";
break;
case GrMorphologyEffect::kDilate_MorphologyType:
fragBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
func = "max";
break;
default:
SkFAIL("Unexpected type");
func = ""; // suppress warning
break;
}
const char* dir;
switch (fDirection) {
case Gr1DKernelEffect::kX_Direction:
dir = "x";
break;
case Gr1DKernelEffect::kY_Direction:
dir = "y";
break;
default:
SkFAIL("Unknown filter direction.");
dir = ""; // suppress warning
}
// vec2 coord = coord2D;
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
// coord.x -= radius * pixelSize;
fragBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, fRadius, pixelSizeInc);
if (fUseRange) {
// highBound = min(highBound, coord.x + (width-1) * pixelSize);
fragBuilder->codeAppendf("\t\tfloat highBound = min(%s.y, coord.%s + %f * %s);",
range, dir, float(width() - 1), pixelSizeInc);
// coord.x = max(lowBound, coord.x);
fragBuilder->codeAppendf("\t\tcoord.%s = max(%s.x, coord.%s);", dir, range, dir);
}
fragBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", width());
fragBuilder->codeAppendf("\t\t\t%s = %s(%s, ", args.fOutputColor, func, args.fOutputColor);
fragBuilder->appendTextureLookup(args.fSamplers[0], "coord");
fragBuilder->codeAppend(");\n");
// coord.x += pixelSize;
fragBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc);
if (fUseRange) {
// coord.x = min(highBound, coord.x);
fragBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir, dir);
}
fragBuilder->codeAppend("\t\t}\n");
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}
示例13: emitCode
void GLCircularRRectEffect::emitCode(EmitArgs& args) {
const CircularRRectEffect& crre = args.fFp.cast<CircularRRectEffect>();
const char *rectName;
const char *radiusPlusHalfName;
// The inner rect is the rrect bounds inset by the radius. Its left, top, right, and bottom
// edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
// only rectangular corners, that side's value corresponds to the rect edge's value outset by
// half a pixel.
fInnerRectUniform = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"innerRect",
&rectName);
fRadiusPlusHalfUniform = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision,
"radiusPlusHalf",
&radiusPlusHalfName);
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
const char* fragmentPos = fragBuilder->fragmentPosition();
// At each quarter-circle corner we compute a vector that is the offset of the fragment position
// from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant
// to that corner. This means that points near the interior near the rrect top edge will have
// a vector that points straight up for both the TL left and TR corners. Computing an
// alpha from this vector at either the TR or TL corner will give the correct result. Similarly,
// fragments near the other three edges will get the correct AA. Fragments in the interior of
// the rrect will have a (0,0) vector at all four corners. So long as the radius > 0.5 they will
// correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas.
// The code below is a simplified version of the above that performs maxs on the vector
// components before computing distances and alpha values so that only one distance computation
// need be computed to determine the min alpha.
//
// For the cases where one half of the rrect is rectangular we drop one of the x or y
// computations, compute a separate rect edge alpha for the rect side, and mul the two computed
// alphas together.
switch (crre.getCircularCornerFlags()) {
case CircularRRectEffect::kAll_CornerFlags:
fragBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
fragBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
fragBuilder->codeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
fragBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf(
"\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTopRight_CornerFlag:
fragBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
fragmentPos, rectName, rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
fragmentPos, rectName);
fragBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf(
"\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
fragBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
fragmentPos, rectName);
fragBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
fragmentPos, rectName);
fragBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
fragmentPos, rectName);
fragBuilder->codeAppendf(
"\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
fragBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
rectName, fragmentPos, fragmentPos, rectName);
fragBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
fragmentPos, rectName);
fragBuilder->codeAppendf(
"\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kLeft_CornerFlags:
fragBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
fragBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
fragBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
rectName, fragmentPos);
fragBuilder->codeAppendf(
"\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
radiusPlusHalfName);
break;
case CircularRRectEffect::kTop_CornerFlags:
fragBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
fragBuilder->codeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
fragBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
//.........这里部分代码省略.........
示例14: emitCode
void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) {
const GrTextureDomain& domain = args.fFp.cast<GrMatrixConvolutionEffect>().domain();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
fKernelUni = uniformHandler->addUniformArray(GrGLSLUniformHandler::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision,
"Kernel",
fKernelSize.width() * fKernelSize.height());
fKernelOffsetUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"KernelOffset");
fGainUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision, "Gain");
fBiasUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kFloat_GrSLType, kDefault_GrSLPrecision, "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);
int kWidth = fKernelSize.width();
int kHeight = fKernelSize.height();
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);");
fragBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc);
fragBuilder->codeAppend("vec4 c;");
for (int y = 0; y < kHeight; y++) {
for (int x = 0; x < kWidth; x++) {
GrGLSLShaderBuilder::ShaderBlock block(fragBuilder);
fragBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, kWidth, x);
SkString coord;
coord.printf("coord + vec2(%d, %d) * %s", x, y, imgInc);
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fGLSLCaps,
domain,
"c",
coord,
args.fSamplers[0]);
if (!fConvolveAlpha) {
fragBuilder->codeAppend("c.rgb /= c.a;");
fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);");
}
fragBuilder->codeAppend("sum += c * k;");
}
}
if (fConvolveAlpha) {
fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
args.fOutputColor, args.fOutputColor, args.fOutputColor);
} else {
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fGLSLCaps,
domain,
"c",
coords2D,
args.fSamplers[0]);
fragBuilder->codeAppendf("%s.a = c.a;", args.fOutputColor);
fragBuilder->codeAppendf("%s.rgb = sum.rgb * %s + %s;", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.fOutputColor, args.fOutputColor);
}
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}