本文整理汇总了C++中GrGLSLFPFragmentBuilder::ensureCoords2D方法的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLFPFragmentBuilder::ensureCoords2D方法的具体用法?C++ GrGLSLFPFragmentBuilder::ensureCoords2D怎么用?C++ GrGLSLFPFragmentBuilder::ensureCoords2D使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrGLSLFPFragmentBuilder
的用法示例。
在下文中一共展示了GrGLSLFPFragmentBuilder::ensureCoords2D方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: emitCode
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrMagnifierEffect& _outer = args.fFp.cast<GrMagnifierEffect>();
(void)_outer;
auto bounds = _outer.bounds();
(void)bounds;
auto srcRect = _outer.srcRect();
(void)srcRect;
auto xInvZoom = _outer.xInvZoom();
(void)xInvZoom;
auto yInvZoom = _outer.yInvZoom();
(void)yInvZoom;
auto xInvInset = _outer.xInvInset();
(void)xInvInset;
auto yInvInset = _outer.yInvInset();
(void)yInvInset;
fBoundsUniformVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "boundsUniform");
fXInvZoomVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvZoom");
fYInvZoomVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvZoom");
fXInvInsetVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvInset");
fYInvInsetVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvInset");
fOffsetVar = args.fUniformHandler->addUniform(
kFragment_GrShaderFlag, kHalf2_GrSLType, kDefault_GrSLPrecision, "offset");
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
"float2 coord = %s;\nfloat2 zoom_coord = float2(%s + half2(coord * "
"float2(half2(half(%s), half(%s)))));\nfloat2 delta = (coord - %s.xy) * "
"%s.zw;\ndelta = min(delta, float2(half2(1.0, 1.0) - half2(delta)));\ndelta *= "
"float2(half2(half(%s), half(%s)));\nhalf weight = 0.0;\nif (delta.x < 2.0 && "
"delta.y < 2.0) {\n delta = float2(half2(2.0, 2.0) - half2(delta));\n half "
"dist = half(length(delta));\n dist = half(max(2.0 - float(dist), 0.0));\n "
"weight = half(min(float(dist * dist), 1.0));\n} else {\n ",
sk_TransformedCoords2D_0.c_str(),
args.fUniformHandler->getUniformCStr(fOffsetVar),
args.fUniformHandler->getUniformCStr(fXInvZoomVar),
args.fUniformHandler->getUniformCStr(fYInvZoomVar),
args.fUniformHandler->getUniformCStr(fBoundsUniformVar),
args.fUniformHandler->getUniformCStr(fBoundsUniformVar),
args.fUniformHandler->getUniformCStr(fXInvInsetVar),
args.fUniformHandler->getUniformCStr(fYInvInsetVar));
fragBuilder->codeAppendf(
"float2 delta_squared = delta * delta;\n weight = half(min(min(delta_squared.x, "
"delta_squared.y), 1.0));\n}\n%s = texture(%s, mix(coord, zoom_coord, "
"float(weight))).%s;\n",
args.fOutputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
}
示例2: emitCode
void emitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
const GrSimpleTextureEffect& _outer = args.fFp.cast<GrSimpleTextureEffect>();
(void)_outer;
auto matrix = _outer.matrix();
(void)matrix;
SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppendf(
"%s = %s * texture(%s, %s).%s;\n", args.fOutputColor,
args.fInputColor ? args.fInputColor : "half4(1)",
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
sk_TransformedCoords2D_0.c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
}
示例3: emitCode
void emitCode(EmitArgs& args) override {
const TwoPointConicalEffect& effect = args.fFp.cast<TwoPointConicalEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
this->emitUniforms(uniformHandler, effect);
fParamUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
"Conical2FSParams");
SkString p0; // r0 for radial case, r0^2 for strip case
p0.appendf("%s", uniformHandler->getUniformVariable(fParamUni).getName().c_str());
const char* tName = "t"; // the gradient
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
const char* p = coords2D.c_str();
if (effect.getType() == Type::kRadial) {
char sign = effect.diffRadius() < 0 ? '-' : '+';
fragBuilder->codeAppendf("half %s = %clength(%s) - %s;", tName, sign, p, p0.c_str());
} else {
// output will default to transparent black (we simply won't write anything
// else to it if invalid, instead of discarding or returning prematurely)
fragBuilder->codeAppendf("%s = half4(0.0,0.0,0.0,0.0);", args.fOutputColor);
fragBuilder->codeAppendf("half temp = %s - %s.y * %s.y;", p0.c_str(), p, p);
fragBuilder->codeAppendf("if (temp >= 0) {");
fragBuilder->codeAppendf("half %s = %s.x + sqrt(temp);", tName, p);
}
this->emitColor(fragBuilder,
uniformHandler,
args.fShaderCaps,
effect,
tName,
args.fOutputColor,
args.fInputColor,
args.fTexSamplers);
if (effect.getType() != Type::kRadial) {
fragBuilder->codeAppendf("}");
}
}
示例4: emitCode
void GrGLPerlinNoise::emitCode(EmitArgs& args) {
const GrPerlinNoiseEffect& pne = args.fFp.cast<GrPerlinNoiseEffect>();
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
SkString vCoords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"baseFrequency");
const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni);
const char* stitchDataUni = nullptr;
if (pne.stitchTiles()) {
fStitchDataUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"stitchData");
stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni);
}
// There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
const char* chanCoordR = "0.125";
const char* chanCoordG = "0.375";
const char* chanCoordB = "0.625";
const char* chanCoordA = "0.875";
const char* chanCoord = "chanCoord";
const char* stitchData = "stitchData";
const char* ratio = "ratio";
const char* noiseVec = "noiseVec";
const char* noiseSmooth = "noiseSmooth";
const char* floorVal = "floorVal";
const char* fractVal = "fractVal";
const char* uv = "uv";
const char* ab = "ab";
const char* latticeIdx = "latticeIdx";
const char* bcoords = "bcoords";
const char* lattice = "lattice";
const char* inc8bit = "0.00390625"; // 1.0 / 256.0
// This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
// [-1,1] vector and perform a dot product between that vector and the provided vector.
const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
// Add noise function
static const GrGLSLShaderVar gPerlinNoiseArgs[] = {
GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
GrGLSLShaderVar(noiseVec, kVec2f_GrSLType)
};
static const GrGLSLShaderVar gPerlinNoiseStitchArgs[] = {
GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
GrGLSLShaderVar(noiseVec, kVec2f_GrSLType),
GrGLSLShaderVar(stitchData, kVec2f_GrSLType)
};
SkString noiseCode;
noiseCode.appendf("\tvec4 %s;\n", floorVal);
noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec);
noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal);
noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec);
// smooth curve : t * t * (3 - 2 * t)
noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);",
noiseSmooth, fractVal, fractVal, fractVal);
// Adjust frequencies if we're stitching tiles
if (pne.stitchTiles()) {
noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
floorVal, stitchData, floorVal, stitchData);
noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
floorVal, stitchData, floorVal, stitchData);
noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
floorVal, stitchData, floorVal, stitchData);
noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
floorVal, stitchData, floorVal, stitchData);
}
// Get texture coordinates and normalize
noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n",
floorVal, floorVal);
// Get permutation for x
{
SkString xCoords("");
xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(),
kVec2f_GrSLType);
noiseCode.append(".r;");
}
// Get permutation for x + 1
{
SkString xCoords("");
xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
noiseCode.appendf("\n\t%s.y = ", latticeIdx);
fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(),
kVec2f_GrSLType);
//.........这里部分代码省略.........
示例5: emitCode
void GrGLConvolutionEffect::emitCode(EmitArgs& args) {
const GrConvolutionEffect& ce = args.fFp.cast<GrConvolutionEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
if (ce.useBounds()) {
fBoundsUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
}
int width = Gr1DKernelEffect::WidthFromRadius(ce.radius());
int arrayCount = (width + 3) / 4;
SkASSERT(4 * arrayCount >= width);
fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"Kernel", arrayCount);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[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.
const char* kVecSuffix[4] = { ".x", ".y", ".z", ".w" };
for (int i = 0; i < width; i++) {
SkString index;
SkString kernelIndex;
index.appendS32(i/4);
kernel.appendArrayAccess(index.c_str(), &kernelIndex);
kernelIndex.append(kVecSuffix[i & 0x3]);
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.fTexSamplers[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());
}
示例6: emitCode
void GrGLBicubicEffect::emitCode(EmitArgs& args) {
const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
fColorSpaceHelper.emitCode(uniformHandler, bicubicEffect.colorSpaceXform());
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
/*
* Filter weights come from Don Mitchell & Arun Netravali's 'Reconstruction Filters in Computer
* Graphics', ACM SIGGRAPH Computer Graphics 22, 4 (Aug. 1988).
* ACM DL: http://dl.acm.org/citation.cfm?id=378514
* Free : http://www.cs.utexas.edu/users/fussell/courses/cs384g/lectures/mitchell/Mitchell.pdf
*
* The authors define a family of cubic filters with two free parameters (B and C):
*
* { (12 - 9B - 6C)|x|^3 + (-18 + 12B + 6C)|x|^2 + (6 - 2B) if |x| < 1
* k(x) = 1/6 { (-B - 6C)|x|^3 + (6B + 30C)|x|^2 + (-12B - 48C)|x| + (8B + 24C) if 1 <= |x| < 2
* { 0 otherwise
*
* Various well-known cubic splines can be generated, and the authors select (1/3, 1/3) as their
* favorite overall spline - this is now commonly known as the Mitchell filter, and is the
* source of the specific weights below.
*
* This is GLSL, so the matrix is column-major (transposed from standard matrix notation).
*/
fragBuilder->codeAppend("mat4 kMitchellCoefficients = mat4("
" 1.0 / 18.0, 16.0 / 18.0, 1.0 / 18.0, 0.0 / 18.0,"
"-9.0 / 18.0, 0.0 / 18.0, 9.0 / 18.0, 0.0 / 18.0,"
"15.0 / 18.0, -36.0 / 18.0, 27.0 / 18.0, -6.0 / 18.0,"
"-7.0 / 18.0, 21.0 / 18.0, -21.0 / 18.0, 7.0 / 18.0);");
fragBuilder->codeAppendf("vec2 coord = %s - %s * vec2(0.5);", 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("coord /= %s;", imgInc);
fragBuilder->codeAppend("vec2 f = fract(coord);");
fragBuilder->codeAppendf("coord = (coord - f + vec2(0.5)) * %s;", imgInc);
fragBuilder->codeAppend("vec4 wx = kMitchellCoefficients * vec4(1.0, f.x, f.x * f.x, f.x * f.x * f.x);");
fragBuilder->codeAppend("vec4 wy = kMitchellCoefficients * vec4(1.0, f.y, f.y * f.y, f.y * f.y * f.y);");
fragBuilder->codeAppend("vec4 rowColors[4];");
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.fShaderCaps,
bicubicEffect.domain(),
sampleVar.c_str(),
coord,
args.fTexSamplers[0]);
}
fragBuilder->codeAppendf(
"vec4 s%d = wx.x * rowColors[0] + wx.y * rowColors[1] + wx.z * rowColors[2] + wx.w * rowColors[3];",
y);
}
SkString bicubicColor("(wy.x * s0 + wy.y * s1 + wy.z * s2 + wy.w * s3)");
if (fColorSpaceHelper.isValid()) {
SkString xformedColor;
fragBuilder->appendColorGamutXform(&xformedColor, bicubicColor.c_str(), &fColorSpaceHelper);
bicubicColor.swap(xformedColor);
}
fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, bicubicColor.c_str(),
args.fInputColor);
}
示例7: emitCode
void GrGLBicubicEffect::emitCode(EmitArgs& args) {
const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>();
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);
GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, bicubicEffect.colorSpaceXform(),
&fColorSpaceXformUni);
SkString cubicBlendName;
static const GrGLSLShaderVar gCubicBlendArgs[] = {
GrGLSLShaderVar("coefficients", kMat44f_GrSLType),
GrGLSLShaderVar("t", kFloat_GrSLType),
GrGLSLShaderVar("c0", kVec4f_GrSLType),
GrGLSLShaderVar("c1", kVec4f_GrSLType),
GrGLSLShaderVar("c2", kVec4f_GrSLType),
GrGLSLShaderVar("c3", kVec4f_GrSLType),
};
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[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,
bicubicEffect.domain(),
sampleVar.c_str(),
coord,
args.fTexSamplers[0]);
}
fragBuilder->codeAppendf(
"\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n",
y, cubicBlendName.c_str(), coeff);
}
SkString bicubicColor;
bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff);
if (colorSpaceHelper.getXformMatrix()) {
SkString xformedColor;
fragBuilder->appendColorGamutXform(&xformedColor, bicubicColor.c_str(), &colorSpaceHelper);
bicubicColor.swap(xformedColor);
}
fragBuilder->codeAppendf("\t%s = %s;\n",
args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str()) *
GrGLSLExpr4(args.fInputColor)).c_str());
}
示例8: emitCode
void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) {
const GrMatrixConvolutionEffect& mce = args.fFp.cast<GrMatrixConvolutionEffect>();
const GrTextureDomain& domain = mce.domain();
int kWidth = mce.kernelSize().width();
int kHeight = mce.kernelSize().height();
int arrayCount = (kWidth * kHeight + 3) / 4;
SkASSERT(4 * arrayCount >= kWidth * kHeight);
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"ImageIncrement");
fKernelUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag, kHalf4_GrSLType,
"Kernel",
arrayCount);
fKernelOffsetUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"KernelOffset");
fGainUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Gain");
fBiasUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "Bias");
const char* kernelOffset = uniformHandler->getUniformCStr(fKernelOffsetUni);
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
const char* kernel = uniformHandler->getUniformCStr(fKernelUni);
const char* gain = uniformHandler->getUniformCStr(fGainUni);
const char* bias = uniformHandler->getUniformCStr(fBiasUni);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
fragBuilder->codeAppend("half4 sum = half4(0, 0, 0, 0);");
fragBuilder->codeAppendf("float2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset, imgInc);
fragBuilder->codeAppend("half4 c;");
const char* kVecSuffix[4] = { ".x", ".y", ".z", ".w" };
for (int y = 0; y < kHeight; y++) {
for (int x = 0; x < kWidth; x++) {
GrGLSLShaderBuilder::ShaderBlock block(fragBuilder);
int offset = y*kWidth + x;
fragBuilder->codeAppendf("half k = %s[%d]%s;", kernel, offset / 4,
kVecSuffix[offset & 0x3]);
SkString coord;
coord.printf("coord + half2(%d, %d) * %s", x, y, imgInc);
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fShaderCaps,
domain,
"c",
coord,
args.fTexSamplers[0]);
if (!mce.convolveAlpha()) {
fragBuilder->codeAppend("c.rgb /= c.a;");
fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);");
}
fragBuilder->codeAppend("sum += c * k;");
}
}
if (mce.convolveAlpha()) {
fragBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.a = clamp(%s.a, 0, 1);", args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
args.fOutputColor, args.fOutputColor, args.fOutputColor);
} else {
fDomain.sampleTexture(fragBuilder,
uniformHandler,
args.fShaderCaps,
domain,
"c",
coords2D,
args.fTexSamplers[0]);
fragBuilder->codeAppendf("%s.a = c.a;", args.fOutputColor);
fragBuilder->codeAppendf("%s.rgb = clamp(sum.rgb * %s + %s, 0, 1);", args.fOutputColor, gain, bias);
fragBuilder->codeAppendf("%s.rgb *= %s.a;", args.fOutputColor, args.fOutputColor);
}
fragBuilder->codeAppendf("%s *= %s;\n", args.fOutputColor, args.fInputColor);
}
示例9: emitCode
void GrGLMorphologyEffect::emitCode(EmitArgs& args) {
const GrMorphologyEffect& me = args.fFp.cast<GrMorphologyEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fPixelSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "PixelSize");
const char* pixelSizeInc = uniformHandler->getUniformCStr(fPixelSizeUni);
fRangeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat2_GrSLType, "Range");
const char* range = uniformHandler->getUniformCStr(fRangeUni);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
const char* func;
switch (me.type()) {
case GrMorphologyEffect::Type::kErode:
fragBuilder->codeAppendf("\t\t%s = half4(1, 1, 1, 1);\n", args.fOutputColor);
func = "min";
break;
case GrMorphologyEffect::Type::kDilate:
fragBuilder->codeAppendf("\t\t%s = half4(0, 0, 0, 0);\n", args.fOutputColor);
func = "max";
break;
default:
SK_ABORT("Unexpected type");
func = ""; // suppress warning
break;
}
const char* dir;
switch (me.direction()) {
case GrMorphologyEffect::Direction::kX:
dir = "x";
break;
case GrMorphologyEffect::Direction::kY:
dir = "y";
break;
default:
SK_ABORT("Unknown filter direction.");
dir = ""; // suppress warning
}
int width = me.width();
// float2 coord = coord2D;
fragBuilder->codeAppendf("\t\tfloat2 coord = %s;\n", coords2D.c_str());
// coord.x -= radius * pixelSize;
fragBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, me.radius(), pixelSizeInc);
if (me.useRange()) {
// 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.fTexSamplers[0], "coord");
fragBuilder->codeAppend(");\n");
// coord.x += pixelSize;
fragBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc);
if (me.useRange()) {
// coord.x = min(highBound, coord.x);
fragBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir, dir);
}
fragBuilder->codeAppend("\t\t}\n");
fragBuilder->codeAppendf("%s *= %s;\n", args.fOutputColor, args.fInputColor);
}