From: Charlie Brej Date: Mon, 27 Oct 2008 16:49:06 +0000 (-0400) Subject: Dither colors in non-default low depth color path X-Git-Tag: 0.6.0~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d3584b4e85ee984c35c1e152af6c7b4dbc34b7c2;p=thirdparty%2Fplymouth.git Dither colors in non-default low depth color path This patch modifies the low color mode (slow) path to dither the colors before flushing them to the scanout buffer. This improves the output quality in those corner cases. --- diff --git a/src/libply/ply-frame-buffer.c b/src/libply/ply-frame-buffer.c index d80a6cdb..dd266469 100644 --- a/src/libply/ply-frame-buffer.c +++ b/src/libply/ply-frame-buffer.c @@ -68,6 +68,10 @@ struct _ply_frame_buffer uint32_t bits_for_blue; uint32_t bits_for_alpha; + int32_t dither_red; + int32_t dither_green; + int32_t dither_blue; + unsigned int bytes_per_pixel; unsigned int row_stride; @@ -315,6 +319,10 @@ ply_frame_buffer_query_device (ply_frame_buffer_t *buffer) buffer->bytes_per_pixel = variable_screen_info.bits_per_pixel >> 3; buffer->row_stride = fixed_screen_info.line_length / buffer->bytes_per_pixel; buffer->size = buffer->area.height * buffer->row_stride * buffer->bytes_per_pixel; + + buffer->dither_red = 0; + buffer->dither_green = 0; + buffer->dither_blue = 0; if (buffer->bytes_per_pixel == 4 && buffer->red_bit_position == 16 && buffer->bits_for_red == 8 && @@ -340,24 +348,37 @@ ply_frame_buffer_map_to_device (ply_frame_buffer_t *buffer) return buffer->map_address != MAP_FAILED; } -__attribute__((__pure__)) static inline uint_fast32_t ply_frame_buffer_pixel_value_to_device_pixel_value (ply_frame_buffer_t *buffer, uint32_t pixel_value) { uint8_t r, g, b, a; + int orig_r, orig_g, orig_b, orig_a; + int i; + + orig_a = pixel_value >> 24; + a = orig_a >> (8 - buffer->bits_for_alpha); - a = pixel_value >> 24; - a >>= (8 - buffer->bits_for_alpha); - - r = (pixel_value >> 16) & 0xff; - r >>= (8 - buffer->bits_for_red); + orig_r = ((pixel_value >> 16) & 0xff) - buffer->dither_red; + r = CLAMP(orig_r, 0, 255) >> (8 - buffer->bits_for_red); - g = (pixel_value >> 8) & 0xff; - g >>= (8 - buffer->bits_for_green); + orig_g = ((pixel_value >> 8) & 0xff) - buffer->dither_green; + g = CLAMP(orig_g, 0, 255) >> (8 - buffer->bits_for_green); - b = pixel_value & 0xff; - b >>= (8 - buffer->bits_for_blue); + orig_b = (pixel_value & 0xff) - buffer->dither_blue; + b = CLAMP(orig_b, 0, 255) >> (8 - buffer->bits_for_blue); + + uint8_t new_r = r << (8 - buffer->bits_for_red); + uint8_t new_g = g << (8 - buffer->bits_for_green); + uint8_t new_b = b << (8 - buffer->bits_for_blue); + for (i=buffer->bits_for_red; i<8; i*=2) new_r |= new_r >> i; + for (i=buffer->bits_for_green; i<8; i*=2) new_g |= new_g >> i; + for (i=buffer->bits_for_blue; i<8; i*=2) new_b |= new_b >> i; + + buffer->dither_red = new_r - orig_r; + buffer->dither_green = new_g - orig_g; + buffer->dither_blue = new_b - orig_b; + return ((a << buffer->alpha_bit_position) | (r << buffer->red_bit_position)