Reland "Snap coordinates for shader nearest-neighbor decal filtering"
This is a reland of 4e68ec693fdbb1a074b744f78e4999b60b517389
Original change's description:
> Snap coordinates for shader nearest-neighbor decal filtering
>
> Bug: skia:10403
> Change-Id: I875b1a4bb7cacbe6721a69aa8ed02118b989729d
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297596
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Bug: skia:10403
Change-Id: Idcf0b9a2d85410901a6d6fc2bedf628122cf9ae4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/297799
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
diff --git a/src/gpu/effects/GrTextureEffect.cpp b/src/gpu/effects/GrTextureEffect.cpp
index 0f1b0fb..5113cbf 100644
--- a/src/gpu/effects/GrTextureEffect.cpp
+++ b/src/gpu/effects/GrTextureEffect.cpp
@@ -671,17 +671,20 @@
}
// Do hard-edge shader transition to border color for kClampToBorderNearest at the
- // subset boundaries.
+ // subset boundaries. Snap the input coordinates to nearest neighbor (with an
+ // epsilon) before comparing to the subset rect to avoid GPU interpolation errors
if (m[0] == ShaderMode::kClampToBorderNearest) {
fb->codeAppendf(
- "if (inCoord.x < %s.x || inCoord.x > %s.z) {"
+ "float snappedX = floor(inCoord.x + 0.001) + 0.5;"
+ "if (snappedX < %s.x || snappedX > %s.z) {"
" textureColor = %s;"
"}",
subsetName, subsetName, borderName);
}
if (m[1] == ShaderMode::kClampToBorderNearest) {
fb->codeAppendf(
- "if (inCoord.y < %s.y || inCoord.y > %s.w) {"
+ "float snappedY = floor(inCoord.y + 0.001) + 0.5;"
+ "if (snappedY < %s.y || snappedY > %s.w) {"
" textureColor = %s;"
"}",
subsetName, subsetName, borderName);