diff options
author | 2012-01-18 21:28:01 +0000 | |
---|---|---|
committer | 2012-01-18 21:28:01 +0000 | |
commit | 13e812c69a9e2b2550871573786fc72b17bdd766 (patch) | |
tree | 7534b25d3a5dde8eeb85eaed64023ff5b0b7c672 /include/core/SkColorPriv.h | |
parent | 90503184f66d5c09bc572e1525e89a28aad8ac5b (diff) |
Interpolate vertical linear gradients for improved quality.
Consolidate interpolation functions, add new faster more accurate dithering
interpolator.
git-svn-id: http://skia.googlecode.com/svn/trunk@3072 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core/SkColorPriv.h')
-rw-r--r-- | include/core/SkColorPriv.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h index 714e845af0..befc249c0a 100644 --- a/include/core/SkColorPriv.h +++ b/include/core/SkColorPriv.h @@ -216,6 +216,57 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { } /** + * Abstract 4-byte interpolation, implemented on top of SkPMColor + * utility functions. Third parameter controls blending of the first two: + * (src, dst, 0) returns dst + * (src, dst, 0xFF) returns src + */ +static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, + U8CPU srcWeight) { + unsigned scale = SkAlpha255To256(srcWeight); + + unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale); + unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale); + unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale); + unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale); + + return SkPackARGB32(a, r, g, b); +} + +/** + * 32b optimized version; currently appears to be 10% faster even on 64b + * architectures than an equivalent 64b version and 30% faster than + * SkFourByteInterp(). Third parameter controls blending of the first two: + * (src, dst, 0) returns dst + * (src, dst, 0xFF) returns src + * ** Does not match the results of SkFourByteInterp() because we use + * a more accurate scale computation! + * TODO: migrate Skia function to using an accurate 255->266 alpha + * conversion. + */ +static inline SkPMColor SkFastFourByteInterp(SkPMColor src, + SkPMColor dst, + U8CPU srcWeight) { + SkASSERT(srcWeight < 256); + + // Reorders ARGB to AG-RB in order to reduce the number of operations. + const uint32_t mask = 0xFF00FF; + uint32_t src_rb = src & mask; + uint32_t src_ag = (src >> 8) & mask; + uint32_t dst_rb = dst & mask; + uint32_t dst_ag = (dst >> 8) & mask; + + // scale = srcWeight + (srcWeight >> 7) is more accurate than + // scale = srcWeight + 1, but 7% slower + int scale = srcWeight + (srcWeight >> 7); + + uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; + uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; + + return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8); +} + +/** * Same as SkPackARGB32, but this version guarantees to not check that the * values are premultiplied in the debug version. */ |