From a836267029be6c91ccf2776ac879d98f77a95909 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 1 Jun 2017 14:45:29 -0400 Subject: [PATCH] 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 Reviewed-by: Florin Malita --- src/shaders/gradients/SkLinearGradient.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp index 17c4fd36a4..aef724389a 100644 --- a/src/shaders/gradients/SkLinearGradient.cpp +++ b/src/shaders/gradients/SkLinearGradient.cpp @@ -560,8 +560,21 @@ template SkPMColor trunc_from_255(const Sk4f& x, const Sk4f& 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::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(post_bias(c4f255, bias)).store(&c);