Prevent outset Ws from going negative
Bug: skia:9028
Change-Id: I8e3d37050d3fce7602eee62ae911eae756e603a2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/211100
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index b9a7b45..e2714a6 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -258,6 +258,19 @@
V4f(0.f)) / denom; /* !B */
}
+ V4f newW = quad->fW + a * e1w + b * e2w;
+ // If newW < 0, scale a and b such that the point reaches the infinity plane instead of crossing
+ // This breaks orthogonality of inset/outsets, but GPUs don't handle negative Ws well so this
+ // is far less visually disturbing (likely not noticeable since it's at extreme perspective).
+ // The alternative correction (multiply xyw by -1) has the disadvantage of changing how local
+ // coordinates would be interpolated.
+ static const float kMinW = 1e-6f;
+ if (any(newW < 0.f)) {
+ V4f scale = if_then_else(newW < kMinW, (kMinW - quad->fW) / (newW - quad->fW), V4f(1.f));
+ a *= scale;
+ b *= scale;
+ }
+
quad->fX += a * e1x + b * e2x;
quad->fY += a * e1y + b * e2y;
quad->fW += a * e1w + b * e2w;