diff options
author | Linus Walleij <triad@df.lth.se> | 2012-09-06 16:52:31 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2012-09-06 16:52:31 +0200 |
commit | 6d463de46b418e6c4c8d1397033608f78b33ab21 (patch) | |
tree | f0d0583e55347f16c894b5308ef27b717f541e17 | |
parent | 2dc1a9727288dd732af47e2618a791be9214dfe4 (diff) | |
download | busybox-w32-6d463de46b418e6c4c8d1397033608f78b33ab21.tar.gz busybox-w32-6d463de46b418e6c4c8d1397033608f78b33ab21.tar.bz2 busybox-w32-6d463de46b418e6c4c8d1397033608f78b33ab21.zip |
fbsplash: support non-RGB565 pixels in 16-bit mode
function old new delta
fbsplash_main 953 989 +36
fb_pixel_value 80 110 +30
Signed-off-by: Linus Walleij <triad@df.lth.se>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/fbsplash.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 988439b25..37ca66559 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c | |||
@@ -50,6 +50,10 @@ struct globals { | |||
50 | struct fb_var_screeninfo scr_var; | 50 | struct fb_var_screeninfo scr_var; |
51 | struct fb_fix_screeninfo scr_fix; | 51 | struct fb_fix_screeninfo scr_fix; |
52 | unsigned bytes_per_pixel; | 52 | unsigned bytes_per_pixel; |
53 | // cached (8 - scr_var.COLOR.length): | ||
54 | unsigned red_shift; | ||
55 | unsigned green_shift; | ||
56 | unsigned blue_shift; | ||
53 | }; | 57 | }; |
54 | #define G (*ptr_to_globals) | 58 | #define G (*ptr_to_globals) |
55 | #define INIT_G() do { \ | 59 | #define INIT_G() do { \ |
@@ -139,6 +143,9 @@ static void fb_open(const char *strfb_device) | |||
139 | break; | 143 | break; |
140 | } | 144 | } |
141 | 145 | ||
146 | G.red_shift = 8 - G.scr_var.red.length; | ||
147 | G.green_shift = 8 - G.scr_var.green.length; | ||
148 | G.blue_shift = 8 - G.scr_var.blue.length; | ||
142 | G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; | 149 | G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; |
143 | 150 | ||
144 | // map the device in memory | 151 | // map the device in memory |
@@ -155,10 +162,13 @@ static void fb_open(const char *strfb_device) | |||
155 | 162 | ||
156 | 163 | ||
157 | /** | 164 | /** |
158 | * Return pixel value of the passed RGB color | 165 | * Return pixel value of the passed RGB color. |
166 | * This is performance critical fn. | ||
159 | */ | 167 | */ |
160 | static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) | 168 | static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) |
161 | { | 169 | { |
170 | /* We assume that the r,g,b values are <= 255 */ | ||
171 | |||
162 | if (G.bytes_per_pixel == 1) { | 172 | if (G.bytes_per_pixel == 1) { |
163 | r = r & 0xe0; // 3-bit red | 173 | r = r & 0xe0; // 3-bit red |
164 | g = (g >> 3) & 0x1c; // 3-bit green | 174 | g = (g >> 3) & 0x1c; // 3-bit green |
@@ -166,10 +176,17 @@ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) | |||
166 | return r + g + b; | 176 | return r + g + b; |
167 | } | 177 | } |
168 | if (G.bytes_per_pixel == 2) { | 178 | if (G.bytes_per_pixel == 2) { |
169 | r = (r & 0xf8) << 8; // 5-bit red | 179 | // ARM PL110 on Integrator/CP has RGBA5551 bit arrangement. |
170 | g = (g & 0xfc) << 3; // 6-bit green | 180 | // We want to support bit locations like that. |
171 | b = b >> 3; // 5-bit blue | 181 | // |
172 | return r + g + b; | 182 | // First shift out unused bits |
183 | r = r >> G.red_shift; | ||
184 | g = g >> G.green_shift; | ||
185 | b = b >> G.blue_shift; | ||
186 | // Then shift the remaining bits to their offset | ||
187 | return (r << G.scr_var.red.offset) + | ||
188 | (g << G.scr_var.green.offset) + | ||
189 | (b << G.scr_var.blue.offset); | ||
173 | } | 190 | } |
174 | // RGB 888 | 191 | // RGB 888 |
175 | return b + (g << 8) + (r << 16); | 192 | return b + (g << 8) + (r << 16); |