Chromium Code Reviews| Index: src/effects/gradients/SkLinearGradient.cpp |
| diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp |
| index a249ae4ac82c2195ce2e559978cf057ce0a8377a..eb119fa354f36b4e731c7833314c3a4fe8833d77 100644 |
| --- a/src/effects/gradients/SkLinearGradient.cpp |
| +++ b/src/effects/gradients/SkLinearGradient.cpp |
| @@ -525,25 +525,49 @@ find_backward(const SkLinearGradient::LinearGradientContext::Rec rec[], float ti |
| return rec; |
| } |
| -template <bool apply_alpha> SkPMColor trunc_from_255(const Sk4f& x) { |
| +template <bool apply_alpha> SkPMColor trunc_from_255(const Sk4f& x, const Sk4f& bias) { |
| SkPMColor c; |
| + |
| +#ifdef SK_SUPPORT_LEGACY_GRADIENT_PREMUL |
| SkNx_cast<uint8_t>(x).store(&c); |
| if (apply_alpha) { |
| c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), |
| SkGetPackedG32(c), SkGetPackedB32(c)); |
| } |
| +#else |
| + Sk4f c4f255; |
| + if (!apply_alpha) { |
| + // when apply_alpha is false, the bias is preapplied. |
| + c4f255 = x; |
| + } else { |
| + const float scale = x[SkPM4f::A] * 1.f / 255; |
|
reed1
2016/10/11 16:31:39
are we sure the 1 / 255 *always* gets resolved at
mtklein
2016/10/11 16:38:15
No, as written this will never be a single multipl
f(malita)
2016/10/11 19:19:06
Done.
|
| + // apply the bias *after* premul |
| + c4f255 = x * Sk4f(scale, scale, scale, 1) + bias; |
| + } |
| + SkNx_cast<uint8_t>(c4f255).store(&c); |
| +#endif |
| return c; |
| } |
| template <bool apply_alpha> void fill(SkPMColor dst[], int count, |
| - const Sk4f& c4, const Sk4f& c4other) { |
| - sk_memset32_dither(dst, trunc_from_255<apply_alpha>(c4), |
| - trunc_from_255<apply_alpha>(c4other), count); |
| + const Sk4f& c4, const Sk4f& bias0, const Sk4f& bias1) { |
| +#ifdef SK_SUPPORT_LEGACY_GRADIENT_PREMUL |
| + const SkPMColor c0 = trunc_from_255<apply_alpha>(c4 + bias0, 0); |
| + const SkPMColor c1 = trunc_from_255<apply_alpha>(c4 + bias1, 0); |
| +#else |
| + const SkPMColor c0 = apply_alpha |
| + ? trunc_from_255<apply_alpha>(c4, bias0) |
| + : trunc_from_255<apply_alpha>(c4 + bias0, 0); |
| + const SkPMColor c1 = apply_alpha |
| + ? trunc_from_255<apply_alpha>(c4, bias1) |
| + : trunc_from_255<apply_alpha>(c4 + bias1, 0); |
| +#endif |
| + sk_memset32_dither(dst, c0, c1, count); |
| } |
| template <bool apply_alpha> void fill(SkPMColor dst[], int count, const Sk4f& c4) { |
| // Assumes that c4 does not need to be dithered. |
| - sk_memset32(dst, trunc_from_255<apply_alpha>(c4), count); |
| + sk_memset32(dst, trunc_from_255<apply_alpha>(c4, 0), count); |
| } |
| /* |
| @@ -573,8 +597,17 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co |
| const Sk4f& dither0, const Sk4f& dither1) { |
| Sk4f dc2 = dc + dc; |
| Sk4f dc4 = dc2 + dc2; |
| - Sk4f cd0 = c + dither0; |
| - Sk4f cd1 = c + dc + dither1; |
| + Sk4f cd0 = c; |
| + Sk4f cd1 = c + dc; |
| +#ifndef SK_SUPPORT_LEGACY_GRADIENT_PREMUL |
| + // when apply_alpha is true, we defer dithering until after premul. |
| + if (!apply_alpha) { |
| +#endif |
| + cd0 += dither0; |
| + cd1 += dither1; |
| +#ifndef SK_SUPPORT_LEGACY_GRADIENT_PREMUL |
| + } |
| +#endif |
| Sk4f cd2 = cd0 + dc2; |
| Sk4f cd3 = cd1 + dc2; |
| while (n >= 4) { |
| @@ -582,10 +615,10 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co |
| Sk4f_ToBytes((uint8_t*)dstC, cd0, cd1, cd2, cd3); |
| dstC += 4; |
| } else { |
| - *dstC++ = trunc_from_255<apply_alpha>(cd0); |
| - *dstC++ = trunc_from_255<apply_alpha>(cd1); |
| - *dstC++ = trunc_from_255<apply_alpha>(cd2); |
| - *dstC++ = trunc_from_255<apply_alpha>(cd3); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd1, dither1); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd2, dither0); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd3, dither1); |
| } |
| cd0 = cd0 + dc4; |
| cd1 = cd1 + dc4; |
| @@ -594,12 +627,12 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co |
| n -= 4; |
| } |
| if (n & 2) { |
| - *dstC++ = trunc_from_255<apply_alpha>(cd0); |
| - *dstC++ = trunc_from_255<apply_alpha>(cd1); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd1, dither1); |
| cd0 = cd0 + dc2; |
| } |
| if (n & 1) { |
| - *dstC++ = trunc_from_255<apply_alpha>(cd0); |
| + *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0); |
| } |
| } |
| @@ -746,9 +779,9 @@ void SkLinearGradient::LinearGradientContext::shade4_clamp(int x, int y, SkPMCol |
| const float pinFx = SkTPin(fx, 0.0f, 1.0f); |
| Sk4f c = lerp_color(pinFx, find_forward(fRecs.begin(), pinFx)); |
| if (fApplyAlphaAfterInterp) { |
| - fill<true>(dstC, count, c + dither0, c + dither1); |
| + fill<true>(dstC, count, c, dither0, dither1); |
| } else { |
| - fill<false>(dstC, count, c + dither0, c + dither1); |
| + fill<false>(dstC, count, c, dither0, dither1); |
| } |
| return; |
| } |