Chromium Code Reviews| Index: include/core/SkColorPriv.h |
| diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h |
| index 40e6e15dc8873d823ff863f33196f852190b39b8..eaac4975c8406ea499e4c58c6a2bfdd0652687fb 100644 |
| --- a/include/core/SkColorPriv.h |
| +++ b/include/core/SkColorPriv.h |
| @@ -200,6 +200,11 @@ static inline unsigned Sk255To256(U8CPU value) { |
| */ |
| #define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) |
| +/** Inverted version of SkAlphaMul that properly subtracts off |
| + * any fractional precision. |
| + */ |
| +#define SkAlphaMulInv256(value, alpha256) (((256<<8) - (value) * (alpha256)) >> 8) |
|
mtklein
2016/07/26 19:29:43
Let's make this a static function and maybe try to
|
| + |
| // The caller may want negative values, so keep all params signed (int) |
| // so we don't accidentally slip into unsigned math and lose the sign |
| // extension when we shift (in SkAlphaMul) |
| @@ -572,9 +577,17 @@ static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { |
| SkASSERT((unsigned)aa <= 255); |
| unsigned src_scale = SkAlpha255To256(aa); |
| - unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale)); |
| + unsigned dst_scale = SkAlphaMulInv256(SkGetPackedA32(src), src_scale); |
| + |
| + const uint32_t mask = 0xFF00FF; |
| + |
| + uint32_t src_rb = (src & mask) * src_scale; |
| + uint32_t src_ag = ((src >> 8) & mask) * src_scale; |
| + |
| + uint32_t dst_rb = (dst & mask) * dst_scale; |
| + uint32_t dst_ag = ((dst >> 8) & mask) * dst_scale; |
| - return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale); |
| + return (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask); |
| } |
| //////////////////////////////////////////////////////////////////////////////////////////// |