Add ShaderBuilders to EmitArgs and remove gettings from ProgBuilder.
BUG=skia: Review URL: https://codereview.chromium.org/1457543003
This commit is contained in:
parent
accaf480c3
commit
4ca2e60343
@ -757,7 +757,7 @@ GrGLPerlinNoise2::GrGLPerlinNoise2(const GrProcessor& processor)
|
||||
}
|
||||
|
||||
void GrGLPerlinNoise2::emitCode(EmitArgs& args) {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
|
||||
fBaseFrequencyUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
@ -1170,7 +1170,7 @@ GrGLImprovedPerlinNoise::GrGLImprovedPerlinNoise(const GrProcessor& processor)
|
||||
}
|
||||
|
||||
void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
|
||||
SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
|
||||
fBaseFrequencyUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
|
@ -67,16 +67,17 @@ public:
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
|
||||
class DCGLFP : public GrGLSLFragmentProcessor {
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder();
|
||||
fpb->codeAppendf("vec2 c = %s;", fpb->ensureFSCoords2D(args.fCoords, 0).c_str());
|
||||
fpb->codeAppend("vec2 r = mod(c, vec2(20.0));");
|
||||
fpb->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);");
|
||||
fpb->codeAppendf("color.rgb *= color.a;"
|
||||
"%s = color * %s;",
|
||||
args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
|
||||
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());
|
||||
}
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override {}
|
||||
};
|
||||
|
@ -179,7 +179,7 @@ public:
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
|
||||
GrGLSLFragmentBuilder* fpb = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
// add uniforms
|
||||
const char* lightDirUniName = nullptr;
|
||||
@ -202,33 +202,35 @@ public:
|
||||
kVec2f_GrSLType, kDefault_GrSLPrecision,
|
||||
"Xform", &xformUniName);
|
||||
|
||||
fpb->codeAppend("vec4 diffuseColor = ");
|
||||
fpb->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0],
|
||||
fragBuilder->codeAppend("vec4 diffuseColor = ");
|
||||
fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0],
|
||||
args.fCoords[0].c_str(),
|
||||
args.fCoords[0].getType());
|
||||
fpb->codeAppend(";");
|
||||
fragBuilder->codeAppend(";");
|
||||
|
||||
fpb->codeAppend("vec4 normalColor = ");
|
||||
fpb->appendTextureLookup(args.fSamplers[1],
|
||||
fragBuilder->codeAppend("vec4 normalColor = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[1],
|
||||
args.fCoords[1].c_str(),
|
||||
args.fCoords[1].getType());
|
||||
fpb->codeAppend(";");
|
||||
fragBuilder->codeAppend(";");
|
||||
|
||||
fpb->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);");
|
||||
fragBuilder->codeAppend("vec3 normal = normalColor.rgb - vec3(0.5);");
|
||||
|
||||
fpb->codeAppendf("mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.0, 0.0, 0.0, 1.0);",
|
||||
xformUniName, xformUniName, xformUniName, xformUniName);
|
||||
fragBuilder->codeAppendf(
|
||||
"mat3 m = mat3(%s.x, -%s.y, 0.0, %s.y, %s.x, 0.0, 0.0, 0.0, 1.0);",
|
||||
xformUniName, xformUniName, xformUniName, xformUniName);
|
||||
|
||||
// TODO: inverse map the light direction vectors in the vertex shader rather than
|
||||
// transforming all the normals here!
|
||||
fpb->codeAppend("normal = normalize(m*normal);");
|
||||
fragBuilder->codeAppend("normal = normalize(m*normal);");
|
||||
|
||||
fpb->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);", lightDirUniName);
|
||||
fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);",
|
||||
lightDirUniName);
|
||||
// diffuse light
|
||||
fpb->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName);
|
||||
fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName);
|
||||
// ambient light
|
||||
fpb->codeAppendf("result += %s;", ambientColorUniName);
|
||||
fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("result += %s;", ambientColorUniName);
|
||||
fragBuilder->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOutputColor);
|
||||
}
|
||||
|
||||
static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
|
||||
|
@ -46,23 +46,23 @@ void GrGLCircleBlurFragmentProcessor::emitCode(EmitArgs& args) {
|
||||
"data",
|
||||
&dataName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char *fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char *fragmentPos = fragBuilder->fragmentPosition();
|
||||
|
||||
if (args.fInputColor) {
|
||||
fsBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
|
||||
fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("vec4 src=vec4(1);");
|
||||
fragBuilder->codeAppendf("vec4 src=vec4(1);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("vec2 vec = %s.xy - %s.xy;", fragmentPos, dataName);
|
||||
fsBuilder->codeAppendf("float dist = (length(vec) - %s.z + 0.5) / %s.w;", dataName, dataName);
|
||||
fragBuilder->codeAppendf("vec2 vec = %s.xy - %s.xy;", fragmentPos, dataName);
|
||||
fragBuilder->codeAppendf("float dist = (length(vec) - %s.z + 0.5) / %s.w;", dataName, dataName);
|
||||
|
||||
fsBuilder->codeAppendf("float intensity = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "vec2(dist, 0.5)");
|
||||
fsBuilder->codeAppend(".a;");
|
||||
fragBuilder->codeAppendf("float intensity = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], "vec2(dist, 0.5)");
|
||||
fragBuilder->codeAppend(".a;");
|
||||
|
||||
fsBuilder->codeAppendf("%s = src * intensity;\n", args.fOutputColor );
|
||||
fragBuilder->codeAppendf("%s = src * intensity;\n", args.fOutputColor );
|
||||
}
|
||||
|
||||
void GrGLCircleBlurFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -146,40 +146,40 @@ void GrGLAlphaThresholdEffect::emitCode(EmitArgs& args) {
|
||||
kFloat_GrSLType, kDefault_GrSLPrecision,
|
||||
"outer_threshold");
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString maskCoords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 1);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString maskCoords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 1);
|
||||
|
||||
fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fsBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
|
||||
fsBuilder->codeAppend("\t\tvec4 input_color = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "coord");
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fsBuilder->codeAppend("\t\tvec4 mask_color = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[1], "mask_coord");
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fragBuilder->codeAppendf("\t\tvec2 mask_coord = %s;\n", maskCoords2D.c_str());
|
||||
fragBuilder->codeAppend("\t\tvec4 input_color = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], "coord");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppend("\t\tvec4 mask_color = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[1], "mask_coord");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
fsBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
|
||||
args.fBuilder->getUniformCStr(fInnerThresholdVar));
|
||||
fsBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
|
||||
args.fBuilder->getUniformCStr(fOuterThresholdVar));
|
||||
fsBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat inner_thresh = %s;\n",
|
||||
args.fBuilder->getUniformCStr(fInnerThresholdVar));
|
||||
fragBuilder->codeAppendf("\t\tfloat outer_thresh = %s;\n",
|
||||
args.fBuilder->getUniformCStr(fOuterThresholdVar));
|
||||
fragBuilder->codeAppend("\t\tfloat mask = mask_color.a;\n");
|
||||
|
||||
fsBuilder->codeAppend("vec4 color = input_color;\n");
|
||||
fsBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
|
||||
"\t\t\tif (color.a > outer_thresh) {\n"
|
||||
"\t\t\t\tfloat scale = outer_thresh / color.a;\n"
|
||||
"\t\t\t\tcolor.rgb *= scale;\n"
|
||||
"\t\t\t\tcolor.a = outer_thresh;\n"
|
||||
"\t\t\t}\n"
|
||||
"\t\t} else if (color.a < inner_thresh) {\n"
|
||||
"\t\t\tfloat scale = inner_thresh / max(0.001, color.a);\n"
|
||||
"\t\t\tcolor.rgb *= scale;\n"
|
||||
"\t\t\tcolor.a = inner_thresh;\n"
|
||||
"\t\t}\n");
|
||||
fragBuilder->codeAppend("vec4 color = input_color;\n");
|
||||
fragBuilder->codeAppend("\t\tif (mask < 0.5) {\n"
|
||||
"\t\t\tif (color.a > outer_thresh) {\n"
|
||||
"\t\t\t\tfloat scale = outer_thresh / color.a;\n"
|
||||
"\t\t\t\tcolor.rgb *= scale;\n"
|
||||
"\t\t\t\tcolor.a = outer_thresh;\n"
|
||||
"\t\t\t}\n"
|
||||
"\t\t} else if (color.a < inner_thresh) {\n"
|
||||
"\t\t\tfloat scale = inner_thresh / max(0.001, color.a);\n"
|
||||
"\t\t\tcolor.rgb *= scale;\n"
|
||||
"\t\t\tcolor.a = inner_thresh;\n"
|
||||
"\t\t}\n");
|
||||
|
||||
fsBuilder->codeAppendf("%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
|
||||
fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
|
||||
}
|
||||
|
||||
void GrGLAlphaThresholdEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
static const bool gUseUnpremul = false;
|
||||
|
||||
static void add_arithmetic_code(GrGLSLFragmentBuilder* fsBuilder,
|
||||
static void add_arithmetic_code(GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* dstColor,
|
||||
const char* outputColor,
|
||||
@ -29,27 +29,27 @@ static void add_arithmetic_code(GrGLSLFragmentBuilder* fsBuilder,
|
||||
bool enforcePMColor) {
|
||||
// We don't try to optimize for this case at all
|
||||
if (nullptr == srcColor) {
|
||||
fsBuilder->codeAppend("const vec4 src = vec4(1);");
|
||||
fragBuilder->codeAppend("const vec4 src = vec4(1);");
|
||||
} else {
|
||||
fsBuilder->codeAppendf("vec4 src = %s;", srcColor);
|
||||
fragBuilder->codeAppendf("vec4 src = %s;", srcColor);
|
||||
if (gUseUnpremul) {
|
||||
fsBuilder->codeAppend("src.rgb = clamp(src.rgb / src.a, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("src.rgb = clamp(src.rgb / src.a, 0.0, 1.0);");
|
||||
}
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("vec4 dst = %s;", dstColor);
|
||||
fragBuilder->codeAppendf("vec4 dst = %s;", dstColor);
|
||||
if (gUseUnpremul) {
|
||||
fsBuilder->codeAppend("dst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("dst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;",
|
||||
outputColor, kUni, kUni, kUni, kUni);
|
||||
fsBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
|
||||
fragBuilder->codeAppendf("%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;",
|
||||
outputColor, kUni, kUni, kUni, kUni);
|
||||
fragBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
|
||||
if (gUseUnpremul) {
|
||||
fsBuilder->codeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
|
||||
fragBuilder->codeAppendf("%s.rgb *= %s.a;", outputColor, outputColor);
|
||||
} else if (enforcePMColor) {
|
||||
fsBuilder->codeAppendf("%s.rgb = min(%s.rgb, %s.a);",
|
||||
outputColor, outputColor, outputColor);
|
||||
fragBuilder->codeAppendf("%s.rgb = min(%s.rgb, %s.a);",
|
||||
outputColor, outputColor, outputColor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public:
|
||||
~GLArithmeticFP() override {}
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString dstColor("dstColor");
|
||||
this->emitChild(0, nullptr, &dstColor, args);
|
||||
|
||||
@ -70,7 +70,11 @@ public:
|
||||
"k");
|
||||
const char* kUni = args.fBuilder->getUniformCStr(fKUni);
|
||||
|
||||
add_arithmetic_code(fsBuilder, args.fInputColor, dstColor.c_str(), args.fOutputColor, kUni,
|
||||
add_arithmetic_code(fragBuilder,
|
||||
args.fInputColor,
|
||||
dstColor.c_str(),
|
||||
args.fOutputColor,
|
||||
kUni,
|
||||
fEnforcePMColor);
|
||||
}
|
||||
|
||||
@ -207,16 +211,18 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor,
|
||||
const char* outColor, const GrXferProcessor& proc) override {
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const GrXferProcessor& proc) override {
|
||||
fKUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, kDefault_GrSLPrecision,
|
||||
"k");
|
||||
const char* kUni = pb->getUniformCStr(fKUni);
|
||||
|
||||
add_arithmetic_code(fsBuilder, srcColor, dstColor, outColor, kUni, fEnforcePMColor);
|
||||
add_arithmetic_code(fragBuilder, srcColor, dstColor, outColor, kUni, fEnforcePMColor);
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -697,20 +697,20 @@ private:
|
||||
typedef GrGLSLFragmentProcessor INHERITED;
|
||||
};
|
||||
|
||||
void OutputRectBlurProfileLookup(GrGLSLFragmentBuilder* fsBuilder,
|
||||
void OutputRectBlurProfileLookup(GrGLSLFragmentBuilder* fragBuilder,
|
||||
const GrGLSLTextureSampler& sampler,
|
||||
const char *output,
|
||||
const char *profileSize, const char *loc,
|
||||
const char *blurred_width,
|
||||
const char *sharp_width) {
|
||||
fsBuilder->codeAppendf("float %s;", output);
|
||||
fsBuilder->codeAppendf("{");
|
||||
fsBuilder->codeAppendf("float coord = ((abs(%s - 0.5 * %s) - 0.5 * %s)) / %s;",
|
||||
fragBuilder->codeAppendf("float %s;", output);
|
||||
fragBuilder->codeAppendf("{");
|
||||
fragBuilder->codeAppendf("float coord = ((abs(%s - 0.5 * %s) - 0.5 * %s)) / %s;",
|
||||
loc, blurred_width, sharp_width, profileSize);
|
||||
fsBuilder->codeAppendf("%s = ", output);
|
||||
fsBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)");
|
||||
fsBuilder->codeAppend(".a;");
|
||||
fsBuilder->codeAppendf("}");
|
||||
fragBuilder->codeAppendf("%s = ", output);
|
||||
fragBuilder->appendTextureLookup(sampler, "vec2(coord,0.5)");
|
||||
fragBuilder->codeAppend(".a;");
|
||||
fragBuilder->codeAppendf("}");
|
||||
}
|
||||
|
||||
|
||||
@ -737,33 +737,33 @@ void GrGLRectBlurEffect::emitCode(EmitArgs& args) {
|
||||
"profileSize",
|
||||
&profileSizeName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char *fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char *fragmentPos = fragBuilder->fragmentPosition();
|
||||
|
||||
if (args.fInputColor) {
|
||||
fsBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
|
||||
fragBuilder->codeAppendf("vec4 src=%s;", args.fInputColor);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("vec4 src=vec4(1);");
|
||||
fragBuilder->codeAppendf("vec4 src=vec4(1);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("%s vec2 translatedPos = %s.xy - %s.xy;", precisionString, fragmentPos,
|
||||
rectName);
|
||||
fsBuilder->codeAppendf("%s float width = %s.z - %s.x;", precisionString, rectName, rectName);
|
||||
fsBuilder->codeAppendf("%s float height = %s.w - %s.y;", precisionString, rectName, rectName);
|
||||
fragBuilder->codeAppendf("%s vec2 translatedPos = %s.xy - %s.xy;", precisionString, fragmentPos,
|
||||
rectName);
|
||||
fragBuilder->codeAppendf("%s float width = %s.z - %s.x;", precisionString, rectName, rectName);
|
||||
fragBuilder->codeAppendf("%s float height = %s.w - %s.y;", precisionString, rectName, rectName);
|
||||
|
||||
fsBuilder->codeAppendf("%s vec2 smallDims = vec2(width - %s, height - %s);", precisionString,
|
||||
profileSizeName, profileSizeName);
|
||||
fsBuilder->codeAppendf("%s float center = 2.0 * floor(%s/2.0 + .25) - 1.0;", precisionString,
|
||||
profileSizeName);
|
||||
fsBuilder->codeAppendf("%s vec2 wh = smallDims - vec2(center,center);", precisionString);
|
||||
fragBuilder->codeAppendf("%s vec2 smallDims = vec2(width - %s, height - %s);", precisionString,
|
||||
profileSizeName, profileSizeName);
|
||||
fragBuilder->codeAppendf("%s float center = 2.0 * floor(%s/2.0 + .25) - 1.0;", precisionString,
|
||||
profileSizeName);
|
||||
fragBuilder->codeAppendf("%s vec2 wh = smallDims - vec2(center,center);", precisionString);
|
||||
|
||||
OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "horiz_lookup", profileSizeName,
|
||||
OutputRectBlurProfileLookup(fragBuilder, args.fSamplers[0], "horiz_lookup", profileSizeName,
|
||||
"translatedPos.x", "width", "wh.x");
|
||||
OutputRectBlurProfileLookup(fsBuilder, args.fSamplers[0], "vert_lookup", profileSizeName,
|
||||
OutputRectBlurProfileLookup(fragBuilder, args.fSamplers[0], "vert_lookup", profileSizeName,
|
||||
"translatedPos.y", "height", "wh.y");
|
||||
|
||||
fsBuilder->codeAppendf("float final = horiz_lookup * vert_lookup;");
|
||||
fsBuilder->codeAppendf("%s = src * final;", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("float final = horiz_lookup * vert_lookup;");
|
||||
fragBuilder->codeAppendf("%s = src * final;", args.fOutputColor);
|
||||
}
|
||||
|
||||
void GrGLRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -1083,34 +1083,36 @@ void GrGLRRectBlurEffect::emitCode(EmitArgs& args) {
|
||||
"blurRadius",
|
||||
&blurRadiusName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* fragmentPos = fragBuilder->fragmentPosition();
|
||||
|
||||
// warp the fragment position to the appropriate part of the 9patch blur texture
|
||||
|
||||
fsBuilder->codeAppendf("vec2 rectCenter = (%s.xy + %s.zw)/2.0;", rectName, rectName);
|
||||
fsBuilder->codeAppendf("vec2 translatedFragPos = %s.xy - %s.xy;", fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("float threshold = %s + 2.0*%s;", cornerRadiusName, blurRadiusName);
|
||||
fsBuilder->codeAppendf("vec2 middle = %s.zw - %s.xy - 2.0*threshold;", rectName, rectName);
|
||||
fragBuilder->codeAppendf("vec2 rectCenter = (%s.xy + %s.zw)/2.0;", rectName, rectName);
|
||||
fragBuilder->codeAppendf("vec2 translatedFragPos = %s.xy - %s.xy;", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("float threshold = %s + 2.0*%s;", cornerRadiusName, blurRadiusName);
|
||||
fragBuilder->codeAppendf("vec2 middle = %s.zw - %s.xy - 2.0*threshold;", rectName, rectName);
|
||||
|
||||
fsBuilder->codeAppendf("if (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {");
|
||||
fsBuilder->codeAppendf("translatedFragPos.x = threshold;\n");
|
||||
fsBuilder->codeAppendf("} else if (translatedFragPos.x >= (middle.x + threshold)) {");
|
||||
fsBuilder->codeAppendf("translatedFragPos.x -= middle.x - 1.0;");
|
||||
fsBuilder->codeAppendf("}");
|
||||
fragBuilder->codeAppendf(
|
||||
"if (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {");
|
||||
fragBuilder->codeAppendf("translatedFragPos.x = threshold;\n");
|
||||
fragBuilder->codeAppendf("} else if (translatedFragPos.x >= (middle.x + threshold)) {");
|
||||
fragBuilder->codeAppendf("translatedFragPos.x -= middle.x - 1.0;");
|
||||
fragBuilder->codeAppendf("}");
|
||||
|
||||
fsBuilder->codeAppendf("if (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {");
|
||||
fsBuilder->codeAppendf("translatedFragPos.y = threshold;");
|
||||
fsBuilder->codeAppendf("} else if (translatedFragPos.y >= (middle.y + threshold)) {");
|
||||
fsBuilder->codeAppendf("translatedFragPos.y -= middle.y - 1.0;");
|
||||
fsBuilder->codeAppendf("}");
|
||||
fragBuilder->codeAppendf(
|
||||
"if (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {");
|
||||
fragBuilder->codeAppendf("translatedFragPos.y = threshold;");
|
||||
fragBuilder->codeAppendf("} else if (translatedFragPos.y >= (middle.y + threshold)) {");
|
||||
fragBuilder->codeAppendf("translatedFragPos.y -= middle.y - 1.0;");
|
||||
fragBuilder->codeAppendf("}");
|
||||
|
||||
fsBuilder->codeAppendf("vec2 proxyDims = vec2(2.0*threshold+1.0);");
|
||||
fsBuilder->codeAppendf("vec2 texCoord = translatedFragPos / proxyDims;");
|
||||
fragBuilder->codeAppendf("vec2 proxyDims = vec2(2.0*threshold+1.0);");
|
||||
fragBuilder->codeAppendf("vec2 texCoord = translatedFragPos / proxyDims;");
|
||||
|
||||
fsBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0], "texCoord");
|
||||
fsBuilder->codeAppend(";");
|
||||
fragBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookupAndModulate(args.fInputColor, args.fSamplers[0], "texCoord");
|
||||
fragBuilder->codeAppend(";");
|
||||
}
|
||||
|
||||
void GrGLRRectBlurEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -264,34 +264,34 @@ void GrColorCubeEffect::GLSLProcessor::emitCode(EmitArgs& args) {
|
||||
// Note: if implemented using texture3D in OpenGL ES older than OpenGL ES 3.0,
|
||||
// the shader might need "#extension GL_OES_texture_3D : enable".
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
// Unpremultiply color
|
||||
fsBuilder->codeAppendf("\tfloat %s = max(%s.a, 0.00001);\n", nonZeroAlpha, args.fInputColor);
|
||||
fsBuilder->codeAppendf("\tvec4 %s = vec4(%s.rgb / %s, %s);\n",
|
||||
unPMColor, args.fInputColor, nonZeroAlpha, nonZeroAlpha);
|
||||
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.
|
||||
fsBuilder->codeAppendf(
|
||||
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.
|
||||
fsBuilder->codeAppendf("vec2 %s = vec2(%s.r, (floor(%s.b) + %s.g) * %s);\n",
|
||||
cCoords1, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
|
||||
fsBuilder->codeAppendf("vec2 %s = vec2(%s.r, (ceil(%s.b) + %s.g) * %s);\n",
|
||||
cCoords2, cubeIdx, cubeIdx, cubeIdx, colorCubeInvSizeUni);
|
||||
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.
|
||||
fsBuilder->codeAppendf("%s = vec4(mix(", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], cCoords1);
|
||||
fsBuilder->codeAppend(".rgb, ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], cCoords2);
|
||||
fragBuilder->codeAppendf("%s = vec4(mix(", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords1);
|
||||
fragBuilder->codeAppend(".rgb, ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], cCoords2);
|
||||
|
||||
// Premultiply color by alpha. Note that the input alpha is not modified by this shader.
|
||||
fsBuilder->codeAppendf(".rgb, fract(%s.b)) * vec3(%s), %s.a);\n",
|
||||
cubeIdx, nonZeroAlpha, args.fInputColor);
|
||||
fragBuilder->codeAppendf(".rgb, fract(%s.b)) * vec3(%s), %s.a);\n",
|
||||
cubeIdx, nonZeroAlpha, args.fInputColor);
|
||||
}
|
||||
|
||||
void GrColorCubeEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -419,19 +419,19 @@ public:
|
||||
// could optimize this case, but we aren't for now.
|
||||
args.fInputColor = "vec4(1)";
|
||||
}
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
|
||||
// transparent black.
|
||||
fsBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n",
|
||||
args.fInputColor);
|
||||
fsBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
|
||||
args.fOutputColor,
|
||||
args.fBuilder->getUniformCStr(fMatrixHandle),
|
||||
args.fInputColor,
|
||||
args.fBuilder->getUniformCStr(fVectorHandle));
|
||||
fsBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n",
|
||||
args.fOutputColor, args.fOutputColor);
|
||||
fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
|
||||
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,
|
||||
args.fBuilder->getUniformCStr(fMatrixHandle),
|
||||
args.fInputColor,
|
||||
args.fBuilder->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);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -557,31 +557,32 @@ void GrGLDisplacementMapEffect::emitCode(EmitArgs& args) {
|
||||
// a number smaller than that to approximate 0, but
|
||||
// leave room for 32-bit float GPU rounding errors.
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
fragBuilder->codeAppendf("\t\tvec4 %s = ", dColor);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
args.fCoords[0].getType());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
// Unpremultiply the displacement
|
||||
fsBuilder->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 = fsBuilder->ensureFSCoords2D(args.fCoords, 1);
|
||||
fsBuilder->codeAppendf("\t\tvec2 %s = %s + %s*(%s.",
|
||||
cCoords, coords2D.c_str(), scaleUni, dColor);
|
||||
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:
|
||||
fsBuilder->codeAppend("r");
|
||||
fragBuilder->codeAppend("r");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kG_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("g");
|
||||
fragBuilder->codeAppend("g");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kB_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("b");
|
||||
fragBuilder->codeAppend("b");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kA_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("a");
|
||||
fragBuilder->codeAppend("a");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
|
||||
default:
|
||||
@ -590,26 +591,26 @@ void GrGLDisplacementMapEffect::emitCode(EmitArgs& args) {
|
||||
|
||||
switch (fYChannelSelector) {
|
||||
case SkDisplacementMapEffect::kR_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("r");
|
||||
fragBuilder->codeAppend("r");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kG_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("g");
|
||||
fragBuilder->codeAppend("g");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kB_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("b");
|
||||
fragBuilder->codeAppend("b");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kA_ChannelSelectorType:
|
||||
fsBuilder->codeAppend("a");
|
||||
fragBuilder->codeAppend("a");
|
||||
break;
|
||||
case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
|
||||
default:
|
||||
SkDEBUGFAIL("Unknown Y channel selector");
|
||||
}
|
||||
fsBuilder->codeAppend("-vec2(0.5));\t\t");
|
||||
fragBuilder->codeAppend("-vec2(0.5));\t\t");
|
||||
|
||||
fGLDomain.sampleTexture(fsBuilder, domain, args.fOutputColor, SkString(cCoords),
|
||||
fGLDomain.sampleTexture(fragBuilder, domain, args.fOutputColor, SkString(cCoords),
|
||||
args.fSamplers[1]);
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
}
|
||||
|
||||
void GrGLDisplacementMapEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -608,8 +608,10 @@ public:
|
||||
* the FS. The default of emitLightColor appends the name of the constant light color uniform
|
||||
* and so this function only needs to be overridden if the light color varies spatially.
|
||||
*/
|
||||
virtual void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) = 0;
|
||||
virtual void emitLightColor(GrGLSLFPBuilder*, const char *surfaceToLight);
|
||||
virtual void emitSurfaceToLight(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, const char* z) = 0;
|
||||
virtual void emitLightColor(GrGLSLFPBuilder*,
|
||||
GrGLSLFragmentBuilder*,
|
||||
const char *surfaceToLight);
|
||||
|
||||
// This is called from GrGLLightingEffect's setData(). Subclasses of GrGLLight must call
|
||||
// INHERITED::setData().
|
||||
@ -634,7 +636,7 @@ class GrGLDistantLight : public GrGLLight {
|
||||
public:
|
||||
virtual ~GrGLDistantLight() {}
|
||||
void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, const char* z) override;
|
||||
|
||||
private:
|
||||
typedef GrGLLight INHERITED;
|
||||
@ -647,7 +649,7 @@ class GrGLPointLight : public GrGLLight {
|
||||
public:
|
||||
virtual ~GrGLPointLight() {}
|
||||
void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, const char* z) override;
|
||||
|
||||
private:
|
||||
typedef GrGLLight INHERITED;
|
||||
@ -660,8 +662,10 @@ class GrGLSpotLight : public GrGLLight {
|
||||
public:
|
||||
virtual ~GrGLSpotLight() {}
|
||||
void setData(const GrGLSLProgramDataManager&, const SkImageFilterLight* light) const override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, const char* z) override;
|
||||
void emitLightColor(GrGLSLFPBuilder*, const char *surfaceToLight) override;
|
||||
void emitSurfaceToLight(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, const char* z) override;
|
||||
void emitLightColor(GrGLSLFPBuilder*,
|
||||
GrGLSLFragmentBuilder*,
|
||||
const char *surfaceToLight) override;
|
||||
|
||||
private:
|
||||
typedef GrGLLight INHERITED;
|
||||
@ -1523,7 +1527,7 @@ protected:
|
||||
*/
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
|
||||
|
||||
virtual void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) = 0;
|
||||
virtual void emitLightFunc(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, SkString* funcName) = 0;
|
||||
|
||||
private:
|
||||
typedef GrGLSLFragmentProcessor INHERITED;
|
||||
@ -1539,7 +1543,7 @@ private:
|
||||
class GrGLDiffuseLightingEffect : public GrGLLightingEffect {
|
||||
public:
|
||||
GrGLDiffuseLightingEffect(const GrProcessor&);
|
||||
void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) override;
|
||||
void emitLightFunc(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, SkString* funcName) override;
|
||||
|
||||
protected:
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
|
||||
@ -1555,7 +1559,7 @@ private:
|
||||
class GrGLSpecularLightingEffect : public GrGLLightingEffect {
|
||||
public:
|
||||
GrGLSpecularLightingEffect(const GrProcessor&);
|
||||
void emitLightFunc(GrGLSLFPBuilder*, SkString* funcName) override;
|
||||
void emitLightFunc(GrGLSLFPBuilder*, GrGLSLFragmentBuilder*, SkString* funcName) override;
|
||||
|
||||
protected:
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
|
||||
@ -1659,8 +1663,9 @@ void GrGLLightingEffect::emitCode(EmitArgs& args) {
|
||||
kFloat_GrSLType, kDefault_GrSLPrecision,
|
||||
"SurfaceScale");
|
||||
fLight->emitLightColorUniform(args.fBuilder);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString lightFunc;
|
||||
this->emitLightFunc(args.fBuilder, &lightFunc);
|
||||
this->emitLightFunc(args.fBuilder, fragBuilder, &lightFunc);
|
||||
static const GrGLSLShaderVar gSobelArgs[] = {
|
||||
GrGLSLShaderVar("a", kFloat_GrSLType),
|
||||
GrGLSLShaderVar("b", kFloat_GrSLType),
|
||||
@ -1671,27 +1676,26 @@ void GrGLLightingEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLShaderVar("scale", kFloat_GrSLType),
|
||||
};
|
||||
SkString sobelFuncName;
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
|
||||
fsBuilder->emitFunction(kFloat_GrSLType,
|
||||
"sobel",
|
||||
SK_ARRAY_COUNT(gSobelArgs),
|
||||
gSobelArgs,
|
||||
"\treturn (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;\n",
|
||||
&sobelFuncName);
|
||||
fragBuilder->emitFunction(kFloat_GrSLType,
|
||||
"sobel",
|
||||
SK_ARRAY_COUNT(gSobelArgs),
|
||||
gSobelArgs,
|
||||
"\treturn (-a + b - 2.0 * c + 2.0 * d -e + f) * scale;\n",
|
||||
&sobelFuncName);
|
||||
static const GrGLSLShaderVar gPointToNormalArgs[] = {
|
||||
GrGLSLShaderVar("x", kFloat_GrSLType),
|
||||
GrGLSLShaderVar("y", kFloat_GrSLType),
|
||||
GrGLSLShaderVar("scale", kFloat_GrSLType),
|
||||
};
|
||||
SkString pointToNormalName;
|
||||
fsBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"pointToNormal",
|
||||
SK_ARRAY_COUNT(gPointToNormalArgs),
|
||||
gPointToNormalArgs,
|
||||
"\treturn normalize(vec3(-x * scale, -y * scale, 1));\n",
|
||||
&pointToNormalName);
|
||||
fragBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"pointToNormal",
|
||||
SK_ARRAY_COUNT(gPointToNormalArgs),
|
||||
gPointToNormalArgs,
|
||||
"\treturn normalize(vec3(-x * scale, -y * scale, 1));\n",
|
||||
&pointToNormalName);
|
||||
|
||||
static const GrGLSLShaderVar gInteriorNormalArgs[] = {
|
||||
GrGLSLShaderVar("m", kFloat_GrSLType, 9),
|
||||
@ -1701,15 +1705,15 @@ void GrGLLightingEffect::emitCode(EmitArgs& args) {
|
||||
pointToNormalName.c_str(),
|
||||
sobelFuncName.c_str());
|
||||
SkString normalName;
|
||||
fsBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"normal",
|
||||
SK_ARRAY_COUNT(gInteriorNormalArgs),
|
||||
gInteriorNormalArgs,
|
||||
normalBody.c_str(),
|
||||
&normalName);
|
||||
fragBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"normal",
|
||||
SK_ARRAY_COUNT(gInteriorNormalArgs),
|
||||
gInteriorNormalArgs,
|
||||
normalBody.c_str(),
|
||||
&normalName);
|
||||
|
||||
fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fsBuilder->codeAppend("\t\tfloat m[9];\n");
|
||||
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fragBuilder->codeAppend("\t\tfloat m[9];\n");
|
||||
|
||||
const char* imgInc = args.fBuilder->getUniformCStr(fImageIncrementUni);
|
||||
const char* surfScale = args.fBuilder->getUniformCStr(fSurfaceScaleUni);
|
||||
@ -1719,23 +1723,23 @@ void GrGLLightingEffect::emitCode(EmitArgs& args) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
SkString texCoords;
|
||||
texCoords.appendf("coord + vec2(%d, %d) * %s", dx, dy, imgInc);
|
||||
fsBuilder->codeAppendf("\t\tm[%d] = ", index++);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], texCoords.c_str());
|
||||
fsBuilder->codeAppend(".a;\n");
|
||||
fragBuilder->codeAppendf("\t\tm[%d] = ", index++);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], texCoords.c_str());
|
||||
fragBuilder->codeAppend(".a;\n");
|
||||
}
|
||||
}
|
||||
fsBuilder->codeAppend("\t\tvec3 surfaceToLight = ");
|
||||
fragBuilder->codeAppend("\t\tvec3 surfaceToLight = ");
|
||||
SkString arg;
|
||||
arg.appendf("%s * m[4]", surfScale);
|
||||
fLight->emitSurfaceToLight(args.fBuilder, arg.c_str());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fsBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
|
||||
args.fOutputColor, lightFunc.c_str(), normalName.c_str(), surfScale);
|
||||
fLight->emitLightColor(args.fBuilder, "surfaceToLight");
|
||||
fsBuilder->codeAppend(");\n");
|
||||
fLight->emitSurfaceToLight(args.fBuilder, fragBuilder, arg.c_str());
|
||||
fragBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppendf("\t\t%s = %s(%s(m, %s), surfaceToLight, ",
|
||||
args.fOutputColor, lightFunc.c_str(), normalName.c_str(), surfScale);
|
||||
fLight->emitLightColor(args.fBuilder, fragBuilder, "surfaceToLight");
|
||||
fragBuilder->codeAppend(");\n");
|
||||
SkString modulate;
|
||||
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLLightingEffect::GenKey(const GrProcessor& proc,
|
||||
@ -1764,7 +1768,9 @@ GrGLDiffuseLightingEffect::GrGLDiffuseLightingEffect(const GrProcessor& proc)
|
||||
: INHERITED(proc) {
|
||||
}
|
||||
|
||||
void GrGLDiffuseLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkString* funcName) {
|
||||
void GrGLDiffuseLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
SkString* funcName) {
|
||||
const char* kd;
|
||||
fKDUni = builder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kFloat_GrSLType, kDefault_GrSLPrecision,
|
||||
@ -1778,12 +1784,12 @@ void GrGLDiffuseLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkString
|
||||
SkString lightBody;
|
||||
lightBody.appendf("\tfloat colorScale = %s * dot(normal, surfaceToLight);\n", kd);
|
||||
lightBody.appendf("\treturn vec4(lightColor * clamp(colorScale, 0.0, 1.0), 1.0);\n");
|
||||
builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
|
||||
"light",
|
||||
SK_ARRAY_COUNT(gLightArgs),
|
||||
gLightArgs,
|
||||
lightBody.c_str(),
|
||||
funcName);
|
||||
fragBuilder->emitFunction(kVec4f_GrSLType,
|
||||
"light",
|
||||
SK_ARRAY_COUNT(gLightArgs),
|
||||
gLightArgs,
|
||||
lightBody.c_str(),
|
||||
funcName);
|
||||
}
|
||||
|
||||
void GrGLDiffuseLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -1846,7 +1852,9 @@ GrGLSpecularLightingEffect::GrGLSpecularLightingEffect(const GrProcessor& proc)
|
||||
: INHERITED(proc) {
|
||||
}
|
||||
|
||||
void GrGLSpecularLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkString* funcName) {
|
||||
void GrGLSpecularLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
SkString* funcName) {
|
||||
const char* ks;
|
||||
const char* shininess;
|
||||
|
||||
@ -1868,12 +1876,12 @@ void GrGLSpecularLightingEffect::emitLightFunc(GrGLSLFPBuilder* builder, SkStrin
|
||||
lightBody.appendf("\tfloat colorScale = %s * pow(dot(normal, halfDir), %s);\n", ks, shininess);
|
||||
lightBody.appendf("\tvec3 color = lightColor * clamp(colorScale, 0.0, 1.0);\n");
|
||||
lightBody.appendf("\treturn vec4(color, max(max(color.r, color.g), color.b));\n");
|
||||
builder->getFragmentShaderBuilder()->emitFunction(kVec4f_GrSLType,
|
||||
"light",
|
||||
SK_ARRAY_COUNT(gLightArgs),
|
||||
gLightArgs,
|
||||
lightBody.c_str(),
|
||||
funcName);
|
||||
fragBuilder->emitFunction(kVec4f_GrSLType,
|
||||
"light",
|
||||
SK_ARRAY_COUNT(gLightArgs),
|
||||
gLightArgs,
|
||||
lightBody.c_str(),
|
||||
funcName);
|
||||
}
|
||||
|
||||
void GrGLSpecularLightingEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -1891,8 +1899,10 @@ void GrGLLight::emitLightColorUniform(GrGLSLFPBuilder* builder) {
|
||||
"LightColor");
|
||||
}
|
||||
|
||||
void GrGLLight::emitLightColor(GrGLSLFPBuilder* builder, const char *surfaceToLight) {
|
||||
builder->getFragmentShaderBuilder()->codeAppend(builder->getUniformCStr(this->lightColorUni()));
|
||||
void GrGLLight::emitLightColor(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char *surfaceToLight) {
|
||||
fragBuilder->codeAppend(builder->getUniformCStr(this->lightColorUni()));
|
||||
}
|
||||
|
||||
void GrGLLight::setData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -1911,12 +1921,14 @@ void GrGLDistantLight::setData(const GrGLSLProgramDataManager& pdman,
|
||||
setUniformNormal3(pdman, fDirectionUni, distantLight->direction());
|
||||
}
|
||||
|
||||
void GrGLDistantLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) {
|
||||
void GrGLDistantLight::emitSurfaceToLight(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* z) {
|
||||
const char* dir;
|
||||
fDirectionUni = builder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec3f_GrSLType, kDefault_GrSLPrecision,
|
||||
"LightDirection", &dir);
|
||||
builder->getFragmentShaderBuilder()->codeAppend(dir);
|
||||
fragBuilder->codeAppend(dir);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1929,14 +1941,15 @@ void GrGLPointLight::setData(const GrGLSLProgramDataManager& pdman,
|
||||
setUniformPoint3(pdman, fLocationUni, pointLight->location());
|
||||
}
|
||||
|
||||
void GrGLPointLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) {
|
||||
void GrGLPointLight::emitSurfaceToLight(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* z) {
|
||||
const char* loc;
|
||||
fLocationUni = builder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec3f_GrSLType, kDefault_GrSLPrecision,
|
||||
"LightLocation", &loc);
|
||||
GrGLSLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
|
||||
loc, fsBuilder->fragmentPosition(), z);
|
||||
fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
|
||||
loc, fragBuilder->fragmentPosition(), z);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1954,18 +1967,20 @@ void GrGLSpotLight::setData(const GrGLSLProgramDataManager& pdman,
|
||||
setUniformNormal3(pdman, fSUni, spotLight->s());
|
||||
}
|
||||
|
||||
void GrGLSpotLight::emitSurfaceToLight(GrGLSLFPBuilder* builder, const char* z) {
|
||||
void GrGLSpotLight::emitSurfaceToLight(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* z) {
|
||||
const char* location;
|
||||
fLocationUni = builder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec3f_GrSLType, kDefault_GrSLPrecision,
|
||||
"LightLocation", &location);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
|
||||
location, fsBuilder->fragmentPosition(), z);
|
||||
fragBuilder->codeAppendf("normalize(%s - vec3(%s.xy, %s))",
|
||||
location, fragBuilder->fragmentPosition(), z);
|
||||
}
|
||||
|
||||
void GrGLSpotLight::emitLightColor(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char *surfaceToLight) {
|
||||
|
||||
const char* color = builder->getUniformCStr(this->lightColorUni()); // created by parent class.
|
||||
@ -2004,15 +2019,14 @@ void GrGLSpotLight::emitLightColor(GrGLSLFPBuilder* builder,
|
||||
color, cosOuter, coneScale);
|
||||
lightColorBody.appendf("\t}\n");
|
||||
lightColorBody.appendf("\treturn %s;\n", color);
|
||||
GrGLSLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
|
||||
fsBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"lightColor",
|
||||
SK_ARRAY_COUNT(gLightColorArgs),
|
||||
gLightColorArgs,
|
||||
lightColorBody.c_str(),
|
||||
&fLightColorFunc);
|
||||
fragBuilder->emitFunction(kVec3f_GrSLType,
|
||||
"lightColor",
|
||||
SK_ARRAY_COUNT(gLightColorArgs),
|
||||
gLightColorArgs,
|
||||
lightColorBody.c_str(),
|
||||
&fLightColorFunc);
|
||||
|
||||
fsBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
|
||||
fragBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -72,14 +72,14 @@ public:
|
||||
args.fInputColor = "vec4(1)";
|
||||
}
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
|
||||
SK_ITU_BT709_LUM_COEFF_R,
|
||||
SK_ITU_BT709_LUM_COEFF_G,
|
||||
SK_ITU_BT709_LUM_COEFF_B,
|
||||
args.fInputColor);
|
||||
fsBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
|
||||
args.fOutputColor);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
fragBuilder->codeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
|
||||
SK_ITU_BT709_LUM_COEFF_R,
|
||||
SK_ITU_BT709_LUM_COEFF_G,
|
||||
SK_ITU_BT709_LUM_COEFF_B,
|
||||
args.fInputColor);
|
||||
fragBuilder->codeAppendf("\t%s = vec4(0, 0, 0, luma);\n",
|
||||
args.fOutputColor);
|
||||
|
||||
}
|
||||
|
||||
|
@ -133,39 +133,39 @@ void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, kDefault_GrSLPrecision, "Bounds");
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fsBuilder->codeAppendf("\t\tvec2 zoom_coord = %s + %s * %s;\n",
|
||||
args.fBuilder->getUniformCStr(fOffsetVar),
|
||||
coords2D.c_str(),
|
||||
args.fBuilder->getUniformCStr(fInvZoomVar));
|
||||
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",
|
||||
args.fBuilder->getUniformCStr(fOffsetVar),
|
||||
coords2D.c_str(),
|
||||
args.fBuilder->getUniformCStr(fInvZoomVar));
|
||||
const char* bounds = args.fBuilder->getUniformCStr(fBoundsVar);
|
||||
fsBuilder->codeAppendf("\t\tvec2 delta = (coord - %s.xy) * %s.zw;\n", bounds, bounds);
|
||||
fsBuilder->codeAppendf("\t\tdelta = min(delta, vec2(1.0, 1.0) - delta);\n");
|
||||
fsBuilder->codeAppendf("\t\tdelta = delta * %s;\n",
|
||||
args.fBuilder->getUniformCStr(fInvInsetVar));
|
||||
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",
|
||||
args.fBuilder->getUniformCStr(fInvInsetVar));
|
||||
|
||||
fsBuilder->codeAppend("\t\tfloat weight = 0.0;\n");
|
||||
fsBuilder->codeAppend("\t\tif (delta.s < 2.0 && delta.t < 2.0) {\n");
|
||||
fsBuilder->codeAppend("\t\t\tdelta = vec2(2.0, 2.0) - delta;\n");
|
||||
fsBuilder->codeAppend("\t\t\tfloat dist = length(delta);\n");
|
||||
fsBuilder->codeAppend("\t\t\tdist = max(2.0 - dist, 0.0);\n");
|
||||
fsBuilder->codeAppend("\t\t\tweight = min(dist * dist, 1.0);\n");
|
||||
fsBuilder->codeAppend("\t\t} else {\n");
|
||||
fsBuilder->codeAppend("\t\t\tvec2 delta_squared = delta * delta;\n");
|
||||
fsBuilder->codeAppend("\t\t\tweight = min(min(delta_squared.x, delta_squared.y), 1.0);\n");
|
||||
fsBuilder->codeAppend("\t\t}\n");
|
||||
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");
|
||||
|
||||
fsBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
|
||||
fsBuilder->codeAppend("\t\tvec4 output_color = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "mix_coord");
|
||||
fsBuilder->codeAppend(";\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");
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
|
||||
SkString modulate;
|
||||
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLMagnifierEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -297,16 +297,16 @@ void GrGLMorphologyEffect::emitCode(EmitArgs& args) {
|
||||
"Range");
|
||||
const char* range = args.fBuilder->getUniformCStr(fRangeUni);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
const char* func;
|
||||
switch (fType) {
|
||||
case GrMorphologyEffect::kErode_MorphologyType:
|
||||
fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", args.fOutputColor);
|
||||
func = "min";
|
||||
break;
|
||||
case GrMorphologyEffect::kDilate_MorphologyType:
|
||||
fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
|
||||
func = "max";
|
||||
break;
|
||||
default:
|
||||
@ -329,30 +329,30 @@ void GrGLMorphologyEffect::emitCode(EmitArgs& args) {
|
||||
}
|
||||
|
||||
// vec2 coord = coord2D;
|
||||
fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
|
||||
// coord.x -= radius * pixelSize;
|
||||
fsBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, fRadius, pixelSizeInc);
|
||||
fragBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, fRadius, pixelSizeInc);
|
||||
if (fUseRange) {
|
||||
// highBound = min(highBound, coord.x + (width-1) * pixelSize);
|
||||
fsBuilder->codeAppendf("\t\tfloat highBound = min(%s.y, coord.%s + %f * %s);",
|
||||
range, dir, float(width() - 1), pixelSizeInc);
|
||||
fragBuilder->codeAppendf("\t\tfloat highBound = min(%s.y, coord.%s + %f * %s);",
|
||||
range, dir, float(width() - 1), pixelSizeInc);
|
||||
// coord.x = max(lowBound, coord.x);
|
||||
fsBuilder->codeAppendf("\t\tcoord.%s = max(%s.x, coord.%s);", dir, range, dir);
|
||||
fragBuilder->codeAppendf("\t\tcoord.%s = max(%s.x, coord.%s);", dir, range, dir);
|
||||
}
|
||||
fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", width());
|
||||
fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", args.fOutputColor, func, args.fOutputColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "coord");
|
||||
fsBuilder->codeAppend(");\n");
|
||||
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;
|
||||
fsBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc);
|
||||
fragBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc);
|
||||
if (fUseRange) {
|
||||
// coord.x = min(highBound, coord.x);
|
||||
fsBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir, dir);
|
||||
fragBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir, dir);
|
||||
}
|
||||
fsBuilder->codeAppend("\t\t}\n");
|
||||
fragBuilder->codeAppend("\t\t}\n");
|
||||
SkString modulate;
|
||||
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLMorphologyEffect::GenKey(const GrProcessor& proc,
|
||||
|
@ -621,19 +621,19 @@ GrGLPerlinNoise::GrGLPerlinNoise(const GrProcessor& processor)
|
||||
}
|
||||
|
||||
void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString vCoords = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
|
||||
fBaseFrequencyUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec2f_GrSLType, kDefault_GrSLPrecision,
|
||||
"baseFrequency");
|
||||
kVec2f_GrSLType, kDefault_GrSLPrecision,
|
||||
"baseFrequency");
|
||||
const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyUni);
|
||||
|
||||
const char* stitchDataUni = nullptr;
|
||||
if (fStitchTiles) {
|
||||
fStitchDataUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec2f_GrSLType, kDefault_GrSLPrecision,
|
||||
"stitchData");
|
||||
kVec2f_GrSLType, kDefault_GrSLPrecision,
|
||||
"stitchData");
|
||||
stitchDataUni = args.fBuilder->getUniformCStr(fStitchDataUni);
|
||||
}
|
||||
|
||||
@ -685,18 +685,18 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
// Adjust frequencies if we're stitching tiles
|
||||
if (fStitchTiles) {
|
||||
noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
|
||||
floorVal, stitchData, floorVal, stitchData);
|
||||
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);
|
||||
floorVal, floorVal);
|
||||
|
||||
// Get permutation for x
|
||||
{
|
||||
@ -704,8 +704,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
|
||||
|
||||
noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.append(".r;");
|
||||
}
|
||||
|
||||
@ -715,8 +715,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
|
||||
|
||||
noiseCode.appendf("\n\t%s.y = ", latticeIdx);
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.append(".r;");
|
||||
}
|
||||
|
||||
@ -740,8 +740,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
SkString latticeCoords("");
|
||||
latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
|
||||
noiseCode.appendf("\n\tvec4 %s = ", lattice);
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
|
||||
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
|
||||
}
|
||||
@ -752,8 +752,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
SkString latticeCoords("");
|
||||
latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
|
||||
noiseCode.append("\n\tlattice = ");
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
|
||||
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
|
||||
}
|
||||
@ -768,8 +768,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
SkString latticeCoords("");
|
||||
latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
|
||||
noiseCode.append("\n\tlattice = ");
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
|
||||
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
|
||||
}
|
||||
@ -780,8 +780,8 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
SkString latticeCoords("");
|
||||
latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
|
||||
noiseCode.append("\n\tlattice = ");
|
||||
fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
|
||||
kVec2f_GrSLType);
|
||||
noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
|
||||
noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
|
||||
}
|
||||
@ -793,38 +793,38 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
|
||||
SkString noiseFuncName;
|
||||
if (fStitchTiles) {
|
||||
fsBuilder->emitFunction(kFloat_GrSLType,
|
||||
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
|
||||
gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
|
||||
fragBuilder->emitFunction(kFloat_GrSLType,
|
||||
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
|
||||
gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
|
||||
} else {
|
||||
fsBuilder->emitFunction(kFloat_GrSLType,
|
||||
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
|
||||
gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
|
||||
fragBuilder->emitFunction(kFloat_GrSLType,
|
||||
"perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
|
||||
gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
|
||||
}
|
||||
|
||||
// There are rounding errors if the floor operation is not performed here
|
||||
fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
|
||||
noiseVec, vCoords.c_str(), baseFrequencyUni);
|
||||
fragBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
|
||||
noiseVec, vCoords.c_str(), baseFrequencyUni);
|
||||
|
||||
// Clear the color accumulator
|
||||
fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor);
|
||||
|
||||
if (fStitchTiles) {
|
||||
// Set up TurbulenceInitial stitch values.
|
||||
fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
|
||||
fragBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
|
||||
fragBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
|
||||
|
||||
// Loop over all octaves
|
||||
fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
|
||||
fragBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
|
||||
|
||||
fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor);
|
||||
if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
|
||||
fsBuilder->codeAppend("abs(");
|
||||
fragBuilder->codeAppend("abs(");
|
||||
}
|
||||
if (fStitchTiles) {
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
|
||||
"\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
|
||||
noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
|
||||
@ -832,7 +832,7 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
|
||||
noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
|
||||
} else {
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
|
||||
"\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
|
||||
noiseFuncName.c_str(), chanCoordR, noiseVec,
|
||||
@ -841,32 +841,32 @@ void GrGLPerlinNoise::emitCode(EmitArgs& args) {
|
||||
noiseFuncName.c_str(), chanCoordA, noiseVec);
|
||||
}
|
||||
if (fType != SkPerlinNoiseShader::kFractalNoise_Type) {
|
||||
fsBuilder->codeAppendf(")"); // end of "abs("
|
||||
fragBuilder->codeAppendf(")"); // end of "abs("
|
||||
}
|
||||
fsBuilder->codeAppendf(" * %s;", ratio);
|
||||
fragBuilder->codeAppendf(" * %s;", ratio);
|
||||
|
||||
fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
|
||||
fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
|
||||
fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
|
||||
fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
|
||||
|
||||
if (fStitchTiles) {
|
||||
fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
|
||||
fragBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
|
||||
}
|
||||
fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
|
||||
fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
|
||||
|
||||
if (fType == SkPerlinNoiseShader::kFractalNoise_Type) {
|
||||
// The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
|
||||
// by fractalNoise and (turbulenceFunctionResult) by turbulence.
|
||||
fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);",
|
||||
args.fOutputColor,args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);",
|
||||
args.fOutputColor,args.fOutputColor);
|
||||
}
|
||||
|
||||
// Clamp values
|
||||
fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
|
||||
|
||||
// Pre-multiply the result
|
||||
fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
|
||||
args.fOutputColor, args.fOutputColor,
|
||||
args.fOutputColor, args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
|
||||
args.fOutputColor, args.fOutputColor,
|
||||
args.fOutputColor, args.fOutputColor);
|
||||
}
|
||||
|
||||
void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
|
||||
|
@ -420,46 +420,46 @@ void GLColorTableEffect::emitCode(EmitArgs& args) {
|
||||
"yoffsets", &yoffsets);
|
||||
static const float kColorScaleFactor = 255.0f / 256.0f;
|
||||
static const float kColorOffsetFactor = 1.0f / 512.0f;
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
if (nullptr == args.fInputColor) {
|
||||
// the input color is solid white (all ones).
|
||||
static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
|
||||
fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
|
||||
kMaxValue, kMaxValue, kMaxValue, kMaxValue);
|
||||
fragBuilder->codeAppendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
|
||||
kMaxValue, kMaxValue, kMaxValue, kMaxValue);
|
||||
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", args.fInputColor);
|
||||
fsBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n",
|
||||
args.fInputColor);
|
||||
fsBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
|
||||
kColorScaleFactor,
|
||||
kColorOffsetFactor, kColorOffsetFactor,
|
||||
kColorOffsetFactor, kColorOffsetFactor);
|
||||
fragBuilder->codeAppendf("\t\tfloat nonZeroAlpha = max(%s.a, .0001);\n", args.fInputColor);
|
||||
fragBuilder->codeAppendf("\t\tvec4 coord = vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha);\n",
|
||||
args.fInputColor);
|
||||
fragBuilder->codeAppendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
|
||||
kColorScaleFactor,
|
||||
kColorOffsetFactor, kColorOffsetFactor,
|
||||
kColorOffsetFactor, kColorOffsetFactor);
|
||||
}
|
||||
|
||||
SkString coord;
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s.a = ", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s.a = ", args.fOutputColor);
|
||||
coord.printf("vec2(coord.a, %s.a)", yoffsets);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s.r = ", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s.r = ", args.fOutputColor);
|
||||
coord.printf("vec2(coord.r, %s.r)", yoffsets);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s.g = ", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s.g = ", args.fOutputColor);
|
||||
coord.printf("vec2(coord.g, %s.g)", yoffsets);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s.b = ", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s.b = ", args.fOutputColor);
|
||||
coord.printf("vec2(coord.b, %s.b)", yoffsets);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], coord.c_str());
|
||||
fragBuilder->codeAppend(";\n");
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1027,61 +1027,61 @@ uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrProcessor& processor) {
|
||||
}
|
||||
|
||||
void GrGLGradientEffect::emitColor(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const GrGradientEffect& ge,
|
||||
const char* gradientTValue,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const TextureSamplerArray& samplers) {
|
||||
GrGLSLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
|
||||
if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){
|
||||
fsBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
|
||||
builder->getUniformVariable(fColorStartUni).c_str(),
|
||||
builder->getUniformVariable(fColorEndUni).c_str(),
|
||||
gradientTValue);
|
||||
fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
|
||||
builder->getUniformVariable(fColorStartUni).c_str(),
|
||||
builder->getUniformVariable(fColorEndUni).c_str(),
|
||||
gradientTValue);
|
||||
// Note that we could skip this step if both colors are known to be opaque. Two
|
||||
// considerations:
|
||||
// The gradient SkShader reporting opaque is more restrictive than necessary in the two pt
|
||||
// case. Make sure the key reflects this optimization (and note that it can use the same
|
||||
// shader as thekBeforeIterp case). This same optimization applies to the 3 color case below.
|
||||
if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
|
||||
fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
|
||||
fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
|
||||
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
|
||||
fragBuilder->codeAppendf("\t%s = %s;\n", outputColor,
|
||||
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
|
||||
} else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) {
|
||||
fsBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
|
||||
gradientTValue);
|
||||
fsBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
|
||||
builder->getUniformVariable(fColorStartUni).c_str());
|
||||
fragBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
|
||||
gradientTValue);
|
||||
fragBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
|
||||
builder->getUniformVariable(fColorStartUni).c_str());
|
||||
if (!builder->glslCaps()->canUseMinAndAbsTogether()) {
|
||||
// The Tegra3 compiler will sometimes never return if we have
|
||||
// min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
|
||||
fsBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
|
||||
fsBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
|
||||
fsBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
|
||||
builder->getUniformVariable(fColorMidUni).c_str());
|
||||
fragBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
|
||||
fragBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
|
||||
fragBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
|
||||
builder->getUniformVariable(fColorMidUni).c_str());
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
|
||||
builder->getUniformVariable(fColorMidUni).c_str());
|
||||
fragBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
|
||||
builder->getUniformVariable(fColorMidUni).c_str());
|
||||
}
|
||||
fsBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
|
||||
builder->getUniformVariable(fColorEndUni).c_str());
|
||||
fragBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
|
||||
builder->getUniformVariable(fColorEndUni).c_str());
|
||||
if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
|
||||
fsBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
|
||||
fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t%s = %s;\n", outputColor,
|
||||
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
|
||||
fragBuilder->codeAppendf("\t%s = %s;\n", outputColor,
|
||||
(GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
|
||||
gradientTValue,
|
||||
builder->getUniformVariable(fFSYUni).c_str());
|
||||
fsBuilder->codeAppendf("\t%s = ", outputColor);
|
||||
fsBuilder->appendTextureLookupAndModulate(inputColor,
|
||||
samplers[0],
|
||||
"coord");
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
|
||||
gradientTValue,
|
||||
builder->getUniformVariable(fFSYUni).c_str());
|
||||
fragBuilder->codeAppendf("\t%s = ", outputColor);
|
||||
fragBuilder->appendTextureLookupAndModulate(inputColor,
|
||||
samplers[0],
|
||||
"coord");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,6 +426,7 @@ protected:
|
||||
// control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
|
||||
// native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
|
||||
void emitColor(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const GrGradientEffect&,
|
||||
const char* gradientTValue,
|
||||
const char* outputColor,
|
||||
|
@ -604,9 +604,13 @@ const GrFragmentProcessor* GrLinearGradient::TestCreate(GrProcessorTestData* d)
|
||||
void GrGLLinearGradient::emitCode(EmitArgs& args) {
|
||||
const GrLinearGradient& ge = args.fFp.cast<GrLinearGradient>();
|
||||
this->emitUniforms(args.fBuilder, ge);
|
||||
SkString t = args.fBuilder->getFragmentShaderBuilder()->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString t = args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
t.append(".x");
|
||||
this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor,
|
||||
this->emitColor(args.fBuilder,
|
||||
args.fFragBuilder,
|
||||
ge, t.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
}
|
||||
|
||||
|
@ -501,9 +501,13 @@ void GrGLRadialGradient::emitCode(EmitArgs& args) {
|
||||
const GrRadialGradient& ge = args.fFp.cast<GrRadialGradient>();
|
||||
this->emitUniforms(args.fBuilder, ge);
|
||||
SkString t("length(");
|
||||
t.append(args.fBuilder->getFragmentShaderBuilder()->ensureFSCoords2D(args.fCoords, 0));
|
||||
t.append(args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0));
|
||||
t.append(")");
|
||||
this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor,
|
||||
this->emitColor(args.fBuilder,
|
||||
args.fFragBuilder,
|
||||
ge, t.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
}
|
||||
|
||||
|
@ -248,8 +248,7 @@ const GrFragmentProcessor* GrSweepGradient::TestCreate(GrProcessorTestData* d) {
|
||||
void GrGLSweepGradient::emitCode(EmitArgs& args) {
|
||||
const GrSweepGradient& ge = args.fFp.cast<GrSweepGradient>();
|
||||
this->emitUniforms(args.fBuilder, ge);
|
||||
SkString coords2D = args.fBuilder->getFragmentShaderBuilder()
|
||||
->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString coords2D = args.fFragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
SkString t;
|
||||
// 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
|
||||
// On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int
|
||||
@ -261,7 +260,11 @@ void GrGLSweepGradient::emitCode(EmitArgs& args) {
|
||||
t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5",
|
||||
coords2D.c_str(), coords2D.c_str());
|
||||
}
|
||||
this->emitColor(args.fBuilder, ge, t.c_str(), args.fOutputColor, args.fInputColor,
|
||||
this->emitColor(args.fBuilder,
|
||||
args.fFragBuilder,
|
||||
ge, t.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
}
|
||||
|
||||
|
@ -242,9 +242,9 @@ void GLEdge2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
SkASSERT(args.fCoords[0].getType() == args.fCoords[1].getType());
|
||||
const char* coords2D;
|
||||
SkString bVar;
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
if (kVec3f_GrSLType == args.fCoords[0].getType()) {
|
||||
fsBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
|
||||
fragBuilder->codeAppendf("\tvec3 interpolants = vec3(%s.xy / %s.z, %s.x / %s.z);\n",
|
||||
args.fCoords[0].c_str(), args.fCoords[0].c_str(),
|
||||
args.fCoords[1].c_str(), args.fCoords[1].c_str());
|
||||
coords2D = "interpolants.xy";
|
||||
@ -256,23 +256,28 @@ void GLEdge2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
|
||||
// output will default to transparent black (we simply won't write anything
|
||||
// else to it if invalid, instead of discarding or returning prematurely)
|
||||
fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
|
||||
// c = (x^2)+(y^2) - params[1]
|
||||
fsBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
|
||||
fragBuilder->codeAppendf("\tfloat %s = dot(%s, %s) - %s;\n",
|
||||
cName.c_str(), coords2D, coords2D, p1.c_str());
|
||||
|
||||
// linear case: t = -c/b
|
||||
fsBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
|
||||
fragBuilder->codeAppendf("\tfloat %s = -(%s / %s);\n", tName.c_str(),
|
||||
cName.c_str(), bVar.c_str());
|
||||
|
||||
// if r(t) > 0, then t will be the x coordinate
|
||||
fsBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
|
||||
fragBuilder->codeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
|
||||
p2.c_str(), p0.c_str());
|
||||
fsBuilder->codeAppend("\t");
|
||||
this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor,
|
||||
fragBuilder->codeAppend("\t");
|
||||
this->emitColor(args.fBuilder,
|
||||
fragBuilder,
|
||||
ge,
|
||||
tName.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
fsBuilder->codeAppend("\t}\n");
|
||||
fragBuilder->codeAppend("\t}\n");
|
||||
}
|
||||
|
||||
void GLEdge2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -511,35 +516,40 @@ void GLFocalOutside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
args.fBuilder->getUniformVariable(fParamUni).appendArrayAccess(1, &p1);
|
||||
|
||||
// if we have a vec3 from being in perspective, convert it to a vec2 first
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
const char* coords2D = coords2DString.c_str();
|
||||
|
||||
// t = p.x * focal.x +/- sqrt(p.x^2 + (1 - focal.x^2) * p.y^2)
|
||||
|
||||
// output will default to transparent black (we simply won't write anything
|
||||
// else to it if invalid, instead of discarding or returning prematurely)
|
||||
fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
|
||||
fsBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
|
||||
fsBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
|
||||
fsBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat xs = %s.x * %s.x;\n", coords2D, coords2D);
|
||||
fragBuilder->codeAppendf("\tfloat ys = %s.y * %s.y;\n", coords2D, coords2D);
|
||||
fragBuilder->codeAppendf("\tfloat d = xs + %s * ys;\n", p1.c_str());
|
||||
|
||||
// Must check to see if we flipped the circle order (to make sure start radius < end radius)
|
||||
// If so we must also flip sign on sqrt
|
||||
if (!fIsFlipped) {
|
||||
fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(),
|
||||
coords2D, p0.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat %s = %s.x * %s + sqrt(d);\n", tName.c_str(),
|
||||
coords2D, p0.c_str());
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(),
|
||||
coords2D, p0.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat %s = %s.x * %s - sqrt(d);\n", tName.c_str(),
|
||||
coords2D, p0.c_str());
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
|
||||
fsBuilder->codeAppend("\t\t");
|
||||
this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor,
|
||||
fragBuilder->codeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
|
||||
fragBuilder->codeAppend("\t\t");
|
||||
this->emitColor(args.fBuilder,
|
||||
fragBuilder,
|
||||
ge,
|
||||
tName.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
fsBuilder->codeAppend("\t}\n");
|
||||
fragBuilder->codeAppend("\t}\n");
|
||||
}
|
||||
|
||||
void GLFocalOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -713,15 +723,20 @@ void GLFocalInside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLShaderVar focal = args.fBuilder->getUniformVariable(fFocalUni);
|
||||
|
||||
// if we have a vec3 from being in perspective, convert it to a vec2 first
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
const char* coords2D = coords2DString.c_str();
|
||||
|
||||
// t = p.x * focalX + length(p)
|
||||
fsBuilder->codeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(),
|
||||
fragBuilder->codeAppendf("\tfloat %s = %s.x * %s + length(%s);\n", tName.c_str(),
|
||||
coords2D, focal.c_str(), coords2D);
|
||||
|
||||
this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor,
|
||||
this->emitColor(args.fBuilder,
|
||||
fragBuilder,
|
||||
ge,
|
||||
tName.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
}
|
||||
|
||||
@ -963,8 +978,8 @@ void GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLShaderVar params = args.fBuilder->getUniformVariable(fParamUni);
|
||||
|
||||
// if we have a vec3 from being in perspective, convert it to a vec2 first
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
const char* coords2D = coords2DString.c_str();
|
||||
|
||||
// p = coords2D
|
||||
@ -975,13 +990,18 @@ void GLCircleInside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
// C = 1 / A
|
||||
// d = dot(e, p) + B
|
||||
// t = d +/- sqrt(d^2 - A * dot(p, p) + C)
|
||||
fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
|
||||
fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(),
|
||||
params.c_str());
|
||||
fsBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
|
||||
tName.c_str(), params.c_str(), params.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
|
||||
fragBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(),
|
||||
params.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
|
||||
tName.c_str(), params.c_str(), params.c_str());
|
||||
|
||||
this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor,
|
||||
this->emitColor(args.fBuilder,
|
||||
fragBuilder,
|
||||
ge,
|
||||
tName.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
}
|
||||
|
||||
@ -1193,13 +1213,13 @@ void GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLShaderVar params = args.fBuilder->getUniformVariable(fParamUni);
|
||||
|
||||
// if we have a vec3 from being in perspective, convert it to a vec2 first
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2DString = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2DString = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
const char* coords2D = coords2DString.c_str();
|
||||
|
||||
// output will default to transparent black (we simply won't write anything
|
||||
// else to it if invalid, instead of discarding or returning prematurely)
|
||||
fsBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t%s = vec4(0.0,0.0,0.0,0.0);\n", args.fOutputColor);
|
||||
|
||||
// p = coords2D
|
||||
// e = center end
|
||||
@ -1210,25 +1230,30 @@ void GLCircleOutside2PtConicalEffect::emitCode(EmitArgs& args) {
|
||||
// d = dot(e, p) + B
|
||||
// t = d +/- sqrt(d^2 - A * dot(p, p) + C)
|
||||
|
||||
fsBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
|
||||
fsBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(),
|
||||
params.c_str());
|
||||
fsBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(),
|
||||
params.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat pDotp = dot(%s, %s);\n", coords2D, coords2D);
|
||||
fragBuilder->codeAppendf("\tfloat d = dot(%s, %s) + %s.y;\n", coords2D, center.c_str(),
|
||||
params.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat deter = d * d - %s.x * pDotp + %s.z;\n", params.c_str(),
|
||||
params.c_str());
|
||||
|
||||
// Must check to see if we flipped the circle order (to make sure start radius < end radius)
|
||||
// If so we must also flip sign on sqrt
|
||||
if (!fIsFlipped) {
|
||||
fsBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat %s = d + sqrt(deter);\n", tName.c_str());
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
|
||||
fragBuilder->codeAppendf("\tfloat %s = d - sqrt(deter);\n", tName.c_str());
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
|
||||
fsBuilder->codeAppend("\t\t");
|
||||
this->emitColor(args.fBuilder, ge, tName.c_str(), args.fOutputColor, args.fInputColor,
|
||||
fragBuilder->codeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
|
||||
fragBuilder->codeAppend("\t\t");
|
||||
this->emitColor(args.fBuilder,
|
||||
fragBuilder,
|
||||
ge,
|
||||
tName.c_str(),
|
||||
args.fOutputColor,
|
||||
args.fInputColor,
|
||||
args.fSamplers);
|
||||
fsBuilder->codeAppend("\t}\n");
|
||||
fragBuilder->codeAppend("\t}\n");
|
||||
}
|
||||
|
||||
void GLCircleOutside2PtConicalEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -64,47 +64,64 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
|
||||
const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(gp);
|
||||
vertBuilder->emitAttributes(gp);
|
||||
|
||||
// Setup pass through color
|
||||
if (!gp.colorIgnored()) {
|
||||
if (gp.hasVertexColor()) {
|
||||
pb->addPassThroughAttribute(gp.inColor(), args.fOutputColor);
|
||||
} else {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix(),
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
gp.inPosition()->fName,
|
||||
gp.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
if (gp.hasExplicitLocalCoords()) {
|
||||
// emit transforms with explicit local coords
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, gp.inLocalCoords()->fName,
|
||||
gp.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inLocalCoords()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
} else if(gp.hasTransformedLocalCoords()) {
|
||||
// transforms have already been applied to vertex attributes on the cpu
|
||||
this->emitTransforms(pb, gp.inLocalCoords()->fName,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gp.inLocalCoords()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
} else {
|
||||
// emit transforms with position
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, gp.inPosition()->fName,
|
||||
gp.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
}
|
||||
|
||||
// Setup coverage as pass through
|
||||
if (!gp.coverageWillBeIgnored()) {
|
||||
if (gp.hasVertexCoverage()) {
|
||||
fs->codeAppendf("float alpha = 1.0;");
|
||||
fragBuilder->codeAppendf("float alpha = 1.0;");
|
||||
args.fPB->addPassThroughAttribute(gp.inCoverage(), "alpha");
|
||||
fs->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
} else if (gp.coverage() == 0xff) {
|
||||
fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
} else {
|
||||
const char* fragCoverage;
|
||||
fCoverageUniform = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
@ -112,7 +129,7 @@ public:
|
||||
kDefault_GrSLPrecision,
|
||||
"Coverage",
|
||||
&fragCoverage);
|
||||
fs->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,11 +153,11 @@ const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor(
|
||||
GLFP() {}
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
this->emitChild(0, nullptr, args);
|
||||
fsBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
|
||||
fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
|
||||
args.fInputColor);
|
||||
fsBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
|
||||
fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
|
||||
}
|
||||
};
|
||||
return new GLFP;
|
||||
|
@ -98,37 +98,43 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
|
||||
const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(ce);
|
||||
vertBuilder->emitAttributes(ce);
|
||||
|
||||
GrGLSLVertToFrag v(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("CircleEdge", &v);
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// setup pass through color
|
||||
if (!ce.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, ce.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, ce.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, ce.inPosition()->fName,
|
||||
ce.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
ce.inPosition()->fName,
|
||||
ce.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);", v.fsIn());
|
||||
fragBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);",
|
||||
v.fsIn());
|
||||
if (ce.isStroked()) {
|
||||
fsBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
|
||||
fragBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha *= innerAlpha;");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
static void GenKey(const GrGeometryProcessor& gp,
|
||||
@ -246,58 +252,63 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
|
||||
const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(ee);
|
||||
vertBuilder->emitAttributes(ee);
|
||||
|
||||
GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
|
||||
vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
|
||||
vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
|
||||
ee.inEllipseOffset()->fName);
|
||||
|
||||
GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("EllipseRadii", &ellipseRadii);
|
||||
vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
|
||||
vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
|
||||
ee.inEllipseRadii()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// setup pass through color
|
||||
if (!ee.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, ee.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, ee.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName,
|
||||
ee.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
ee.inPosition()->fName,
|
||||
ee.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
// for outer curve
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||
ellipseRadii.fsIn());
|
||||
fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
|
||||
fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
|
||||
fragBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||
ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("float grad_dot = dot(grad, grad);");
|
||||
|
||||
// avoid calling inversesqrt on zero.
|
||||
fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
|
||||
fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
|
||||
fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
|
||||
|
||||
// for inner curve
|
||||
if (ee.isStroked()) {
|
||||
fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
|
||||
ellipseOffsets.fsIn(), ellipseRadii.fsIn());
|
||||
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
|
||||
ellipseRadii.fsIn());
|
||||
fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
|
||||
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
|
||||
ellipseOffsets.fsIn(), ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
|
||||
ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
|
||||
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
static void GenKey(const GrGeometryProcessor& gp,
|
||||
@ -421,73 +432,81 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
|
||||
const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(ee);
|
||||
vertBuilder->emitAttributes(ee);
|
||||
|
||||
GrGLSLVertToFrag offsets0(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("EllipseOffsets0", &offsets0);
|
||||
vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
|
||||
vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
|
||||
ee.inEllipseOffsets0()->fName);
|
||||
|
||||
GrGLSLVertToFrag offsets1(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("EllipseOffsets1", &offsets1);
|
||||
vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
|
||||
vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
|
||||
ee.inEllipseOffsets1()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// setup pass through color
|
||||
if (!ee.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, ee.inPosition()->fName, ee.viewMatrix(),
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
ee.inPosition()->fName,
|
||||
ee.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
ee.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
// for outer curve
|
||||
fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
|
||||
fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
|
||||
offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
|
||||
fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
|
||||
offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn());
|
||||
|
||||
fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
|
||||
fragBuilder->codeAppend("float grad_dot = dot(grad, grad);");
|
||||
// avoid calling inversesqrt on zero.
|
||||
fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
|
||||
if (kHairline == ee.getMode()) {
|
||||
// can probably do this with one step
|
||||
fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
|
||||
fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
|
||||
} else {
|
||||
fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
|
||||
}
|
||||
|
||||
// for inner curve
|
||||
if (kStroke == ee.getMode()) {
|
||||
fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
|
||||
fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
|
||||
fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
|
||||
fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
|
||||
offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
|
||||
offsets1.fsIn());
|
||||
fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
|
||||
fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
|
||||
fragBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
|
||||
fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
|
||||
fragBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
|
||||
fragBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
|
||||
offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
|
||||
offsets1.fsIn());
|
||||
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
|
||||
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
static void GenKey(const GrGeometryProcessor& gp,
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
|
||||
|
||||
// emit transforms
|
||||
@ -40,12 +40,12 @@ public:
|
||||
kDefault_GrSLPrecision,
|
||||
"Color",
|
||||
&stagedLocalVarName);
|
||||
fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
|
||||
}
|
||||
|
||||
// setup constant solid coverage
|
||||
if (pathProc.opts().readsCoverage()) {
|
||||
fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,50 +549,54 @@ public:
|
||||
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
|
||||
const QuadEdgeEffect& qe = args.fGP.cast<QuadEdgeEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(qe);
|
||||
vertBuilder->emitAttributes(qe);
|
||||
|
||||
GrGLSLVertToFrag v(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("QuadEdge", &v);
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), qe.inQuadEdge()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!qe.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, qe.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, qe.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, qe.inPosition()->fName,
|
||||
qe.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
qe.inPosition()->fName,
|
||||
qe.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("float edgeAlpha;");
|
||||
fragBuilder->codeAppendf("float edgeAlpha;");
|
||||
|
||||
// keep the derivative instructions outside the conditional
|
||||
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
|
||||
// today we know z and w are in device space. We could use derivatives
|
||||
fsBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),
|
||||
v.fsIn());
|
||||
fsBuilder->codeAppendf ("} else {");
|
||||
fsBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(),
|
||||
v.fsIn());
|
||||
fsBuilder->codeAppendf("edgeAlpha = "
|
||||
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
|
||||
fragBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),
|
||||
v.fsIn());
|
||||
fragBuilder->codeAppendf ("} else {");
|
||||
fragBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,"
|
||||
" 2.0*%s.x*duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(),
|
||||
v.fsIn());
|
||||
fragBuilder->codeAppendf("edgeAlpha = "
|
||||
"clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& gp,
|
||||
|
@ -73,79 +73,89 @@ GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
|
||||
|
||||
void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(gp);
|
||||
vertBuilder->emitAttributes(gp);
|
||||
|
||||
GrGLSLVertToFrag v(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("ConicCoeffs", &v);
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!gp.colorIgnored()) {
|
||||
this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(args.fPB, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix(), &fViewMatrixUniform);
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
gp.inPosition()->fName,
|
||||
gp.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms with position
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(),
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppend("float edgeAlpha;");
|
||||
fragBuilder->codeAppend("float edgeAlpha;");
|
||||
|
||||
switch (fEdgeType) {
|
||||
case kHairlineAA_GrProcessorEdgeType: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
|
||||
fsBuilder->codeAppendf("float dfdx ="
|
||||
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("float dfdy ="
|
||||
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
|
||||
fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
|
||||
fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("func = abs(func);");
|
||||
fsBuilder->codeAppend("edgeAlpha = func / gFM;");
|
||||
fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
|
||||
fragBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
|
||||
fragBuilder->codeAppendf("float dfdx ="
|
||||
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("float dfdy ="
|
||||
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
|
||||
fragBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
|
||||
fragBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("func = abs(func);");
|
||||
fragBuilder->codeAppend("edgeAlpha = func / gFM;");
|
||||
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
break;
|
||||
}
|
||||
case kFillAA_GrProcessorEdgeType: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
|
||||
fsBuilder->codeAppendf("float dfdx ="
|
||||
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("float dfdy ="
|
||||
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
|
||||
fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
|
||||
fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha = func / gFM;");
|
||||
fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
|
||||
fragBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
|
||||
fragBuilder->codeAppendf("float dfdx ="
|
||||
"2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("float dfdy ="
|
||||
"2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
|
||||
fragBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
|
||||
fragBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha = func / gFM;");
|
||||
fragBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
break;
|
||||
}
|
||||
case kFillBW_GrProcessorEdgeType: {
|
||||
fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
|
||||
fragBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -160,9 +170,9 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
kDefault_GrSLPrecision,
|
||||
"Coverage",
|
||||
&coverageScale);
|
||||
fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
|
||||
fragBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -289,65 +299,78 @@ GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
|
||||
|
||||
void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(gp);
|
||||
vertBuilder->emitAttributes(gp);
|
||||
|
||||
GrGLSLVertToFrag v(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("HairQuadEdge", &v);
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!gp.colorIgnored()) {
|
||||
this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(args.fPB, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, gp.inPosition()->fName, gp.viewMatrix(), &fViewMatrixUniform);
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
gp.inPosition()->fName,
|
||||
gp.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms with position
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(),
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
gp.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("float edgeAlpha;");
|
||||
fragBuilder->codeAppendf("float edgeAlpha;");
|
||||
|
||||
switch (fEdgeType) {
|
||||
case kHairlineAA_GrProcessorEdgeType: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
|
||||
" 2.0 * %s.x * duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
|
||||
fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
|
||||
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
|
||||
" 2.0 * %s.x * duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
|
||||
fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
break;
|
||||
}
|
||||
case kFillAA_GrProcessorEdgeType: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
|
||||
" 2.0 * %s.x * duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
|
||||
fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
|
||||
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
|
||||
" 2.0 * %s.x * duvdy.x - duvdy.y);",
|
||||
v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
|
||||
fragBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
|
||||
break;
|
||||
}
|
||||
case kFillBW_GrProcessorEdgeType: {
|
||||
fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
|
||||
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -357,13 +380,13 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
if (0xff != gp.coverageScale()) {
|
||||
const char* coverageScale;
|
||||
fCoverageScaleUniform = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kFloat_GrSLType,
|
||||
kDefault_GrSLPrecision,
|
||||
"Coverage",
|
||||
&coverageScale);
|
||||
fsBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
|
||||
kFloat_GrSLType,
|
||||
kDefault_GrSLPrecision,
|
||||
"Coverage",
|
||||
&coverageScale);
|
||||
fragBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,30 +499,38 @@ GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor)
|
||||
}
|
||||
|
||||
void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(gp);
|
||||
vertBuilder->emitAttributes(gp);
|
||||
|
||||
GrGLSLVertToFrag v(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!gp.colorIgnored()) {
|
||||
this->setupUniformColor(args.fPB, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(args.fPB, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(args.fPB, gpArgs, gp.inPosition()->fName, gp.viewMatrix(),
|
||||
this->setupPosition(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
gp.inPosition()->fName,
|
||||
gp.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms with position
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, gp.inPosition()->fName, args.fTransformsIn,
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
gp.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
|
||||
GrGLSLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
|
||||
GrGLSLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
|
||||
@ -510,72 +541,77 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
GrGLSLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
|
||||
GrGLSLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
|
||||
|
||||
fsBuilder->declAppend(edgeAlpha);
|
||||
fsBuilder->declAppend(dklmdx);
|
||||
fsBuilder->declAppend(dklmdy);
|
||||
fsBuilder->declAppend(dfdx);
|
||||
fsBuilder->declAppend(dfdy);
|
||||
fsBuilder->declAppend(gF);
|
||||
fsBuilder->declAppend(gFM);
|
||||
fsBuilder->declAppend(func);
|
||||
fragBuilder->declAppend(edgeAlpha);
|
||||
fragBuilder->declAppend(dklmdx);
|
||||
fragBuilder->declAppend(dklmdy);
|
||||
fragBuilder->declAppend(dfdx);
|
||||
fragBuilder->declAppend(dfdy);
|
||||
fragBuilder->declAppend(gF);
|
||||
fragBuilder->declAppend(gFM);
|
||||
fragBuilder->declAppend(func);
|
||||
|
||||
switch (fEdgeType) {
|
||||
case kHairlineAA_GrProcessorEdgeType: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
|
||||
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
|
||||
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
|
||||
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
|
||||
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
|
||||
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
|
||||
fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
|
||||
fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
|
||||
fsBuilder->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());
|
||||
fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
|
||||
fsBuilder->codeAppendf("%s = %s / %s;",
|
||||
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
|
||||
fsBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
|
||||
edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
|
||||
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
|
||||
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
|
||||
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
|
||||
fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
|
||||
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
|
||||
gFM.c_str(), gF.c_str(), gF.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
|
||||
func.c_str(), v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s / %s;",
|
||||
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
|
||||
fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
|
||||
edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
|
||||
// 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: {
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
|
||||
fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
|
||||
fsBuilder->codeAppendf("%s ="
|
||||
"3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
|
||||
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
|
||||
fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
|
||||
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
|
||||
fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
|
||||
fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
|
||||
fsBuilder->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());
|
||||
fsBuilder->codeAppendf("%s = %s / %s;",
|
||||
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
|
||||
fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
|
||||
edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s ="
|
||||
"3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
|
||||
dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
|
||||
fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
|
||||
dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
|
||||
dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
|
||||
fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
|
||||
fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
|
||||
gFM.c_str(), gF.c_str(), gF.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
|
||||
func.c_str(), v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = %s / %s;",
|
||||
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
|
||||
fragBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
|
||||
edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
// Add line below for smooth cubic ramp
|
||||
// fsBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
|
||||
// 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: {
|
||||
fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
|
||||
edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
|
||||
edgeAlpha.c_str(), v.fsIn(), v.fsIn(),
|
||||
v.fsIn(), v.fsIn(), v.fsIn());
|
||||
fragBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -583,7 +619,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
}
|
||||
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
|
||||
fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
|
||||
}
|
||||
|
||||
void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp,
|
||||
|
@ -72,39 +72,42 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLShaderVar("c2", kVec4f_GrSLType),
|
||||
GrGLSLShaderVar("c3", kVec4f_GrSLType),
|
||||
};
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
fsBuilder->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);
|
||||
fsBuilder->codeAppendf("\tvec2 coord = %s - %s * vec2(0.5);\n", coords2D.c_str(), imgInc);
|
||||
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.
|
||||
fsBuilder->codeAppendf("\tcoord /= %s;\n", imgInc);
|
||||
fsBuilder->codeAppend("\tvec2 f = fract(coord);\n");
|
||||
fsBuilder->codeAppendf("\tcoord = (coord - f + vec2(0.5)) * %s;\n", imgInc);
|
||||
fsBuilder->codeAppend("\tvec4 rowColors[4];\n");
|
||||
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(fsBuilder, domain, sampleVar.c_str(), coord, args.fSamplers[0]);
|
||||
fDomain.sampleTexture(fragBuilder, domain, sampleVar.c_str(), coord, args.fSamplers[0]);
|
||||
}
|
||||
fsBuilder->codeAppendf("\tvec4 s%d = %s(%s, f.x, rowColors[0], rowColors[1], rowColors[2], rowColors[3]);\n", y, cubicBlendName.c_str(), coeff);
|
||||
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);
|
||||
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutputColor,(GrGLSLExpr4(bicubicColor.c_str()) *
|
||||
GrGLSLExpr4(args.fInputColor)).c_str());
|
||||
fragBuilder->codeAppendf("\t%s = %s;\n",
|
||||
args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str()) *
|
||||
GrGLSLExpr4(args.fInputColor)).c_str());
|
||||
}
|
||||
|
||||
void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -22,10 +22,10 @@ public:
|
||||
const GrBitmapTextGeoProc& cte = args.fGP.cast<GrBitmapTextGeoProc>();
|
||||
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(cte);
|
||||
vertBuilder->emitAttributes(cte);
|
||||
|
||||
// compute numbers to be hardcoded to convert texture coordinates from int to float
|
||||
SkASSERT(cte.numTextures() == 1);
|
||||
@ -36,45 +36,50 @@ public:
|
||||
|
||||
GrGLSLVertToFrag v(kVec2f_GrSLType);
|
||||
pb->addVarying("TextureCoords", &v);
|
||||
vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(),
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
||||
cte.inTextureCoords()->fName);
|
||||
vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", v.vsOut(),
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
||||
cte.inTextureCoords()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!cte.colorIgnored()) {
|
||||
if (cte.hasVertexColor()) {
|
||||
pb->addPassThroughAttribute(cte.inColor(), args.fOutputColor);
|
||||
} else {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, cte.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, cte.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, cte.inPosition()->fName,
|
||||
cte.localMatrix(), args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
cte.inPosition()->fName,
|
||||
cte.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
if (cte.maskFormat() == kARGB_GrMaskFormat) {
|
||||
fsBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookupAndModulate(args.fOutputColor,
|
||||
args.fSamplers[0],
|
||||
v.fsIn(),
|
||||
kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";");
|
||||
fsBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookupAndModulate(args.fOutputColor,
|
||||
args.fSamplers[0],
|
||||
v.fsIn(),
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(";");
|
||||
fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = ", args.fOutputCoverage);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";");
|
||||
fragBuilder->codeAppendf("%s = ", args.fOutputCoverage);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], v.fsIn(), kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(";");
|
||||
if (cte.maskFormat() == kA565_GrMaskFormat) {
|
||||
// set alpha to be max of rgb coverage
|
||||
fsBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
|
||||
args.fOutputCoverage, args.fOutputCoverage,
|
||||
args.fOutputCoverage, args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
|
||||
args.fOutputCoverage, args.fOutputCoverage,
|
||||
args.fOutputCoverage, args.fOutputCoverage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,23 +30,23 @@ public:
|
||||
SkString tmpDecl;
|
||||
tmpVar.appendDecl(args.fBuilder->glslCaps(), &tmpDecl);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
fsBuilder->codeAppendf("%s;", tmpDecl.c_str());
|
||||
fragBuilder->codeAppendf("%s;", tmpDecl.c_str());
|
||||
|
||||
fsBuilder->codeAppendf("%s = ", tmpVar.c_str());
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
fragBuilder->codeAppendf("%s = ", tmpVar.c_str());
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
args.fCoords[0].getType());
|
||||
fsBuilder->codeAppend(";");
|
||||
fragBuilder->codeAppend(";");
|
||||
|
||||
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
|
||||
SkASSERT(fSwapRedAndBlue);
|
||||
fsBuilder->codeAppendf("%s = %s.bgra;", args.fOutputColor, tmpVar.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s.bgra;", args.fOutputColor, tmpVar.c_str());
|
||||
} else {
|
||||
const char* swiz = fSwapRedAndBlue ? "bgr" : "rgb";
|
||||
switch (fPMConversion) {
|
||||
case GrConfigConversionEffect::kMulByAlpha_RoundUp_PMConversion:
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"%s = vec4(ceil(%s.%s * %s.a * 255.0) / 255.0, %s.a);",
|
||||
tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
||||
break;
|
||||
@ -55,17 +55,17 @@ public:
|
||||
// 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.
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"%s = vec4(floor(%s.%s * %s.a * 255.0 + 0.001) / 255.0, %s.a);",
|
||||
tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
||||
break;
|
||||
case GrConfigConversionEffect::kDivByAlpha_RoundUp_PMConversion:
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(ceil(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
|
||||
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
||||
break;
|
||||
case GrConfigConversionEffect::kDivByAlpha_RoundDown_PMConversion:
|
||||
fsBuilder->codeAppendf(
|
||||
fragBuilder->codeAppendf(
|
||||
"%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(floor(%s.%s / %s.a * 255.0) / 255.0, %s.a);",
|
||||
tmpVar.c_str(), tmpVar.c_str(), tmpVar.c_str(), swiz, tmpVar.c_str(), tmpVar.c_str());
|
||||
break;
|
||||
@ -73,11 +73,11 @@ public:
|
||||
SkFAIL("Unknown conversion op.");
|
||||
break;
|
||||
}
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str());
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, tmpVar.c_str());
|
||||
}
|
||||
SkString modulate;
|
||||
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrProcessor& processor, const GrGLSLCaps&,
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
GLConstColorProcessor() : fPrevColor(GrColor_ILLEGAL) {}
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* colorUni;
|
||||
fColorUniform = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec4f_GrSLType, kMedium_GrSLPrecision, "constantColor",
|
||||
@ -27,14 +27,14 @@ public:
|
||||
}
|
||||
switch (mode) {
|
||||
case GrConstColorProcessor::kIgnore_InputMode:
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUni);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorUni);
|
||||
break;
|
||||
case GrConstColorProcessor::kModulateRGBA_InputMode:
|
||||
fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, args.fInputColor,
|
||||
fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputColor, args.fInputColor,
|
||||
colorUni);
|
||||
break;
|
||||
case GrConstColorProcessor::kModulateA_InputMode:
|
||||
fsBuilder->codeAppendf("%s = %s.a * %s;", args.fOutputColor, args.fInputColor,
|
||||
fragBuilder->codeAppendf("%s = %s.a * %s;", args.fOutputColor, args.fInputColor,
|
||||
colorUni);
|
||||
break;
|
||||
}
|
||||
|
@ -111,32 +111,32 @@ void GLAARectEffect::emitCode(EmitArgs& args) {
|
||||
"rect",
|
||||
&rectName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* fragmentPos = fragBuilder->fragmentPosition();
|
||||
if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) {
|
||||
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
|
||||
// numbers, xSub and ySub.
|
||||
fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
|
||||
fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppend("\t\tfloat xSub, ySub;\n");
|
||||
fragBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos);
|
||||
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
|
||||
// covered.
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n");
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
|
||||
fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n");
|
||||
fragBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos);
|
||||
}
|
||||
|
||||
if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) {
|
||||
fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
|
||||
fragBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
|
||||
}
|
||||
fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
}
|
||||
|
||||
void GLAARectEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -197,26 +197,26 @@ void GrGLConvexPolyEffect::emitCode(EmitArgs& args) {
|
||||
"edges",
|
||||
cpe.getEdgeCount(),
|
||||
&edgeArrayName);
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n");
|
||||
fsBuilder->codeAppend("\t\tfloat edge;\n");
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
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) {
|
||||
fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
|
||||
edgeArrayName, i, fragmentPos, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n",
|
||||
edgeArrayName, i, fragmentPos, fragmentPos);
|
||||
if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) {
|
||||
fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n");
|
||||
} else {
|
||||
fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
|
||||
fragBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n");
|
||||
}
|
||||
fsBuilder->codeAppend("\t\talpha *= edge;\n");
|
||||
fragBuilder->codeAppend("\t\talpha *= edge;\n");
|
||||
}
|
||||
|
||||
if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) {
|
||||
fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
|
||||
fragBuilder->codeAppend("\talpha = 1.0 - alpha;\n");
|
||||
}
|
||||
fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
fragBuilder->codeAppendf("\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
}
|
||||
|
||||
void GrGLConvexPolyEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -60,16 +60,16 @@ void GrGLConvolutionEffect::emitCode(EmitArgs& args) {
|
||||
kFloat_GrSLType, kDefault_GrSLPrecision,
|
||||
"Kernel", this->width());
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", args.fOutputColor);
|
||||
|
||||
int width = this->width();
|
||||
const GrGLSLShaderVar& kernel = args.fBuilder->getUniformVariable(fKernelUni);
|
||||
const char* imgInc = args.fBuilder->getUniformCStr(fImageIncrementUni);
|
||||
|
||||
fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
|
||||
fragBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc);
|
||||
|
||||
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
|
||||
for (int i = 0; i < width; i++) {
|
||||
@ -84,21 +84,21 @@ void GrGLConvolutionEffect::emitCode(EmitArgs& args) {
|
||||
// to have a bug that caused corruption.
|
||||
const char* bounds = args.fBuilder->getUniformCStr(fBoundsUni);
|
||||
const char* component = this->direction() == Gr1DKernelEffect::kY_Direction ? "y" : "x";
|
||||
fsBuilder->codeAppendf("if (coord.%s >= %s.x && coord.%s <= %s.y) {",
|
||||
component, bounds, component, bounds);
|
||||
fragBuilder->codeAppendf("if (coord.%s >= %s.x && coord.%s <= %s.y) {",
|
||||
component, bounds, component, bounds);
|
||||
}
|
||||
fsBuilder->codeAppendf("\t\t%s += ", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "coord");
|
||||
fsBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s += ", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], "coord");
|
||||
fragBuilder->codeAppendf(" * %s;\n", kernelIndex.c_str());
|
||||
if (this->useBounds()) {
|
||||
fsBuilder->codeAppend("}");
|
||||
fragBuilder->codeAppend("}");
|
||||
}
|
||||
fsBuilder->codeAppendf("\t\tcoord += %s;\n", imgInc);
|
||||
fragBuilder->codeAppendf("\t\tcoord += %s;\n", imgInc);
|
||||
}
|
||||
|
||||
SkString modulate;
|
||||
GrGLSLMulVarBy4f(&modulate, args.fOutputColor, args.fInputColor);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLConvolutionEffect::onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -72,12 +72,12 @@ public:
|
||||
private:
|
||||
void emitOutputsForBlendState(const EmitArgs& args) override {
|
||||
const CoverageSetOpXP& xp = args.fXP.cast<CoverageSetOpXP>();
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
|
||||
if (xp.invertCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("%s = 1.0 - %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,26 +146,29 @@ private:
|
||||
const CustomXP& xp = args.fXP.cast<CustomXP>();
|
||||
SkASSERT(xp.hasHWBlendEquation());
|
||||
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
fragBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
|
||||
|
||||
// Apply coverage by multiplying it into the src color before blending. Mixed samples will
|
||||
// "just work" automatically. (See onGetOptimizations())
|
||||
if (xp.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = %s * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage, args.fInputColor);
|
||||
fragBuilder->codeAppendf("%s = %s * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage, args.fInputColor);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor);
|
||||
}
|
||||
}
|
||||
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor,
|
||||
const char* outColor, const GrXferProcessor& proc) override {
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const GrXferProcessor& proc) override {
|
||||
const CustomXP& xp = proc.cast<CustomXP>();
|
||||
SkASSERT(!xp.hasHWBlendEquation());
|
||||
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
GrGLSLBlend::AppendMode(fsBuilder, srcColor, dstColor, outColor, xp.mode());
|
||||
GrGLSLBlend::AppendMode(fragBuilder, srcColor, dstColor, outColor, xp.mode());
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
|
@ -852,50 +852,55 @@ GLDashingCircleEffect::GLDashingCircleEffect() {
|
||||
void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
const DashingCircleEffect& dce = args.fGP.cast<DashingCircleEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(dce);
|
||||
vertBuilder->emitAttributes(dce);
|
||||
|
||||
// XY are dashPos, Z is dashInterval
|
||||
GrGLSLVertToFrag dashParams(kVec3f_GrSLType);
|
||||
args.fPB->addVarying("DashParam", &dashParams);
|
||||
vsBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", dashParams.vsOut(), dce.inDashParams()->fName);
|
||||
|
||||
// x refers to circle radius - 0.5, y refers to cicle's center x coord
|
||||
GrGLSLVertToFrag circleParams(kVec2f_GrSLType);
|
||||
args.fPB->addVarying("CircleParams", &circleParams);
|
||||
vsBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", circleParams.vsOut(), dce.inCircleParams()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!dce.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, dce.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, dce.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, dce.inPosition()->fName, dce.localMatrix(),
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
dce.inPosition()->fName,
|
||||
dce.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
// transforms all points so that we can compare them to our test circle
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn(),
|
||||
dashParams.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashParams.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn());
|
||||
fsBuilder->codeAppend("float dist = length(center - fragPosShifted);");
|
||||
fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
dashParams.fsIn(), dashParams.fsIn(), dashParams.fsIn(),
|
||||
dashParams.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", dashParams.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 center = vec2(%s.y, 0.0);", circleParams.fsIn());
|
||||
fragBuilder->codeAppend("float dist = length(center - fragPosShifted);");
|
||||
if (dce.aaMode() != kBW_DashAAMode) {
|
||||
fsBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn());
|
||||
fsBuilder->codeAppend("diff = 1.0 - diff;");
|
||||
fsBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);");
|
||||
fragBuilder->codeAppendf("float diff = dist - %s.x;", circleParams.fsIn());
|
||||
fragBuilder->codeAppend("diff = 1.0 - diff;");
|
||||
fragBuilder->codeAppend("float alpha = clamp(diff, 0.0, 1.0);");
|
||||
} else {
|
||||
fsBuilder->codeAppendf("float alpha = 1.0;");
|
||||
fsBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circleParams.fsIn());
|
||||
fragBuilder->codeAppendf("float alpha = 1.0;");
|
||||
fragBuilder->codeAppendf("alpha *= dist < %s.x + 0.5 ? 1.0 : 0.0;", circleParams.fsIn());
|
||||
}
|
||||
fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -1058,69 +1063,74 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
||||
const DashingLineEffect& de = args.fGP.cast<DashingLineEffect>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(de);
|
||||
vertBuilder->emitAttributes(de);
|
||||
|
||||
// XY refers to dashPos, Z is the dash interval length
|
||||
GrGLSLVertToFrag inDashParams(kVec3f_GrSLType);
|
||||
args.fPB->addVarying("DashParams", &inDashParams, GrSLPrecision::kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.inDashParams()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", inDashParams.vsOut(), de.inDashParams()->fName);
|
||||
|
||||
// The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5),
|
||||
// respectively.
|
||||
GrGLSLVertToFrag inRectParams(kVec4f_GrSLType);
|
||||
args.fPB->addVarying("RectParams", &inRectParams, GrSLPrecision::kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", inRectParams.vsOut(), de.inRectParams()->fName);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Setup pass through color
|
||||
if (!de.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, de.inPosition()->fName);
|
||||
this->setupPosition(pb, vertBuilder, gpArgs, de.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(args.fPB, gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(),
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(args.fPB,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
de.inPosition()->fName,
|
||||
de.localMatrix(),
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
// transforms all points so that we can compare them to our test rect
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
inDashParams.fsIn(), inDashParams.fsIn(), inDashParams.fsIn(),
|
||||
inDashParams.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDashParams.fsIn());
|
||||
fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;",
|
||||
inDashParams.fsIn(), inDashParams.fsIn(), inDashParams.fsIn(),
|
||||
inDashParams.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 fragPosShifted = vec2(xShifted, %s.y);", inDashParams.fsIn());
|
||||
if (de.aaMode() == kEdgeAA_DashAAMode) {
|
||||
// The amount of coverage removed in x and y by the edges is computed as a pair of negative
|
||||
// numbers, xSub and ySub.
|
||||
fsBuilder->codeAppend("float xSub, ySub;");
|
||||
fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
|
||||
fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
|
||||
fsBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRectParams.fsIn());
|
||||
fsBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppend("float xSub, ySub;");
|
||||
fragBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("ySub = min(fragPosShifted.y - %s.y, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("ySub += min(%s.w - fragPosShifted.y, 0.0);", inRectParams.fsIn());
|
||||
// Now compute coverage in x and y and multiply them to get the fraction of the pixel
|
||||
// covered.
|
||||
fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));");
|
||||
fragBuilder->codeAppendf(
|
||||
"float alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));");
|
||||
} else if (de.aaMode() == kMSAA_DashAAMode) {
|
||||
// For MSAA, we don't modulate the alpha by the Y distance, since MSAA coverage will handle
|
||||
// AA on the the top and bottom edges. The shader is only responsible for intra-dash alpha.
|
||||
fsBuilder->codeAppend("float xSub;");
|
||||
fsBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
|
||||
fsBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppend("float xSub;");
|
||||
fragBuilder->codeAppendf("xSub = min(fragPosShifted.x - %s.x, 0.0);", inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("xSub += min(%s.z - fragPosShifted.x, 0.0);", inRectParams.fsIn());
|
||||
// Now compute coverage in x to get the fraction of the pixel covered.
|
||||
fsBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0));");
|
||||
fragBuilder->codeAppendf("float alpha = (1.0 + max(xSub, -1.0));");
|
||||
} else {
|
||||
// Assuming the bounding geometry is tight so no need to check y values
|
||||
fsBuilder->codeAppendf("float alpha = 1.0;");
|
||||
fsBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;",
|
||||
inRectParams.fsIn());
|
||||
fsBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;",
|
||||
inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("float alpha = 1.0;");
|
||||
fragBuilder->codeAppendf("alpha *= (fragPosShifted.x - %s.x) > -0.5 ? 1.0 : 0.0;",
|
||||
inRectParams.fsIn());
|
||||
fragBuilder->codeAppendf("alpha *= (%s.z - fragPosShifted.x) >= -0.5 ? 1.0 : 0.0;",
|
||||
inRectParams.fsIn());
|
||||
}
|
||||
fsBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -63,8 +63,8 @@ private:
|
||||
// This emit code should be empty. However, on the nexus 6 there is a driver bug where if
|
||||
// you do not give gl_FragColor a value, the gl context is lost and we end up drawing
|
||||
// nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
fragBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary);
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
|
@ -35,14 +35,14 @@ public:
|
||||
const GrDistanceFieldA8TextGeoProc& dfTexEffect =
|
||||
args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(dfTexEffect);
|
||||
vertBuilder->emitAttributes(dfTexEffect);
|
||||
|
||||
#ifdef SK_GAMMA_APPLY_TO_A8
|
||||
// adjust based on gamma
|
||||
@ -58,24 +58,32 @@ public:
|
||||
if (dfTexEffect.hasVertexColor()) {
|
||||
pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
|
||||
} else {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
// add varyings
|
||||
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
|
||||
GrGLSLVertToFrag st(kVec2f_GrSLType);
|
||||
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
|
||||
pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
||||
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);
|
||||
@ -86,29 +94,29 @@ public:
|
||||
|
||||
GrGLSLVertToFrag uv(kVec2f_GrSLType);
|
||||
pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
||||
dfTexEffect.inTextureCoords()->fName);
|
||||
vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
||||
dfTexEffect.inTextureCoords()->fName);
|
||||
|
||||
// Use highp to work around aliasing issues
|
||||
fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
||||
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
||||
|
||||
fsBuilder->codeAppend("\tfloat texColor = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0],
|
||||
"uv",
|
||||
kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(".r;\n");
|
||||
fsBuilder->codeAppend("\tfloat distance = "
|
||||
fragBuilder->codeAppend("\tfloat texColor = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0],
|
||||
"uv",
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(".r;\n");
|
||||
fragBuilder->codeAppend("\tfloat distance = "
|
||||
SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
||||
#ifdef SK_GAMMA_APPLY_TO_A8
|
||||
// adjust width based on gamma
|
||||
fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
||||
fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
||||
#endif
|
||||
|
||||
fsBuilder->codeAppend("float afwidth;");
|
||||
fragBuilder->codeAppend("float afwidth;");
|
||||
if (isSimilarity) {
|
||||
// For uniform scale, we adjust for the effect of the transformation on the distance
|
||||
// by using the length of the gradient of the texture coordinates. We use st coordinates
|
||||
@ -116,33 +124,33 @@ public:
|
||||
|
||||
// this gives us a smooth step across approximately one fragment
|
||||
// we use y to work around a Mali400 bug in the x direction
|
||||
fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
|
||||
st.fsIn());
|
||||
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
|
||||
st.fsIn());
|
||||
} 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.
|
||||
fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
||||
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
|
||||
fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fsBuilder->codeAppend("} else {");
|
||||
fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fsBuilder->codeAppend("}");
|
||||
fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fragBuilder->codeAppend("} else {");
|
||||
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fragBuilder->codeAppend("}");
|
||||
|
||||
fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
|
||||
fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
|
||||
fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
|
||||
fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
|
||||
// this gives us a smooth step across approximately one fragment
|
||||
fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
}
|
||||
fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
||||
fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
||||
@ -286,14 +294,14 @@ public:
|
||||
const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistanceFieldPathGeoProc>();
|
||||
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(dfTexEffect);
|
||||
vertBuilder->emitAttributes(dfTexEffect);
|
||||
|
||||
GrGLSLVertToFrag v(kVec2f_GrSLType);
|
||||
pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision);
|
||||
@ -303,18 +311,26 @@ public:
|
||||
if (dfTexEffect.hasVertexColor()) {
|
||||
pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
|
||||
} else {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
}
|
||||
vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
||||
vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn,
|
||||
args.fTransformsOut);
|
||||
|
||||
const char* textureSizeUniName = nullptr;
|
||||
fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
@ -322,54 +338,54 @@ public:
|
||||
"TextureSize", &textureSizeUniName);
|
||||
|
||||
// Use highp to work around aliasing issues
|
||||
fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
|
||||
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
|
||||
|
||||
fsBuilder->codeAppend("float texColor = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0],
|
||||
"uv",
|
||||
kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(".r;");
|
||||
fsBuilder->codeAppend("float distance = "
|
||||
fragBuilder->codeAppend("float texColor = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0],
|
||||
"uv",
|
||||
kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(".r;");
|
||||
fragBuilder->codeAppend("float distance = "
|
||||
SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
|
||||
|
||||
fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
|
||||
fsBuilder->codeAppend("float afwidth;");
|
||||
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
|
||||
fragBuilder->codeAppend("float afwidth;");
|
||||
if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
|
||||
// For uniform scale, we adjust for the effect of the transformation on the distance
|
||||
// by using the length of the gradient of the texture coordinates. We use st coordinates
|
||||
// to ensure we're mapping 1:1 from texel space to pixel space.
|
||||
|
||||
// this gives us a smooth step across approximately one fragment
|
||||
fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
|
||||
fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
|
||||
} else {
|
||||
// For general transforms, to determine the amount of correction we multiply a unit
|
||||
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
|
||||
// (which is the inverse transform for this fragment) and take the length of the result.
|
||||
fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
|
||||
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
|
||||
fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fsBuilder->codeAppend("} else {");
|
||||
fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fsBuilder->codeAppend("}");
|
||||
fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fragBuilder->codeAppend("} else {");
|
||||
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fragBuilder->codeAppend("}");
|
||||
|
||||
fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
||||
fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
||||
fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
||||
fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
||||
fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
|
||||
// this gives us a smooth step across approximately one fragment
|
||||
fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
}
|
||||
fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
||||
fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
|
||||
|
||||
fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override {
|
||||
@ -502,30 +518,40 @@ public:
|
||||
args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
|
||||
GrGLSLGPBuilder* pb = args.fPB;
|
||||
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
|
||||
|
||||
// emit attributes
|
||||
vsBuilder->emitAttributes(dfTexEffect);
|
||||
vertBuilder->emitAttributes(dfTexEffect);
|
||||
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
// setup pass through color
|
||||
if (!dfTexEffect.colorIgnored()) {
|
||||
this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
|
||||
this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorUniform);
|
||||
}
|
||||
|
||||
// Setup position
|
||||
this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
|
||||
this->setupPosition(pb,
|
||||
vertBuilder,
|
||||
gpArgs,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(pb, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
|
||||
args.fTransformsIn, args.fTransformsOut);
|
||||
this->emitTransforms(pb,
|
||||
vertBuilder,
|
||||
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);
|
||||
pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);
|
||||
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);
|
||||
@ -536,62 +562,61 @@ public:
|
||||
|
||||
GrGLSLVertToFrag uv(kVec2f_GrSLType);
|
||||
pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
|
||||
vsBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(),
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth,
|
||||
GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight,
|
||||
dfTexEffect.inTextureCoords()->fName);
|
||||
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
|
||||
GrGLSLFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
|
||||
SkAssertResult(fsBuilder->enableFeature(
|
||||
SkAssertResult(fragBuilder->enableFeature(
|
||||
GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
|
||||
|
||||
// create LCD offset adjusted by inverse of transform
|
||||
// Use highp to work around aliasing issues
|
||||
fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
||||
fsBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
|
||||
fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(pb->glslCaps(),
|
||||
kHigh_GrSLPrecision));
|
||||
|
||||
SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
|
||||
if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
|
||||
fsBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
||||
fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
||||
fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
|
||||
}
|
||||
if (isUniformScale) {
|
||||
fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
|
||||
fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
|
||||
fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
|
||||
fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
|
||||
} else {
|
||||
fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
|
||||
fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
|
||||
|
||||
fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
||||
fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
||||
fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
|
||||
fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
|
||||
fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
|
||||
fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
|
||||
}
|
||||
|
||||
// green is distance to uv center
|
||||
fsBuilder->codeAppend("\tvec4 texColor = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fsBuilder->codeAppend("\tvec3 distance;\n");
|
||||
fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
|
||||
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
|
||||
fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
|
||||
fsBuilder->codeAppend("\ttexColor = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
|
||||
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
|
||||
fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
|
||||
fsBuilder->codeAppend("\ttexColor = ");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");
|
||||
fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
|
||||
fragBuilder->codeAppend("\ttexColor = ");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppend("\tdistance.z = texColor.r;\n");
|
||||
|
||||
fsBuilder->codeAppend("\tdistance = "
|
||||
fragBuilder->codeAppend("\tdistance = "
|
||||
"vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");
|
||||
|
||||
// adjust width based on gamma
|
||||
@ -599,46 +624,46 @@ public:
|
||||
fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kVec3f_GrSLType, kDefault_GrSLPrecision,
|
||||
"DistanceAdjust", &distanceAdjustUniName);
|
||||
fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
||||
fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
|
||||
|
||||
// To be strictly correct, we should compute the anti-aliasing factor separately
|
||||
// for each color component. However, this is only important when using perspective
|
||||
// transformations, and even then using a single factor seems like a reasonable
|
||||
// trade-off between quality and speed.
|
||||
fsBuilder->codeAppend("float afwidth;");
|
||||
fragBuilder->codeAppend("float afwidth;");
|
||||
if (isUniformScale) {
|
||||
// For uniform scale, we adjust for the effect of the transformation on the distance
|
||||
// by using the length of the gradient of the 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
|
||||
fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
|
||||
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
|
||||
} 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.
|
||||
fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
|
||||
fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
|
||||
// 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
|
||||
fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fsBuilder->codeAppend("} else {");
|
||||
fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fsBuilder->codeAppend("}");
|
||||
fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fsBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
|
||||
fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
|
||||
fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
|
||||
fragBuilder->codeAppend("} else {");
|
||||
fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
|
||||
fragBuilder->codeAppend("}");
|
||||
fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
|
||||
fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");
|
||||
|
||||
// this gives us a smooth step across approximately one fragment
|
||||
fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppend(
|
||||
fragBuilder->codeAppend(
|
||||
"vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
|
||||
// set alpha to be max of rgb coverage
|
||||
fsBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
|
||||
fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");
|
||||
|
||||
fsBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
|
||||
fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
|
||||
}
|
||||
|
||||
void setData(const GrGLSLProgramDataManager& pdman,
|
||||
|
@ -73,7 +73,7 @@ GLDitherEffect::GLDitherEffect(const GrProcessor&) {
|
||||
}
|
||||
|
||||
void GLDitherEffect::emitCode(EmitArgs& args) {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
// Generate a random number based on the fragment position. For this
|
||||
// random number generator, we use the "GLSL rand" function
|
||||
// that seems to be floating around on the internet. It works under
|
||||
@ -83,11 +83,11 @@ void GLDitherEffect::emitCode(EmitArgs& args) {
|
||||
|
||||
// For each channel c, add the random offset to the pixel to either bump
|
||||
// it up or let it remain constant during quantization.
|
||||
fsBuilder->codeAppendf("\t\tfloat r = "
|
||||
"fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
|
||||
fsBuilder->fragmentPosition());
|
||||
fsBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
|
||||
args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
|
||||
fragBuilder->codeAppendf("\t\tfloat r = "
|
||||
"fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
|
||||
fragBuilder->fragmentPosition());
|
||||
fragBuilder->codeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
|
||||
args.fOutputColor, GrGLSLExpr4(args.fInputColor).c_str());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -64,41 +64,40 @@ void GrGLMatrixConvolutionEffect::emitCode(EmitArgs& args) {
|
||||
int kWidth = fKernelSize.width();
|
||||
int kHeight = fKernelSize.height();
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
fsBuilder->codeAppend("vec4 sum = vec4(0, 0, 0, 0);");
|
||||
fsBuilder->codeAppendf("vec2 coord = %s - %s * %s;", coords2D.c_str(), kernelOffset,
|
||||
imgInc);
|
||||
fsBuilder->codeAppend("vec4 c;");
|
||||
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(fsBuilder);
|
||||
fsBuilder->codeAppendf("float k = %s[%d * %d + %d];", kernel, y, 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(fsBuilder, domain, "c", coord, args.fSamplers[0]);
|
||||
fDomain.sampleTexture(fragBuilder, domain, "c", coord, args.fSamplers[0]);
|
||||
if (!fConvolveAlpha) {
|
||||
fsBuilder->codeAppend("c.rgb /= c.a;");
|
||||
fsBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("c.rgb /= c.a;");
|
||||
fragBuilder->codeAppend("c.rgb = clamp(c.rgb, 0.0, 1.0);");
|
||||
}
|
||||
fsBuilder->codeAppend("sum += c * k;");
|
||||
fragBuilder->codeAppend("sum += c * k;");
|
||||
}
|
||||
}
|
||||
if (fConvolveAlpha) {
|
||||
fsBuilder->codeAppendf("%s = sum * %s + %s;", args.fOutputColor, gain, bias);
|
||||
fsBuilder->codeAppendf("%s.rgb = clamp(%s.rgb, 0.0, %s.a);",
|
||||
args.fOutputColor, args.fOutputColor, args.fOutputColor);
|
||||
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(fsBuilder, domain, "c", coords2D, args.fSamplers[0]);
|
||||
fsBuilder->codeAppendf("%s.a = c.a;", args.fOutputColor);
|
||||
fsBuilder->codeAppendf("%s.rgb = sum.rgb * %s + %s;", args.fOutputColor, gain, bias);
|
||||
fsBuilder->codeAppendf("%s.rgb *= %s.a;", args.fOutputColor, args.fOutputColor);
|
||||
fDomain.sampleTexture(fragBuilder, 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);
|
||||
fsBuilder->codeAppend(modulate.c_str());
|
||||
fragBuilder->codeAppend(modulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLMatrixConvolutionEffect::GenKey(const GrProcessor& processor,
|
||||
|
@ -124,8 +124,8 @@ void GLCircleEffect::emitCode(EmitArgs& args) {
|
||||
"circle",
|
||||
&circleName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* fragmentPos = fragBuilder->fragmentPosition();
|
||||
|
||||
SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType());
|
||||
// TODO: Right now the distance to circle caclulation is performed in a space normalized to the
|
||||
@ -133,20 +133,20 @@ void GLCircleEffect::emitCode(EmitArgs& args) {
|
||||
// mediump. It'd be nice to only to this on mediump devices but we currently don't have the
|
||||
// caps here.
|
||||
if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
|
||||
fsBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;\n",
|
||||
circleName, fragmentPos, circleName, circleName);
|
||||
fragBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;\n",
|
||||
circleName, fragmentPos, circleName, circleName);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) * %s.w)) * %s.z;\n",
|
||||
circleName, fragmentPos, circleName, circleName);
|
||||
fragBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) * %s.w)) * %s.z;\n",
|
||||
circleName, fragmentPos, circleName, circleName);
|
||||
}
|
||||
if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) {
|
||||
fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
|
||||
} else {
|
||||
fsBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
|
||||
fragBuilder->codeAppend("\t\td = d > 0.5 ? 1.0 : 0.0;\n");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("d")).c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("d")).c_str());
|
||||
}
|
||||
|
||||
void GLCircleEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
|
||||
@ -296,39 +296,39 @@ void GLEllipseEffect::emitCode(EmitArgs& args) {
|
||||
"ellipse",
|
||||
&ellipseName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* fragmentPos = fragBuilder->fragmentPosition();
|
||||
|
||||
// d is the offset to the ellipse center
|
||||
fsBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
|
||||
fsBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
|
||||
fragBuilder->codeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
|
||||
fragBuilder->codeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
|
||||
// implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
|
||||
fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
|
||||
fragBuilder->codeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
|
||||
// grad_dot is the squared length of the gradient of the implicit.
|
||||
fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
|
||||
// avoid calling inversesqrt on zero.
|
||||
fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
|
||||
fragBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
|
||||
|
||||
switch (ee.getEdgeType()) {
|
||||
case kFillAA_GrProcessorEdgeType:
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
|
||||
break;
|
||||
case kInverseFillAA_GrProcessorEdgeType:
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
|
||||
break;
|
||||
case kFillBW_GrProcessorEdgeType:
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n");
|
||||
break;
|
||||
case kInverseFillBW_GrProcessorEdgeType:
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n");
|
||||
break;
|
||||
case kHairlineAA_GrProcessorEdgeType:
|
||||
SkFAIL("Hairline not expected here.");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
}
|
||||
|
||||
void GLEllipseEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps&,
|
||||
|
@ -382,44 +382,44 @@ private:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void append_color_output(const PorterDuffXferProcessor& xp,
|
||||
GrGLSLXPFragmentBuilder* fsBuilder,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
BlendFormula::OutputType outputType, const char* output,
|
||||
const char* inColor, const char* inCoverage) {
|
||||
switch (outputType) {
|
||||
case BlendFormula::kNone_OutputType:
|
||||
fsBuilder->codeAppendf("%s = vec4(0.0);", output);
|
||||
fragBuilder->codeAppendf("%s = vec4(0.0);", output);
|
||||
break;
|
||||
case BlendFormula::kCoverage_OutputType:
|
||||
// We can have a coverage formula while not reading coverage if there are mixed samples.
|
||||
fsBuilder->codeAppendf("%s = %s;",
|
||||
fragBuilder->codeAppendf("%s = %s;",
|
||||
output, xp.readsCoverage() ? inCoverage : "vec4(1.0)");
|
||||
break;
|
||||
case BlendFormula::kModulate_OutputType:
|
||||
if (xp.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s * %s;", output, inColor, inCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = %s;", output, inColor);
|
||||
fragBuilder->codeAppendf("%s = %s;", output, inColor);
|
||||
}
|
||||
break;
|
||||
case BlendFormula::kSAModulate_OutputType:
|
||||
if (xp.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s.a * %s;", output, inColor, inCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = %s;", output, inColor);
|
||||
fragBuilder->codeAppendf("%s = %s;", output, inColor);
|
||||
}
|
||||
break;
|
||||
case BlendFormula::kISAModulate_OutputType:
|
||||
if (xp.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage);
|
||||
fragBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", output, inColor, inCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inColor);
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0 - %s.a);", output, inColor);
|
||||
}
|
||||
break;
|
||||
case BlendFormula::kISCModulate_OutputType:
|
||||
if (xp.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output, inColor, inCoverage);
|
||||
fragBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;", output, inColor, inCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(1.0) - %s;", output, inColor);
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0) - %s;", output, inColor);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -441,14 +441,14 @@ public:
|
||||
private:
|
||||
void emitOutputsForBlendState(const EmitArgs& args) override {
|
||||
const PorterDuffXferProcessor& xp = args.fXP.cast<PorterDuffXferProcessor>();
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
|
||||
BlendFormula blendFormula = xp.getBlendFormula();
|
||||
if (blendFormula.hasSecondaryOutput()) {
|
||||
append_color_output(xp, fsBuilder, blendFormula.fSecondaryOutputType,
|
||||
append_color_output(xp, fragBuilder, blendFormula.fSecondaryOutputType,
|
||||
args.fOutputSecondary, args.fInputColor, args.fInputCoverage);
|
||||
}
|
||||
append_color_output(xp, fsBuilder, blendFormula.fPrimaryOutputType,
|
||||
append_color_output(xp, fragBuilder, blendFormula.fPrimaryOutputType,
|
||||
args.fOutputPrimary, args.fInputColor, args.fInputCoverage);
|
||||
}
|
||||
|
||||
@ -544,12 +544,15 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, const char* srcColor, const char* dstColor,
|
||||
const char* outColor, const GrXferProcessor& proc) override {
|
||||
void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const char* srcColor,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
const GrXferProcessor& proc) override {
|
||||
const ShaderPDXferProcessor& xp = proc.cast<ShaderPDXferProcessor>();
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder();
|
||||
|
||||
GrGLSLBlend::AppendMode(fsBuilder, srcColor, dstColor, outColor, xp.getXfermode());
|
||||
GrGLSLBlend::AppendMode(fragBuilder, srcColor, dstColor, outColor, xp.getXfermode());
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
|
||||
@ -625,9 +628,9 @@ public:
|
||||
|
||||
private:
|
||||
void emitOutputsForBlendState(const EmitArgs& args) override {
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
|
||||
args.fInputCoverage);
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
fragBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
|
||||
args.fInputCoverage);
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {};
|
||||
|
@ -165,8 +165,8 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
|
||||
"radiusPlusHalf",
|
||||
&radiusPlusHalfName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
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
|
||||
@ -184,96 +184,104 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
|
||||
// alphas together.
|
||||
switch (crre.getCircularCornerFlags()) {
|
||||
case CircularRRectEffect::kAll_CornerFlags:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n",
|
||||
fragmentPos, rectName, rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n",
|
||||
rectName, fragmentPos, fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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:
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
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");
|
||||
fragBuilder->codeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n",
|
||||
rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf(
|
||||
"\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
break;
|
||||
case CircularRRectEffect::kRight_CornerFlags:
|
||||
fsBuilder->codeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
fragBuilder->codeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf(
|
||||
"\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
break;
|
||||
case CircularRRectEffect::kBottom_CornerFlags:
|
||||
fsBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fsBuilder->codeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
fragBuilder->codeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n",
|
||||
fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf(
|
||||
"\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n",
|
||||
radiusPlusHalfName);
|
||||
break;
|
||||
}
|
||||
|
||||
if (kInverseFillAA_GrProcessorEdgeType == crre.getEdgeType()) {
|
||||
fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
|
||||
fragBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
}
|
||||
|
||||
void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
|
||||
@ -503,8 +511,8 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
|
||||
"innerRect",
|
||||
&rectName);
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
const char* fragmentPos = fsBuilder->fragmentPosition();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const char* fragmentPos = fragBuilder->fragmentPosition();
|
||||
// At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
|
||||
// to the ellipse 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
|
||||
@ -517,8 +525,8 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
|
||||
// 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.
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
|
||||
fsBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
fragBuilder->codeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
|
||||
fragBuilder->codeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
|
||||
// The uniforms with the inv squared radii are highp to prevent underflow.
|
||||
switch (erre.getRRect().getType()) {
|
||||
case SkRRect::kSimple_Type: {
|
||||
@ -528,9 +536,9 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
|
||||
kVec2f_GrSLType, kHigh_GrSLPrecision,
|
||||
"invRadiiXY",
|
||||
&invRadiiXYSqdName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
|
||||
fragBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
|
||||
// Z is the x/y offsets divided by squared radii.
|
||||
fsBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
|
||||
fragBuilder->codeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName);
|
||||
break;
|
||||
}
|
||||
case SkRRect::kNinePatch_Type: {
|
||||
@ -540,33 +548,33 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
|
||||
kVec4f_GrSLType, kHigh_GrSLPrecision,
|
||||
"invRadiiLTRB",
|
||||
&invRadiiLTRBSqdName);
|
||||
fsBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
|
||||
fragBuilder->codeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
|
||||
// Z is the x/y offsets divided by squared radii. We only care about the (at most) one
|
||||
// corner where both the x and y offsets are positive, hence the maxes. (The inverse
|
||||
// squared radii will always be positive.)
|
||||
fsBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
|
||||
invRadiiLTRBSqdName, invRadiiLTRBSqdName);
|
||||
fragBuilder->codeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n",
|
||||
invRadiiLTRBSqdName, invRadiiLTRBSqdName);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SkFAIL("RRect should always be simple or nine-patch.");
|
||||
}
|
||||
// implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
|
||||
fsBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
|
||||
fragBuilder->codeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n");
|
||||
// grad_dot is the squared length of the gradient of the implicit.
|
||||
fsBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n");
|
||||
// avoid calling inversesqrt on zero.
|
||||
fsBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
|
||||
fsBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
|
||||
fragBuilder->codeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n");
|
||||
fragBuilder->codeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n");
|
||||
|
||||
if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) {
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n");
|
||||
} else {
|
||||
fsBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
|
||||
fragBuilder->codeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
fragBuilder->codeAppendf("\t\t%s = %s;\n", args.fOutputColor,
|
||||
(GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
|
||||
}
|
||||
|
||||
void GLEllipticalRRectEffect::GenKey(const GrProcessor& effect, const GrGLSLCaps&,
|
||||
|
@ -17,13 +17,13 @@ public:
|
||||
GrGLSimpleTextureEffect(const GrProcessor&) {}
|
||||
|
||||
virtual void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
fsBuilder->codeAppendf("\t%s = ", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookupAndModulate(args.fInputColor,
|
||||
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());
|
||||
fsBuilder->codeAppend(";\n");
|
||||
fragBuilder->codeAppend(";\n");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -195,9 +195,9 @@ void GrGLTextureDomainEffect::emitCode(EmitArgs& args) {
|
||||
const GrTextureDomainEffect& textureDomainEffect = args.fFp.cast<GrTextureDomainEffect>();
|
||||
const GrTextureDomain& domain = textureDomainEffect.textureDomain();
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
SkString coords2D = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
fGLDomain.sampleTexture(fsBuilder, domain, args.fOutputColor, coords2D, args.fSamplers[0],
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkString coords2D = fragBuilder->ensureFSCoords2D(args.fCoords, 0);
|
||||
fGLDomain.sampleTexture(fragBuilder, domain, args.fOutputColor, coords2D, args.fSamplers[0],
|
||||
args.fInputColor);
|
||||
}
|
||||
|
||||
|
@ -89,13 +89,13 @@ GrGLSLFragmentProcessor* ComposeTwoFragmentProcessor::onCreateGLSLInstance() con
|
||||
|
||||
void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
|
||||
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
const ComposeTwoFragmentProcessor& cs = args.fFp.cast<ComposeTwoFragmentProcessor>();
|
||||
|
||||
const char* inputColor = nullptr;
|
||||
if (args.fInputColor) {
|
||||
inputColor = "inputColor";
|
||||
fsBuilder->codeAppendf("vec4 inputColor = vec4(%s.rgb, 1.0);", args.fInputColor);
|
||||
fragBuilder->codeAppendf("vec4 inputColor = vec4(%s.rgb, 1.0);", args.fInputColor);
|
||||
}
|
||||
|
||||
// declare outputColor and emit the code for each of the two children
|
||||
@ -107,12 +107,16 @@ void GLComposeTwoFragmentProcessor::emitCode(EmitArgs& args) {
|
||||
|
||||
// emit blend code
|
||||
SkXfermode::Mode mode = cs.getMode();
|
||||
fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
|
||||
GrGLSLBlend::AppendMode(fsBuilder, srcColor.c_str(), dstColor.c_str(), args.fOutputColor, mode);
|
||||
fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
|
||||
GrGLSLBlend::AppendMode(fragBuilder,
|
||||
srcColor.c_str(),
|
||||
dstColor.c_str(),
|
||||
args.fOutputColor,
|
||||
mode);
|
||||
|
||||
// re-multiply the output color by the input color's alpha
|
||||
if (args.fInputColor) {
|
||||
fsBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
|
||||
fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +223,7 @@ public:
|
||||
GLComposeOneFragmentProcessor(const GrProcessor& processor) {}
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
SkXfermode::Mode mode = args.fFp.cast<ComposeOneFragmentProcessor>().mode();
|
||||
ComposeOneFragmentProcessor::Child child =
|
||||
args.fFp.cast<ComposeOneFragmentProcessor>().child();
|
||||
@ -229,17 +233,17 @@ public:
|
||||
const char* inputColor = args.fInputColor;
|
||||
// We don't try to optimize for this case at all
|
||||
if (!inputColor) {
|
||||
fsBuilder->codeAppendf("const vec4 ones = vec4(1);");
|
||||
fragBuilder->codeAppendf("const vec4 ones = vec4(1);");
|
||||
inputColor = "ones";
|
||||
}
|
||||
|
||||
// emit blend code
|
||||
fsBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
|
||||
fragBuilder->codeAppendf("// Compose Xfer Mode: %s\n", SkXfermode::ModeName(mode));
|
||||
const char* childStr = childColor.c_str();
|
||||
if (ComposeOneFragmentProcessor::kDst_Child == child) {
|
||||
GrGLSLBlend::AppendMode(fsBuilder, inputColor, childStr, args.fOutputColor, mode);
|
||||
GrGLSLBlend::AppendMode(fragBuilder, inputColor, childStr, args.fOutputColor, mode);
|
||||
} else {
|
||||
GrGLSLBlend::AppendMode(fsBuilder, childStr, inputColor, args.fOutputColor, mode);
|
||||
GrGLSLBlend::AppendMode(fragBuilder, childStr, inputColor, args.fOutputColor, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,22 +64,22 @@ public:
|
||||
GLSLProcessor(const GrProcessor&) {}
|
||||
|
||||
virtual void emitCode(EmitArgs& args) override {
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
const char* yuvMatrix = nullptr;
|
||||
fMatrixUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
kMat44f_GrSLType, kDefault_GrSLPrecision,
|
||||
"YUVMatrix", &yuvMatrix);
|
||||
fsBuilder->codeAppendf("\t%s = vec4(\n\t\t", args.fOutputColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
args.fCoords[0].getType());
|
||||
fsBuilder->codeAppend(".r,\n\t\t");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[1], args.fCoords[1].c_str(),
|
||||
args.fCoords[1].getType());
|
||||
fsBuilder->codeAppend(".r,\n\t\t");
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[2], args.fCoords[2].c_str(),
|
||||
args.fCoords[2].getType());
|
||||
fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
|
||||
fragBuilder->codeAppendf("\t%s = vec4(\n\t\t", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], args.fCoords[0].c_str(),
|
||||
args.fCoords[0].getType());
|
||||
fragBuilder->codeAppend(".r,\n\t\t");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[1], args.fCoords[1].c_str(),
|
||||
args.fCoords[1].getType());
|
||||
fragBuilder->codeAppend(".r,\n\t\t");
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[2], args.fCoords[2].c_str(),
|
||||
args.fCoords[2].getType());
|
||||
fragBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -95,7 +95,7 @@ GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi
|
||||
fArgs.fPrimitiveProcessor->numAttribs() == 0);
|
||||
this->addVarying(name, v, fsPrecision);
|
||||
SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
|
||||
varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back();
|
||||
varyingInfo.fVariable = fFS.fInputs.back();
|
||||
varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
|
||||
return SeparableVaryingHandle(varyingInfo.fLocation);
|
||||
}
|
||||
@ -260,6 +260,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp,
|
||||
this->emitSamplers(fp, &samplers, ifp);
|
||||
|
||||
GrGLSLFragmentProcessor::EmitArgs args(this,
|
||||
&fFS,
|
||||
fp,
|
||||
outColor,
|
||||
inColor,
|
||||
@ -284,7 +285,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp,
|
||||
SkSTArray<4, GrGLSLTextureSampler> samplers(gp.numTextures());
|
||||
this->emitSamplers(gp, &samplers, fGeometryProcessor);
|
||||
|
||||
GrGLSLGeometryProcessor::EmitArgs args(this, gp, outColor, outCoverage, samplers,
|
||||
GrGLSLGeometryProcessor::EmitArgs args(this, &fVS, &fFS, gp, outColor, outCoverage, samplers,
|
||||
fCoordTransforms, &fOutCoords);
|
||||
fGeometryProcessor->fGLProc->emitCode(args);
|
||||
|
||||
@ -320,9 +321,9 @@ void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
|
||||
SkSTArray<4, GrGLSLTextureSampler> samplers(xp.numTextures());
|
||||
this->emitSamplers(xp, &samplers, fXferProcessor);
|
||||
|
||||
GrGLSLXferProcessor::EmitArgs args(this, xp, colorIn.c_str(), coverageIn.c_str(),
|
||||
fFS.getPrimaryColorOutputName(),
|
||||
fFS.getSecondaryColorOutputName(), samplers);
|
||||
GrGLSLXferProcessor::EmitArgs args(this, &fFS, xp, colorIn.c_str(), coverageIn.c_str(),
|
||||
fFS.getPrimaryColorOutputName(),
|
||||
fFS.getSecondaryColorOutputName(), samplers);
|
||||
fXferProcessor->fGLProc->emitCode(args);
|
||||
|
||||
// We have to check that effects and the code they emit are consistent, ie if an effect
|
||||
|
@ -25,20 +25,20 @@ void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
|
||||
}
|
||||
|
||||
void GrGLSLFragmentProcessor::emitChild(int childIndex, const char* inputColor,
|
||||
SkString* outputColor, EmitArgs& args) {
|
||||
SkString* outputColor, EmitArgs& args) {
|
||||
|
||||
SkASSERT(outputColor);
|
||||
GrGLSLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder();
|
||||
outputColor->append(fb->getMangleString());
|
||||
fb->codeAppendf("vec4 %s;", outputColor->c_str());
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
outputColor->append(fragBuilder->getMangleString());
|
||||
fragBuilder->codeAppendf("vec4 %s;", outputColor->c_str());
|
||||
this->internalEmitChild(childIndex, inputColor, outputColor->c_str(), args);
|
||||
}
|
||||
|
||||
void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inputColor,
|
||||
const char* outputColor, EmitArgs& args) {
|
||||
GrGLSLFragmentBuilder* fb = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
|
||||
fb->onBeforeChildProcEmitCode(); // call first so mangleString is updated
|
||||
fragBuilder->onBeforeChildProcEmitCode(); // call first so mangleString is updated
|
||||
|
||||
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
|
||||
|
||||
@ -90,17 +90,18 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
|
||||
}
|
||||
|
||||
// emit the code for the child in its own scope
|
||||
fb->codeAppend("{\n");
|
||||
fb->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
|
||||
fb->getMangleString().c_str(), childProc.name());
|
||||
fragBuilder->codeAppend("{\n");
|
||||
fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex,
|
||||
fragBuilder->getMangleString().c_str(), childProc.name());
|
||||
EmitArgs childArgs(args.fBuilder,
|
||||
fragBuilder,
|
||||
childProc,
|
||||
outputColor,
|
||||
inputColor,
|
||||
childCoords,
|
||||
childSamplers);
|
||||
this->childProcessor(childIndex)->emitCode(childArgs);
|
||||
fb->codeAppend("}\n");
|
||||
fragBuilder->codeAppend("}\n");
|
||||
|
||||
fb->onAfterChildProcEmitCode();
|
||||
fragBuilder->onAfterChildProcEmitCode();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
class GrProcessor;
|
||||
class GrProcessorKeyBuilder;
|
||||
class GrGLSLFPBuilder;
|
||||
class GrGLSLFragmentBuilder;
|
||||
class GrGLSLCaps;
|
||||
|
||||
class GrGLSLFragmentProcessor {
|
||||
@ -51,18 +52,21 @@ public:
|
||||
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLFPBuilder* builder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const GrFragmentProcessor& fp,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const GrGLSLTransformedCoordsArray& coords,
|
||||
const TextureSamplerArray& samplers)
|
||||
: fBuilder(builder)
|
||||
, fFragBuilder(fragBuilder)
|
||||
, fFp(fp)
|
||||
, fOutputColor(outputColor)
|
||||
, fInputColor(inputColor)
|
||||
, fCoords(coords)
|
||||
, fSamplers(samplers) {}
|
||||
GrGLSLFPBuilder* fBuilder;
|
||||
GrGLSLFragmentBuilder* fFragBuilder;
|
||||
const GrFragmentProcessor& fFp;
|
||||
const char* fOutputColor;
|
||||
const char* fInputColor;
|
||||
|
@ -13,19 +13,19 @@
|
||||
#include "glsl/GrGLSLVertexShaderBuilder.h"
|
||||
|
||||
void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) {
|
||||
GrGLSLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
|
||||
GrGLSLVertexBuilder* vBuilder = args.fVertBuilder;
|
||||
GrGPArgs gpArgs;
|
||||
this->onEmitCode(args, &gpArgs);
|
||||
vsBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar);
|
||||
vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar);
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb,
|
||||
GrGLSLVertexBuilder* vb,
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const SkMatrix& localMatrix,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
GrGLSLVertexBuilder* vb = pb->getVertexShaderBuilder();
|
||||
tout->push_back_n(tin.count());
|
||||
fInstalledTransforms.push_back_n(tin.count());
|
||||
for (int i = 0; i < tin.count(); i++) {
|
||||
@ -93,10 +93,10 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb,
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb,
|
||||
GrGLSLVertexBuilder* vb,
|
||||
const char* localCoords,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
GrGLSLVertexBuilder* vb = pb->getVertexShaderBuilder();
|
||||
tout->push_back_n(tin.count());
|
||||
for (int i = 0; i < tin.count(); i++) {
|
||||
const ProcCoords& coordTransforms = tin[i];
|
||||
@ -122,22 +122,22 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLGPBuilder* pb,
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb,
|
||||
GrGLSLVertexBuilder* vertBuilder,
|
||||
GrGPArgs* gpArgs,
|
||||
const char* posName) {
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
|
||||
vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
|
||||
vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
|
||||
}
|
||||
|
||||
void GrGLSLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb,
|
||||
GrGLSLVertexBuilder* vertBuilder,
|
||||
GrGPArgs* gpArgs,
|
||||
const char* posName,
|
||||
const SkMatrix& mat,
|
||||
UniformHandle* viewMatrixUniform) {
|
||||
GrGLSLVertexBuilder* vsBuilder = pb->getVertexShaderBuilder();
|
||||
if (mat.isIdentity()) {
|
||||
gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
|
||||
vsBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
|
||||
vertBuilder->codeAppendf("vec2 %s = %s;", gpArgs->fPositionVar.c_str(), posName);
|
||||
} else {
|
||||
const char* viewMatrixName;
|
||||
*viewMatrixUniform = pb->addUniform(GrGLSLProgramBuilder::kVertex_Visibility,
|
||||
@ -146,12 +146,12 @@ void GrGLSLGeometryProcessor::setupPosition(GrGLSLGPBuilder* pb,
|
||||
&viewMatrixName);
|
||||
if (!mat.hasPerspective()) {
|
||||
gpArgs->fPositionVar.set(kVec2f_GrSLType, "pos2");
|
||||
vsBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));",
|
||||
gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
|
||||
vertBuilder->codeAppendf("vec2 %s = vec2(%s * vec3(%s, 1));",
|
||||
gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
|
||||
} else {
|
||||
gpArgs->fPositionVar.set(kVec3f_GrSLType, "pos3");
|
||||
vsBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);",
|
||||
gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
|
||||
vertBuilder->codeAppendf("vec3 %s = %s * vec3(%s, 1);",
|
||||
gpArgs->fPositionVar.c_str(), viewMatrixName, posName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,15 +43,17 @@ public:
|
||||
protected:
|
||||
// Emit a uniform matrix for each coord transform.
|
||||
void emitTransforms(GrGLSLGPBuilder* gp,
|
||||
GrGLSLVertexBuilder* vb,
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout) {
|
||||
this->emitTransforms(gp, posVar, localCoords, SkMatrix::I(), tin, tout);
|
||||
this->emitTransforms(gp, vb, posVar, localCoords, SkMatrix::I(), tin, tout);
|
||||
}
|
||||
|
||||
// Emit pre-transformed coords as a vertex attribute per coord-transform.
|
||||
void emitTransforms(GrGLSLGPBuilder*,
|
||||
GrGLSLVertexBuilder*,
|
||||
const GrShaderVar& posVar,
|
||||
const char* localCoords,
|
||||
const SkMatrix& localMatrix,
|
||||
@ -60,6 +62,7 @@ protected:
|
||||
|
||||
// caller has emitted transforms via attributes
|
||||
void emitTransforms(GrGLSLGPBuilder*,
|
||||
GrGLSLVertexBuilder*,
|
||||
const char* localCoords,
|
||||
const TransformsIn& tin,
|
||||
TransformsOut* tout);
|
||||
@ -71,8 +74,12 @@ protected:
|
||||
};
|
||||
|
||||
// Create the correct type of position variable given the CTM
|
||||
void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName);
|
||||
void setupPosition(GrGLSLGPBuilder*, GrGPArgs*, const char* posName, const SkMatrix& mat,
|
||||
void setupPosition(GrGLSLGPBuilder*, GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
|
||||
void setupPosition(GrGLSLGPBuilder*,
|
||||
GrGLSLVertexBuilder*,
|
||||
GrGPArgs*,
|
||||
const char* posName,
|
||||
const SkMatrix& mat,
|
||||
UniformHandle* viewMatrixUniform);
|
||||
|
||||
static uint32_t ComputePosKey(const SkMatrix& mat) {
|
||||
|
@ -33,9 +33,9 @@ SkMatrix GrGLSLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatri
|
||||
}
|
||||
|
||||
void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLGPBuilder* pb,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* outputName,
|
||||
UniformHandle* colorUniform) {
|
||||
GrGLSLFragmentBuilder* fs = pb->getFragmentShaderBuilder();
|
||||
SkASSERT(colorUniform);
|
||||
const char* stagedLocalVarName;
|
||||
*colorUniform = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
|
||||
@ -43,5 +43,5 @@ void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLGPBuilder* pb,
|
||||
kDefault_GrSLPrecision,
|
||||
"Color",
|
||||
&stagedLocalVarName);
|
||||
fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
|
||||
fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
class GrBatchTracker;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrGLSLVertexBuilder;
|
||||
class GrGLSLFragmentBuilder;
|
||||
class GrGLSLGPBuilder;
|
||||
|
||||
class GrGLSLPrimitiveProcessor {
|
||||
@ -30,6 +32,8 @@ public:
|
||||
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLGPBuilder* pb,
|
||||
GrGLSLVertexBuilder* vertBuilder,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const GrPrimitiveProcessor& gp,
|
||||
const char* outputColor,
|
||||
const char* outputCoverage,
|
||||
@ -37,6 +41,8 @@ public:
|
||||
const TransformsIn& transformsIn,
|
||||
TransformsOut* transformsOut)
|
||||
: fPB(pb)
|
||||
, fVertBuilder(vertBuilder)
|
||||
, fFragBuilder(fragBuilder)
|
||||
, fGP(gp)
|
||||
, fOutputColor(outputColor)
|
||||
, fOutputCoverage(outputCoverage)
|
||||
@ -44,6 +50,8 @@ public:
|
||||
, fTransformsIn(transformsIn)
|
||||
, fTransformsOut(transformsOut) {}
|
||||
GrGLSLGPBuilder* fPB;
|
||||
GrGLSLVertexBuilder* fVertBuilder;
|
||||
GrGLSLFragmentBuilder* fFragBuilder;
|
||||
const GrPrimitiveProcessor& fGP;
|
||||
const char* fOutputColor;
|
||||
const char* fOutputCoverage;
|
||||
@ -76,6 +84,7 @@ public:
|
||||
|
||||
protected:
|
||||
void setupUniformColor(GrGLSLGPBuilder* pb,
|
||||
GrGLSLFragmentBuilder* fragBuilder,
|
||||
const char* outputName,
|
||||
UniformHandle* colorUniform);
|
||||
|
||||
|
@ -165,10 +165,6 @@ public:
|
||||
const char* name, GrGLSLVertToFrag*,
|
||||
GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0;
|
||||
|
||||
// TODO rename getFragmentBuilder
|
||||
virtual GrGLSLFragmentBuilder* getFragmentShaderBuilder() = 0;
|
||||
virtual GrGLSLVertexBuilder* getVertexShaderBuilder() = 0;
|
||||
|
||||
/*
|
||||
* *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
||||
*/
|
||||
@ -178,8 +174,6 @@ public:
|
||||
/* a specializations for FPs. Lets the user add uniforms and FS code */
|
||||
class GrGLSLFPBuilder : public virtual GrGLSLUniformBuilder {
|
||||
public:
|
||||
virtual GrGLSLFragmentBuilder* getFragmentShaderBuilder() = 0;
|
||||
|
||||
/*
|
||||
* *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
||||
*/
|
||||
@ -188,8 +182,6 @@ public:
|
||||
/* a specializations for XPs. Lets the user add uniforms and FS code */
|
||||
class GrGLSLXPBuilder : public virtual GrGLSLUniformBuilder {
|
||||
public:
|
||||
virtual GrGLSLXPFragmentBuilder* getFragmentShaderBuilder() = 0;
|
||||
|
||||
/*
|
||||
* *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
|
||||
*/
|
||||
@ -201,9 +193,6 @@ class GrGLSLProgramBuilder : public GrGLSLGPBuilder,
|
||||
public:
|
||||
typedef GrGpu::DrawArgs DrawArgs;
|
||||
|
||||
GrGLSLXPFragmentBuilder* getFragmentShaderBuilder() override { return &fFS; }
|
||||
GrGLSLVertexBuilder* getVertexShaderBuilder() override { return &fVS; }
|
||||
|
||||
// Handles for program uniforms (other than per-effect uniforms)
|
||||
struct BuiltinUniformHandles {
|
||||
UniformHandle fRTAdjustmentUni;
|
||||
|
@ -18,8 +18,8 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrGLSLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
|
||||
const char* dstColor = fsBuilder->dstColor();
|
||||
GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
|
||||
const char* dstColor = fragBuilder->dstColor();
|
||||
|
||||
if (args.fXP.getDstTexture()) {
|
||||
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
|
||||
@ -27,9 +27,9 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
|
||||
if (args.fXP.readsCoverage()) {
|
||||
// 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
|
||||
fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
|
||||
" discard;"
|
||||
"}", args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
|
||||
" discard;"
|
||||
"}", args.fInputCoverage);
|
||||
}
|
||||
|
||||
const char* dstTopLeftName;
|
||||
@ -45,36 +45,40 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
|
||||
kDefault_GrSLPrecision,
|
||||
"DstTextureCoordScale",
|
||||
&dstCoordScaleName);
|
||||
const char* fragPos = fsBuilder->fragmentPosition();
|
||||
const char* fragPos = fragBuilder->fragmentPosition();
|
||||
|
||||
fsBuilder->codeAppend("// Read color from copy of the destination.\n");
|
||||
fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
|
||||
fragPos, dstTopLeftName, dstCoordScaleName);
|
||||
fragBuilder->codeAppend("// Read color from copy of the destination.\n");
|
||||
fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
|
||||
fragPos, dstTopLeftName, dstCoordScaleName);
|
||||
|
||||
if (!topDown) {
|
||||
fsBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
|
||||
fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
|
||||
}
|
||||
|
||||
fsBuilder->codeAppendf("vec4 %s = ", dstColor);
|
||||
fsBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
|
||||
fsBuilder->codeAppend(";");
|
||||
fragBuilder->codeAppendf("vec4 %s = ", dstColor);
|
||||
fragBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
|
||||
fragBuilder->codeAppend(";");
|
||||
}
|
||||
|
||||
this->emitBlendCodeForDstRead(args.fPB, args.fInputColor, dstColor, args.fOutputPrimary,
|
||||
this->emitBlendCodeForDstRead(args.fPB,
|
||||
fragBuilder,
|
||||
args.fInputColor,
|
||||
dstColor,
|
||||
args.fOutputPrimary,
|
||||
args.fXP);
|
||||
|
||||
// Apply coverage.
|
||||
if (args.fXP.dstReadUsesMixedSamples()) {
|
||||
if (args.fXP.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s *= %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("%s *= %s;", args.fOutputPrimary, args.fInputCoverage);
|
||||
fragBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputSecondary);
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputSecondary);
|
||||
}
|
||||
} else if (args.fXP.readsCoverage()) {
|
||||
fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage,
|
||||
args.fOutputPrimary, args.fInputCoverage, dstColor);
|
||||
fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
|
||||
args.fOutputPrimary, args.fInputCoverage,
|
||||
args.fOutputPrimary, args.fInputCoverage, dstColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "glsl/GrGLSLProgramDataManager.h"
|
||||
#include "glsl/GrGLSLTextureSampler.h"
|
||||
|
||||
class GrGLSLXPFragmentBuilder;
|
||||
class GrGLSLXPBuilder;
|
||||
class GrXferProcessor;
|
||||
|
||||
@ -22,6 +23,7 @@ public:
|
||||
typedef GrGLSLTextureSampler::TextureSamplerArray TextureSamplerArray;
|
||||
struct EmitArgs {
|
||||
EmitArgs(GrGLSLXPBuilder* pb,
|
||||
GrGLSLXPFragmentBuilder* fragBuilder,
|
||||
const GrXferProcessor& xp,
|
||||
const char* inputColor,
|
||||
const char* inputCoverage,
|
||||
@ -29,6 +31,7 @@ public:
|
||||
const char* outputSecondary,
|
||||
const TextureSamplerArray& samplers)
|
||||
: fPB(pb)
|
||||
, fXPFragBuilder(fragBuilder)
|
||||
, fXP(xp)
|
||||
, fInputColor(inputColor)
|
||||
, fInputCoverage(inputCoverage)
|
||||
@ -37,6 +40,7 @@ public:
|
||||
, fSamplers(samplers) {}
|
||||
|
||||
GrGLSLXPBuilder* fPB;
|
||||
GrGLSLXPFragmentBuilder* fXPFragBuilder;
|
||||
const GrXferProcessor& fXP;
|
||||
const char* fInputColor;
|
||||
const char* fInputCoverage;
|
||||
@ -75,6 +79,7 @@ private:
|
||||
* method if it can construct a GrXferProcessor that reads the dst color.
|
||||
*/
|
||||
virtual void emitBlendCodeForDstRead(GrGLSLXPBuilder*,
|
||||
GrGLSLXPFragmentBuilder*,
|
||||
const char* srcColor,
|
||||
const char* dstColor,
|
||||
const char* outColor,
|
||||
|
@ -48,11 +48,11 @@ public:
|
||||
|
||||
virtual void emitCode(EmitArgs& args) override {
|
||||
// pass through
|
||||
GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
|
||||
GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
if (args.fInputColor) {
|
||||
fsBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
|
||||
fragBuilder->codeAppendf("%s = %s;\n", args.fOutputColor, args.fInputColor);
|
||||
} else {
|
||||
fsBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
|
||||
fragBuilder->codeAppendf("%s = vec4(1.0);\n", args.fOutputColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user