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; |
} |