Commit 0da2ea1b37622ea6608031b5cd9dcca8f1b0e12d
1 parent
1a6f0dbc
fix endianness problem sharing the videoram buffer
[ The following text is in the "UTF-8" character set. ]
[ Your display is set for the "koi8-r" character set. ]
[ Some characters may be displayed incorrectly. ]
This patch fixes vga rendering when the guest endianness differs from
the host endianness: in this case we can only share the buffer if the
bpp is 32 and we must change the pixelformat accordingly.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6413 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
62 additions
and
11 deletions
console.c
| @@ -1449,7 +1449,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y, | @@ -1449,7 +1449,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y, | ||
| 1449 | } | 1449 | } |
| 1450 | } | 1450 | } |
| 1451 | 1451 | ||
| 1452 | -static PixelFormat qemu_default_pixelformat(int bpp) | 1452 | +PixelFormat qemu_different_endianness_pixelformat(int bpp) |
| 1453 | { | 1453 | { |
| 1454 | PixelFormat pf; | 1454 | PixelFormat pf; |
| 1455 | 1455 | ||
| @@ -1460,17 +1460,48 @@ static PixelFormat qemu_default_pixelformat(int bpp) | @@ -1460,17 +1460,48 @@ static PixelFormat qemu_default_pixelformat(int bpp) | ||
| 1460 | pf.depth = bpp == 32 ? 24 : bpp; | 1460 | pf.depth = bpp == 32 ? 24 : bpp; |
| 1461 | 1461 | ||
| 1462 | switch (bpp) { | 1462 | switch (bpp) { |
| 1463 | - case 8: | ||
| 1464 | - pf.rmask = 0x000000E0; | ||
| 1465 | - pf.gmask = 0x0000001C; | ||
| 1466 | - pf.bmask = 0x00000003; | ||
| 1467 | - pf.rmax = 7; | ||
| 1468 | - pf.gmax = 7; | ||
| 1469 | - pf.bmax = 3; | ||
| 1470 | - pf.rshift = 5; | ||
| 1471 | - pf.gshift = 2; | ||
| 1472 | - pf.bshift = 0; | 1463 | + case 24: |
| 1464 | + pf.rmask = 0x000000FF; | ||
| 1465 | + pf.gmask = 0x0000FF00; | ||
| 1466 | + pf.bmask = 0x00FF0000; | ||
| 1467 | + pf.rmax = 255; | ||
| 1468 | + pf.gmax = 255; | ||
| 1469 | + pf.bmax = 255; | ||
| 1470 | + pf.rshift = 0; | ||
| 1471 | + pf.gshift = 8; | ||
| 1472 | + pf.bshift = 16; | ||
| 1473 | break; | 1473 | break; |
| 1474 | + case 32: | ||
| 1475 | + pf.rmask = 0x0000FF00; | ||
| 1476 | + pf.gmask = 0x00FF0000; | ||
| 1477 | + pf.bmask = 0xFF000000; | ||
| 1478 | + pf.amask = 0x00000000; | ||
| 1479 | + pf.amax = 255; | ||
| 1480 | + pf.rmax = 255; | ||
| 1481 | + pf.gmax = 255; | ||
| 1482 | + pf.bmax = 255; | ||
| 1483 | + pf.ashift = 0; | ||
| 1484 | + pf.rshift = 8; | ||
| 1485 | + pf.gshift = 16; | ||
| 1486 | + pf.bshift = 24; | ||
| 1487 | + break; | ||
| 1488 | + default: | ||
| 1489 | + break; | ||
| 1490 | + } | ||
| 1491 | + return pf; | ||
| 1492 | +} | ||
| 1493 | + | ||
| 1494 | +PixelFormat qemu_default_pixelformat(int bpp) | ||
| 1495 | +{ | ||
| 1496 | + PixelFormat pf; | ||
| 1497 | + | ||
| 1498 | + memset(&pf, 0x00, sizeof(PixelFormat)); | ||
| 1499 | + | ||
| 1500 | + pf.bits_per_pixel = bpp; | ||
| 1501 | + pf.bytes_per_pixel = bpp / 8; | ||
| 1502 | + pf.depth = bpp == 32 ? 24 : bpp; | ||
| 1503 | + | ||
| 1504 | + switch (bpp) { | ||
| 1474 | case 16: | 1505 | case 16: |
| 1475 | pf.rmask = 0x0000F800; | 1506 | pf.rmask = 0x0000F800; |
| 1476 | pf.gmask = 0x000007E0; | 1507 | pf.gmask = 0x000007E0; |
| @@ -1483,13 +1514,24 @@ static PixelFormat qemu_default_pixelformat(int bpp) | @@ -1483,13 +1514,24 @@ static PixelFormat qemu_default_pixelformat(int bpp) | ||
| 1483 | pf.bshift = 0; | 1514 | pf.bshift = 0; |
| 1484 | break; | 1515 | break; |
| 1485 | case 24: | 1516 | case 24: |
| 1517 | + pf.rmask = 0x00FF0000; | ||
| 1518 | + pf.gmask = 0x0000FF00; | ||
| 1519 | + pf.bmask = 0x000000FF; | ||
| 1520 | + pf.rmax = 255; | ||
| 1521 | + pf.gmax = 255; | ||
| 1522 | + pf.bmax = 255; | ||
| 1523 | + pf.rshift = 16; | ||
| 1524 | + pf.gshift = 8; | ||
| 1525 | + pf.bshift = 0; | ||
| 1486 | case 32: | 1526 | case 32: |
| 1487 | pf.rmask = 0x00FF0000; | 1527 | pf.rmask = 0x00FF0000; |
| 1488 | pf.gmask = 0x0000FF00; | 1528 | pf.gmask = 0x0000FF00; |
| 1489 | pf.bmask = 0x000000FF; | 1529 | pf.bmask = 0x000000FF; |
| 1530 | + pf.amax = 255; | ||
| 1490 | pf.rmax = 255; | 1531 | pf.rmax = 255; |
| 1491 | pf.gmax = 255; | 1532 | pf.gmax = 255; |
| 1492 | pf.bmax = 255; | 1533 | pf.bmax = 255; |
| 1534 | + pf.ashift = 24; | ||
| 1493 | pf.rshift = 16; | 1535 | pf.rshift = 16; |
| 1494 | pf.gshift = 8; | 1536 | pf.gshift = 8; |
| 1495 | pf.bshift = 0; | 1537 | pf.bshift = 0; |
console.h
| @@ -134,6 +134,8 @@ DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface, | @@ -134,6 +134,8 @@ DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface, | ||
| 134 | DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, | 134 | DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, |
| 135 | int linesize, uint8_t *data); | 135 | int linesize, uint8_t *data); |
| 136 | void qemu_free_displaysurface(DisplaySurface *surface); | 136 | void qemu_free_displaysurface(DisplaySurface *surface); |
| 137 | +PixelFormat qemu_different_endianness_pixelformat(int bpp); | ||
| 138 | +PixelFormat qemu_default_pixelformat(int bpp); | ||
| 137 | 139 | ||
| 138 | static inline int is_buffer_shared(DisplaySurface *surface) | 140 | static inline int is_buffer_shared(DisplaySurface *surface) |
| 139 | { | 141 | { |
hw/vga.c
| @@ -1623,12 +1623,19 @@ static void vga_draw_graphic(VGAState *s, int full_update) | @@ -1623,12 +1623,19 @@ static void vga_draw_graphic(VGAState *s, int full_update) | ||
| 1623 | disp_width != s->last_width || | 1623 | disp_width != s->last_width || |
| 1624 | height != s->last_height || | 1624 | height != s->last_height || |
| 1625 | s->last_depth != depth) { | 1625 | s->last_depth != depth) { |
| 1626 | +#if defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) | ||
| 1626 | if (depth == 16 || depth == 32) { | 1627 | if (depth == 16 || depth == 32) { |
| 1628 | +#else | ||
| 1629 | + if (depth == 32) { | ||
| 1630 | +#endif | ||
| 1627 | if (is_graphic_console()) { | 1631 | if (is_graphic_console()) { |
| 1628 | qemu_free_displaysurface(s->ds->surface); | 1632 | qemu_free_displaysurface(s->ds->surface); |
| 1629 | s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, | 1633 | s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, |
| 1630 | s->line_offset, | 1634 | s->line_offset, |
| 1631 | s->vram_ptr + (s->start_addr * 4)); | 1635 | s->vram_ptr + (s->start_addr * 4)); |
| 1636 | +#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) | ||
| 1637 | + s->ds->surface->pf = qemu_different_endianness_pixelformat(depth); | ||
| 1638 | +#endif | ||
| 1632 | dpy_resize(s->ds); | 1639 | dpy_resize(s->ds); |
| 1633 | } else { | 1640 | } else { |
| 1634 | qemu_console_resize(s->ds, disp_width, height); | 1641 | qemu_console_resize(s->ds, disp_width, height); |