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>
This commit is contained in:
Lee Salzman 2017-06-01 14:45:29 -04:00 committed by Skia Commit-Bot
parent 5df94d508e
commit a836267029

View File

@ -560,8 +560,21 @@ template <bool apply_alpha> 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<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);