Don't go out of our way to do vector calc in GrTextureEffect
We aren't concerned with testing on Chorizo anymore.
Change-Id: Ia82bca260088495971cbe2ac0e65b0c8928c24d9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/270196
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/effects/GrTextureEffect.cpp b/src/gpu/effects/GrTextureEffect.cpp
index cbfe3ce..5f1c788 100644
--- a/src/gpu/effects/GrTextureEffect.cpp
+++ b/src/gpu/effects/GrTextureEffect.cpp
@@ -235,39 +235,6 @@
public:
void emitCode(EmitArgs& args) override {
- auto appendWrap = [](GrGLSLShaderBuilder* builder, ShaderMode mode, const char* inCoord,
- const char* domainStart, const char* domainEnd, bool is2D,
- const char* out) {
- switch (mode) {
- case ShaderMode::kNone:
- builder->codeAppendf("%s = %s;\n", out, inCoord);
- break;
- case ShaderMode::kDecal:
- // The lookup coordinate to use for decal will be clamped just like
- // kClamp_Mode, it's just that the post-processing will be different, so
- // fall through
- case ShaderMode::kClamp:
- builder->codeAppendf("%s = clamp(%s, %s, %s);", out, inCoord, domainStart,
- domainEnd);
- break;
- case ShaderMode::kRepeat:
- builder->codeAppendf("%s = mod(%s - %s, %s - %s) + %s;", out, inCoord,
- domainStart, domainEnd, domainStart, domainStart);
- break;
- case ShaderMode::kMirrorRepeat: {
- const char* type = is2D ? "float2" : "float";
- builder->codeAppend("{");
- builder->codeAppendf("%s w = %s - %s;", type, domainEnd, domainStart);
- builder->codeAppendf("%s w2 = 2 * w;", type);
- builder->codeAppendf("%s m = mod(%s - %s, w2);", type, inCoord,
- domainStart);
- builder->codeAppendf("%s = mix(m, w2 - m, step(w, m)) + %s;", out,
- domainStart);
- builder->codeAppend("}");
- break;
- }
- }
- };
auto te = args.fFp.cast<GrTextureEffect>();
const char* coords;
if (args.fFp.coordTransformsApplyToLocalCoords()) {
@@ -290,33 +257,53 @@
// Always use a local variable for the input coordinates; often callers pass in an
// expression and we want to cache it across all of its references in the code below
- auto inCoords = fb->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
+ fb->codeAppendf(
+ "float2 inCoord = %s;",
+ fb->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint).c_str());
fb->codeAppend("float2 clampedCoord;");
- SkString start;
- SkString end;
- if (te.fShaderModes[0] == te.fShaderModes[1]) {
- // Doing the domain setup using vectors seems to avoid shader compilation issues
- // on Chromecast, possibly due to reducing shader length.
- start.printf("%s.xy", subsetName);
- end.printf("%s.zw", subsetName);
- appendWrap(fb, te.fShaderModes[0], inCoords.c_str(), start.c_str(), end.c_str(),
- true, "clampedCoord");
- } else {
- SkString origX, origY;
- // Apply x mode to the x coordinate using the left and right edges of the domain
- // rect (stored as the x and z components of the domain uniform).
- start.printf("%s.x", subsetName);
- end.printf("%s.z", subsetName);
- origX.printf("%s.x", inCoords.c_str());
- appendWrap(fb, te.fShaderModes[0], origX.c_str(), start.c_str(), end.c_str(),
- false, "clampedCoord.x");
- // Repeat the same logic for y.
- start.printf("%s.y", subsetName);
- end.printf("%s.w", subsetName);
- origY.printf("%s.y", inCoords.c_str());
- appendWrap(fb, te.fShaderModes[1], origY.c_str(), start.c_str(), end.c_str(),
- false, "clampedCoord.y");
- }
+
+ auto subsetCoord = [fb, subsetName](ShaderMode mode, const char* coordSwizzle,
+ const char* subsetStartSwizzle,
+ const char* subsetStopSwizzle) {
+ switch (mode) {
+ case ShaderMode::kNone:
+ fb->codeAppendf("clampedCoord.%s = inCoord.%s;\n", coordSwizzle,
+ coordSwizzle);
+ break;
+ case ShaderMode::kDecal:
+ // The lookup coordinate to use for decal will be clamped just like
+ // kClamp_Mode, it's just that the post-processing will be different, so
+ // fall through
+ case ShaderMode::kClamp:
+ fb->codeAppendf("clampedCoord.%s = clamp(inCoord.%s, %s.%s, %s.%s);",
+ coordSwizzle, coordSwizzle, subsetName,
+ subsetStartSwizzle, subsetName, subsetStopSwizzle);
+ break;
+ case ShaderMode::kRepeat:
+ fb->codeAppendf(
+ "clampedCoord.%s = mod(inCoord.%s - %s.%s, %s.%s - %s.%s) + "
+ "%s.%s;",
+ coordSwizzle, coordSwizzle, subsetName, subsetStartSwizzle,
+ subsetName, subsetStopSwizzle, subsetName, subsetStartSwizzle,
+ subsetName, subsetStartSwizzle);
+ break;
+ case ShaderMode::kMirrorRepeat: {
+ fb->codeAppend("{");
+ fb->codeAppendf("float w = %s.%s - %s.%s;", subsetName,
+ subsetStopSwizzle, subsetName, subsetStartSwizzle);
+ fb->codeAppendf("float w2 = 2 * w;");
+ fb->codeAppendf("float m = mod(inCoord.%s - %s.%s, w2);", coordSwizzle,
+ subsetName, subsetStartSwizzle);
+ fb->codeAppendf("clampedCoord.%s = mix(m, w2 - m, step(w, m)) + %s.%s;",
+ coordSwizzle, subsetName, subsetStartSwizzle);
+ fb->codeAppend("}");
+ break;
+ }
+ }
+ };
+
+ subsetCoord(te.fShaderModes[0], "x", "x", "z");
+ subsetCoord(te.fShaderModes[1], "y", "y", "w");
SkString textureLookup;
fb->appendTextureLookup(&textureLookup, args.fTexSamplers[0], "clampedCoord");
fb->codeAppendf("half4 textureColor = %s;", textureLookup.c_str());
@@ -336,16 +323,16 @@
// behavior depending on if it's 0 or 1.
if (decalX && decalY) {
fb->codeAppendf(
- "half err = max(half(abs(clampedCoord.x - %s.x) * %s.x), "
- " half(abs(clampedCoord.y - %s.y) * %s.y));",
- inCoords.c_str(), decalName, inCoords.c_str(), decalName);
+ "half err = max(half(abs(clampedCoord.x - inCoord.x) * %s.x), "
+ " half(abs(clampedCoord.y - inCoord.y) * %s.y));",
+ decalName, decalName);
} else if (decalX) {
- fb->codeAppendf("half err = half(abs(clampedCoord.x - %s.x) * %s.x);",
- inCoords.c_str(), decalName);
+ fb->codeAppendf("half err = half(abs(clampedCoord.x - inCoord.x) * %s.x);",
+ decalName);
} else {
SkASSERT(decalY);
- fb->codeAppendf("half err = half(abs(clampedCoord.y - %s.y) * %s.y);",
- inCoords.c_str(), decalName);
+ fb->codeAppendf("half err = half(abs(clampedCoord.y - inCoord.y) * %s.y);",
+ decalName);
}
// Apply a transform to the error rate, which let's us simulate nearest or