summaryrefslogtreecommitdiff
path: root/drivers/video/cfb_console.c
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2008-08-08 18:00:40 +0200
committerWolfgang Denk <wd@denx.de>2008-08-11 00:24:58 +0200
commite84d568fa2a9f4ce7888141e71676368ef6b3f25 (patch)
tree28fbae861adb3083be37154b399cc2f5c1a05c3e /drivers/video/cfb_console.c
parentd9015f6a50d7258125349ef5c2af836458a0029a (diff)
downloadu-boot-imx-e84d568fa2a9f4ce7888141e71676368ef6b3f25.zip
u-boot-imx-e84d568fa2a9f4ce7888141e71676368ef6b3f25.tar.gz
u-boot-imx-e84d568fa2a9f4ce7888141e71676368ef6b3f25.tar.bz2
video: fix bug in cfb_console code
FILL_15BIT_555RGB macro extension for pixel swapping by commit bed53753dd1d7e6bcbea4339be0fb7760214cc35 introduced a bug in cfb_console: Bitmaps with odd-numbered width won't be rendered correctly and even U-Boot crashes are observed on some platforms while repeated rendering of such bitmaps with "bmp display". Also if a bitmap is rendered to an odd-numbered x starting position, the same problem occurs. This patch is an attempt to fix it. Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'drivers/video/cfb_console.c')
-rw-r--r--drivers/video/cfb_console.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 97a37ba..d313e90 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -751,24 +751,10 @@ void video_puts (const char *s)
fb ++; \
}
-#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP)
#define FILL_15BIT_555RGB(r,g,b) { \
*(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
fb += 2; \
}
-#else
-static int tgl;
-static unsigned short p0;
-#define FILL_15BIT_555RGB(r,g,b) { \
- if (!tgl++) { \
- p0 = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
- } else { \
- tgl=0; \
- *(unsigned long *)(fb-2) = (SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3)))<<16) | p0; \
- } \
- fb += 2; \
-}
-#endif
#define FILL_16BIT_565RGB(r,g,b) { \
*(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
@@ -796,6 +782,20 @@ static unsigned short p0;
}
#endif
+#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
+static void inline fill_555rgb_pswap(uchar *fb, int x,
+ u8 r, u8 g, u8 b)
+{
+ ushort *dst = (ushort *)fb;
+ ushort color = (ushort)(((r >> 3) << 10) |
+ ((g >> 3) << 5) |
+ (b >> 3));
+ if (x & 1)
+ *(--dst) = color;
+ else
+ *(++dst) = color;
+}
+#endif
/*
* Display the BMP file located at address bmp_image.
@@ -927,11 +927,20 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
break;
case GDF_15BIT_555RGB:
while (ycount--) {
+#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
+ int xpos = x;
+#endif
WATCHDOG_RESET ();
xcount = width;
while (xcount--) {
cte = bmp->color_table[*bmap++];
+#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP)
FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
+#else
+ fill_555rgb_pswap (fb, xpos++, cte.red,
+ cte.green, cte.blue);
+ fb += 2;
+#endif
}
bmap += padded_line;
fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
@@ -993,10 +1002,19 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
break;
case GDF_15BIT_555RGB:
while (ycount--) {
+#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
+ int xpos = x;
+#endif
WATCHDOG_RESET ();
xcount = width;
while (xcount--) {
+#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP)
FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
+#else
+ fill_555rgb_pswap (fb, xpos++, bmap[2],
+ bmap[1], bmap[0]);
+ fb += 2;
+#endif
bmap += 3;
}
bmap += padded_line;
@@ -1103,6 +1121,9 @@ void logo_plot (void *screen, int width, int x, int y)
}
while (ycount--) {
+#if defined(VIDEO_FB_16BPP_PIXEL_SWAP)
+ int xpos = x;
+#endif
xcount = VIDEO_LOGO_WIDTH;
while (xcount--) {
r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
@@ -1121,15 +1142,7 @@ void logo_plot (void *screen, int width, int x, int y)
*(unsigned short *) dest =
SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
#else
- {
- if (!tgl++) {
- p0 = SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
- } else {
- *(unsigned long *)(dest-2) =
- (SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)))<<16) | p0;
- tgl=0;
- }
- }
+ fill_555rgb_pswap (dest, xpos++, r, g, b);
#endif
break;
case GDF_16BIT_565RGB: