Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | #define R16_BITS 5 |
michael@0 | 2 | #define G16_BITS 6 |
michael@0 | 3 | #define B16_BITS 5 |
michael@0 | 4 | |
michael@0 | 5 | #define R16_SHIFT (B16_BITS + G16_BITS) |
michael@0 | 6 | #define G16_SHIFT (B16_BITS) |
michael@0 | 7 | #define B16_SHIFT 0 |
michael@0 | 8 | |
michael@0 | 9 | #define MASK 0xff |
michael@0 | 10 | #define ONE_HALF 0x80 |
michael@0 | 11 | |
michael@0 | 12 | #define A_SHIFT 8 * 3 |
michael@0 | 13 | #define R_SHIFT 8 * 2 |
michael@0 | 14 | #define G_SHIFT 8 |
michael@0 | 15 | #define A_MASK 0xff000000 |
michael@0 | 16 | #define R_MASK 0xff0000 |
michael@0 | 17 | #define G_MASK 0xff00 |
michael@0 | 18 | |
michael@0 | 19 | #define RB_MASK 0xff00ff |
michael@0 | 20 | #define AG_MASK 0xff00ff00 |
michael@0 | 21 | #define RB_ONE_HALF 0x800080 |
michael@0 | 22 | #define RB_MASK_PLUS_ONE 0x10000100 |
michael@0 | 23 | |
michael@0 | 24 | #define ALPHA_8(x) ((x) >> A_SHIFT) |
michael@0 | 25 | #define RED_8(x) (((x) >> R_SHIFT) & MASK) |
michael@0 | 26 | #define GREEN_8(x) (((x) >> G_SHIFT) & MASK) |
michael@0 | 27 | #define BLUE_8(x) ((x) & MASK) |
michael@0 | 28 | |
michael@0 | 29 | // This uses the same dithering technique that Skia does. |
michael@0 | 30 | // It is essentially preturbing the lower bit based on the |
michael@0 | 31 | // high bit |
michael@0 | 32 | static inline uint16_t dither_32_to_16(uint32_t c) |
michael@0 | 33 | { |
michael@0 | 34 | uint8_t b = BLUE_8(c); |
michael@0 | 35 | uint8_t g = GREEN_8(c); |
michael@0 | 36 | uint8_t r = RED_8(c); |
michael@0 | 37 | r = ((r << 1) - ((r >> (8 - R16_BITS) << (8 - R16_BITS)) | (r >> R16_BITS))) >> (8 - R16_BITS); |
michael@0 | 38 | g = ((g << 1) - ((g >> (8 - G16_BITS) << (8 - G16_BITS)) | (g >> G16_BITS))) >> (8 - G16_BITS); |
michael@0 | 39 | b = ((b << 1) - ((b >> (8 - B16_BITS) << (8 - B16_BITS)) | (b >> B16_BITS))) >> (8 - B16_BITS); |
michael@0 | 40 | return ((r << R16_SHIFT) | (g << G16_SHIFT) | (b << B16_SHIFT)); |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | static inline uint16_t dither_8888_to_0565(uint32_t color, pixman_bool_t toggle) |
michael@0 | 44 | { |
michael@0 | 45 | // alternate between a preturbed truncation and a regular truncation |
michael@0 | 46 | if (toggle) { |
michael@0 | 47 | return dither_32_to_16(color); |
michael@0 | 48 | } else { |
michael@0 | 49 | return convert_8888_to_0565(color); |
michael@0 | 50 | } |
michael@0 | 51 | } |