提交 b1424e03 编写于 作者: G Gerd Hoffmann 提交者: Anthony Liguori

vga: fix byteswapping.

In case host and guest endianness differ the vga code first creates
a shared surface (using qemu_create_displaysurface_from), then goes
patch the surface format to indicate that the bytes must be swapped.

The switch to pixman broke that hack as the format patching isn't
propagated into the pixman image, so ui code using the pixman image
directly (such as vnc) uses the wrong format.

Fix that by adding a byteswap parameter to
qemu_create_displaysurface_from, so we'll use the correct format
when creating the surface (and the pixman image) and don't have
to patch the format afterwards.

[ v2: unbreak xen build ]

Cc: qemu-stable@nongnu.org
Cc: mark.cave-ayland@ilande.co.uk
Cc: agraf@suse.de
Signed-off-by: NGerd Hoffmann <kraxel@redhat.com>
Message-id: 1361349432-23884-1-git-send-email-kraxel@redhat.com
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 ba43da36
......@@ -118,7 +118,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.surface.height,
qxl->guest_primary.bits_pp,
qxl->guest_primary.abs_stride,
qxl->guest_primary.data);
qxl->guest_primary.data,
false);
} else {
qemu_resize_displaysurface(vga->ds,
qxl->guest_primary.surface.width,
......
......@@ -1643,6 +1643,11 @@ 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;
#else
static const bool byteswap = true;
#endif
full_update |= update_basic_params(s);
......@@ -1685,18 +1690,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
disp_width != s->last_width ||
height != s->last_height ||
s->last_depth != depth) {
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
if (depth == 16 || depth == 32) {
#else
if (depth == 32) {
#endif
if (depth == 32 || (depth == 16 && !byteswap)) {
qemu_free_displaysurface(s->ds);
s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,
s->line_offset,
s->vram_ptr + (s->start_addr * 4));
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
#endif
s->vram_ptr + (s->start_addr * 4), byteswap);
dpy_gfx_resize(s->ds);
} else {
qemu_console_resize(s->ds, disp_width, height);
......@@ -1715,7 +1713,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
s->ds->surface = qemu_create_displaysurface_from(disp_width,
height, depth,
s->line_offset,
s->vram_ptr + (s->start_addr * 4));
s->vram_ptr + (s->start_addr * 4), byteswap);
dpy_gfx_setdata(s->ds);
}
......
......@@ -1074,7 +1074,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
ds_get_height(s->vga.ds),
32,
ds_get_linesize(s->vga.ds),
s->vga.vram_ptr);
s->vga.vram_ptr, false);
ppm_save(filename, ds, errp);
g_free(ds);
}
......
......@@ -756,7 +756,8 @@ static void xenfb_update(void *opaque)
qemu_free_displaysurface(xenfb->c.ds);
xenfb->c.ds->surface = qemu_create_displaysurface_from
(xenfb->width, xenfb->height, xenfb->depth,
xenfb->row_stride, xenfb->pixels + xenfb->offset);
xenfb->row_stride, xenfb->pixels + xenfb->offset,
false);
break;
default:
/* we must convert stuff */
......
......@@ -184,7 +184,8 @@ struct DisplayState {
void register_displaystate(DisplayState *ds);
DisplayState *get_displaystate(void);
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data);
int linesize, uint8_t *data,
bool byteswap);
PixelFormat qemu_different_endianness_pixelformat(int bpp);
PixelFormat qemu_default_pixelformat(int bpp);
......
......@@ -1339,11 +1339,16 @@ DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
}
DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data)
int linesize, uint8_t *data,
bool byteswap)
{
DisplaySurface *surface = g_new0(DisplaySurface, 1);
surface->pf = qemu_default_pixelformat(bpp);
if (byteswap) {
surface->pf = qemu_different_endianness_pixelformat(bpp);
} else {
surface->pf = qemu_default_pixelformat(bpp);
}
surface->format = qemu_pixman_get_format(&surface->pf);
assert(surface->format != 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册