From 9e057c0b09c3018cd24c7a49995f8b66d5b3d1eb Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 21 Jun 2014 15:39:31 +1000 Subject: [PATCH 01/10] vga: Start cutting out non-32bpp conversion support Nowadays, we either share a surface with the host, or we create a 32bpp ARGB console surface. So we only need to draw/convert to 32bpp, enabling us to remove all but one instance of vga_template.h inclusion (to be further cleaned up), rgb_to_pixel_* etc... Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 258 ++++------------------------------------------- 1 file changed, 22 insertions(+), 236 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index df0c010823..47e5d70de6 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1006,81 +1006,12 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) } } -typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, - const uint8_t *font_ptr, int h, - uint32_t fgcol, uint32_t bgcol); -typedef void vga_draw_glyph9_func(uint8_t *d, int linesize, - const uint8_t *font_ptr, int h, - uint32_t fgcol, uint32_t bgcol, int dup9); typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, const uint8_t *s, int width); -#define DEPTH 8 -#include "vga_template.h" - -#define DEPTH 15 -#include "vga_template.h" - -#define BGR_FORMAT -#define DEPTH 15 -#include "vga_template.h" - -#define DEPTH 16 -#include "vga_template.h" - -#define BGR_FORMAT -#define DEPTH 16 -#include "vga_template.h" - #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; - col = rgb_to_pixel8(r, g, b); - col |= col << 8; - col |= col << 16; - return col; -} - -static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b) -{ - unsigned int col; - col = rgb_to_pixel15(r, g, b); - col |= col << 16; - return col; -} - -static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g, - unsigned int b) -{ - unsigned int col; - col = rgb_to_pixel15bgr(r, g, b); - col |= col << 16; - return col; -} - -static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b) -{ - unsigned int col; - col = rgb_to_pixel16(r, g, b); - col |= col << 16; - return col; -} - -static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g, - unsigned int b) -{ - unsigned int col; - col = rgb_to_pixel16bgr(r, g, b); - col |= col << 16; - return col; -} static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) { @@ -1089,13 +1020,6 @@ 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(VGACommonState *s) { @@ -1202,56 +1126,6 @@ static int update_basic_params(VGACommonState *s) return full_update; } -#define NB_DEPTHS 7 - -static inline int get_depth_index(DisplaySurface *s) -{ - switch (surface_bits_per_pixel(s)) { - default: - case 8: - return 0; - case 15: - return 1; - case 16: - return 2; - case 32: - if (is_surface_bgr(s)) { - return 4; - } else { - return 3; - } - } -} - -static vga_draw_glyph8_func * const 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, - vga_draw_glyph8_16, - vga_draw_glyph8_16, -}; - -static vga_draw_glyph8_func * const 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, - vga_draw_glyph16_16, - vga_draw_glyph16_16, -}; - -static vga_draw_glyph9_func * const 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, - vga_draw_glyph9_16, - vga_draw_glyph9_16, -}; static const uint8_t cursor_glyph[32 * 4] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -1303,18 +1177,6 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight *pcheight = cheight; } -typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b); - -static rgb_to_pixel_dup_func * const 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, - rgb_to_pixel15bgr_dup, - rgb_to_pixel16bgr_dup, -}; - /* * Text mode update * Missing: @@ -1331,11 +1193,9 @@ static void vga_draw_text(VGACommonState *s, int full_update) uint32_t offset, fgcol, bgcol, v, cursor_offset; uint8_t *d1, *d, *src, *dest, *cursor_ptr; const uint8_t *font_ptr, *font_base[2]; - int dup9, line_offset, depth_index; + int dup9, line_offset; uint32_t *palette; uint32_t *ch_attr_ptr; - vga_draw_glyph8_func *vga_draw_glyph8; - vga_draw_glyph9_func *vga_draw_glyph9; int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); /* compute font data address (in plane 2) */ @@ -1387,8 +1247,7 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->last_cw = cw; full_update = 1; } - s->rgb_to_pixel = - rgb_to_pixel_dup_table[get_depth_index(surface)]; + s->rgb_to_pixel = rgb_to_pixel32_dup; full_update |= update_palette16(s); palette = s->last_palette; x_incr = cw * surface_bytes_per_pixel(surface); @@ -1422,13 +1281,6 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->cursor_visible_phase = !s->cursor_visible_phase; } - depth_index = get_depth_index(surface); - if (cw == 16) - vga_draw_glyph8 = vga_draw_glyph16_table[depth_index]; - else - vga_draw_glyph8 = vga_draw_glyph8_table[depth_index]; - vga_draw_glyph9 = vga_draw_glyph9_table[depth_index]; - dest = surface_data(surface); linesize = surface_stride(surface); ch_attr_ptr = s->last_ch_attr; @@ -1458,17 +1310,20 @@ static void vga_draw_text(VGACommonState *s, int full_update) font_ptr += 32 * 4 * ch; bgcol = palette[cattr >> 4]; fgcol = palette[cattr & 0x0f]; - if (cw != 9) { - vga_draw_glyph8(d1, linesize, - font_ptr, cheight, fgcol, bgcol); + if (cw == 16) { + vga_draw_glyph16_32(d1, linesize, + font_ptr, cheight, fgcol, bgcol); + } else if (cw != 9) { + vga_draw_glyph8_32(d1, linesize, + font_ptr, cheight, fgcol, bgcol); } else { dup9 = 0; if (ch >= 0xb0 && ch <= 0xdf && (s->ar[VGA_ATC_MODE] & 0x04)) { dup9 = 1; } - vga_draw_glyph9(d1, linesize, - font_ptr, cheight, fgcol, bgcol, dup9); + vga_draw_glyph9_32(d1, linesize, + font_ptr, cheight, fgcol, bgcol, dup9); } if (src == cursor_ptr && !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && @@ -1483,12 +1338,15 @@ static void vga_draw_text(VGACommonState *s, int full_update) if (line_last >= line_start && line_start < cheight) { h = line_last - line_start + 1; d = d1 + linesize * line_start; - if (cw != 9) { - vga_draw_glyph8(d, linesize, - cursor_glyph, h, fgcol, bgcol); + if (cw == 16) { + vga_draw_glyph16_32(d, linesize, + cursor_glyph, h, fgcol, bgcol); + } else if (cw != 9) { + vga_draw_glyph8_32(d, linesize, + cursor_glyph, h, fgcol, bgcol); } else { - vga_draw_glyph9(d, linesize, - cursor_glyph, h, fgcol, bgcol, 1); + vga_draw_glyph9_32(d, linesize, + cursor_glyph, h, fgcol, bgcol, 1); } } } @@ -1525,86 +1383,17 @@ enum { VGA_DRAW_LINE_NB, }; -static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = { - vga_draw_line2_8, - vga_draw_line2_16, - vga_draw_line2_16, +static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { vga_draw_line2_32, - vga_draw_line2_32, - vga_draw_line2_16, - vga_draw_line2_16, - - vga_draw_line2d2_8, - vga_draw_line2d2_16, - vga_draw_line2d2_16, vga_draw_line2d2_32, - vga_draw_line2d2_32, - vga_draw_line2d2_16, - vga_draw_line2d2_16, - - vga_draw_line4_8, - vga_draw_line4_16, - vga_draw_line4_16, vga_draw_line4_32, - vga_draw_line4_32, - vga_draw_line4_16, - vga_draw_line4_16, - - vga_draw_line4d2_8, - vga_draw_line4d2_16, - vga_draw_line4d2_16, vga_draw_line4d2_32, - vga_draw_line4d2_32, - vga_draw_line4d2_16, - vga_draw_line4d2_16, - - vga_draw_line8d2_8, - vga_draw_line8d2_16, - vga_draw_line8d2_16, vga_draw_line8d2_32, - vga_draw_line8d2_32, - vga_draw_line8d2_16, - vga_draw_line8d2_16, - - vga_draw_line8_8, - vga_draw_line8_16, - vga_draw_line8_16, vga_draw_line8_32, - vga_draw_line8_32, - vga_draw_line8_16, - vga_draw_line8_16, - - vga_draw_line15_8, - vga_draw_line15_15, - vga_draw_line15_16, vga_draw_line15_32, - vga_draw_line15_32bgr, - vga_draw_line15_15bgr, - vga_draw_line15_16bgr, - - vga_draw_line16_8, - vga_draw_line16_15, - vga_draw_line16_16, vga_draw_line16_32, - vga_draw_line16_32bgr, - vga_draw_line16_15bgr, - vga_draw_line16_16bgr, - - vga_draw_line24_8, - vga_draw_line24_15, - vga_draw_line24_16, vga_draw_line24_32, - vga_draw_line24_32bgr, - vga_draw_line24_15bgr, - vga_draw_line24_16bgr, - - vga_draw_line32_8, - vga_draw_line32_15, - vga_draw_line32_16, vga_draw_line32_32, - vga_draw_line32_32bgr, - vga_draw_line32_15bgr, - vga_draw_line32_16bgr, }; static int vga_get_bpp(VGACommonState *s) @@ -1753,8 +1542,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) dpy_gfx_replace_surface(s->con, surface); } - s->rgb_to_pixel = - rgb_to_pixel_dup_table[get_depth_index(surface)]; + s->rgb_to_pixel = rgb_to_pixel32_dup; if (shift_control == 0) { full_update |= update_palette16(s); @@ -1803,8 +1591,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) break; } } - vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + - get_depth_index(surface)]; + vga_draw_line = vga_draw_line_table[v]; if (!is_buffer_shared(surface) && s->cursor_invalidate) { s->cursor_invalidate(s); @@ -1902,8 +1689,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update) if (s->last_scr_width <= 0 || s->last_scr_height <= 0) return; - s->rgb_to_pixel = - rgb_to_pixel_dup_table[get_depth_index(surface)]; + s->rgb_to_pixel = rgb_to_pixel32_dup; if (surface_bits_per_pixel(surface) == 8) { val = s->rgb_to_pixel(0, 0, 0); } else { From d2e043a804141ec0a896270d25d6ae370c473ddd Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 21 Jun 2014 15:51:52 +1000 Subject: [PATCH 02/10] vga: Remove remainder of old conversion cruft All the macros used to generate different versions of vga_template.h are now unnecessary, take them all out and remove the _32 suffix from most functions. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 46 ++++--- hw/display/vga_template.h | 249 +++++++++++++------------------------- 2 files changed, 106 insertions(+), 189 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 47e5d70de6..721309f1aa 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1009,10 +1009,8 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, const uint8_t *s, int width); -#define DEPTH 32 #include "vga_template.h" - static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) { unsigned int col; @@ -1311,19 +1309,19 @@ static void vga_draw_text(VGACommonState *s, int full_update) bgcol = palette[cattr >> 4]; fgcol = palette[cattr & 0x0f]; if (cw == 16) { - vga_draw_glyph16_32(d1, linesize, - font_ptr, cheight, fgcol, bgcol); + vga_draw_glyph16(d1, linesize, + font_ptr, cheight, fgcol, bgcol); } else if (cw != 9) { - vga_draw_glyph8_32(d1, linesize, - font_ptr, cheight, fgcol, bgcol); + vga_draw_glyph8(d1, linesize, + font_ptr, cheight, fgcol, bgcol); } else { dup9 = 0; if (ch >= 0xb0 && ch <= 0xdf && (s->ar[VGA_ATC_MODE] & 0x04)) { dup9 = 1; } - vga_draw_glyph9_32(d1, linesize, - font_ptr, cheight, fgcol, bgcol, dup9); + vga_draw_glyph9(d1, linesize, + font_ptr, cheight, fgcol, bgcol, dup9); } if (src == cursor_ptr && !(s->cr[VGA_CRTC_CURSOR_START] & 0x20) && @@ -1339,14 +1337,14 @@ static void vga_draw_text(VGACommonState *s, int full_update) h = line_last - line_start + 1; d = d1 + linesize * line_start; if (cw == 16) { - vga_draw_glyph16_32(d, linesize, - cursor_glyph, h, fgcol, bgcol); + vga_draw_glyph16(d, linesize, + cursor_glyph, h, fgcol, bgcol); } else if (cw != 9) { - vga_draw_glyph8_32(d, linesize, - cursor_glyph, h, fgcol, bgcol); + vga_draw_glyph8(d, linesize, + cursor_glyph, h, fgcol, bgcol); } else { - vga_draw_glyph9_32(d, linesize, - cursor_glyph, h, fgcol, bgcol, 1); + vga_draw_glyph9(d, linesize, + cursor_glyph, h, fgcol, bgcol, 1); } } } @@ -1384,16 +1382,16 @@ enum { }; static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { - vga_draw_line2_32, - vga_draw_line2d2_32, - vga_draw_line4_32, - vga_draw_line4d2_32, - vga_draw_line8d2_32, - vga_draw_line8_32, - vga_draw_line15_32, - vga_draw_line16_32, - vga_draw_line24_32, - vga_draw_line32_32, + vga_draw_line2, + vga_draw_line2d2, + vga_draw_line4, + vga_draw_line4d2, + vga_draw_line8d2, + vga_draw_line8, + vga_draw_line15, + vga_draw_line16, + vga_draw_line24, + vga_draw_line32, }; static int vga_get_bpp(VGACommonState *s) diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h index 90ec9c208f..0660b520fb 100644 --- a/hw/display/vga_template.h +++ b/hw/display/vga_template.h @@ -22,41 +22,9 @@ * THE SOFTWARE. */ -#if DEPTH == 8 -#define BPP 1 -#define PIXEL_TYPE uint8_t -#elif DEPTH == 15 || DEPTH == 16 -#define BPP 2 -#define PIXEL_TYPE uint16_t -#elif DEPTH == 32 -#define BPP 4 -#define PIXEL_TYPE uint32_t -#else -#error unsupport depth -#endif - -#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, - uint32_t xorcol, - uint32_t bgcol) +static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data, + uint32_t xorcol, uint32_t bgcol) { -#if BPP == 1 - ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol; - ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; -#elif BPP == 2 - ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol; - ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol; - ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol; - ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; -#else ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; @@ -65,10 +33,24 @@ static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol; ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol; ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol; -#endif } -static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize, +static void vga_draw_glyph8(uint8_t *d, int linesize, + const uint8_t *font_ptr, int h, + uint32_t fgcol, uint32_t bgcol) +{ + uint32_t font_data, xorcol; + + xorcol = bgcol ^ fgcol; + do { + font_data = font_ptr[0]; + vga_draw_glyph_line(d, font_data, xorcol, bgcol); + font_ptr += 4; + d += linesize; + } while (--h); +} + +static void vga_draw_glyph16(uint8_t *d, int linesize, const uint8_t *font_ptr, int h, uint32_t fgcol, uint32_t bgcol) { @@ -77,63 +59,24 @@ static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize, xorcol = bgcol ^ fgcol; do { font_data = font_ptr[0]; - glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol); + vga_draw_glyph_line(d, expand4to8[font_data >> 4], + xorcol, bgcol); + vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f], + xorcol, bgcol); font_ptr += 4; d += linesize; } while (--h); } -static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize, - const uint8_t *font_ptr, int h, - uint32_t fgcol, uint32_t bgcol) -{ - uint32_t font_data, xorcol; - - xorcol = bgcol ^ fgcol; - do { - font_data = font_ptr[0]; - glue(vga_draw_glyph_line_, DEPTH)(d, - expand4to8[font_data >> 4], - xorcol, bgcol); - glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP, - expand4to8[font_data & 0x0f], - xorcol, bgcol); - font_ptr += 4; - d += linesize; - } while (--h); -} - -static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, - const uint8_t *font_ptr, int h, - uint32_t fgcol, uint32_t bgcol, int dup9) +static void vga_draw_glyph9(uint8_t *d, int linesize, + const uint8_t *font_ptr, int h, + uint32_t fgcol, uint32_t bgcol, int dup9) { uint32_t font_data, xorcol, v; xorcol = bgcol ^ fgcol; do { font_data = font_ptr[0]; -#if BPP == 1 - stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol); - v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol; - stl_p(((uint32_t *)d)+1, v); - if (dup9) - ((uint8_t *)d)[8] = v >> (24 * (1 - BIG)); - else - ((uint8_t *)d)[8] = bgcol; - -#elif BPP == 2 - stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol); - stl_p(((uint32_t *)d)+1, - (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol); - stl_p(((uint32_t *)d)+2, - (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol); - v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol; - stl_p(((uint32_t *)d)+3, v); - if (dup9) - ((uint16_t *)d)[8] = v >> (16 * (1 - BIG)); - else - ((uint16_t *)d)[8] = bgcol; -#else ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol; ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol; ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol; @@ -147,7 +90,6 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, ((uint32_t *)d)[8] = v; else ((uint32_t *)d)[8] = bgcol; -#endif font_ptr += 4; d += linesize; } while (--h); @@ -156,8 +98,8 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize, /* * 4 color mode */ -static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line2(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t plane_mask, *palette, data, v; int x; @@ -170,36 +112,30 @@ static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d, data &= plane_mask; v = expand2[GET_PLANE(data, 0)]; v |= expand2[GET_PLANE(data, 2)] << 2; - ((PIXEL_TYPE *)d)[0] = palette[v >> 12]; - ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf]; - ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf]; - ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf]; + ((uint32_t *)d)[0] = palette[v >> 12]; + ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf]; + ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf]; + ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf]; v = expand2[GET_PLANE(data, 1)]; v |= expand2[GET_PLANE(data, 3)] << 2; - ((PIXEL_TYPE *)d)[4] = palette[v >> 12]; - ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf]; - ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf]; - ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf]; - d += BPP * 8; + ((uint32_t *)d)[4] = palette[v >> 12]; + ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; + ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; + ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; + d += 32; s += 4; } } -#if BPP == 1 -#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v) -#elif BPP == 2 -#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v) -#else #define PUT_PIXEL2(d, n, v) \ ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v) -#endif /* * 4 color mode, dup2 horizontal */ -static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t plane_mask, *palette, data, v; int x; @@ -223,7 +159,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); - d += BPP * 16; + d += 64; s += 4; } } @@ -231,8 +167,8 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d, /* * 16 color mode */ -static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line4(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t plane_mask, data, v, *palette; int x; @@ -247,15 +183,15 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, v |= expand4[GET_PLANE(data, 1)] << 1; v |= expand4[GET_PLANE(data, 2)] << 2; v |= expand4[GET_PLANE(data, 3)] << 3; - ((PIXEL_TYPE *)d)[0] = palette[v >> 28]; - ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf]; - ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf]; - ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf]; - ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf]; - ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf]; - ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf]; - ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf]; - d += BPP * 8; + ((uint32_t *)d)[0] = palette[v >> 28]; + ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf]; + ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf]; + ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf]; + ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf]; + ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf]; + ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf]; + ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf]; + d += 32; s += 4; } } @@ -263,8 +199,8 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d, /* * 16 color mode, dup2 horizontal */ -static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t plane_mask, data, v, *palette; int x; @@ -287,7 +223,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]); PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]); PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]); - d += BPP * 16; + d += 64; s += 4; } } @@ -297,8 +233,8 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d, * * XXX: add plane_mask support (never used in standard VGA modes) */ -static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t *palette; int x; @@ -310,7 +246,7 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, PUT_PIXEL2(d, 1, palette[s[1]]); PUT_PIXEL2(d, 2, palette[s[2]]); PUT_PIXEL2(d, 3, palette[s[3]]); - d += BPP * 8; + d += 32; s += 4; } } @@ -320,8 +256,8 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d, * * XXX: add plane_mask support (never used in standard VGA modes) */ -static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line8(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { uint32_t *palette; int x; @@ -329,33 +265,28 @@ static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d, palette = s1->last_palette; width >>= 3; for(x = 0; x < width; x++) { - ((PIXEL_TYPE *)d)[0] = palette[s[0]]; - ((PIXEL_TYPE *)d)[1] = palette[s[1]]; - ((PIXEL_TYPE *)d)[2] = palette[s[2]]; - ((PIXEL_TYPE *)d)[3] = palette[s[3]]; - ((PIXEL_TYPE *)d)[4] = palette[s[4]]; - ((PIXEL_TYPE *)d)[5] = palette[s[5]]; - ((PIXEL_TYPE *)d)[6] = palette[s[6]]; - ((PIXEL_TYPE *)d)[7] = palette[s[7]]; - d += BPP * 8; + ((uint32_t *)d)[0] = palette[s[0]]; + ((uint32_t *)d)[1] = palette[s[1]]; + ((uint32_t *)d)[2] = palette[s[2]]; + ((uint32_t *)d)[3] = palette[s[3]]; + ((uint32_t *)d)[4] = palette[s[4]]; + ((uint32_t *)d)[5] = palette[s[5]]; + ((uint32_t *)d)[6] = palette[s[6]]; + ((uint32_t *)d)[7] = palette[s[7]]; + d += 32; s += 8; } } -#endif /* DEPTH != 15 */ - /* XXX: optimize */ /* * 15 bit color */ -static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line15(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { -#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) - memcpy(d, s, width * 2); -#else int w; uint32_t v, r, g, b; @@ -365,22 +296,18 @@ static void glue(vga_draw_line15_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, r = (v >> 7) & 0xf8; g = (v >> 2) & 0xf8; b = (v << 3) & 0xf8; - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 2; - d += BPP; + d += 4; } while (--w != 0); -#endif } /* * 16 bit color */ -static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line16(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { -#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) - memcpy(d, s, width * 2); -#else int w; uint32_t v, r, g, b; @@ -390,18 +317,17 @@ static void glue(vga_draw_line16_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, r = (v >> 8) & 0xf8; g = (v >> 3) & 0xfc; b = (v << 3) & 0xf8; - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 2; - d += BPP; + d += 4; } while (--w != 0); -#endif } /* * 24 bit color */ -static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line24(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t r, g, b; @@ -417,19 +343,19 @@ static void glue(vga_draw_line24_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, g = s[1]; r = s[2]; #endif - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 3; - d += BPP; + d += 4; } while (--w != 0); } /* * 32 bit color */ -static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line32(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { -#if DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT) +#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) memcpy(d, s, width * 4); #else int w; @@ -446,16 +372,9 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(VGACommonState *s1, uint8_t *d, g = s[1]; r = s[2]; #endif - ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b); + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 4; - d += BPP; + d += 4; } while (--w != 0); #endif } - -#undef PUT_PIXEL2 -#undef DEPTH -#undef BPP -#undef PIXEL_TYPE -#undef PIXEL_NAME -#undef BGR_FORMAT From 46c3a8c8ebe2966cc1f7af12626f89c83d547bfb Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2014 09:48:28 +1000 Subject: [PATCH 03/10] vga: Separate LE and BE conversion functions Provide different functions for converting from an LE vs a BE framebuffer. We cannot rely on the simple cases always being shared surfaces since cirrus will need to always shadow for cursor emulation, so we need the full set of functions to be able to later handle runtime switching. Signed-off-by: Benjamin Herrenschmidt \ Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 43 +++++++++------ hw/display/vga_template.h | 111 +++++++++++++++++++++++++++++--------- 2 files changed, 113 insertions(+), 41 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 721309f1aa..451c3543bc 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1374,10 +1374,14 @@ enum { VGA_DRAW_LINE4D2, VGA_DRAW_LINE8D2, VGA_DRAW_LINE8, - VGA_DRAW_LINE15, - VGA_DRAW_LINE16, - VGA_DRAW_LINE24, - VGA_DRAW_LINE32, + VGA_DRAW_LINE15_LE, + VGA_DRAW_LINE16_LE, + VGA_DRAW_LINE24_LE, + VGA_DRAW_LINE32_LE, + VGA_DRAW_LINE15_BE, + VGA_DRAW_LINE16_BE, + VGA_DRAW_LINE24_BE, + VGA_DRAW_LINE32_BE, VGA_DRAW_LINE_NB, }; @@ -1388,10 +1392,14 @@ static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { vga_draw_line4d2, vga_draw_line8d2, vga_draw_line8, - vga_draw_line15, - vga_draw_line16, - vga_draw_line24, - vga_draw_line32, + vga_draw_line15_le, + vga_draw_line16_le, + vga_draw_line24_le, + vga_draw_line32_le, + vga_draw_line15_be, + vga_draw_line16_be, + vga_draw_line24_be, + vga_draw_line32_be, }; static int vga_get_bpp(VGACommonState *s) @@ -1464,10 +1472,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; -#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) - static const bool byteswap = false; +#if defined(TARGET_WORDS_BIGENDIAN) + static const bool big_endian_fb = true; #else - static const bool byteswap = true; + static const bool big_endian_fb = false; +#endif +#if defined(HOST_WORDS_BIGENDIAN) + static const bool byteswap = !big_endian_fb; +#else + static const bool byteswap = big_endian_fb; #endif full_update |= update_basic_params(s); @@ -1572,19 +1585,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) bits = 8; break; case 15: - v = VGA_DRAW_LINE15; + v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; bits = 16; break; case 16: - v = VGA_DRAW_LINE16; + v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; bits = 16; break; case 24: - v = VGA_DRAW_LINE24; + v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; bits = 24; break; case 32: - v = VGA_DRAW_LINE32; + v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; bits = 32; break; } diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h index 0660b520fb..94f6de2046 100644 --- a/hw/display/vga_template.h +++ b/hw/display/vga_template.h @@ -278,21 +278,36 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d, } } - -/* XXX: optimize */ - /* * 15 bit color */ -static void vga_draw_line15(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t v, r, g, b; w = width; do { - v = lduw_p((void *)s); + v = lduw_le_p((void *)s); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t v, r, g, b; + + w = width; + do { + v = lduw_be_p((void *)s); r = (v >> 7) & 0xf8; g = (v >> 2) & 0xf8; b = (v << 3) & 0xf8; @@ -305,15 +320,33 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d, /* * 16 bit color */ -static void vga_draw_line16(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t v, r, g, b; w = width; do { - v = lduw_p((void *)s); + v = lduw_le_p((void *)s); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t v, r, g, b; + + w = width; + do { + v = lduw_be_p((void *)s); r = (v >> 8) & 0xf8; g = (v >> 3) & 0xfc; b = (v << 3) & 0xf8; @@ -326,23 +359,34 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d, /* * 24 bit color */ -static void vga_draw_line24(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t r, g, b; w = width; do { -#if defined(TARGET_WORDS_BIGENDIAN) - r = s[0]; - g = s[1]; - b = s[2]; -#else b = s[0]; g = s[1]; r = s[2]; -#endif + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 3; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t r, g, b; + + w = width; + do { + r = s[0]; + g = s[1]; + b = s[2]; ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 3; d += 4; @@ -352,10 +396,10 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d, /* * 32 bit color */ -static void vga_draw_line32(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { -#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +#ifndef HOST_WORDS_BIGENDIAN memcpy(d, s, width * 4); #else int w; @@ -363,15 +407,30 @@ static void vga_draw_line32(VGACommonState *s1, uint8_t *d, w = width; do { -#if defined(TARGET_WORDS_BIGENDIAN) - r = s[1]; - g = s[2]; - b = s[3]; -#else b = s[0]; g = s[1]; r = s[2]; -#endif + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 4; + d += 4; + } while (--w != 0); +#endif +} + +static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ +#ifdef HOST_WORDS_BIGENDIAN + memcpy(d, s, width * 4); +#else + int w; + uint32_t r, g, b; + + w = width; + do { + r = s[1]; + g = s[2]; + b = s[3]; ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 4; d += 4; From d3c2343af09b2e1a568ccac608b8b3d10a36c20c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 22 Jun 2014 11:00:50 +1000 Subject: [PATCH 04/10] vga: Remove rgb_to_pixel indirection We always use rgb_to_pixel32 nowadays. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/cirrus_vga.c | 15 +++++++++------ hw/display/vga.c | 31 ++++++++++--------------------- hw/display/vga_int.h | 2 -- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index db330e9548..6f8d149d60 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -29,6 +29,7 @@ #include "hw/hw.h" #include "hw/pci/pci.h" #include "ui/console.h" +#include "ui/pixel_ops.h" #include "vga_int.h" #include "hw/loader.h" @@ -2212,6 +2213,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) } else { src += (s->vga.sr[0x13] & 0x3f) * 256; src += (scr_y - s->hw_cursor_y) * 4; + + poffset = 128; content = ((uint32_t *)src)[0] | ((uint32_t *)(src + 128))[0]; @@ -2229,12 +2232,12 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) x2 = s->vga.last_scr_width; w = x2 - x1; palette = s->cirrus_hidden_palette; - color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]), - c6_to_8(palette[0x0 * 3 + 1]), - c6_to_8(palette[0x0 * 3 + 2])); - color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]), - c6_to_8(palette[0xf * 3 + 1]), - c6_to_8(palette[0xf * 3 + 2])); + color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]), + c6_to_8(palette[0x0 * 3 + 1]), + c6_to_8(palette[0x0 * 3 + 2])); + color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]), + c6_to_8(palette[0xf * 3 + 1]), + c6_to_8(palette[0xf * 3 + 2])); bpp = surface_bytes_per_pixel(surface); d1 += x1 * bpp; switch (surface_bits_per_pixel(surface)) { diff --git a/hw/display/vga.c b/hw/display/vga.c index 451c3543bc..9d06691b1c 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1011,13 +1011,6 @@ typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, #include "vga_template.h" -static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b) -{ - unsigned int col; - col = rgb_to_pixel32(r, g, b); - return col; -} - /* return true if the palette was modified */ static int update_palette16(VGACommonState *s) { @@ -1034,9 +1027,9 @@ static int update_palette16(VGACommonState *s) v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f); } v = v * 3; - col = s->rgb_to_pixel(c6_to_8(s->palette[v]), - c6_to_8(s->palette[v + 1]), - c6_to_8(s->palette[v + 2])); + col = rgb_to_pixel32(c6_to_8(s->palette[v]), + c6_to_8(s->palette[v + 1]), + c6_to_8(s->palette[v + 2])); if (col != palette[i]) { full_update = 1; palette[i] = col; @@ -1056,13 +1049,13 @@ static int update_palette256(VGACommonState *s) v = 0; for(i = 0; i < 256; i++) { if (s->dac_8bit) { - col = s->rgb_to_pixel(s->palette[v], - s->palette[v + 1], - s->palette[v + 2]); + col = rgb_to_pixel32(s->palette[v], + s->palette[v + 1], + s->palette[v + 2]); } else { - col = s->rgb_to_pixel(c6_to_8(s->palette[v]), - c6_to_8(s->palette[v + 1]), - c6_to_8(s->palette[v + 2])); + col = rgb_to_pixel32(c6_to_8(s->palette[v]), + c6_to_8(s->palette[v + 1]), + c6_to_8(s->palette[v + 2])); } if (col != palette[i]) { full_update = 1; @@ -1245,7 +1238,6 @@ static void vga_draw_text(VGACommonState *s, int full_update) s->last_cw = cw; full_update = 1; } - s->rgb_to_pixel = rgb_to_pixel32_dup; full_update |= update_palette16(s); palette = s->last_palette; x_incr = cw * surface_bytes_per_pixel(surface); @@ -1553,8 +1545,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) dpy_gfx_replace_surface(s->con, surface); } - s->rgb_to_pixel = rgb_to_pixel32_dup; - if (shift_control == 0) { full_update |= update_palette16(s); if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { @@ -1700,9 +1690,8 @@ static void vga_draw_blank(VGACommonState *s, int full_update) if (s->last_scr_width <= 0 || s->last_scr_height <= 0) return; - s->rgb_to_pixel = rgb_to_pixel32_dup; if (surface_bits_per_pixel(surface) == 8) { - val = s->rgb_to_pixel(0, 0, 0); + val = rgb_to_pixel32(0, 0, 0); } else { val = 0; } diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index bbc0cb2ad8..9073370a84 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -154,8 +154,6 @@ typedef struct VGACommonState { bool cursor_visible_phase; int64_t cursor_blink_time; uint32_t cursor_offset; - unsigned int (*rgb_to_pixel)(unsigned int r, - unsigned int g, unsigned b); const GraphicHwOps *hw_ops; bool full_update_text; bool full_update_gfx; From 2c79f2a2ecba89abe6304ef39c79cb9b3e616bcd Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 22 Jun 2014 11:03:49 +1000 Subject: [PATCH 05/10] vga: Simplify vga_draw_blank() a bit The test for surface_bits_per_pixel() isn't necessary anymore, the 8bpp case never happens. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 9d06691b1c..c3df0c59c3 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1682,7 +1682,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) static void vga_draw_blank(VGACommonState *s, int full_update) { DisplaySurface *surface = qemu_console_surface(s->con); - int i, w, val; + int i, w; uint8_t *d; if (!full_update) @@ -1690,15 +1690,10 @@ static void vga_draw_blank(VGACommonState *s, int full_update) if (s->last_scr_width <= 0 || s->last_scr_height <= 0) return; - if (surface_bits_per_pixel(surface) == 8) { - val = rgb_to_pixel32(0, 0, 0); - } else { - val = 0; - } w = s->last_scr_width * surface_bytes_per_pixel(surface); d = surface_data(surface); for(i = 0; i < s->last_scr_height; i++) { - memset(d, val, w); + memset(d, 0, w); d += surface_stride(surface); } dpy_gfx_update(s->con, 0, 0, From 70a041fe2cc26b7a58c17e26f797fbc2c90c535a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 22 Jun 2014 11:04:24 +1000 Subject: [PATCH 06/10] cirrus: Remove non-32bpp cursor drawing We only draw cursor on non-shared surfaces (so it seems...) and these are always 32bpp Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/cirrus_vga.c | 62 +++++++++++-------- hw/display/cirrus_vga_template.h | 102 ------------------------------- 2 files changed, 35 insertions(+), 129 deletions(-) delete mode 100644 hw/display/cirrus_vga_template.h diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 6f8d149d60..8a5b76c403 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2171,20 +2171,44 @@ static void cirrus_cursor_invalidate(VGACommonState *s1) } } -#define DEPTH 8 -#include "cirrus_vga_template.h" +static void vga_draw_cursor_line(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; -#define DEPTH 16 -#include "cirrus_vga_template.h" - -#define DEPTH 32 -#include "cirrus_vga_template.h" + 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; + 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; + } + d += 4; + } +} static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) { CirrusVGAState *s = container_of(s1, CirrusVGAState, vga); - DisplaySurface *surface = qemu_console_surface(s->vga.con); - int w, h, bpp, x1, x2, poffset; + int w, h, x1, x2, poffset; unsigned int color0, color1; const uint8_t *palette, *src; uint32_t content; @@ -2238,24 +2262,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]), c6_to_8(palette[0xf * 3 + 1]), c6_to_8(palette[0xf * 3 + 2])); - bpp = surface_bytes_per_pixel(surface); - d1 += x1 * bpp; - switch (surface_bits_per_pixel(surface)) { - default: - break; - case 8: - vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff); - break; - case 15: - vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff); - break; - case 16: - vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff); - break; - case 32: - vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff); - break; - } + d1 += x1 * 4; + vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff); } /*************************************** diff --git a/hw/display/cirrus_vga_template.h b/hw/display/cirrus_vga_template.h deleted file mode 100644 index 3b28280588..0000000000 --- a/hw/display/cirrus_vga_template.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * QEMU Cirrus VGA Emulator templates - * - * Copyright (c) 2003 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#if DEPTH == 8 -#define BPP 1 -#elif DEPTH == 15 || DEPTH == 16 -#define BPP 2 -#elif DEPTH == 32 -#define BPP 4 -#else -#error unsupported depth -#endif - -static 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; - } -} - -#undef DEPTH -#undef BPP From ace89b8ff21cc3fb20986a334e54e6e6a1ccf729 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 22 Jun 2014 18:28:05 +1000 Subject: [PATCH 07/10] vga: Remove some "should be done in BIOS" comments Not all platforms have a VGA BIOS, powerpc typically relies on using the DISPI interface to initialize the card. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index c3df0c59c3..21aa2c670b 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -761,14 +761,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED; vbe_fixup_regs(s); - /* clear the screen (should be done in BIOS) */ + /* clear the screen */ if (!(val & VBE_DISPI_NOCLEARMEM)) { memset(s->vram_ptr, 0, s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); } - /* we initialize the VGA graphic mode (should be done - in BIOS) */ + /* we initialize the VGA graphic mode */ /* graphic mode + memory map 1 */ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | VGA_GR06_GRAPHICS_MODE; @@ -801,7 +800,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) (shift_control << 5); s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ } else { - /* XXX: the bios should do that */ s->bank_offset = 0; } s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0; From e657d8ef3c810c4c46d3a61bb76103f77bdb499b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 23 Jun 2014 11:46:06 +1000 Subject: [PATCH 08/10] vga: Rename vga_template.h to vga-helpers.h It's no longer a template, we only instanciate the file once. Keep it a #included file so the functions remain static. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/{vga_template.h => vga-helpers.h} | 0 hw/display/vga.c | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename hw/display/{vga_template.h => vga-helpers.h} (100%) diff --git a/hw/display/vga_template.h b/hw/display/vga-helpers.h similarity index 100% rename from hw/display/vga_template.h rename to hw/display/vga-helpers.h diff --git a/hw/display/vga.c b/hw/display/vga.c index 21aa2c670b..9f60f88610 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1007,7 +1007,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val) typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d, const uint8_t *s, int width); -#include "vga_template.h" +#include "vga-helpers.h" /* return true if the palette was modified */ static int update_palette16(VGACommonState *s) From 2c7d8736af209c7e5840c16a9167ad954774ce4c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 7 Jul 2014 09:50:12 +1000 Subject: [PATCH 09/10] vga: Make fb endian a common state variable And initialize it based on target endian Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 32 +++++++++++++++++++------------- hw/display/vga_int.h | 1 + 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 9f60f88610..49a4b8bb8f 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1461,16 +1461,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; - vga_draw_line_func *vga_draw_line; -#if defined(TARGET_WORDS_BIGENDIAN) - static const bool big_endian_fb = true; + vga_draw_line_func *vga_draw_line = NULL; +#ifdef HOST_WORDS_BIGENDIAN + bool byteswap = !s->big_endian_fb; #else - static const bool big_endian_fb = false; -#endif -#if defined(HOST_WORDS_BIGENDIAN) - static const bool byteswap = !big_endian_fb; -#else - static const bool byteswap = big_endian_fb; + bool byteswap = s->big_endian_fb; #endif full_update |= update_basic_params(s); @@ -1573,19 +1568,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) bits = 8; break; case 15: - v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; + v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; bits = 16; break; case 16: - v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; + v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; bits = 16; break; case 24: - v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; + v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; bits = 24; break; case 32: - v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; + v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; bits = 32; break; } @@ -2129,6 +2124,17 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) s->update_retrace_info = vga_precise_update_retrace_info; break; } + + /* + * Set default fb endian based on target, should probably be turned + * into a device attribute set by the machine/platform to remove + * all target endian dependencies from this file. + */ +#ifdef TARGET_WORDS_BIGENDIAN + s->big_endian_fb = true; +#else + s->big_endian_fb = false; +#endif vga_dirty_log_start(s); } diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index 9073370a84..28d67cf236 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -157,6 +157,7 @@ typedef struct VGACommonState { const GraphicHwOps *hw_ops; bool full_update_text; bool full_update_gfx; + bool big_endian_fb; /* hardware mouse cursor support */ uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; void (*cursor_invalidate)(struct VGACommonState *s); From c3b10605147f9113b8b157d7226d3e215184bc0e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 23 Jun 2014 13:57:41 +1000 Subject: [PATCH 10/10] vga: Add endian to vmstate Include the endian state in the migration stream as an optional subsection which we only include when the endian isn't the default, thus enabling backward compatibility of the common case. Signed-off-by: Benjamin Herrenschmidt Changes by kraxel: * Remove bochs dispi interface changes. We'll do that in a different way to make sure we don't conflict with possible future bochs dispi interface changes. * keep live migration bits. Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson --- hw/display/vga.c | 41 +++++++++++++++++++++++++++++++++++++---- hw/display/vga_int.h | 2 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 49a4b8bb8f..19e7f23bd3 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1508,7 +1508,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (s->line_offset != s->last_line_offset || disp_width != s->last_width || height != s->last_height || - s->last_depth != depth) { + s->last_depth != depth || + s->last_byteswap != byteswap) { if (depth == 32 || (depth == 16 && !byteswap)) { pixman_format_code_t format = qemu_default_pixman_format(depth, !byteswap); @@ -1526,6 +1527,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) s->last_height = height; s->last_line_offset = s->line_offset; s->last_depth = depth; + s->last_byteswap = byteswap; full_update = 1; } else if (is_buffer_shared(surface) && (full_update || surface_data(surface) != s->vram_ptr @@ -1789,6 +1791,7 @@ void vga_common_reset(VGACommonState *s) s->cursor_start = 0; s->cursor_end = 0; s->cursor_offset = 0; + s->big_endian_fb = s->default_endian_fb; memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table)); memset(s->last_palette, '\0', sizeof(s->last_palette)); memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr)); @@ -2020,6 +2023,28 @@ static int vga_common_post_load(void *opaque, int version_id) return 0; } +static bool vga_endian_state_needed(void *opaque) +{ + VGACommonState *s = opaque; + + /* + * Only send the endian state if it's different from the + * default one, thus ensuring backward compatibility for + * migration of the common case + */ + return s->default_endian_fb != s->big_endian_fb; +} + +const VMStateDescription vmstate_vga_endian = { + .name = "vga.endian", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL(big_endian_fb, VGACommonState), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_vga_common = { .name = "vga", .version_id = 2, @@ -2056,6 +2081,14 @@ const VMStateDescription vmstate_vga_common = { VMSTATE_UINT32(vbe_line_offset, VGACommonState), VMSTATE_UINT32(vbe_bank_mask, VGACommonState), VMSTATE_END_OF_LIST() + }, + .subsections = (VMStateSubsection []) { + { + .vmsd = &vmstate_vga_endian, + .needed = vga_endian_state_needed, + }, { + /* empty */ + } } }; @@ -2126,14 +2159,14 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) } /* - * Set default fb endian based on target, should probably be turned + * Set default fb endian based on target, could probably be turned * into a device attribute set by the machine/platform to remove * all target endian dependencies from this file. */ #ifdef TARGET_WORDS_BIGENDIAN - s->big_endian_fb = true; + s->default_endian_fb = true; #else - s->big_endian_fb = false; + s->default_endian_fb = false; #endif vga_dirty_log_start(s); } diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index 28d67cf236..ed69e064a8 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -150,6 +150,7 @@ typedef struct VGACommonState { uint32_t last_width, last_height; /* in chars or pixels */ uint32_t last_scr_width, last_scr_height; /* in pixels */ uint32_t last_depth; /* in bits */ + bool last_byteswap; uint8_t cursor_start, cursor_end; bool cursor_visible_phase; int64_t cursor_blink_time; @@ -158,6 +159,7 @@ typedef struct VGACommonState { bool full_update_text; bool full_update_gfx; bool big_endian_fb; + bool default_endian_fb; /* hardware mouse cursor support */ uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32]; void (*cursor_invalidate)(struct VGACommonState *s);