From d3079cd241329456462e5b9d1bce7ddcf658fe35 Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 10 May 2006 22:17:36 +0000 Subject: [PATCH] bgr32 pixel format support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1912 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/vga.c | 79 +++++++++++++++++++-------- hw/vga_template.h | 160 ++++++++++++++++++++++++++++-------------------------- sdl.c | 5 ++ vl.h | 1 + 4 files changed, 144 insertions(+), 101 deletions(-) diff --git a/hw/vga.c b/hw/vga.c index a712790..b4eacc3 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -808,6 +808,11 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign return (r << 16) | (g << 8) | b; } +static inline unsigned int rgb_to_pixel32bgr(unsigned int r, unsigned int g, unsigned b) +{ + return (b << 16) | (g << 8) | r; +} + #define DEPTH 8 #include "vga_template.h" @@ -820,6 +825,10 @@ static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsign #define DEPTH 32 #include "vga_template.h" +#define BGR_FORMAT +#define DEPTH 32 +#include "vga_template.h" + static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b) { unsigned int col; @@ -852,6 +861,13 @@ static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned return col; } +static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b) +{ + unsigned int col; + col = rgb_to_pixel32bgr(r, g, b); + return col; +} + /* return true if the palette was modified */ static int update_palette16(VGAState *s) { @@ -948,9 +964,11 @@ static int update_basic_params(VGAState *s) return full_update; } -static inline int get_depth_index(int depth) +#define NB_DEPTHS 5 + +static inline int get_depth_index(DisplayState *s) { - switch(depth) { + switch(s->depth) { default: case 8: return 0; @@ -959,29 +977,35 @@ static inline int get_depth_index(int depth) case 16: return 2; case 32: - return 3; + if (s->bgr) + return 4; + else + return 3; } } -static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = { +static vga_draw_glyph8_func *vga_draw_glyph8_table[NB_DEPTHS] = { vga_draw_glyph8_8, vga_draw_glyph8_16, vga_draw_glyph8_16, vga_draw_glyph8_32, + vga_draw_glyph8_32, }; -static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = { +static vga_draw_glyph8_func *vga_draw_glyph16_table[NB_DEPTHS] = { vga_draw_glyph16_8, vga_draw_glyph16_16, vga_draw_glyph16_16, vga_draw_glyph16_32, + vga_draw_glyph16_32, }; -static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = { +static vga_draw_glyph9_func *vga_draw_glyph9_table[NB_DEPTHS] = { vga_draw_glyph9_8, vga_draw_glyph9_16, vga_draw_glyph9_16, vga_draw_glyph9_32, + vga_draw_glyph9_32, }; static const uint8_t cursor_glyph[32 * 4] = { @@ -1103,7 +1127,7 @@ static void vga_draw_text(VGAState *s, int full_update) } cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4; - depth_index = get_depth_index(s->ds->depth); + depth_index = get_depth_index(s->ds); if (cw == 16) vga_draw_glyph8 = vga_draw_glyph16_table[depth_index]; else @@ -1196,56 +1220,76 @@ enum { VGA_DRAW_LINE_NB, }; -static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = { +static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = { vga_draw_line2_8, vga_draw_line2_16, vga_draw_line2_16, vga_draw_line2_32, + vga_draw_line2_32, vga_draw_line2d2_8, vga_draw_line2d2_16, vga_draw_line2d2_16, vga_draw_line2d2_32, + vga_draw_line2d2_32, vga_draw_line4_8, vga_draw_line4_16, vga_draw_line4_16, vga_draw_line4_32, + vga_draw_line4_32, vga_draw_line4d2_8, vga_draw_line4d2_16, vga_draw_line4d2_16, vga_draw_line4d2_32, + vga_draw_line4d2_32, vga_draw_line8d2_8, vga_draw_line8d2_16, vga_draw_line8d2_16, vga_draw_line8d2_32, + vga_draw_line8d2_32, vga_draw_line8_8, vga_draw_line8_16, vga_draw_line8_16, vga_draw_line8_32, + vga_draw_line8_32, vga_draw_line15_8, vga_draw_line15_15, vga_draw_line15_16, vga_draw_line15_32, + vga_draw_line15_32bgr, vga_draw_line16_8, vga_draw_line16_15, vga_draw_line16_16, vga_draw_line16_32, + vga_draw_line16_32bgr, vga_draw_line24_8, vga_draw_line24_15, vga_draw_line24_16, vga_draw_line24_32, + vga_draw_line24_32bgr, vga_draw_line32_8, vga_draw_line32_15, vga_draw_line32_16, vga_draw_line32_32, + vga_draw_line32_32bgr, +}; + +typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b); + +static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = { + rgb_to_pixel8_dup, + rgb_to_pixel15_dup, + rgb_to_pixel16_dup, + rgb_to_pixel32_dup, + rgb_to_pixel32bgr_dup, }; static int vga_get_bpp(VGAState *s) @@ -1362,7 +1406,7 @@ static void vga_draw_graphic(VGAState *s, int full_update) break; } } - vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)]; + vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; if (disp_width != s->last_width || height != s->last_height) { @@ -1492,21 +1536,8 @@ static void vga_update_display(void *opaque) if (s->ds->depth == 0) { /* nothing to do */ } else { - switch(s->ds->depth) { - case 8: - s->rgb_to_pixel = rgb_to_pixel8_dup; - break; - case 15: - s->rgb_to_pixel = rgb_to_pixel15_dup; - break; - default: - case 16: - s->rgb_to_pixel = rgb_to_pixel16_dup; - break; - case 32: - s->rgb_to_pixel = rgb_to_pixel32_dup; - break; - } + s->rgb_to_pixel = + rgb_to_pixel_dup_table[get_depth_index(s->ds)]; full_update = 0; if (!(s->ar_index & 0x20)) { diff --git a/hw/vga_template.h b/hw/vga_template.h index 909571e..4ea938e 100644 --- a/hw/vga_template.h +++ b/hw/vga_template.h @@ -35,7 +35,13 @@ #error unsupport depth #endif -#if DEPTH != 15 +#ifdef BGR_FORMAT +#define PIXEL_NAME glue(DEPTH, bgr) +#else +#define PIXEL_NAME DEPTH +#endif /* BGR_FORMAT */ + +#if DEPTH != 15 && !defined(BGR_FORMAT) static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, uint32_t font_data, @@ -334,6 +340,72 @@ static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d, } } +void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, + const uint8_t *src1, + int poffset, int w, + unsigned int color0, + unsigned int color1, + unsigned int color_xor) +{ + const uint8_t *plane0, *plane1; + int x, b0, b1; + uint8_t *d; + + d = d1; + plane0 = src1; + plane1 = src1 + poffset; + for(x = 0; x < w; x++) { + b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1; + b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1; +#if DEPTH == 8 + switch(b0 | (b1 << 1)) { + case 0: + break; + case 1: + d[0] ^= color_xor; + break; + case 2: + d[0] = color0; + break; + case 3: + d[0] = color1; + break; + } +#elif DEPTH == 16 + switch(b0 | (b1 << 1)) { + case 0: + break; + case 1: + ((uint16_t *)d)[0] ^= color_xor; + break; + case 2: + ((uint16_t *)d)[0] = color0; + break; + case 3: + ((uint16_t *)d)[0] = color1; + break; + } +#elif DEPTH == 32 + switch(b0 | (b1 << 1)) { + case 0: + break; + case 1: + ((uint32_t *)d)[0] ^= color_xor; + break; + case 2: + ((uint32_t *)d)[0] = color0; + break; + case 3: + ((uint32_t *)d)[0] = color1; + break; + } +#else +#error unsupported depth +#endif + d += BPP; + } +} + #endif /* DEPTH != 15 */ @@ -342,7 +414,7 @@ static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d, /* * 15 bit color */ -static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, +static void glue(vga_draw_line15_, PIXEL_NAME)(VGAState *s1, uint8_t *d, const uint8_t *s, int width) { #if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) @@ -357,7 +429,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, r = (v >> 7) & 0xf8; g = (v >> 2) & 0xf8; b = (v << 3) & 0xf8; - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b); + ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); s += 2; d += BPP; } while (--w != 0); @@ -367,7 +439,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, /* * 16 bit color */ -static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, +static void glue(vga_draw_line16_, PIXEL_NAME)(VGAState *s1, uint8_t *d, const uint8_t *s, int width) { #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) @@ -382,7 +454,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, r = (v >> 8) & 0xf8; g = (v >> 3) & 0xfc; b = (v << 3) & 0xf8; - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b); + ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); s += 2; d += BPP; } while (--w != 0); @@ -392,7 +464,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, /* * 24 bit color */ -static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, +static void glue(vga_draw_line24_, PIXEL_NAME)(VGAState *s1, uint8_t *d, const uint8_t *s, int width) { int w; @@ -409,7 +481,7 @@ static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, g = s[1]; r = s[2]; #endif - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b); + ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); s += 3; d += BPP; } while (--w != 0); @@ -418,7 +490,7 @@ static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, /* * 32 bit color */ -static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, +static void glue(vga_draw_line32_, PIXEL_NAME)(VGAState *s1, uint8_t *d, const uint8_t *s, int width) { #if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) @@ -438,82 +510,16 @@ static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, g = s[1]; r = s[2]; #endif - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b); + ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); s += 4; d += BPP; } while (--w != 0); #endif } -#if DEPTH != 15 -void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, - const uint8_t *src1, - int poffset, int w, - unsigned int color0, - unsigned int color1, - unsigned int color_xor) -{ - const uint8_t *plane0, *plane1; - int x, b0, b1; - uint8_t *d; - - d = d1; - plane0 = src1; - plane1 = src1 + poffset; - for(x = 0; x < w; x++) { - b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1; - b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1; -#if DEPTH == 8 - switch(b0 | (b1 << 1)) { - case 0: - break; - case 1: - d[0] ^= color_xor; - break; - case 2: - d[0] = color0; - break; - case 3: - d[0] = color1; - break; - } -#elif DEPTH == 16 - switch(b0 | (b1 << 1)) { - case 0: - break; - case 1: - ((uint16_t *)d)[0] ^= color_xor; - break; - case 2: - ((uint16_t *)d)[0] = color0; - break; - case 3: - ((uint16_t *)d)[0] = color1; - break; - } -#elif DEPTH == 32 - switch(b0 | (b1 << 1)) { - case 0: - break; - case 1: - ((uint32_t *)d)[0] ^= color_xor; - break; - case 2: - ((uint32_t *)d)[0] = color0; - break; - case 3: - ((uint32_t *)d)[0] = color1; - break; - } -#else -#error unsupported depth -#endif - d += BPP; - } -} -#endif - #undef PUT_PIXEL2 #undef DEPTH #undef BPP #undef PIXEL_TYPE +#undef PIXEL_NAME +#undef BGR_FORMAT diff --git a/sdl.c b/sdl.c index 72a7080..ec4f93c 100644 --- a/sdl.c +++ b/sdl.c @@ -81,6 +81,11 @@ static void sdl_resize(DisplayState *ds, int w, int h) ds->data = screen->pixels; ds->linesize = screen->pitch; ds->depth = screen->format->BitsPerPixel; + if (ds->depth == 32 && screen->format->Rshift == 0) { + ds->bgr = 1; + } else { + ds->bgr = 0; + } ds->width = w; ds->height = h; } diff --git a/vl.h b/vl.h index 58a7877..7d51ff5 100644 --- a/vl.h +++ b/vl.h @@ -677,6 +677,7 @@ struct DisplayState { uint8_t *data; int linesize; int depth; + int bgr; /* BGR color order instead of RGB. Only valid for depth == 32 */ int width; int height; void *opaque; -- 2.7.4