diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-10-02 12:28:50 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-10-02 12:28:50 +0100 |
commit | fbcaca994df3d750ab98e61e36195aac07dab741 (patch) | |
tree | 175018b467fd7ff88830287d9153cff191b8443d /hw | |
parent | 1831e150606a221898bf46ffaf0453e9952cbbc4 (diff) | |
parent | c3b10605147f9113b8b157d7226d3e215184bc0e (diff) | |
download | qemu-fbcaca994df3d750ab98e61e36195aac07dab741.zip qemu-fbcaca994df3d750ab98e61e36195aac07dab741.tar.gz qemu-fbcaca994df3d750ab98e61e36195aac07dab741.tar.bz2 |
Merge remote-tracking branch 'remotes/kraxel/tags/pull-vga-20141002-1' into staging
vga: cleanups, prepare for endianness switching
# gpg: Signature made Thu 02 Oct 2014 08:10:49 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
* remotes/kraxel/tags/pull-vga-20141002-1:
vga: Add endian to vmstate
vga: Make fb endian a common state variable
vga: Rename vga_template.h to vga-helpers.h
vga: Remove some "should be done in BIOS" comments
cirrus: Remove non-32bpp cursor drawing
vga: Simplify vga_draw_blank() a bit
vga: Remove rgb_to_pixel indirection
vga: Separate LE and BE conversion functions
vga: Remove remainder of old conversion cruft
vga: Start cutting out non-32bpp conversion support
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/display/cirrus_vga.c | 79 | ||||
-rw-r--r-- | hw/display/cirrus_vga_template.h | 102 | ||||
-rw-r--r-- | hw/display/vga-helpers.h (renamed from hw/display/vga_template.h) | 318 | ||||
-rw-r--r-- | hw/display/vga.c | 382 | ||||
-rw-r--r-- | hw/display/vga_int.h | 5 |
5 files changed, 296 insertions, 590 deletions
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index db330e9..8a5b76c 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" @@ -2170,20 +2171,44 @@ static void cirrus_cursor_invalidate(VGACommonState *s1) } } -#define DEPTH 8 -#include "cirrus_vga_template.h" - -#define DEPTH 16 -#include "cirrus_vga_template.h" - -#define DEPTH 32 -#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; + + 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; @@ -2212,6 +2237,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,30 +2256,14 @@ 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])); - 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; - } + 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])); + 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 3b28280..0000000 --- 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 diff --git a/hw/display/vga_template.h b/hw/display/vga-helpers.h index 90ec9c2..94f6de2 100644 --- a/hw/display/vga_template.h +++ b/hw/display/vga-helpers.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,25 +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, - const uint8_t *font_ptr, int h, - uint32_t fgcol, uint32_t bgcol) +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]; - glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol); + vga_draw_glyph_line(d, font_data, xorcol, bgcol); font_ptr += 4; d += linesize; } while (--h); } -static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize, +static void vga_draw_glyph16(uint8_t *d, int linesize, const uint8_t *font_ptr, int h, uint32_t fgcol, uint32_t bgcol) { @@ -92,48 +59,24 @@ static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize, 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); + 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_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,107 +265,141 @@ 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_le(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; 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; - ((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); +} + +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; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + 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_le(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; 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; - ((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); +} + +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; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + 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_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 - ((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); +} + +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; } 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_le(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) +#ifndef HOST_WORDS_BIGENDIAN memcpy(d, s, width * 4); #else int w; @@ -437,25 +407,33 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(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 - ((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 +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; + } while (--w != 0); +#endif +} diff --git a/hw/display/vga.c b/hw/display/vga.c index df0c010..19e7f23 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; @@ -1006,95 +1004,10 @@ 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) -{ - unsigned int col; - col = rgb_to_pixel32(r, g, b); - 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; -} +#include "vga-helpers.h" /* return true if the palette was modified */ static int update_palette16(VGACommonState *s) @@ -1112,9 +1025,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; @@ -1134,13 +1047,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; @@ -1202,56 +1115,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 +1166,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 +1182,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 +1236,6 @@ 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)]; full_update |= update_palette16(s); palette = s->last_palette; x_incr = cw * surface_bytes_per_pixel(surface); @@ -1422,13 +1269,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,7 +1298,10 @@ 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) { + if (cw == 16) { + vga_draw_glyph16(d1, linesize, + font_ptr, cheight, fgcol, bgcol); + } else if (cw != 9) { vga_draw_glyph8(d1, linesize, font_ptr, cheight, fgcol, bgcol); } else { @@ -1483,7 +1326,10 @@ 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) { + if (cw == 16) { + vga_draw_glyph16(d, linesize, + cursor_glyph, h, fgcol, bgcol); + } else if (cw != 9) { vga_draw_glyph8(d, linesize, cursor_glyph, h, fgcol, bgcol); } else { @@ -1518,93 +1364,32 @@ 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, }; -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, - 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 vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { + vga_draw_line2, + vga_draw_line2d2, + vga_draw_line4, + vga_draw_line4d2, + vga_draw_line8d2, + vga_draw_line8, + 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) @@ -1676,11 +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(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) - static const bool byteswap = false; + vga_draw_line_func *vga_draw_line = NULL; +#ifdef HOST_WORDS_BIGENDIAN + bool byteswap = !s->big_endian_fb; #else - static const bool byteswap = true; + bool byteswap = s->big_endian_fb; #endif full_update |= update_basic_params(s); @@ -1723,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); @@ -1741,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 @@ -1753,9 +1540,6 @@ 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)]; - if (shift_control == 0) { full_update |= update_palette16(s); if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { @@ -1786,25 +1570,24 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) bits = 8; break; case 15: - v = VGA_DRAW_LINE15; + v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; bits = 16; break; case 16: - v = VGA_DRAW_LINE16; + v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; bits = 16; break; case 24: - v = VGA_DRAW_LINE24; + v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; bits = 24; break; case 32: - v = VGA_DRAW_LINE32; + v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; bits = 32; 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); @@ -1894,7 +1677,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) @@ -1902,17 +1685,10 @@ 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)]; - if (surface_bits_per_pixel(surface) == 8) { - val = s->rgb_to_pixel(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, @@ -2015,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)); @@ -2246,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, @@ -2282,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 */ + } } }; @@ -2350,6 +2157,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, 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->default_endian_fb = true; +#else + 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 bbc0cb2..ed69e06 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -150,15 +150,16 @@ 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; 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; + 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); |