fix premultiplied color generation in linear gradients when using fApplyAlphaAfterInterp
BUG=skia:
Change-Id: I771797498f60313022cd3a9e53037e98b3b3590b
Reviewed-on: https://skia-review.googlesource.com/17818
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp
index 17c4fd3..aef7243 100644
--- a/src/shaders/gradients/SkLinearGradient.cpp
+++ b/src/shaders/gradients/SkLinearGradient.cpp
@@ -560,8 +560,21 @@
SkPMColor c;
Sk4f c4f255 = x;
if (apply_alpha) {
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_ALPHATRUNC
+ static constexpr float alphaScale = 1;
+#else
+ // Due to use of multiplication by the 1/255 reciprocal instead of division by 255,
+ // non-integer alpha values very close to their ceiling can push the color values
+ // above the alpha value, which will become an invalid premultiplied color. So nudge
+ // alpha up slightly by a compensating scale to keep it above the color values.
+ // To do this, multiply alpha by a number slightly greater than 1 to compensate
+ // for error in scaling from the 1/255 approximation. Since this error is then
+ // scaled by the alpha value, we need to scale the epsilon by 255 to get a safe
+ // upper bound on the error.
+ static constexpr float alphaScale = 1 + 255*std::numeric_limits<float>::epsilon();
+#endif
const float scale = x[SkPM4f::A] * (1 / 255.f);
- c4f255 *= Sk4f(scale, scale, scale, 1);
+ c4f255 *= Sk4f(scale, scale, scale, alphaScale);
}
SkNx_cast<uint8_t>(post_bias<apply_alpha>(c4f255, bias)).store(&c);