qxl: fix local renderer
The local spice renderer assumes the primary surface is located at the start of the "ram" bar. This used to be a requirement in qxl hardware revision 1. In revision 2+ this is relaxed. Nevertheless guest drivers continued to use the traditional location, for historical and backward compatibility reasons. The qxl kms driver doesn't though as it depends on qxl revision 4+ anyway. Result is that local rendering is hosed for recent linux guests, you'll get pixel garbage with non-spice ui (gtk, sdl, vnc) and when doing screendumps. Fix that by doing a proper mapping of the guest-specified memory location. https://bugzilla.redhat.com/show_bug.cgi?id=948717 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
18b203850a
commit
c58c7b959b
@ -31,10 +31,6 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||
if (is_buffer_shared(surface)) {
|
||||
return;
|
||||
}
|
||||
if (!qxl->guest_primary.data) {
|
||||
trace_qxl_render_blit_guest_primary_initialized();
|
||||
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||
}
|
||||
trace_qxl_render_blit(qxl->guest_primary.qxl_stride,
|
||||
rect->left, rect->right, rect->top, rect->bottom);
|
||||
src = qxl->guest_primary.data;
|
||||
@ -104,7 +100,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
|
||||
if (qxl->guest_primary.resized) {
|
||||
qxl->guest_primary.resized = 0;
|
||||
qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
|
||||
qxl->guest_primary.data = qxl_phys2virt(qxl,
|
||||
qxl->guest_primary.surface.mem,
|
||||
MEMSLOT_GROUP_GUEST);
|
||||
if (!qxl->guest_primary.data) {
|
||||
return;
|
||||
}
|
||||
qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
|
||||
qxl->num_dirty_rects = 1;
|
||||
trace_qxl_render_guest_primary_resized(
|
||||
@ -128,6 +129,10 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
}
|
||||
dpy_gfx_replace_surface(vga->con, surface);
|
||||
}
|
||||
|
||||
if (!qxl->guest_primary.data) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < qxl->num_dirty_rects; i++) {
|
||||
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user