diff options
95 files changed, 1135 insertions, 1112 deletions
diff --git a/bench/ColorPrivBench.cpp b/bench/ColorPrivBench.cpp index 314f0cb28f..46aacd74c9 100644 --- a/bench/ColorPrivBench.cpp +++ b/bench/ColorPrivBench.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ #include "Benchmark.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkRandom.h" #include "SkString.h" diff --git a/bench/InterpBench.cpp b/bench/InterpBench.cpp index f259b83cc5..16cc499166 100644 --- a/bench/InterpBench.cpp +++ b/bench/InterpBench.cpp @@ -6,7 +6,7 @@ */ #include "Benchmark.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkFixed.h" #include "SkMatrix.h" #include "SkPaint.h" diff --git a/bench/MathBench.cpp b/bench/MathBench.cpp index 3b0fd099ab..72161549d2 100644 --- a/bench/MathBench.cpp +++ b/bench/MathBench.cpp @@ -6,7 +6,7 @@ */ #include "Benchmark.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkFixed.h" #include "SkMathPriv.h" #include "SkMatrix.h" diff --git a/gm/bitmappremul.cpp b/gm/bitmappremul.cpp index 31a565018d..85e30bea42 100644 --- a/gm/bitmappremul.cpp +++ b/gm/bitmappremul.cpp @@ -8,7 +8,7 @@ #include "gm.h" #include "SkBitmap.h" #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" /** * This GM checks that bitmap pixels are unpremultiplied before being exported diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h index 12c2277656..8ec4541754 100644 --- a/include/core/SkColorPriv.h +++ b/include/core/SkColorPriv.h @@ -8,171 +8,6 @@ #ifndef SkColorPriv_DEFINED #define SkColorPriv_DEFINED -// turn this own for extra debug checking when blending onto 565 -#ifdef SK_DEBUG - #define CHECK_FOR_565_OVERFLOW -#endif - -#include "SkColor.h" -#include "SkMath.h" - -////////////////////////////////////////////////////////////////////////////// - -#define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF)) - -/* - * Skia's 32bit backend only supports 1 sizzle order at a time (compile-time). - * This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B. - * - * For easier compatibility with Skia's GPU backend, we further restrict these - * to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does - * not directly correspond to the same shift-order, since we have to take endianess - * into account. - * - * Here we enforce this constraint. - */ - -#ifdef SK_CPU_BENDIAN - #define SK_RGBA_R32_SHIFT 24 - #define SK_RGBA_G32_SHIFT 16 - #define SK_RGBA_B32_SHIFT 8 - #define SK_RGBA_A32_SHIFT 0 - - #define SK_BGRA_B32_SHIFT 24 - #define SK_BGRA_G32_SHIFT 16 - #define SK_BGRA_R32_SHIFT 8 - #define SK_BGRA_A32_SHIFT 0 -#else - #define SK_RGBA_R32_SHIFT 0 - #define SK_RGBA_G32_SHIFT 8 - #define SK_RGBA_B32_SHIFT 16 - #define SK_RGBA_A32_SHIFT 24 - - #define SK_BGRA_B32_SHIFT 0 - #define SK_BGRA_G32_SHIFT 8 - #define SK_BGRA_R32_SHIFT 16 - #define SK_BGRA_A32_SHIFT 24 -#endif - -#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA) - #error "can't define PMCOLOR to be RGBA and BGRA" -#endif - -#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \ - (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \ - SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \ - SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \ - SK_B32_SHIFT == SK_RGBA_B32_SHIFT) - -#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \ - (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \ - SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \ - SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \ - SK_B32_SHIFT == SK_BGRA_B32_SHIFT) - - -#define SK_A_INDEX (SK_A32_SHIFT/8) -#define SK_R_INDEX (SK_R32_SHIFT/8) -#define SK_G_INDEX (SK_G32_SHIFT/8) -#define SK_B_INDEX (SK_B32_SHIFT/8) - -#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA - #error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values" -#endif - -#if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA - #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values" -#endif - -#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA) - // deduce which to define from the _SHIFT defines - - #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA - #define SK_PMCOLOR_IS_RGBA - #elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA - #define SK_PMCOLOR_IS_BGRA - #else - #error "need 32bit packing to be either RGBA or BGRA" - #endif -#endif - -// hide these now that we're done -#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA -#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA - -////////////////////////////////////////////////////////////////////////////// - -// Reverse the bytes coorsponding to RED and BLUE in a packed pixels. Note the -// pair of them are in the same 2 slots in both RGBA and BGRA, thus there is -// no need to pass in the colortype to this function. -static inline uint32_t SkSwizzle_RB(uint32_t c) { - static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT); - - unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF; - unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF; - return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT); -} - -static inline uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { - SkASSERT_IS_BYTE(a); - SkASSERT_IS_BYTE(r); - SkASSERT_IS_BYTE(g); - SkASSERT_IS_BYTE(b); - return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) | - (g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT); -} - -static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { - SkASSERT_IS_BYTE(a); - SkASSERT_IS_BYTE(r); - SkASSERT_IS_BYTE(g); - SkASSERT_IS_BYTE(b); - return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) | - (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT); -} - -static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) { -#ifdef SK_PMCOLOR_IS_RGBA - return c; -#else - return SkSwizzle_RB(c); -#endif -} - -static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) { -#ifdef SK_PMCOLOR_IS_BGRA - return c; -#else - return SkSwizzle_RB(c); -#endif -} - -////////////////////////////////////////////////////////////////////////////// - -///@{ -/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/ -#define SK_ITU_BT709_LUM_COEFF_R (0.2126f) -#define SK_ITU_BT709_LUM_COEFF_G (0.7152f) -#define SK_ITU_BT709_LUM_COEFF_B (0.0722f) -///@} - -///@{ -/** A float value which specifies this channel's contribution to luminance. */ -#define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R -#define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G -#define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B -///@} - -/** Computes the luminance from the given r, g, and b in accordance with - SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space. -*/ -static inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) { - //The following is - //r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B - //with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256). - return (r * 54 + g * 183 + b * 19) >> 8; -} - /** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a byte into a scale value, so that we can say scale * value >> 8 instead of alpha * value / 255. @@ -186,217 +21,16 @@ static inline unsigned SkAlpha255To256(U8CPU alpha) { return alpha + 1; } -/** - * Turn a 0..255 value into a 0..256 value, rounding up if the value is >= 0x80. - * This is slightly more accurate than SkAlpha255To256. - */ -static inline unsigned Sk255To256(U8CPU value) { - SkASSERT(SkToU8(value) == value); - return value + (value >> 7); -} - -/** Multiplify value by 0..256, and shift the result down 8 - (i.e. return (value * alpha256) >> 8) - */ -#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) - -/** Calculates 256 - (value * alpha256) / 255 in range [0,256], - * for [0,255] value and [0,256] alpha256. - */ -static inline U16CPU SkAlphaMulInv256(U16CPU value, U16CPU alpha256) { - unsigned prod = 0xFFFF - value * alpha256; - return (prod + (prod >> 8)) >> 8; -} - -// 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) -static inline int SkAlphaBlend(int src, int dst, int scale256) { - SkASSERT((unsigned)scale256 <= 256); - return dst + SkAlphaMul(src - dst, scale256); -} - -/** - * Returns (src * alpha + dst * (255 - alpha)) / 255 - * - * This is more accurate than SkAlphaBlend, but slightly slower - */ -static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { - SkASSERT((int16_t)src == src); - SkASSERT((int16_t)dst == dst); - SkASSERT((uint8_t)alpha == alpha); - - int prod = (src - dst) * alpha + 128; - prod = (prod + (prod >> 8)) >> 8; - return dst + prod; -} - -static inline U8CPU SkUnitScalarClampToByte(SkScalar x) { - return static_cast<U8CPU>(SkScalarPin(x, 0, 1) * 255 + 0.5); -} - -#define SK_R16_BITS 5 -#define SK_G16_BITS 6 -#define SK_B16_BITS 5 - -#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS) -#define SK_G16_SHIFT (SK_B16_BITS) -#define SK_B16_SHIFT 0 - -#define SK_R16_MASK ((1 << SK_R16_BITS) - 1) -#define SK_G16_MASK ((1 << SK_G16_BITS) - 1) -#define SK_B16_MASK ((1 << SK_B16_BITS) - 1) - -#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK) -#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK) -#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK) - -#define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK) -#define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK) -#define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK) - -static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) { - SkASSERT(r <= SK_R16_MASK); - SkASSERT(g <= SK_G16_MASK); - SkASSERT(b <= SK_B16_MASK); - - return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT)); -} - -#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT) -#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT) -#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT) - -/** Expand the 16bit color into a 32bit value that can be scaled all at once - by a value up to 32. Used in conjunction with SkCompact_rgb_16. -*/ -static inline uint32_t SkExpand_rgb_16(U16CPU c) { - SkASSERT(c == (uint16_t)c); - - return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE); -} - -/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit - color value. The computation yields only 16bits of valid data, but we claim - to return 32bits, so that the compiler won't generate extra instructions to - "clean" the top 16bits. However, the top 16 can contain garbage, so it is - up to the caller to safely ignore them. -*/ -static inline U16CPU SkCompact_rgb_16(uint32_t c) { - return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE); -} - -/** Scale the 16bit color value by the 0..256 scale parameter. - The computation yields only 16bits of valid data, but we claim - to return 32bits, so that the compiler won't generate extra instructions to - "clean" the top 16bits. -*/ -static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) { - return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5); -} - -// this helper explicitly returns a clean 16bit value (but slower) -#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s) - -/** Blend pre-expanded RGB32 with 16bit color value by the 0..32 scale parameter. - The computation yields only 16bits of valid data, but we claim to return - 32bits, so that the compiler won't generate extra instructions to "clean" - the top 16bits. -*/ -static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst, unsigned scale) { - uint32_t dst_expand = SkExpand_rgb_16(dst) * scale; - return SkCompact_rgb_16((src_expand + dst_expand) >> 5); -} - -/** Blend src and dst 16bit colors by the 0..256 scale parameter. - The computation yields only 16bits of valid data, but we claim - to return 32bits, so that the compiler won't generate extra instructions to - "clean" the top 16bits. -*/ -static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) { - SkASSERT((unsigned)srcScale <= 256); - - srcScale >>= 3; - - uint32_t src32 = SkExpand_rgb_16(src); - uint32_t dst32 = SkExpand_rgb_16(dst); - return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); -} - -static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], - int srcScale, int count) { - SkASSERT(count > 0); - SkASSERT((unsigned)srcScale <= 256); - - srcScale >>= 3; - - do { - uint32_t src32 = SkExpand_rgb_16(*src++); - uint32_t dst32 = SkExpand_rgb_16(*dst); - *dst++ = static_cast<uint16_t>( - SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5))); - } while (--count > 0); -} - -#ifdef SK_DEBUG - static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) { - SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); - SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); - SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); - - return a + b; - } -#else - #define SkRGB16Add(a, b) ((a) + (b)) -#endif - -/////////////////////////////////////////////////////////////////////////////// - #define SK_A32_BITS 8 -#define SK_R32_BITS 8 -#define SK_G32_BITS 8 -#define SK_B32_BITS 8 #define SK_A32_MASK ((1 << SK_A32_BITS) - 1) -#define SK_R32_MASK ((1 << SK_R32_BITS) - 1) -#define SK_G32_MASK ((1 << SK_G32_BITS) - 1) -#define SK_B32_MASK ((1 << SK_B32_BITS) - 1) -#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24) +#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24) #define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24) #define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24) #define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24) #define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK) -#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK) -#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK) -#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK) - -#ifdef SK_DEBUG - #define SkPMColorAssert(color_value) \ - do { \ - SkPMColor pm_color_value = (color_value); \ - uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \ - SkA32Assert(alpha_color_value); \ - SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \ - SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \ - SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \ - } while (false) -#else - #define SkPMColorAssert(c) -#endif - -static inline bool SkPMColorValid(SkPMColor c) { - auto a = SkGetPackedA32(c); - bool valid = a <= SK_A32_MASK - && SkGetPackedR32(c) <= a - && SkGetPackedG32(c) <= a - && SkGetPackedB32(c) <= a; - if (valid) { - SkPMColorAssert(c); // Make sure we're consistent when it counts. - } - return valid; -} /** * Pack the components into a SkPMColor, checking (in the debug version) that @@ -412,132 +46,6 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); } -static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) { - return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c), - SkGetPackedG32(c), SkGetPackedB32(c)); -} - -static inline uint32_t SkPackPMColor_as_BGRA(SkPMColor c) { - return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c), - SkGetPackedG32(c), SkGetPackedB32(c)); -} - -/** - * 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 - * srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255] - */ -static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst, - unsigned scale) { - 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); -} - -/** - * 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); - return SkFourByteInterp256(src, dst, scale); -} - -/** - * 0xAARRGGBB -> 0x00AA00GG, 0x00RR00BB - */ -static inline void SkSplay(uint32_t color, uint32_t* ag, uint32_t* rb) { - const uint32_t mask = 0x00FF00FF; - *ag = (color >> 8) & mask; - *rb = color & mask; -} - -/** - * 0xAARRGGBB -> 0x00AA00GG00RR00BB - * (note, ARGB -> AGRB) - */ -static inline uint64_t SkSplay(uint32_t color) { - const uint32_t mask = 0x00FF00FF; - uint64_t agrb = (color >> 8) & mask; // 0x0000000000AA00GG - agrb <<= 32; // 0x00AA00GG00000000 - agrb |= color & mask; // 0x00AA00GG00RR00BB - return agrb; -} - -/** - * 0xAAxxGGxx, 0xRRxxBBxx-> 0xAARRGGBB - */ -static inline uint32_t SkUnsplay(uint32_t ag, uint32_t rb) { - const uint32_t mask = 0xFF00FF00; - return (ag & mask) | ((rb & mask) >> 8); -} - -/** - * 0xAAxxGGxxRRxxBBxx -> 0xAARRGGBB - * (note, AGRB -> ARGB) - */ -static inline uint32_t SkUnsplay(uint64_t agrb) { - const uint32_t mask = 0xFF00FF00; - return SkPMColor( - ((agrb & mask) >> 8) | // 0x00RR00BB - ((agrb >> 32) & mask)); // 0xAARRGGBB -} - -static inline SkPMColor SkFastFourByteInterp256_32(SkPMColor src, SkPMColor dst, unsigned scale) { - SkASSERT(scale <= 256); - - // Two 8-bit blends per two 32-bit registers, with space to make sure the math doesn't collide. - uint32_t src_ag, src_rb, dst_ag, dst_rb; - SkSplay(src, &src_ag, &src_rb); - SkSplay(dst, &dst_ag, &dst_rb); - - const uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; - const uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; - - return SkUnsplay(ret_ag, ret_rb); -} - -static inline SkPMColor SkFastFourByteInterp256_64(SkPMColor src, SkPMColor dst, unsigned scale) { - SkASSERT(scale <= 256); - // Four 8-bit blends in one 64-bit register, with space to make sure the math doesn't collide. - return SkUnsplay(SkSplay(src) * scale + (256-scale) * SkSplay(dst)); -} - -// TODO(mtklein): Replace slow versions with fast versions, using scale + (scale>>7) everywhere. - -/** - * Same as SkFourByteInterp256, but faster. - */ -static inline SkPMColor SkFastFourByteInterp256(SkPMColor src, SkPMColor dst, unsigned scale) { - // On a 64-bit machine, _64 is about 10% faster than _32, but ~40% slower on a 32-bit machine. - if (sizeof(void*) == 4) { - return SkFastFourByteInterp256_32(src, dst, scale); - } else { - return SkFastFourByteInterp256_64(src, dst, scale); - } -} - -/** - * Nearly the same as SkFourByteInterp, but faster and a touch more accurate, due to better - * srcWeight scaling to [0, 256]. - */ -static inline SkPMColor SkFastFourByteInterp(SkPMColor src, - SkPMColor dst, - U8CPU srcWeight) { - SkASSERT(srcWeight <= 255); - // scale = srcWeight + (srcWeight >> 7) is more accurate than - // scale = srcWeight + 1, but 7% slower - return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7)); -} - /** * Same as SkPackARGB32, but this version guarantees to not check that the * values are premultiplied in the debug version. @@ -547,21 +55,6 @@ static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); } -static inline -SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { - SkA32Assert(a); - SkR32Assert(r); - SkG32Assert(g); - SkB32Assert(b); - - if (a != 255) { - r = SkMulDiv255Round(r, a); - g = SkMulDiv255Round(g, a); - b = SkMulDiv255Round(b, a); - } - return SkPackARGB32(a, r, g, b); -} - // When Android is compiled optimizing for size, SkAlphaMulQ doesn't get // inlined; forcing inlining significantly improves performance. static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { @@ -576,509 +69,4 @@ static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); } -/** - * Interpolates between colors src and dst using [0,256] scale. - */ -static inline SkPMColor SkPMLerp(SkPMColor src, SkPMColor dst, unsigned scale) { - return SkFastFourByteInterp256(src, dst, scale); -} - -static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { - SkASSERT((unsigned)aa <= 255); - - unsigned src_scale = SkAlpha255To256(aa); - 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 (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// Convert a 32bit pixel to a 16bit pixel (no dither) - -#define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS)) -#define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS)) -#define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS)) - -#ifdef SK_DEBUG - static inline unsigned SkR32ToR16(unsigned r) { - SkR32Assert(r); - return SkR32ToR16_MACRO(r); - } - static inline unsigned SkG32ToG16(unsigned g) { - SkG32Assert(g); - return SkG32ToG16_MACRO(g); - } - static inline unsigned SkB32ToB16(unsigned b) { - SkB32Assert(b); - return SkB32ToB16_MACRO(b); - } -#else - #define SkR32ToR16(r) SkR32ToR16_MACRO(r) - #define SkG32ToG16(g) SkG32ToG16_MACRO(g) - #define SkB32ToB16(b) SkB32ToB16_MACRO(b) -#endif - -#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK) -#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK) -#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK) - -static inline U16CPU SkPixel32ToPixel16(SkPMColor c) { - unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT; - unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT; - unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT; - return r | g | b; -} - -static inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { - return (SkR32ToR16(r) << SK_R16_SHIFT) | - (SkG32ToG16(g) << SK_G16_SHIFT) | - (SkB32ToB16(b) << SK_B16_SHIFT); -} - -#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src)) - -///////////////////////////////////////////////////////////////////////////////////////// -// Fast dither from 32->16 - -#define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1) - -static inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { - r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS); - g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS); - b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS); - - return SkPackRGB16(r, g, b); -} - -static inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) { - return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); -} - -/* Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits) - It is now suitable for combining with a scaled expanded_rgb_16 color - as in SkSrcOver32To16(). - We must do this 565 high-bit replication, in order for the subsequent add - to saturate properly (and not overflow). If we take the 8 bits as is, it is - possible to overflow. -*/ -static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) { - unsigned sr = SkPacked32ToR16(c); - unsigned sg = SkPacked32ToG16(c); - unsigned sb = SkPacked32ToB16(c); - - sr = (sr << 5) | sr; - sg = (sg << 5) | (sg >> 1); - sb = (sb << 5) | sb; - return (sr << 11) | (sg << 21) | (sb << 0); -} - -/* SrcOver the 32bit src color with the 16bit dst, returning a 16bit value - (with dirt in the high 16bits, so caller beware). -*/ -static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) { - unsigned sr = SkGetPackedR32(src); - unsigned sg = SkGetPackedG32(src); - unsigned sb = SkGetPackedB32(src); - - unsigned dr = SkGetPackedR16(dst); - unsigned dg = SkGetPackedG16(dst); - unsigned db = SkGetPackedB16(dst); - - unsigned isa = 255 - SkGetPackedA32(src); - - dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS); - dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS); - db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS); - - return SkPackRGB16(dr, dg, db); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// Convert a 16bit pixel to a 32bit pixel - -static inline unsigned SkR16ToR32(unsigned r) { - return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8)); -} - -static inline unsigned SkG16ToG32(unsigned g) { - return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8)); -} - -static inline unsigned SkB16ToB32(unsigned b) { - return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8)); -} - -#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c)) -#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c)) -#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c)) - -static inline SkPMColor SkPixel16ToPixel32(U16CPU src) { - SkASSERT(src == SkToU16(src)); - - unsigned r = SkPacked16ToR32(src); - unsigned g = SkPacked16ToG32(src); - unsigned b = SkPacked16ToB32(src); - - SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); - SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); - SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); - - return SkPackARGB32(0xFF, r, g, b); -} - -// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor -static inline SkColor SkPixel16ToColor(U16CPU src) { - SkASSERT(src == SkToU16(src)); - - unsigned r = SkPacked16ToR32(src); - unsigned g = SkPacked16ToG32(src); - unsigned b = SkPacked16ToB32(src); - - SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); - SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); - SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); - - return SkColorSetRGB(r, g, b); -} - -/////////////////////////////////////////////////////////////////////////////// - -typedef uint16_t SkPMColor16; - -// Put in OpenGL order (r g b a) -#define SK_A4444_SHIFT 0 -#define SK_R4444_SHIFT 12 -#define SK_G4444_SHIFT 8 -#define SK_B4444_SHIFT 4 - -#define SkA32To4444(a) ((unsigned)(a) >> 4) -#define SkR32To4444(r) ((unsigned)(r) >> 4) -#define SkG32To4444(g) ((unsigned)(g) >> 4) -#define SkB32To4444(b) ((unsigned)(b) >> 4) - -static inline U8CPU SkReplicateNibble(unsigned nib) { - SkASSERT(nib <= 0xF); - return (nib << 4) | nib; -} - -#define SkA4444ToA32(a) SkReplicateNibble(a) -#define SkR4444ToR32(r) SkReplicateNibble(r) -#define SkG4444ToG32(g) SkReplicateNibble(g) -#define SkB4444ToB32(b) SkReplicateNibble(b) - -#define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF) -#define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF) -#define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF) -#define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF) - -#define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c)) -#define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c)) -#define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c)) -#define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c)) - -#ifdef SK_DEBUG -static inline void SkPMColor16Assert(U16CPU c) { - unsigned a = SkGetPackedA4444(c); - unsigned r = SkGetPackedR4444(c); - unsigned g = SkGetPackedG4444(c); - unsigned b = SkGetPackedB4444(c); - - SkASSERT(a <= 0xF); - SkASSERT(r <= a); - SkASSERT(g <= a); - SkASSERT(b <= a); -} -#else -#define SkPMColor16Assert(c) -#endif - -static inline unsigned SkAlpha15To16(unsigned a) { - SkASSERT(a <= 0xF); - return a + (a >> 3); -} - -#ifdef SK_DEBUG - static inline int SkAlphaMul4(int value, int scale) { - SkASSERT((unsigned)scale <= 0x10); - return value * scale >> 4; - } -#else - #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4) -#endif - -static inline unsigned SkR4444ToR565(unsigned r) { - SkASSERT(r <= 0xF); - return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS)); -} - -static inline unsigned SkG4444ToG565(unsigned g) { - SkASSERT(g <= 0xF); - return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS)); -} - -static inline unsigned SkB4444ToB565(unsigned b) { - SkASSERT(b <= 0xF); - return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS)); -} - -static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, - unsigned g, unsigned b) { - SkASSERT(a <= 0xF); - SkASSERT(r <= a); - SkASSERT(g <= a); - SkASSERT(b <= a); - - return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | - (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); -} - -static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) { - SkASSERT(scale <= 16); - - const unsigned mask = 0xF0F; //gMask_0F0F; - -#if 0 - unsigned rb = ((c & mask) * scale) >> 4; - unsigned ag = ((c >> 4) & mask) * scale; - return (rb & mask) | (ag & ~mask); -#else - unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12); - unsigned scaled_c = (expanded_c * scale) >> 4; - return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4)); -#endif -} - -/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at - once by a value up to 16. -*/ -static inline uint32_t SkExpand_4444(U16CPU c) { - SkASSERT(c == (uint16_t)c); - - const unsigned mask = 0xF0F; //gMask_0F0F; - return (c & mask) | ((c & ~mask) << 12); -} - -static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { - unsigned sa = SkGetPackedA4444(s); - unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); - unsigned sg = SkG4444ToG565(SkGetPackedG4444(s)); - unsigned sb = SkB4444ToB565(SkGetPackedB4444(s)); - - // To avoid overflow, we have to clear the low bit of the synthetic sg - // if the src alpha is <= 7. - // to see why, try blending 0x4444 on top of 565-white and watch green - // overflow (sum == 64) - sg &= ~(~(sa >> 3) & 1); - - unsigned scale = SkAlpha15To16(15 - sa); - unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale); - unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale); - unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale); - -#if 0 - if (sg + dg > 63) { - SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg); - } -#endif - return SkPackRGB16(sr + dr, sg + dg, sb + db); -} - -static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) { - SkASSERT((unsigned)scale16 <= 16); - - return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); -} - -static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { - uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | - (SkGetPackedR4444(c) << SK_R32_SHIFT) | - (SkGetPackedG4444(c) << SK_G32_SHIFT) | - (SkGetPackedB4444(c) << SK_B32_SHIFT); - return d | (d << 4); -} - -static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) { - return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) | - (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) | - (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) | - (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT); -} - -// cheap 2x2 dither -static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, - U8CPU g, U8CPU b) { - // to ensure that we stay a legal premultiplied color, we take the max() - // of the truncated and dithered alpha values. If we didn't, cases like - // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...) - // which is not legal premultiplied, since a < color - unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4; - a = SkMax32(a >> 4, dithered_a); - // these we just dither in place - r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4; - g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4; - b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4; - - return SkPackARGB4444(a, r, g, b); -} - -static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) { - return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c), - SkGetPackedG32(c), SkGetPackedB32(c)); -} - -/* Assumes 16bit is in standard RGBA order. - Transforms a normal ARGB_8888 into the same byte order as - expanded ARGB_4444, but keeps each component 8bits -*/ -static inline uint32_t SkExpand_8888(SkPMColor c) { - return (((c >> SK_R32_SHIFT) & 0xFF) << 24) | - (((c >> SK_G32_SHIFT) & 0xFF) << 8) | - (((c >> SK_B32_SHIFT) & 0xFF) << 16) | - (((c >> SK_A32_SHIFT) & 0xFF) << 0); -} - -/* Undo the operation of SkExpand_8888, turning the argument back into - a SkPMColor. -*/ -static inline SkPMColor SkCompact_8888(uint32_t c) { - return (((c >> 24) & 0xFF) << SK_R32_SHIFT) | - (((c >> 8) & 0xFF) << SK_G32_SHIFT) | - (((c >> 16) & 0xFF) << SK_B32_SHIFT) | - (((c >> 0) & 0xFF) << SK_A32_SHIFT); -} - -/* Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format, - but this routine just keeps the high 4bits of each component in the low - 4bits of the result (just like a newly expanded PMColor16). -*/ -static inline uint32_t SkExpand32_4444(SkPMColor c) { - return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) | - (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) | - (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) | - (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0); -} - -// takes two values and alternamtes them as part of a memset16 -// used for cheap 2x2 dithering when the colors are opaque -void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n); - -/////////////////////////////////////////////////////////////////////////////// - -static inline int SkUpscale31To32(int value) { - SkASSERT((unsigned)value <= 31); - return value + (value >> 4); -} - -static inline int SkBlend32(int src, int dst, int scale) { - SkASSERT((unsigned)src <= 0xFF); - SkASSERT((unsigned)dst <= 0xFF); - SkASSERT((unsigned)scale <= 32); - return dst + ((src - dst) * scale >> 5); -} - -static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB, - SkPMColor dst, uint16_t mask) { - if (mask == 0) { - return dst; - } - - /* We want all of these in 5bits, hence the shifts in case one of them - * (green) is 6bits. - */ - int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); - int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); - int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); - - // Now upscale them to 0..32, so we can use blend32 - maskR = SkUpscale31To32(maskR); - maskG = SkUpscale31To32(maskG); - maskB = SkUpscale31To32(maskB); - - // srcA has been upscaled to 256 before passed into this function - maskR = maskR * srcA >> 8; - maskG = maskG * srcA >> 8; - maskB = maskB * srcA >> 8; - - int dstR = SkGetPackedR32(dst); - int dstG = SkGetPackedG32(dst); - int dstB = SkGetPackedB32(dst); - - // LCD blitting is only supported if the dst is known/required - // to be opaque - return SkPackARGB32(0xFF, - SkBlend32(srcR, dstR, maskR), - SkBlend32(srcG, dstG, maskG), - SkBlend32(srcB, dstB, maskB)); -} - -static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB, - SkPMColor dst, uint16_t mask, - SkPMColor opaqueDst) { - if (mask == 0) { - return dst; - } - - if (0xFFFF == mask) { - return opaqueDst; - } - - /* We want all of these in 5bits, hence the shifts in case one of them - * (green) is 6bits. - */ - int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); - int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); - int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); - - // Now upscale them to 0..32, so we can use blend32 - maskR = SkUpscale31To32(maskR); - maskG = SkUpscale31To32(maskG); - maskB = SkUpscale31To32(maskB); - - int dstR = SkGetPackedR32(dst); - int dstG = SkGetPackedG32(dst); - int dstB = SkGetPackedB32(dst); - - // LCD blitting is only supported if the dst is known/required - // to be opaque - return SkPackARGB32(0xFF, - SkBlend32(srcR, dstR, maskR), - SkBlend32(srcG, dstG, maskG), - SkBlend32(srcB, dstB, maskB)); -} - -static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t mask[], - SkColor src, int width, SkPMColor) { - int srcA = SkColorGetA(src); - int srcR = SkColorGetR(src); - int srcG = SkColorGetG(src); - int srcB = SkColorGetB(src); - - srcA = SkAlpha255To256(srcA); - - for (int i = 0; i < width; i++) { - dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]); - } -} - -static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t mask[], - SkColor src, int width, - SkPMColor opaqueDst) { - int srcR = SkColorGetR(src); - int srcG = SkColorGetG(src); - int srcB = SkColorGetB(src); - - for (int i = 0; i < width; i++) { - dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], - opaqueDst); - } -} - #endif diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp index 6df3c93403..60785ba35f 100644 --- a/src/codec/SkBmpCodec.cpp +++ b/src/codec/SkBmpCodec.cpp @@ -10,7 +10,7 @@ #include "SkBmpRLECodec.h" #include "SkBmpStandardCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkStream.h" /* diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp index aec56ee2fa..ddcc47b20c 100644 --- a/src/codec/SkBmpMaskCodec.cpp +++ b/src/codec/SkBmpMaskCodec.cpp @@ -7,7 +7,7 @@ #include "SkBmpMaskCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" /* * Creates an instance of the decoder diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp index 23a2c98eb1..bd4624e6ca 100644 --- a/src/codec/SkBmpRLECodec.cpp +++ b/src/codec/SkBmpRLECodec.cpp @@ -7,7 +7,7 @@ #include "SkBmpRLECodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkStream.h" /* diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index 53aa91c6fa..0ddcbb529a 100644 --- a/src/codec/SkBmpStandardCodec.cpp +++ b/src/codec/SkBmpStandardCodec.cpp @@ -7,7 +7,7 @@ #include "SkBmpStandardCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkStream.h" /* diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h index 93d2925fc4..84215b9fb3 100644 --- a/src/codec/SkCodecPriv.h +++ b/src/codec/SkCodecPriv.h @@ -8,7 +8,7 @@ #ifndef SkCodecPriv_DEFINED #define SkCodecPriv_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXform.h" #include "SkColorSpaceXformPriv.h" #include "SkColorTable.h" diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp index c41d826940..970cc980ba 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -32,7 +32,7 @@ #include "SkCodecAnimation.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorTable.h" #include "SkGifCodec.h" #include "SkMakeUnique.h" diff --git a/src/codec/SkHeifCodec.cpp b/src/codec/SkHeifCodec.cpp index 10675112b7..4a92c24bfe 100644 --- a/src/codec/SkHeifCodec.cpp +++ b/src/codec/SkHeifCodec.cpp @@ -10,7 +10,7 @@ #ifdef SK_HAS_HEIF_LIBRARY #include "SkCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkEndian.h" #include "SkStream.h" diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp index 24549faea4..2936b1a9ea 100644 --- a/src/codec/SkIcoCodec.cpp +++ b/src/codec/SkIcoCodec.cpp @@ -7,7 +7,7 @@ #include "SkBmpCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkData.h" #include "SkIcoCodec.h" #include "SkPngCodec.h" diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 32ec0c1a43..33c316a57c 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -9,7 +9,7 @@ #include "SkJpegCodec.h" #include "SkJpegDecoderMgr.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkStream.h" #include "SkTemplates.h" diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp index 2df10ee24c..81e3d6e8e8 100644 --- a/src/codec/SkMaskSwizzler.cpp +++ b/src/codec/SkMaskSwizzler.cpp @@ -6,7 +6,7 @@ */ #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMaskSwizzler.h" static void swizzle_mask16_to_rgba_opaque( diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 08f23dddea..cb215e1c6c 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -7,7 +7,7 @@ #include "SkBitmap.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace.h" #include "SkColorSpacePriv.h" #include "SkColorTable.h" diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp index f739247721..91abe75a6e 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -7,7 +7,7 @@ #include "SkCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkData.h" #include "SkJpegCodec.h" #include "SkMakeUnique.h" diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index f77d7fa726..8d865daaf9 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -6,7 +6,7 @@ */ #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkHalf.h" #include "SkOpts.h" #include "SkSwizzler.h" diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp index bc796c4fcc..63380e109c 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -7,7 +7,7 @@ #include "SkCodec.h" #include "SkCodecPriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorTable.h" #include "SkData.h" #include "SkStream.h" diff --git a/src/core/Sk4px.h b/src/core/Sk4px.h index 05378a8bc8..bc95596efe 100644 --- a/src/core/Sk4px.h +++ b/src/core/Sk4px.h @@ -10,7 +10,7 @@ #include "SkNx.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" // This file may be included multiple times by .cpp files with different flags, leading // to different definitions. Usually that doesn't matter because it's all inlined, but diff --git a/src/core/SkAAClip.cpp b/src/core/SkAAClip.cpp index 7ef82eda2b..51891c9bbd 100644 --- a/src/core/SkAAClip.cpp +++ b/src/core/SkAAClip.cpp @@ -8,7 +8,7 @@ #include "SkAAClip.h" #include "SkAtomics.h" #include "SkBlitter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkPath.h" #include "SkScan.h" #include "SkUtils.h" diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index 005e2157fe..812dbb6182 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -7,7 +7,7 @@ #include "SkAtomics.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorTable.h" #include "SkConvertPixels.h" #include "SkData.h" diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index d58c017604..e5643974ef 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -8,7 +8,7 @@ #include "SkBitmapCache.h" #include "SkBitmapController.h" #include "SkBitmapProcState.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkPaint.h" #include "SkShader.h" // for tilemodes #include "SkUtilsArm.h" diff --git a/src/core/SkBitmapProcState_filter.h b/src/core/SkBitmapProcState_filter.h index dfc18d8a2b..a30b76d3b0 100644 --- a/src/core/SkBitmapProcState_filter.h +++ b/src/core/SkBitmapProcState_filter.h @@ -6,7 +6,7 @@ */ -#include "SkColorPriv.h" +#include "SkColorData.h" /* Filter_32_opaque diff --git a/src/core/SkBlitMask_D32.cpp b/src/core/SkBlitMask_D32.cpp index c39ecfb759..c30fb1d435 100644 --- a/src/core/SkBlitMask_D32.cpp +++ b/src/core/SkBlitMask_D32.cpp @@ -7,7 +7,7 @@ #include "SkBlitMask.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkOpts.h" SkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) { diff --git a/src/core/SkBlitRow_D32.cpp b/src/core/SkBlitRow_D32.cpp index 9494557d92..d4a005bf51 100644 --- a/src/core/SkBlitRow_D32.cpp +++ b/src/core/SkBlitRow_D32.cpp @@ -7,7 +7,7 @@ #include "SkBlitRow.h" #include "SkBlitMask.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkOpts.h" #include "SkUtils.h" diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 618eed5871..5eb5dd80d0 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -684,7 +684,7 @@ SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, /////////////////////////////////////////////////////////////////////////////// #include "SkColorShader.h" -#include "SkColorPriv.h" +#include "SkColorData.h" class Sk3DShader : public SkShaderBase { public: diff --git a/src/core/SkBlitter_A8.cpp b/src/core/SkBlitter_A8.cpp index a82d3f4f54..4d3f7ce8cf 100644 --- a/src/core/SkBlitter_A8.cpp +++ b/src/core/SkBlitter_A8.cpp @@ -6,7 +6,7 @@ */ #include "SkCoreBlitters.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkShader.h" #include "SkXfermodePriv.h" diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index c0f10535f6..83c448c145 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -6,7 +6,7 @@ */ #include "SkCoreBlitters.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkShader.h" #include "SkUtils.h" #include "SkXfermodePriv.h" diff --git a/src/core/SkBlurImageFilter.cpp b/src/core/SkBlurImageFilter.cpp index 70489737ab..18bbff2a7e 100644 --- a/src/core/SkBlurImageFilter.cpp +++ b/src/core/SkBlurImageFilter.cpp @@ -8,7 +8,7 @@ #include "SkBlurImageFilter.h" #include "SkAutoPixmapStorage.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkGpuBlurUtils.h" #include "SkOpts.h" diff --git a/src/core/SkColor.cpp b/src/core/SkColor.cpp index d41184a428..6c9f0093d0 100644 --- a/src/core/SkColor.cpp +++ b/src/core/SkColor.cpp @@ -6,7 +6,7 @@ */ #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkFixed.h" SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { diff --git a/src/core/SkColorData.h b/src/core/SkColorData.h new file mode 100644 index 0000000000..a6aa8c8df4 --- /dev/null +++ b/src/core/SkColorData.h @@ -0,0 +1,1027 @@ +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkColorData_DEFINED +#define SkColorData_DEFINED + +// turn this own for extra debug checking when blending onto 565 +#ifdef SK_DEBUG + #define CHECK_FOR_565_OVERFLOW +#endif + +#include "SkColor.h" +#include "SkColorPriv.h" +#include "SkMath.h" + +////////////////////////////////////////////////////////////////////////////// + +#define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF)) + +/* + * Skia's 32bit backend only supports 1 sizzle order at a time (compile-time). + * This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B. + * + * For easier compatibility with Skia's GPU backend, we further restrict these + * to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does + * not directly correspond to the same shift-order, since we have to take endianess + * into account. + * + * Here we enforce this constraint. + */ + +#ifdef SK_CPU_BENDIAN + #define SK_RGBA_R32_SHIFT 24 + #define SK_RGBA_G32_SHIFT 16 + #define SK_RGBA_B32_SHIFT 8 + #define SK_RGBA_A32_SHIFT 0 + + #define SK_BGRA_B32_SHIFT 24 + #define SK_BGRA_G32_SHIFT 16 + #define SK_BGRA_R32_SHIFT 8 + #define SK_BGRA_A32_SHIFT 0 +#else + #define SK_RGBA_R32_SHIFT 0 + #define SK_RGBA_G32_SHIFT 8 + #define SK_RGBA_B32_SHIFT 16 + #define SK_RGBA_A32_SHIFT 24 + + #define SK_BGRA_B32_SHIFT 0 + #define SK_BGRA_G32_SHIFT 8 + #define SK_BGRA_R32_SHIFT 16 + #define SK_BGRA_A32_SHIFT 24 +#endif + +#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA) + #error "can't define PMCOLOR to be RGBA and BGRA" +#endif + +#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \ + (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \ + SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \ + SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \ + SK_B32_SHIFT == SK_RGBA_B32_SHIFT) + +#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \ + (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \ + SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \ + SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \ + SK_B32_SHIFT == SK_BGRA_B32_SHIFT) + + +#define SK_A_INDEX (SK_A32_SHIFT/8) +#define SK_R_INDEX (SK_R32_SHIFT/8) +#define SK_G_INDEX (SK_G32_SHIFT/8) +#define SK_B_INDEX (SK_B32_SHIFT/8) + +#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA + #error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values" +#endif + +#if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values" +#endif + +#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA) + // deduce which to define from the _SHIFT defines + + #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA + #define SK_PMCOLOR_IS_RGBA + #elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + #define SK_PMCOLOR_IS_BGRA + #else + #error "need 32bit packing to be either RGBA or BGRA" + #endif +#endif + +// hide these now that we're done +#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA +#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA + +////////////////////////////////////////////////////////////////////////////// + +// Reverse the bytes coorsponding to RED and BLUE in a packed pixels. Note the +// pair of them are in the same 2 slots in both RGBA and BGRA, thus there is +// no need to pass in the colortype to this function. +static inline uint32_t SkSwizzle_RB(uint32_t c) { + static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT); + + unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF; + unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF; + return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT); +} + +static inline uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT_IS_BYTE(a); + SkASSERT_IS_BYTE(r); + SkASSERT_IS_BYTE(g); + SkASSERT_IS_BYTE(b); + return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) | + (g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT); +} + +static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + SkASSERT_IS_BYTE(a); + SkASSERT_IS_BYTE(r); + SkASSERT_IS_BYTE(g); + SkASSERT_IS_BYTE(b); + return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) | + (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT); +} + +static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) { +#ifdef SK_PMCOLOR_IS_RGBA + return c; +#else + return SkSwizzle_RB(c); +#endif +} + +static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) { +#ifdef SK_PMCOLOR_IS_BGRA + return c; +#else + return SkSwizzle_RB(c); +#endif +} + +////////////////////////////////////////////////////////////////////////////// + +///@{ +/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/ +#define SK_ITU_BT709_LUM_COEFF_R (0.2126f) +#define SK_ITU_BT709_LUM_COEFF_G (0.7152f) +#define SK_ITU_BT709_LUM_COEFF_B (0.0722f) +///@} + +///@{ +/** A float value which specifies this channel's contribution to luminance. */ +#define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R +#define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G +#define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B +///@} + +/** Computes the luminance from the given r, g, and b in accordance with + SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space. +*/ +static inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) { + //The following is + //r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B + //with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256). + return (r * 54 + g * 183 + b * 19) >> 8; +} + +/** + * Turn a 0..255 value into a 0..256 value, rounding up if the value is >= 0x80. + * This is slightly more accurate than SkAlpha255To256. + */ +static inline unsigned Sk255To256(U8CPU value) { + SkASSERT(SkToU8(value) == value); + return value + (value >> 7); +} + +/** Multiplify value by 0..256, and shift the result down 8 + (i.e. return (value * alpha256) >> 8) + */ +#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) + +/** Calculates 256 - (value * alpha256) / 255 in range [0,256], + * for [0,255] value and [0,256] alpha256. + */ +static inline U16CPU SkAlphaMulInv256(U16CPU value, U16CPU alpha256) { + unsigned prod = 0xFFFF - value * alpha256; + return (prod + (prod >> 8)) >> 8; +} + +// 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) +static inline int SkAlphaBlend(int src, int dst, int scale256) { + SkASSERT((unsigned)scale256 <= 256); + return dst + SkAlphaMul(src - dst, scale256); +} + +/** + * Returns (src * alpha + dst * (255 - alpha)) / 255 + * + * This is more accurate than SkAlphaBlend, but slightly slower + */ +static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { + SkASSERT((int16_t)src == src); + SkASSERT((int16_t)dst == dst); + SkASSERT((uint8_t)alpha == alpha); + + int prod = (src - dst) * alpha + 128; + prod = (prod + (prod >> 8)) >> 8; + return dst + prod; +} + +static inline U8CPU SkUnitScalarClampToByte(SkScalar x) { + return static_cast<U8CPU>(SkScalarPin(x, 0, 1) * 255 + 0.5); +} + +#define SK_R16_BITS 5 +#define SK_G16_BITS 6 +#define SK_B16_BITS 5 + +#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS) +#define SK_G16_SHIFT (SK_B16_BITS) +#define SK_B16_SHIFT 0 + +#define SK_R16_MASK ((1 << SK_R16_BITS) - 1) +#define SK_G16_MASK ((1 << SK_G16_BITS) - 1) +#define SK_B16_MASK ((1 << SK_B16_BITS) - 1) + +#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK) +#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK) +#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK) + +#define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK) +#define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK) +#define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK) + +static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) { + SkASSERT(r <= SK_R16_MASK); + SkASSERT(g <= SK_G16_MASK); + SkASSERT(b <= SK_B16_MASK); + + return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT)); +} + +#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT) +#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT) +#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT) + +/** Expand the 16bit color into a 32bit value that can be scaled all at once + by a value up to 32. Used in conjunction with SkCompact_rgb_16. +*/ +static inline uint32_t SkExpand_rgb_16(U16CPU c) { + SkASSERT(c == (uint16_t)c); + + return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE); +} + +/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit + color value. The computation yields only 16bits of valid data, but we claim + to return 32bits, so that the compiler won't generate extra instructions to + "clean" the top 16bits. However, the top 16 can contain garbage, so it is + up to the caller to safely ignore them. +*/ +static inline U16CPU SkCompact_rgb_16(uint32_t c) { + return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE); +} + +/** Scale the 16bit color value by the 0..256 scale parameter. + The computation yields only 16bits of valid data, but we claim + to return 32bits, so that the compiler won't generate extra instructions to + "clean" the top 16bits. +*/ +static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) { + return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5); +} + +// this helper explicitly returns a clean 16bit value (but slower) +#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s) + +/** Blend pre-expanded RGB32 with 16bit color value by the 0..32 scale parameter. + The computation yields only 16bits of valid data, but we claim to return + 32bits, so that the compiler won't generate extra instructions to "clean" + the top 16bits. +*/ +static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst, unsigned scale) { + uint32_t dst_expand = SkExpand_rgb_16(dst) * scale; + return SkCompact_rgb_16((src_expand + dst_expand) >> 5); +} + +/** Blend src and dst 16bit colors by the 0..256 scale parameter. + The computation yields only 16bits of valid data, but we claim + to return 32bits, so that the compiler won't generate extra instructions to + "clean" the top 16bits. +*/ +static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) { + SkASSERT((unsigned)srcScale <= 256); + + srcScale >>= 3; + + uint32_t src32 = SkExpand_rgb_16(src); + uint32_t dst32 = SkExpand_rgb_16(dst); + return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); +} + +static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], + int srcScale, int count) { + SkASSERT(count > 0); + SkASSERT((unsigned)srcScale <= 256); + + srcScale >>= 3; + + do { + uint32_t src32 = SkExpand_rgb_16(*src++); + uint32_t dst32 = SkExpand_rgb_16(*dst); + *dst++ = static_cast<uint16_t>( + SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5))); + } while (--count > 0); +} + +#ifdef SK_DEBUG + static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) { + SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); + SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); + SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); + + return a + b; + } +#else + #define SkRGB16Add(a, b) ((a) + (b)) +#endif + +/////////////////////////////////////////////////////////////////////////////// + +#define SK_R32_BITS 8 +#define SK_G32_BITS 8 +#define SK_B32_BITS 8 + +#define SK_R32_MASK ((1 << SK_R32_BITS) - 1) +#define SK_G32_MASK ((1 << SK_G32_BITS) - 1) +#define SK_B32_MASK ((1 << SK_B32_BITS) - 1) + +#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK) +#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK) +#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK) + +#ifdef SK_DEBUG + #define SkPMColorAssert(color_value) \ + do { \ + SkPMColor pm_color_value = (color_value); \ + uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \ + SkA32Assert(alpha_color_value); \ + SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \ + } while (false) +#else + #define SkPMColorAssert(c) +#endif + +static inline bool SkPMColorValid(SkPMColor c) { + auto a = SkGetPackedA32(c); + bool valid = a <= SK_A32_MASK + && SkGetPackedR32(c) <= a + && SkGetPackedG32(c) <= a + && SkGetPackedB32(c) <= a; + if (valid) { + SkPMColorAssert(c); // Make sure we're consistent when it counts. + } + return valid; +} + +static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) { + return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); +} + +static inline uint32_t SkPackPMColor_as_BGRA(SkPMColor c) { + return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); +} + +/** + * 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 + * srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255] + */ +static inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst, + unsigned scale) { + 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); +} + +/** + * 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); + return SkFourByteInterp256(src, dst, scale); +} + +/** + * 0xAARRGGBB -> 0x00AA00GG, 0x00RR00BB + */ +static inline void SkSplay(uint32_t color, uint32_t* ag, uint32_t* rb) { + const uint32_t mask = 0x00FF00FF; + *ag = (color >> 8) & mask; + *rb = color & mask; +} + +/** + * 0xAARRGGBB -> 0x00AA00GG00RR00BB + * (note, ARGB -> AGRB) + */ +static inline uint64_t SkSplay(uint32_t color) { + const uint32_t mask = 0x00FF00FF; + uint64_t agrb = (color >> 8) & mask; // 0x0000000000AA00GG + agrb <<= 32; // 0x00AA00GG00000000 + agrb |= color & mask; // 0x00AA00GG00RR00BB + return agrb; +} + +/** + * 0xAAxxGGxx, 0xRRxxBBxx-> 0xAARRGGBB + */ +static inline uint32_t SkUnsplay(uint32_t ag, uint32_t rb) { + const uint32_t mask = 0xFF00FF00; + return (ag & mask) | ((rb & mask) >> 8); +} + +/** + * 0xAAxxGGxxRRxxBBxx -> 0xAARRGGBB + * (note, AGRB -> ARGB) + */ +static inline uint32_t SkUnsplay(uint64_t agrb) { + const uint32_t mask = 0xFF00FF00; + return SkPMColor( + ((agrb & mask) >> 8) | // 0x00RR00BB + ((agrb >> 32) & mask)); // 0xAARRGGBB +} + +static inline SkPMColor SkFastFourByteInterp256_32(SkPMColor src, SkPMColor dst, unsigned scale) { + SkASSERT(scale <= 256); + + // Two 8-bit blends per two 32-bit registers, with space to make sure the math doesn't collide. + uint32_t src_ag, src_rb, dst_ag, dst_rb; + SkSplay(src, &src_ag, &src_rb); + SkSplay(dst, &dst_ag, &dst_rb); + + const uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; + const uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; + + return SkUnsplay(ret_ag, ret_rb); +} + +static inline SkPMColor SkFastFourByteInterp256_64(SkPMColor src, SkPMColor dst, unsigned scale) { + SkASSERT(scale <= 256); + // Four 8-bit blends in one 64-bit register, with space to make sure the math doesn't collide. + return SkUnsplay(SkSplay(src) * scale + (256-scale) * SkSplay(dst)); +} + +// TODO(mtklein): Replace slow versions with fast versions, using scale + (scale>>7) everywhere. + +/** + * Same as SkFourByteInterp256, but faster. + */ +static inline SkPMColor SkFastFourByteInterp256(SkPMColor src, SkPMColor dst, unsigned scale) { + // On a 64-bit machine, _64 is about 10% faster than _32, but ~40% slower on a 32-bit machine. + if (sizeof(void*) == 4) { + return SkFastFourByteInterp256_32(src, dst, scale); + } else { + return SkFastFourByteInterp256_64(src, dst, scale); + } +} + +/** + * Nearly the same as SkFourByteInterp, but faster and a touch more accurate, due to better + * srcWeight scaling to [0, 256]. + */ +static inline SkPMColor SkFastFourByteInterp(SkPMColor src, + SkPMColor dst, + U8CPU srcWeight) { + SkASSERT(srcWeight <= 255); + // scale = srcWeight + (srcWeight >> 7) is more accurate than + // scale = srcWeight + 1, but 7% slower + return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7)); +} + +static inline +SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + SkA32Assert(a); + SkR32Assert(r); + SkG32Assert(g); + SkB32Assert(b); + + if (a != 255) { + r = SkMulDiv255Round(r, a); + g = SkMulDiv255Round(g, a); + b = SkMulDiv255Round(b, a); + } + return SkPackARGB32(a, r, g, b); +} + +/** + * Interpolates between colors src and dst using [0,256] scale. + */ +static inline SkPMColor SkPMLerp(SkPMColor src, SkPMColor dst, unsigned scale) { + return SkFastFourByteInterp256(src, dst, scale); +} + +static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { + SkASSERT((unsigned)aa <= 255); + + unsigned src_scale = SkAlpha255To256(aa); + 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 (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// Convert a 32bit pixel to a 16bit pixel (no dither) + +#define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS)) +#define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS)) +#define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS)) + +#ifdef SK_DEBUG + static inline unsigned SkR32ToR16(unsigned r) { + SkR32Assert(r); + return SkR32ToR16_MACRO(r); + } + static inline unsigned SkG32ToG16(unsigned g) { + SkG32Assert(g); + return SkG32ToG16_MACRO(g); + } + static inline unsigned SkB32ToB16(unsigned b) { + SkB32Assert(b); + return SkB32ToB16_MACRO(b); + } +#else + #define SkR32ToR16(r) SkR32ToR16_MACRO(r) + #define SkG32ToG16(g) SkG32ToG16_MACRO(g) + #define SkB32ToB16(b) SkB32ToB16_MACRO(b) +#endif + +#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK) +#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK) +#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK) + +static inline U16CPU SkPixel32ToPixel16(SkPMColor c) { + unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT; + unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT; + unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT; + return r | g | b; +} + +static inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { + return (SkR32ToR16(r) << SK_R16_SHIFT) | + (SkG32ToG16(g) << SK_G16_SHIFT) | + (SkB32ToB16(b) << SK_B16_SHIFT); +} + +#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src)) + +///////////////////////////////////////////////////////////////////////////////////////// +// Fast dither from 32->16 + +#define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1) + +static inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { + r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS); + g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS); + b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS); + + return SkPackRGB16(r, g, b); +} + +static inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) { + return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); +} + +/* Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits) + It is now suitable for combining with a scaled expanded_rgb_16 color + as in SkSrcOver32To16(). + We must do this 565 high-bit replication, in order for the subsequent add + to saturate properly (and not overflow). If we take the 8 bits as is, it is + possible to overflow. +*/ +static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) { + unsigned sr = SkPacked32ToR16(c); + unsigned sg = SkPacked32ToG16(c); + unsigned sb = SkPacked32ToB16(c); + + sr = (sr << 5) | sr; + sg = (sg << 5) | (sg >> 1); + sb = (sb << 5) | sb; + return (sr << 11) | (sg << 21) | (sb << 0); +} + +/* SrcOver the 32bit src color with the 16bit dst, returning a 16bit value + (with dirt in the high 16bits, so caller beware). +*/ +static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) { + unsigned sr = SkGetPackedR32(src); + unsigned sg = SkGetPackedG32(src); + unsigned sb = SkGetPackedB32(src); + + unsigned dr = SkGetPackedR16(dst); + unsigned dg = SkGetPackedG16(dst); + unsigned db = SkGetPackedB16(dst); + + unsigned isa = 255 - SkGetPackedA32(src); + + dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS); + dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS); + db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS); + + return SkPackRGB16(dr, dg, db); +} + +//////////////////////////////////////////////////////////////////////////////////////////// +// Convert a 16bit pixel to a 32bit pixel + +static inline unsigned SkR16ToR32(unsigned r) { + return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8)); +} + +static inline unsigned SkG16ToG32(unsigned g) { + return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8)); +} + +static inline unsigned SkB16ToB32(unsigned b) { + return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8)); +} + +#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c)) +#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c)) +#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c)) + +static inline SkPMColor SkPixel16ToPixel32(U16CPU src) { + SkASSERT(src == SkToU16(src)); + + unsigned r = SkPacked16ToR32(src); + unsigned g = SkPacked16ToG32(src); + unsigned b = SkPacked16ToB32(src); + + SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); + SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); + SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); + + return SkPackARGB32(0xFF, r, g, b); +} + +// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor +static inline SkColor SkPixel16ToColor(U16CPU src) { + SkASSERT(src == SkToU16(src)); + + unsigned r = SkPacked16ToR32(src); + unsigned g = SkPacked16ToG32(src); + unsigned b = SkPacked16ToB32(src); + + SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); + SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); + SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); + + return SkColorSetRGB(r, g, b); +} + +/////////////////////////////////////////////////////////////////////////////// + +typedef uint16_t SkPMColor16; + +// Put in OpenGL order (r g b a) +#define SK_A4444_SHIFT 0 +#define SK_R4444_SHIFT 12 +#define SK_G4444_SHIFT 8 +#define SK_B4444_SHIFT 4 + +#define SkA32To4444(a) ((unsigned)(a) >> 4) +#define SkR32To4444(r) ((unsigned)(r) >> 4) +#define SkG32To4444(g) ((unsigned)(g) >> 4) +#define SkB32To4444(b) ((unsigned)(b) >> 4) + +static inline U8CPU SkReplicateNibble(unsigned nib) { + SkASSERT(nib <= 0xF); + return (nib << 4) | nib; +} + +#define SkA4444ToA32(a) SkReplicateNibble(a) +#define SkR4444ToR32(r) SkReplicateNibble(r) +#define SkG4444ToG32(g) SkReplicateNibble(g) +#define SkB4444ToB32(b) SkReplicateNibble(b) + +#define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF) +#define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF) +#define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF) +#define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF) + +#define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c)) +#define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c)) +#define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c)) +#define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c)) + +#ifdef SK_DEBUG +static inline void SkPMColor16Assert(U16CPU c) { + unsigned a = SkGetPackedA4444(c); + unsigned r = SkGetPackedR4444(c); + unsigned g = SkGetPackedG4444(c); + unsigned b = SkGetPackedB4444(c); + + SkASSERT(a <= 0xF); + SkASSERT(r <= a); + SkASSERT(g <= a); + SkASSERT(b <= a); +} +#else +#define SkPMColor16Assert(c) +#endif + +static inline unsigned SkAlpha15To16(unsigned a) { + SkASSERT(a <= 0xF); + return a + (a >> 3); +} + +#ifdef SK_DEBUG + static inline int SkAlphaMul4(int value, int scale) { + SkASSERT((unsigned)scale <= 0x10); + return value * scale >> 4; + } +#else + #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4) +#endif + +static inline unsigned SkR4444ToR565(unsigned r) { + SkASSERT(r <= 0xF); + return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS)); +} + +static inline unsigned SkG4444ToG565(unsigned g) { + SkASSERT(g <= 0xF); + return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS)); +} + +static inline unsigned SkB4444ToB565(unsigned b) { + SkASSERT(b <= 0xF); + return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS)); +} + +static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, + unsigned g, unsigned b) { + SkASSERT(a <= 0xF); + SkASSERT(r <= a); + SkASSERT(g <= a); + SkASSERT(b <= a); + + return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | + (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); +} + +static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) { + SkASSERT(scale <= 16); + + const unsigned mask = 0xF0F; //gMask_0F0F; + +#if 0 + unsigned rb = ((c & mask) * scale) >> 4; + unsigned ag = ((c >> 4) & mask) * scale; + return (rb & mask) | (ag & ~mask); +#else + unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12); + unsigned scaled_c = (expanded_c * scale) >> 4; + return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4)); +#endif +} + +/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at + once by a value up to 16. +*/ +static inline uint32_t SkExpand_4444(U16CPU c) { + SkASSERT(c == (uint16_t)c); + + const unsigned mask = 0xF0F; //gMask_0F0F; + return (c & mask) | ((c & ~mask) << 12); +} + +static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { + unsigned sa = SkGetPackedA4444(s); + unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); + unsigned sg = SkG4444ToG565(SkGetPackedG4444(s)); + unsigned sb = SkB4444ToB565(SkGetPackedB4444(s)); + + // To avoid overflow, we have to clear the low bit of the synthetic sg + // if the src alpha is <= 7. + // to see why, try blending 0x4444 on top of 565-white and watch green + // overflow (sum == 64) + sg &= ~(~(sa >> 3) & 1); + + unsigned scale = SkAlpha15To16(15 - sa); + unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale); + unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale); + unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale); + +#if 0 + if (sg + dg > 63) { + SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg); + } +#endif + return SkPackRGB16(sr + dr, sg + dg, sb + db); +} + +static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) { + SkASSERT((unsigned)scale16 <= 16); + + return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); +} + +static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { + uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | + (SkGetPackedR4444(c) << SK_R32_SHIFT) | + (SkGetPackedG4444(c) << SK_G32_SHIFT) | + (SkGetPackedB4444(c) << SK_B32_SHIFT); + return d | (d << 4); +} + +static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) { + return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) | + (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) | + (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) | + (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT); +} + +// cheap 2x2 dither +static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, + U8CPU g, U8CPU b) { + // to ensure that we stay a legal premultiplied color, we take the max() + // of the truncated and dithered alpha values. If we didn't, cases like + // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...) + // which is not legal premultiplied, since a < color + unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4; + a = SkMax32(a >> 4, dithered_a); + // these we just dither in place + r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4; + g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4; + b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4; + + return SkPackARGB4444(a, r, g, b); +} + +static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) { + return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c), + SkGetPackedG32(c), SkGetPackedB32(c)); +} + +/* Assumes 16bit is in standard RGBA order. + Transforms a normal ARGB_8888 into the same byte order as + expanded ARGB_4444, but keeps each component 8bits +*/ +static inline uint32_t SkExpand_8888(SkPMColor c) { + return (((c >> SK_R32_SHIFT) & 0xFF) << 24) | + (((c >> SK_G32_SHIFT) & 0xFF) << 8) | + (((c >> SK_B32_SHIFT) & 0xFF) << 16) | + (((c >> SK_A32_SHIFT) & 0xFF) << 0); +} + +/* Undo the operation of SkExpand_8888, turning the argument back into + a SkPMColor. +*/ +static inline SkPMColor SkCompact_8888(uint32_t c) { + return (((c >> 24) & 0xFF) << SK_R32_SHIFT) | + (((c >> 8) & 0xFF) << SK_G32_SHIFT) | + (((c >> 16) & 0xFF) << SK_B32_SHIFT) | + (((c >> 0) & 0xFF) << SK_A32_SHIFT); +} + +/* Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format, + but this routine just keeps the high 4bits of each component in the low + 4bits of the result (just like a newly expanded PMColor16). +*/ +static inline uint32_t SkExpand32_4444(SkPMColor c) { + return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) | + (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) | + (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) | + (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0); +} + +// takes two values and alternamtes them as part of a memset16 +// used for cheap 2x2 dithering when the colors are opaque +void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n); + +/////////////////////////////////////////////////////////////////////////////// + +static inline int SkUpscale31To32(int value) { + SkASSERT((unsigned)value <= 31); + return value + (value >> 4); +} + +static inline int SkBlend32(int src, int dst, int scale) { + SkASSERT((unsigned)src <= 0xFF); + SkASSERT((unsigned)dst <= 0xFF); + SkASSERT((unsigned)scale <= 32); + return dst + ((src - dst) * scale >> 5); +} + +static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB, + SkPMColor dst, uint16_t mask) { + if (mask == 0) { + return dst; + } + + /* We want all of these in 5bits, hence the shifts in case one of them + * (green) is 6bits. + */ + int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); + int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); + int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); + + // Now upscale them to 0..32, so we can use blend32 + maskR = SkUpscale31To32(maskR); + maskG = SkUpscale31To32(maskG); + maskB = SkUpscale31To32(maskB); + + // srcA has been upscaled to 256 before passed into this function + maskR = maskR * srcA >> 8; + maskG = maskG * srcA >> 8; + maskB = maskB * srcA >> 8; + + int dstR = SkGetPackedR32(dst); + int dstG = SkGetPackedG32(dst); + int dstB = SkGetPackedB32(dst); + + // LCD blitting is only supported if the dst is known/required + // to be opaque + return SkPackARGB32(0xFF, + SkBlend32(srcR, dstR, maskR), + SkBlend32(srcG, dstG, maskG), + SkBlend32(srcB, dstB, maskB)); +} + +static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB, + SkPMColor dst, uint16_t mask, + SkPMColor opaqueDst) { + if (mask == 0) { + return dst; + } + + if (0xFFFF == mask) { + return opaqueDst; + } + + /* We want all of these in 5bits, hence the shifts in case one of them + * (green) is 6bits. + */ + int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); + int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); + int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); + + // Now upscale them to 0..32, so we can use blend32 + maskR = SkUpscale31To32(maskR); + maskG = SkUpscale31To32(maskG); + maskB = SkUpscale31To32(maskB); + + int dstR = SkGetPackedR32(dst); + int dstG = SkGetPackedG32(dst); + int dstB = SkGetPackedB32(dst); + + // LCD blitting is only supported if the dst is known/required + // to be opaque + return SkPackARGB32(0xFF, + SkBlend32(srcR, dstR, maskR), + SkBlend32(srcG, dstG, maskG), + SkBlend32(srcB, dstB, maskB)); +} + +static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t mask[], + SkColor src, int width, SkPMColor) { + int srcA = SkColorGetA(src); + int srcR = SkColorGetR(src); + int srcG = SkColorGetG(src); + int srcB = SkColorGetB(src); + + srcA = SkAlpha255To256(srcA); + + for (int i = 0; i < width; i++) { + dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]); + } +} + +static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t mask[], + SkColor src, int width, + SkPMColor opaqueDst) { + int srcR = SkColorGetR(src); + int srcG = SkColorGetG(src); + int srcB = SkColorGetB(src); + + for (int i = 0; i < width; i++) { + dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i], + opaqueDst); + } +} + +#endif diff --git a/src/core/SkColorMatrixFilterRowMajor255.cpp b/src/core/SkColorMatrixFilterRowMajor255.cpp index e2d6c37118..17a549f59e 100644 --- a/src/core/SkColorMatrixFilterRowMajor255.cpp +++ b/src/core/SkColorMatrixFilterRowMajor255.cpp @@ -6,7 +6,7 @@ */ #include "SkColorMatrixFilterRowMajor255.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkNx.h" #include "SkPM4fPriv.h" #include "SkRasterPipeline.h" diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp index b5290aab8e..b936aec489 100644 --- a/src/core/SkColorSpaceXform.cpp +++ b/src/core/SkColorSpaceXform.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_A2B.h" #include "SkColorSpace_Base.h" #include "SkColorSpace_XYZ.h" diff --git a/src/core/SkColorSpaceXform_A2B.cpp b/src/core/SkColorSpaceXform_A2B.cpp index e2434d640a..cc80145af1 100644 --- a/src/core/SkColorSpaceXform_A2B.cpp +++ b/src/core/SkColorSpaceXform_A2B.cpp @@ -7,7 +7,7 @@ #include "SkColorSpaceXform_A2B.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_A2B.h" #include "SkColorSpace_XYZ.h" #include "SkColorSpacePriv.h" diff --git a/src/core/SkDither.h b/src/core/SkDither.h index 463b50403d..b73f72e3df 100644 --- a/src/core/SkDither.h +++ b/src/core/SkDither.h @@ -9,13 +9,13 @@ #ifndef SkDither_DEFINED #define SkDither_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #define SK_DitherValueMax4444 15 #define SK_DitherValueMax565 7 /* need to use macros for bit-counts for each component, and then - move these into SkColorPriv.h + move these into SkColorData.h */ #define SkDITHER_R32_FOR_565_MACRO(r, d) (r + d - (r >> 5)) diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index be9d2a18f9..bf91aa15b5 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -12,7 +12,7 @@ #include "SkBlendModePriv.h" #include "SkBlitter.h" #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDevice.h" #include "SkDeviceLooper.h" #include "SkDraw.h" diff --git a/src/core/SkMaskGamma.h b/src/core/SkMaskGamma.h index 3142534152..89e062e7cc 100644 --- a/src/core/SkMaskGamma.h +++ b/src/core/SkMaskGamma.h @@ -10,7 +10,7 @@ #include "SkTypes.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkRefCnt.h" /** diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp index 0d4aba72fb..cd81946a52 100644 --- a/src/core/SkMipMap.cpp +++ b/src/core/SkMipMap.cpp @@ -7,7 +7,7 @@ #include "SkMipMap.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkHalf.h" #include "SkMathPriv.h" #include "SkNx.h" diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp index 1e2e8de73b..98c6532e8c 100644 --- a/src/core/SkModeColorFilter.cpp +++ b/src/core/SkModeColorFilter.cpp @@ -9,7 +9,7 @@ #include "SkBlendModePriv.h" #include "SkBlitRow.h" #include "SkColorFilter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkModeColorFilter.h" #include "SkPM4f.h" diff --git a/src/core/SkPM4f.h b/src/core/SkPM4f.h index 82a6f1275f..dd54403a7b 100644 --- a/src/core/SkPM4f.h +++ b/src/core/SkPM4f.h @@ -8,7 +8,7 @@ #ifndef SkPM4f_DEFINED #define SkPM4f_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkNx.h" static inline Sk4f swizzle_rb(const Sk4f& x) { diff --git a/src/core/SkPM4fPriv.h b/src/core/SkPM4fPriv.h index be65159fb8..b9250438ba 100644 --- a/src/core/SkPM4fPriv.h +++ b/src/core/SkPM4fPriv.h @@ -8,7 +8,7 @@ #ifndef SkPM4fPriv_DEFINED #define SkPM4fPriv_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace.h" #include "SkColorSpace_Base.h" #include "SkArenaAlloc.h" diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp index 5a6b27d8d7..1cee0a9d02 100644 --- a/src/core/SkPixmap.cpp +++ b/src/core/SkPixmap.cpp @@ -7,7 +7,7 @@ #include "SkBitmap.h" #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkConvertPixels.h" #include "SkData.h" #include "SkImageInfoPriv.h" diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index b2860e8f5c..98036cf8a0 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -9,7 +9,7 @@ #include "SkAutoMalloc.h" #include "SkAutoPixmapStorage.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDescriptor.h" #include "SkDraw.h" #include "SkGlyph.h" diff --git a/src/core/SkScan_Antihair.cpp b/src/core/SkScan_Antihair.cpp index 474255bd8d..a552253ffa 100644 --- a/src/core/SkScan_Antihair.cpp +++ b/src/core/SkScan_Antihair.cpp @@ -8,7 +8,7 @@ #include "SkScan.h" #include "SkBlitter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkLineClipper.h" #include "SkRasterClip.h" #include "SkFDot6.h" diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp index b39f79b969..bf0f21a0e2 100644 --- a/src/core/SkSpriteBlitter_ARGB32.cpp +++ b/src/core/SkSpriteBlitter_ARGB32.cpp @@ -9,7 +9,7 @@ #include "SkArenaAlloc.h" #include "SkBlitRow.h" #include "SkColorFilter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkTemplates.h" #include "SkUtils.h" #include "SkXfermodePriv.h" diff --git a/src/core/SkUnPreMultiply.cpp b/src/core/SkUnPreMultiply.cpp index a15e7d13a3..528a610892 100644 --- a/src/core/SkUnPreMultiply.cpp +++ b/src/core/SkUnPreMultiply.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ #include "SkUnPreMultiply.h" -#include "SkColorPriv.h" +#include "SkColorData.h" SkColor SkUnPreMultiply::PMColorToColor(SkPMColor c) { const unsigned a = SkGetPackedA32(c); diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 8a66363f74..7ac87ed116 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -6,7 +6,7 @@ */ #include "SkBlendModePriv.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMathPriv.h" #include "SkOnce.h" #include "SkOpts.h" diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp index 165bae2c49..cd2d83996a 100644 --- a/src/effects/SkBlurMask.cpp +++ b/src/effects/SkBlurMask.cpp @@ -409,7 +409,7 @@ static int boxBlurInterp(const uint8_t* src, int src_y_stride, uint8_t* dst, -#include "SkColorPriv.h" +#include "SkColorData.h" static void merge_src_with_blur(uint8_t dst[], int dstRB, const uint8_t src[], int srcRB, diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp index ff17af1a48..2c26cce69f 100644 --- a/src/effects/SkDisplacementMapEffect.cpp +++ b/src/effects/SkDisplacementMapEffect.cpp @@ -13,7 +13,7 @@ #include "SkSpecialImage.h" #include "SkWriteBuffer.h" #include "SkUnPreMultiply.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #if SK_SUPPORT_GPU #include "GrClip.h" #include "GrContext.h" diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 1b8849a982..d9fae43fa8 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -7,7 +7,7 @@ #include "SkLightingImageFilter.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkPoint3.h" #include "SkReadBuffer.h" diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp index 4422733b61..5c5edcdd48 100644 --- a/src/effects/SkLumaColorFilter.cpp +++ b/src/effects/SkLumaColorFilter.cpp @@ -7,7 +7,7 @@ #include "SkLumaColorFilter.h" #include "SkPM4f.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkRasterPipeline.h" #include "SkString.h" diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index 215444b501..4af375b553 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -8,7 +8,7 @@ #include "SkMagnifierImageFilter.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkReadBuffer.h" #include "SkSpecialImage.h" diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp index ce84f3ea10..a31ee3db33 100644 --- a/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -7,7 +7,7 @@ #include "SkMatrixConvolutionImageFilter.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkReadBuffer.h" #include "SkSpecialImage.h" diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 5f59637e51..629222ddc8 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -8,7 +8,7 @@ #include "SkMorphologyImageFilter.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkOpts.h" #include "SkReadBuffer.h" diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index 2101bd65c9..0cda71394e 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -9,7 +9,7 @@ #include "SkPM4f.h" #include "SkArenaAlloc.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkString.h" diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index ddc5d99b5e..4ad789269c 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -8,7 +8,7 @@ #include "SkXfermodeImageFilter.h" #include "SkArithmeticImageFilter.h" #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpaceXformer.h" #include "SkReadBuffer.h" #include "SkSpecialImage.h" diff --git a/src/gpu/GrTessellator.h b/src/gpu/GrTessellator.h index dd92015cc2..a09b7c2e43 100644 --- a/src/gpu/GrTessellator.h +++ b/src/gpu/GrTessellator.h @@ -9,6 +9,7 @@ #define GrTessellator_DEFINED #include "GrColor.h" +#include "SkColorData.h" #include "SkPoint.h" class SkPath; diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h index 66b625ad09..7ecec96477 100644 --- a/src/gpu/SkGr.h +++ b/src/gpu/SkGr.h @@ -15,7 +15,7 @@ #include "SkBlendModePriv.h" #include "SkCanvas.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkFilterQuality.h" #include "SkImageInfo.h" #include "SkMatrix.h" diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h index a17b30b104..d5de065732 100644 --- a/src/images/SkImageEncoderFns.h +++ b/src/images/SkImageEncoderFns.h @@ -14,7 +14,7 @@ #include "SkBitmap.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkICC.h" #include "SkOpts.h" diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp index fe228fea75..9fade2449a 100644 --- a/src/images/SkJpegEncoder.cpp +++ b/src/images/SkJpegEncoder.cpp @@ -9,7 +9,7 @@ #ifdef SK_HAS_JPEG_LIBRARY -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkImageEncoderFns.h" #include "SkImageInfoPriv.h" diff --git a/src/images/SkWebpEncoder.cpp b/src/images/SkWebpEncoder.cpp index c43ab8628f..3c08fdcfa4 100644 --- a/src/images/SkWebpEncoder.cpp +++ b/src/images/SkWebpEncoder.cpp @@ -19,7 +19,7 @@ #ifdef SK_HAS_WEBP_LIBRARY #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkImageEncoderFns.h" #include "SkStream.h" diff --git a/src/jumper/SkJumper.cpp b/src/jumper/SkJumper.cpp index 6890ec387a..22d6e086d4 100644 --- a/src/jumper/SkJumper.cpp +++ b/src/jumper/SkJumper.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkCpu.h" #include "SkJumper.h" #include "SkOnce.h" diff --git a/src/opts/SkBitmapProcState_arm_neon.cpp b/src/opts/SkBitmapProcState_arm_neon.cpp index 51dbb5cf50..b954d8512a 100644 --- a/src/opts/SkBitmapProcState_arm_neon.cpp +++ b/src/opts/SkBitmapProcState_arm_neon.cpp @@ -7,7 +7,7 @@ #include "SkBitmapProcState.h" #include "SkBitmapProcState_filter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkPaint.h" #include "SkShader.h" // for tilemodes #include "SkUtilsArm.h" diff --git a/src/opts/SkBitmapProcState_filter_neon.h b/src/opts/SkBitmapProcState_filter_neon.h index 5cf0ac4622..5352ce41e5 100644 --- a/src/opts/SkBitmapProcState_filter_neon.h +++ b/src/opts/SkBitmapProcState_filter_neon.h @@ -6,7 +6,7 @@ */ #include <arm_neon.h> -#include "SkColorPriv.h" +#include "SkColorData.h" /* * Filter_32_opaque diff --git a/src/opts/SkBitmapProcState_opts_SSE2.cpp b/src/opts/SkBitmapProcState_opts_SSE2.cpp index 6a739dc1be..d0b93503a9 100644 --- a/src/opts/SkBitmapProcState_opts_SSE2.cpp +++ b/src/opts/SkBitmapProcState_opts_SSE2.cpp @@ -8,7 +8,7 @@ #include <emmintrin.h> #include "SkBitmapProcState_opts_SSE2.h" #include "SkBitmapProcState_utils.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkPaint.h" #include "SkUtils.h" diff --git a/src/opts/SkBitmapProcState_opts_SSSE3.cpp b/src/opts/SkBitmapProcState_opts_SSSE3.cpp index 7890e8a4c6..baabe69510 100644 --- a/src/opts/SkBitmapProcState_opts_SSSE3.cpp +++ b/src/opts/SkBitmapProcState_opts_SSSE3.cpp @@ -6,7 +6,7 @@ */ #include "SkBitmapProcState_opts_SSSE3.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkPaint.h" #include "SkUtils.h" diff --git a/src/opts/SkBlitMask_opts_arm.cpp b/src/opts/SkBlitMask_opts_arm.cpp index c5a9ea4f3e..f283ac8396 100644 --- a/src/opts/SkBlitMask_opts_arm.cpp +++ b/src/opts/SkBlitMask_opts_arm.cpp @@ -6,7 +6,7 @@ */ #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkBlitMask.h" #include "SkUtilsArm.h" #include "SkBlitMask_opts_arm_neon.h" diff --git a/src/opts/SkBlitRow_opts.h b/src/opts/SkBlitRow_opts.h index 3cf858527b..b35849263b 100644 --- a/src/opts/SkBlitRow_opts.h +++ b/src/opts/SkBlitRow_opts.h @@ -9,7 +9,7 @@ #define SkBlitRow_opts_DEFINED #include "Sk4px.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMSAN.h" #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 diff --git a/src/opts/SkBlitRow_opts_SSE2.cpp b/src/opts/SkBlitRow_opts_SSE2.cpp index 7f03907d1c..d0ba5f5a54 100644 --- a/src/opts/SkBlitRow_opts_SSE2.cpp +++ b/src/opts/SkBlitRow_opts_SSE2.cpp @@ -8,7 +8,7 @@ #include <emmintrin.h> #include "SkBitmapProcState_opts_SSE2.h" #include "SkBlitRow_opts_SSE2.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColor_opts_SSE2.h" #include "SkDither.h" #include "SkMSAN.h" diff --git a/src/opts/SkBlitRow_opts_arm_neon.cpp b/src/opts/SkBlitRow_opts_arm_neon.cpp index 7a9534ca84..530eac5693 100644 --- a/src/opts/SkBlitRow_opts_arm_neon.cpp +++ b/src/opts/SkBlitRow_opts_arm_neon.cpp @@ -9,7 +9,7 @@ #include "SkBlitMask.h" #include "SkBlitRow.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDither.h" #include "SkMathPriv.h" #include "SkUtils.h" diff --git a/src/opts/SkBlurImageFilter_opts.h b/src/opts/SkBlurImageFilter_opts.h index b6b429816c..08c2121778 100644 --- a/src/opts/SkBlurImageFilter_opts.h +++ b/src/opts/SkBlurImageFilter_opts.h @@ -8,7 +8,7 @@ #ifndef SkBlurImageFilter_opts_DEFINED #define SkBlurImageFilter_opts_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkRect.h" #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 diff --git a/src/opts/SkColor_opts_SSE2.h b/src/opts/SkColor_opts_SSE2.h index 5453f20d4b..d998ed50b8 100644 --- a/src/opts/SkColor_opts_SSE2.h +++ b/src/opts/SkColor_opts_SSE2.h @@ -42,7 +42,7 @@ static inline __m128i SkAlphaMulAlpha_SSE2(const __m128i& a, return prod; } -// Portable version SkAlphaMulQ is in SkColorPriv.h. +// Portable version SkAlphaMulQ is in SkColorData.h. static inline __m128i SkAlphaMulQ_SSE2(const __m128i& c, const __m128i& scale) { const __m128i mask = _mm_set1_epi32(0xFF00FF); __m128i s = _mm_or_si128(_mm_slli_epi32(scale, 16), scale); @@ -80,7 +80,7 @@ static inline __m128i SkAlphaMulQ_SSE2(const __m128i& c, const unsigned scale) { return _mm_or_si128(rb, ag); } -// Portable version SkFastFourByteInterp256 is in SkColorPriv.h. +// Portable version SkFastFourByteInterp256 is in SkColorData.h. static inline __m128i SkFastFourByteInterp256_SSE2(const __m128i& src, const __m128i& dst, const unsigned src_scale) { // Computes dst + (((src - dst)*src_scale)>>8) const __m128i mask = _mm_set1_epi32(0x00FF00FF); @@ -107,7 +107,7 @@ static inline __m128i SkFastFourByteInterp256_SSE2(const __m128i& src, const __m return _mm_add_epi8(dst, diff); } -// Portable version SkPMLerp is in SkColorPriv.h +// Portable version SkPMLerp is in SkColorData.h static inline __m128i SkPMLerp_SSE2(const __m128i& src, const __m128i& dst, const unsigned scale) { return SkFastFourByteInterp256_SSE2(src, dst, scale); } @@ -238,7 +238,7 @@ static inline __m128i SkPixel32ToPixel16_ToU16_SSE2(const __m128i& src_pixel1, return d_pixel; } -// Portable version is SkPMSrcOver in SkColorPriv.h. +// Portable version is SkPMSrcOver in SkColorData.h. static inline __m128i SkPMSrcOver_SSE2(const __m128i& src, const __m128i& dst) { return _mm_add_epi32(src, SkAlphaMulQ_SSE2(dst, _mm_sub_epi32(_mm_set1_epi32(256), diff --git a/src/opts/SkColor_opts_neon.h b/src/opts/SkColor_opts_neon.h index c316ab4031..ca00301148 100644 --- a/src/opts/SkColor_opts_neon.h +++ b/src/opts/SkColor_opts_neon.h @@ -9,7 +9,7 @@ #define SkColor_opts_neon_DEFINED #include "SkTypes.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include <arm_neon.h> diff --git a/src/opts/SkSwizzler_opts.h b/src/opts/SkSwizzler_opts.h index 4d9da5cc8d..699b11cb16 100644 --- a/src/opts/SkSwizzler_opts.h +++ b/src/opts/SkSwizzler_opts.h @@ -8,7 +8,7 @@ #ifndef SkSwizzler_opts_DEFINED #define SkSwizzler_opts_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3 #include <immintrin.h> diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp index ca4257adb2..8c312963da 100644 --- a/src/pdf/SkPDFBitmap.cpp +++ b/src/pdf/SkPDFBitmap.cpp @@ -7,7 +7,7 @@ #include "SkPDFBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkData.h" #include "SkDeflate.h" #include "SkImage.h" @@ -46,7 +46,7 @@ static void fill_stream(SkWStream* out, char value, size_t n) { out->write(buffer, n % sizeof(buffer)); } -// TODO(reed@): Decide if these five functions belong in SkColorPriv.h +// TODO(reed@): Decide if these five functions belong in SkColorData.h static bool SkIsBGRA(SkColorType ct) { SkASSERT(kBGRA_8888_SkColorType == ct || kRGBA_8888_SkColorType == ct); return kBGRA_8888_SkColorType == ct; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index f892438ca3..0f2ef15f63 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -8,7 +8,7 @@ #include "SkAdvancedTypefaceMetrics.h" #include "SkBitmap.h" #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDescriptor.h" #include "SkFDot6.h" #include "SkFontDescriptor.h" diff --git a/src/ports/SkFontHost_FreeType_common.cpp b/src/ports/SkFontHost_FreeType_common.cpp index 864f75dee8..e027c8802f 100644 --- a/src/ports/SkFontHost_FreeType_common.cpp +++ b/src/ports/SkFontHost_FreeType_common.cpp @@ -9,7 +9,7 @@ #include "SkBitmap.h" #include "SkCanvas.h" #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkFDot6.h" #include "SkFontHost_FreeType_common.h" #include "SkPath.h" diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index 9456f0366a..2564ab5b04 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -22,7 +22,7 @@ #include "SkAdvancedTypefaceMetrics.h" #include "SkAutoMalloc.h" #include "SkCGUtils.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDescriptor.h" #include "SkEndian.h" #include "SkFloatingPoint.h" @@ -1050,7 +1050,7 @@ void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) { glyph->fHeight = SkToU16(skIBounds.height()); } -#include "SkColorPriv.h" +#include "SkColorData.h" static void build_power_table(uint8_t table[]) { for (int i = 0; i < 256; i++) { diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 4a0aabede9..42785e9f1b 100644 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -10,7 +10,7 @@ #include "SkAdvancedTypefaceMetrics.h" #include "SkBase64.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkData.h" #include "SkDescriptor.h" #include "SkFontDescriptor.h" @@ -1100,7 +1100,7 @@ static const uint8_t* getInverseGammaTableClearType() { return gTableClearType; } -#include "SkColorPriv.h" +#include "SkColorData.h" //Cannot assume that the input rgb is gray due to possible setting of kGenA8FromLCD_Flag. template<bool APPLY_PREBLEND> diff --git a/src/ports/SkImageEncoder_CG.cpp b/src/ports/SkImageEncoder_CG.cpp index 8c2a542fc3..91827bd9bb 100644 --- a/src/ports/SkImageEncoder_CG.cpp +++ b/src/ports/SkImageEncoder_CG.cpp @@ -11,7 +11,7 @@ #include "SkBitmap.h" #include "SkCGUtils.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkData.h" #include "SkStream.h" #include "SkStreamPriv.h" diff --git a/src/ports/SkScalerContext_win_dw.cpp b/src/ports/SkScalerContext_win_dw.cpp index a84e653f28..b7fbe8f171 100644 --- a/src/ports/SkScalerContext_win_dw.cpp +++ b/src/ports/SkScalerContext_win_dw.cpp @@ -652,7 +652,7 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* metrics) { /////////////////////////////////////////////////////////////////////////////// -#include "SkColorPriv.h" +#include "SkColorData.h" static void bilevel_to_bw(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph) { const int width = glyph.fWidth; diff --git a/src/shaders/SkComposeShader.cpp b/src/shaders/SkComposeShader.cpp index 0bc8c8c7cf..a587f52eba 100644 --- a/src/shaders/SkComposeShader.cpp +++ b/src/shaders/SkComposeShader.cpp @@ -9,7 +9,7 @@ #include "SkBlendModePriv.h" #include "SkComposeShader.h" #include "SkColorFilter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorShader.h" #include "SkRasterPipeline.h" #include "SkReadBuffer.h" diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h index 59c9541b28..c5a9b179ac 100644 --- a/src/shaders/gradients/SkGradientShaderPriv.h +++ b/src/shaders/gradients/SkGradientShaderPriv.h @@ -14,7 +14,7 @@ #include "SkArenaAlloc.h" #include "SkAutoMalloc.h" #include "SkClampRange.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace.h" #include "SkOnce.h" #include "SkPM4fPriv.h" diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp index 5820d8571d..512e8cc334 100644 --- a/src/utils/SkPatchUtils.cpp +++ b/src/utils/SkPatchUtils.cpp @@ -7,7 +7,7 @@ #include "SkPatchUtils.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkGeometry.h" #include "SkPM4f.h" diff --git a/src/utils/SkPatchUtils.h b/src/utils/SkPatchUtils.h index 75c10e85ea..ee7a1f6dbc 100644 --- a/src/utils/SkPatchUtils.h +++ b/src/utils/SkPatchUtils.h @@ -8,7 +8,7 @@ #ifndef SkPatchUtils_DEFINED #define SkPatchUtils_DEFINED -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMatrix.h" #include "SkVertices.h" diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp index 7c49ba6688..aff59bf36d 100755 --- a/src/utils/SkShadowTessellator.cpp +++ b/src/utils/SkShadowTessellator.cpp @@ -6,7 +6,7 @@ */ #include "SkShadowTessellator.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDrawShadowInfo.h" #include "SkGeometry.h" #include "SkInsetConvexPolygon.h" diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp index 0e34c9105f..288ae9608b 100644 --- a/src/utils/SkShadowUtils.cpp +++ b/src/utils/SkShadowUtils.cpp @@ -8,7 +8,7 @@ #include "SkShadowUtils.h" #include "SkCanvas.h" #include "SkColorFilter.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkDevice.h" #include "SkDrawShadowInfo.h" #include "SkPath.h" diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp index b5df42364b..fd55d91707 100644 --- a/src/utils/mac/SkCreateCGImageRef.cpp +++ b/src/utils/mac/SkCreateCGImageRef.cpp @@ -10,7 +10,7 @@ #include "SkCGUtils.h" #include "SkBitmap.h" -#include "SkColorPriv.h" +#include "SkColorData.h" static CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) { CGBitmapInfo info = kCGBitmapByteOrder32Big; diff --git a/tests/ColorPrivTest.cpp b/tests/ColorPrivTest.cpp index 02885d0982..d2045e8e4a 100644 --- a/tests/ColorPrivTest.cpp +++ b/tests/ColorPrivTest.cpp @@ -1,6 +1,13 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + #include "Test.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #define ASSERT(expr) REPORTER_ASSERT(r, expr) diff --git a/tests/ColorTest.cpp b/tests/ColorTest.cpp index 5a6f0fbce3..13f48ed5fe 100644 --- a/tests/ColorTest.cpp +++ b/tests/ColorTest.cpp @@ -6,7 +6,7 @@ */ #include "SkColor.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMathPriv.h" #include "SkRandom.h" #include "SkUnPreMultiply.h" diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp index bbd551e1e9..fcbd63ddca 100644 --- a/tests/MathTest.cpp +++ b/tests/MathTest.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkEndian.h" #include "SkFDot6.h" #include "SkFixed.h" diff --git a/tests/ReadPixelsTest.cpp b/tests/ReadPixelsTest.cpp index ce01004afa..a296c46e5a 100644 --- a/tests/ReadPixelsTest.cpp +++ b/tests/ReadPixelsTest.cpp @@ -6,7 +6,7 @@ */ #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkColorSpace_Base.h" #include "SkHalf.h" #include "SkImageInfoPriv.h" diff --git a/tests/SrcOverTest.cpp b/tests/SrcOverTest.cpp index df315983ea..e8726d19d5 100644 --- a/tests/SrcOverTest.cpp +++ b/tests/SrcOverTest.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkColorPriv.h" +#include "SkColorData.h" #include "Test.h" // our std SkAlpha255To256 diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp index 6e8b7d6ee5..81dcbe7f6d 100644 --- a/tests/WritePixelsTest.cpp +++ b/tests/WritePixelsTest.cpp @@ -6,7 +6,7 @@ */ #include "SkCanvas.h" -#include "SkColorPriv.h" +#include "SkColorData.h" #include "SkMathPriv.h" #include "SkSurface.h" #include "Test.h" |