本文整理汇总了C++中GrGLSLUniformHandler类的典型用法代码示例。如果您正苦于以下问题:C++ GrGLSLUniformHandler类的具体用法?C++ GrGLSLUniformHandler怎么用?C++ GrGLSLUniformHandler使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了GrGLSLUniformHandler类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: onEmitCode
void onEmitCode(EmitArgs& args) override {
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
// add uniform
const char* xformUniName = nullptr;
fXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat22f_GrSLType,
kDefault_GrSLPrecision, "Xform", &xformUniName);
SkString dstNormalColorName("dstNormalColor");
this->emitChild(0, nullptr, &dstNormalColorName, args);
fragBuilder->codeAppendf("vec3 normal = normalize(%s.rgb - vec3(0.5));",
dstNormalColorName.c_str());
// If there's no x & y components, return (0, 0, +/- 1) instead to avoid division by 0
fragBuilder->codeAppend( "if (abs(normal.z) > 0.999) {");
fragBuilder->codeAppendf(" %s = normalize(vec4(0.0, 0.0, normal.z, 0.0));",
args.fOutputColor);
// Else, Normalizing the transformed X and Y, while keeping constant both Z and the
// vector's angle in the XY plane. This maintains the "slope" for the surface while
// appropriately rotating the normal regardless of any anisotropic scaling that occurs.
// Here, we call 'scaling factor' the number that must divide the transformed X and Y so
// that the normal's length remains equal to 1.
fragBuilder->codeAppend( "} else {");
fragBuilder->codeAppendf(" vec2 transformed = %s * normal.xy;",
xformUniName);
fragBuilder->codeAppend( " float scalingFactorSquared = "
"( (transformed.x * transformed.x) "
"+ (transformed.y * transformed.y) )"
"/(1.0 - (normal.z * normal.z));");
fragBuilder->codeAppendf(" %s = vec4(transformed*inversesqrt(scalingFactorSquared),"
"normal.z, 0.0);",
args.fOutputColor);
fragBuilder->codeAppend( "}");
}
示例2: emitCode
void emitCode(EmitArgs& args) override {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fMatrixHandle = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kMat44f_GrSLType, kDefault_GrSLPrecision,
"ColorMatrix");
fVectorHandle = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"ColorMatrixVector");
if (nullptr == args.fInputColor) {
// could optimize this case, but we aren't for now.
args.fInputColor = "vec4(1)";
}
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
// transparent black.
fragBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n",
args.fInputColor);
fragBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
args.fOutputColor,
uniformHandler->getUniformCStr(fMatrixHandle),
args.fInputColor,
uniformHandler->getUniformCStr(fVectorHandle));
fragBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n",
args.fOutputColor, args.fOutputColor);
fragBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
}
示例3: emitCode
void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
if (!args.fXP.willReadDstColor()) {
this->emitOutputsForBlendState(args);
return;
}
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
const char* dstColor = fragBuilder->dstColor();
if (args.fXP.getDstTexture()) {
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
if (args.fInputCoverage) {
// We don't think any shaders actually output negative coverage, but just as a safety
// check for floating point precision errors we compare with <= here
fragBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
" discard;"
"}", args.fInputCoverage);
}
const char* dstTopLeftName;
const char* dstCoordScaleName;
fDstTopLeftUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstTextureUpperLeft",
&dstTopLeftName);
fDstScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType,
kDefault_GrSLPrecision,
"DstTextureCoordScale",
&dstCoordScaleName);
const char* fragPos = fragBuilder->fragmentPosition();
fragBuilder->codeAppend("// Read color from copy of the destination.\n");
fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
fragPos, dstTopLeftName, dstCoordScaleName);
if (!topDown) {
fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
}
fragBuilder->codeAppendf("vec4 %s = ", dstColor);
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
fragBuilder->codeAppend(";");
}
this->emitBlendCodeForDstRead(fragBuilder,
uniformHandler,
args.fInputColor,
args.fInputCoverage,
dstColor,
args.fOutputPrimary,
args.fOutputSecondary,
args.fXP);
}
示例4: 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);
}
}
示例5: max
void GrColorCubeEffect::GLSLProcessor::emitCode(EmitArgs& args) {
if (nullptr == args.fInputColor) {
args.fInputColor = "vec4(1)";
}
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fColorCubeSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"Size");
const char* colorCubeSizeUni = uniformHandler->getUniformCStr(fColorCubeSizeUni);
fColorCubeInvSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"InvSize");
const char* colorCubeInvSizeUni = uniformHandler->getUniformCStr(fColorCubeInvSizeUni);
const char* nonZeroAlpha = "nonZeroAlpha";
const char* unPMColor = "unPMColor";
const char* cubeIdx = "cubeIdx";
const char* cCoords1 = "cCoords1";
const char* cCoords2 = "cCoords2";
// Note: if implemented using texture3D in OpenGL ES older than OpenGL ES 3.0,
// the shader might need "#extension GL_OES_texture_3D : enable".
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// Unpremultiply color
fragBuilder->codeAppendf("\tfloat %s = max(%s.a, 0.00001);\n", nonZeroAlpha, args.fInputColor);
fragBuilder->codeAppendf("\tvec4 %s = vec4(%s.rgb / %s, %s);\n",
unPMColor, args.fInputColor, nonZeroAlpha, nonZeroAlpha);
// Fit input color into the cube.
fragBuilder->codeAppendf(
"vec3 %s = vec3(%s.rg * vec2((%s - 1.0) * %s) + vec2(0.5 * %s), %s.b * (%s - 1.0));\n",
cubeIdx, unPMColor, colorCubeSizeUni, colorCubeInvSizeUni, colorCubeInvSizeUni,
unPMColor, colorCubeSizeUni);
// Compute y coord for for texture fetches.
fragBuilder->codeAppendf("vec2 %s = vec2(%s.r, (floor(%s.b) + %s.g) * %s);\n",
cCoords1, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
fragBuilder->codeAppendf("vec2 %s = vec2(%s.r, (ceil(%s.b) + %s.g) * %s);\n",
cCoords2, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
// Apply the cube.
fragBuilder->codeAppendf("%s = vec4(mix(", args.fOutputColor);
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords1);
fragBuilder->codeAppend(".bgr, ");
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords2);
// Premultiply color by alpha. Note that the input alpha is not modified by this shader.
fragBuilder->codeAppendf(".bgr, fract(%s.b)) * vec3(%s), %s.a);\n",
cubeIdx, nonZeroAlpha, args.fInputColor);
}
示例6: emitCode
void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fOffsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"Offset");
fInvZoomVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvZoom");
fInvInsetVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"InvInset");
fBoundsVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec4f_GrSLType, kDefault_GrSLPrecision,
"Bounds");
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
fragBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
uniformHandler->getUniformCStr(fOffsetVar),
coords2D.c_str(),
uniformHandler->getUniformCStr(fInvZoomVar));
const char* bounds = uniformHandler->getUniformCStr(fBoundsVar);
fragBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds);
fragBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n");
fragBuilder->codeAppendf("\t\tdelta = delta * %s;\n",
uniformHandler->getUniformCStr(fInvInsetVar));
fragBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
fragBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
fragBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
fragBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
fragBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
fragBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
fragBuilder->codeAppend("\t\t} else {\n");
fragBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
fragBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
fragBuilder->codeAppend("\t\t}\n");
fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
fragBuilder->codeAppend("\t\tvec4 output_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord");
fragBuilder->codeAppend(";\n");
fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
SkString modulate;
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
fragBuilder->codeAppend(modulate.c_str());
}
示例7: emitCode
void GrGLAlphaThresholdFragmentProcessor::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"inner_threshold");
fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kDefault_GrSLPrecision,
"outer_threshold");
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
fragBuilder->codeAppendf("vec2 coord = %s;", coords2D.c_str());
fragBuilder->codeAppendf("vec2 mask_coord = %s;", maskCoords2D.c_str());
fragBuilder->codeAppend("vec4 input_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord");
fragBuilder->codeAppend(";");
fragBuilder->codeAppend("vec4 mask_color = ");
fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord");
fragBuilder->codeAppend(";");
fragBuilder->codeAppendf("float inner_thresh = %s;",
uniformHandler->getUniformCStr(fInnerThresholdVar));
fragBuilder->codeAppendf("float outer_thresh = %s;",
uniformHandler->getUniformCStr(fOuterThresholdVar));
fragBuilder->codeAppend("float mask = mask_color.a;");
fragBuilder->codeAppend("vec4 color = input_color;");
fragBuilder->codeAppend("if (mask < 0.5) {"
"if (color.a > outer_thresh) {"
"float scale = outer_thresh / color.a;"
"color.rgb *= scale;"
"color.a = outer_thresh;"
"}"
"} else if (color.a < inner_thresh) {"
"float scale = inner_thresh / max(0.001, color.a);"
"color.rgb *= scale;"
"color.a = inner_thresh;"
"}");
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor,
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
}
示例8: 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());
}
示例9: onEmitCode
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const PLSFinishEffect& fe = args.fGP.cast<PLSFinishEffect>();
GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fUseEvenOdd = uniformHandler->addUniform(kFragment_GrShaderFlag,
kFloat_GrSLType, kLow_GrSLPrecision,
"useEvenOdd");
const char* useEvenOdd = uniformHandler->getUniformCStr(fUseEvenOdd);
varyingHandler->emitAttributes(fe);
this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName);
this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
fe.inPosition()->fName, fe.localMatrix(), args.fTransformsIn,
args.fTransformsOut);
GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
SkAssertResult(fsBuilder->enableFeature(
GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
fsBuilder->codeAppend("float coverage;");
fsBuilder->codeAppendf("if (%s != 0.0) {", useEvenOdd);
fsBuilder->codeAppend("coverage = float(abs(pls.windings[0]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[1]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[2]) % 2) * 0.25;");
fsBuilder->codeAppend("coverage += float(abs(pls.windings[3]) % 2) * 0.25;");
fsBuilder->codeAppend("} else {");
fsBuilder->codeAppend("coverage = pls.windings[0] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[1] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[2] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("coverage += pls.windings[3] != 0 ? 0.25 : 0.0;");
fsBuilder->codeAppend("}");
if (!fe.colorIgnored()) {
this->setupUniformColor(fsBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
}
fsBuilder->codeAppendf("%s = vec4(coverage);", args.fOutputCoverage);
fsBuilder->codeAppendf("%s = vec4(1.0, 0.0, 1.0, 1.0);", args.fOutputColor);
}
示例10: appendTextureLookup
void GrGLSLShaderBuilder::appendTextureLookup(SkString* out,
const GrGLSLTextureSampler& sampler,
const char* coordName,
GrSLType varyingType) const {
const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps();
GrGLSLUniformHandler* uniformHandler = fProgramBuilder->uniformHandler();
GrSLType samplerType = uniformHandler->getUniformVariable(sampler.fSamplerUniform).getType();
if (samplerType == kSampler2DRect_GrSLType) {
if (varyingType == kVec2f_GrSLType) {
out->appendf("%s(%s, textureSize(%s) * %s)",
GrGLSLTexture2DFunctionName(varyingType, samplerType,
glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
coordName);
} else {
out->appendf("%s(%s, vec3(textureSize(%s) * %s.xy, %s.z))",
GrGLSLTexture2DFunctionName(varyingType, samplerType,
glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
coordName,
coordName);
}
} else {
out->appendf("%s(%s, %s)",
GrGLSLTexture2DFunctionName(varyingType, samplerType, glslCaps->generation()),
uniformHandler->getUniformCStr(sampler.fSamplerUniform),
coordName);
}
// This refers to any swizzling we may need to get from some backend internal format to the
// format used in GrPixelConfig. If this is implemented by the GrGpu object, then swizzle will
// be rgba. For shader prettiness we omit the swizzle rather than appending ".rgba".
const GrSwizzle& configSwizzle = glslCaps->configTextureSwizzle(sampler.config());
if (configSwizzle != GrSwizzle::RGBA()) {
out->appendf(".%s", configSwizzle.c_str());
}
}
示例11: 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);
//.........这里部分代码省略.........
示例12: emitCode
void GLCircularRRectEffect::emitCode(EmitArgs& args) {
const CircularRRectEffect& crre = args.fFp.cast<CircularRRectEffect>();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
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 = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
"innerRect", &rectName);
// x is (r + .5) and y is 1/(r + .5)
fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
"radiusPlusHalf", &radiusPlusHalfName);
// If we're on a device where float != fp32 then the length calculation could overflow.
SkString clampedCircleDistance;
if (!args.fShaderCaps->floatIs32Bits()) {
clampedCircleDistance.printf("clamp(%s.x * (1.0 - length(dxy * %s.y)), 0.0, 1.0);",
radiusPlusHalfName, radiusPlusHalfName);
} else {
clampedCircleDistance.printf("clamp(%s.x - length(dxy), 0.0, 1.0);", radiusPlusHalfName);
}
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// 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("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
fragBuilder->codeAppendf("half alpha = %s;", clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
rectName);
fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(sk_FragCoord.x - %s.z, "
"%s.y - sk_FragCoord.y), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
rectName);
fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(%s.x - sk_FragCoord.x, "
"sk_FragCoord.y - %s.w), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kLeft_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
fragBuilder->codeAppendf("half alpha = rightAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTop_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
//.........这里部分代码省略.........
示例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: emitCode
void GrGLBicubicEffect::emitCode(EmitArgs& args) {
const GrTextureDomain& domain = args.fFp.cast<GrBicubicEffect>().domain();
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
fCoefficientsUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kMat44f_GrSLType, kDefault_GrSLPrecision,
"Coefficients");
fImageIncrementUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
kVec2f_GrSLType, kDefault_GrSLPrecision,
"ImageIncrement");
const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni);
const char* coeff = uniformHandler->getUniformCStr(fCoefficientsUni);
SkString cubicBlendName;
static const GrGLSLShaderVar gCubicBlendArgs[] = {
GrGLSLShaderVar("coefficients", kMat44f_GrSLType),
GrGLSLShaderVar("t", kFloat_GrSLType),
GrGLSLShaderVar("c0", kVec4f_GrSLType),
GrGLSLShaderVar("c1", kVec4f_GrSLType),
GrGLSLShaderVar("c2", kVec4f_GrSLType),
GrGLSLShaderVar("c3", kVec4f_GrSLType),
};
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
fragBuilder->emitFunction(kVec4f_GrSLType,
"cubicBlend",
SK_ARRAY_COUNT(gCubicBlendArgs),
gCubicBlendArgs,
"\tvec4 ts = vec4(1.0, t, t * t, t * t * t);\n"
"\tvec4 c = coefficients * ts;\n"
"\treturn c.x * c0 + c.y * c1 + c.z * c2 + c.w * c3;\n",
&cubicBlendName);
fragBuilder->codeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
// We unnormalize the coord in order to determine our fractional offset (f) within the texel
// We then snap coord to a texel center and renormalize. The snap prevents cases where the
// starting coords are near a texel boundary and accumulations of imgInc would cause us to skip/
// double hit a texel.
fragBuilder->codeAppendf("\tcoord /= %s;\n", imgInc);
fragBuilder->codeAppend("\tvec2 f = fract(coord);\n");
fragBuilder->codeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
fragBuilder->codeAppend("\tvec4 rowColors[4];\n");
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
SkString coord;
coord.printf("coord + %s * vec2(%d, %d)", imgInc, x - 1, y - 1);
SkString sampleVar;
sampleVar.printf("rowColors[%d]", x);
fDomain.sampleTexture(fragBuilder,
args.fUniformHandler,
args.fGLSLCaps,
domain,
sampleVar.c_str(),
coord,
args.fTexSamplers[0]);
}
fragBuilder->codeAppendf(
"\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n",
y, cubicBlendName.c_str(), coeff);
}
SkString bicubicColor;
bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff);
fragBuilder->codeAppendf("\t%s = %s;\n",
args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str()) *
GrGLSLExpr4(args.fInputColor)).c_str());
}