Hi On Wed, Sep 19, 2018 at 2:33 PM Gerd Hoffmann <kra...@redhat.com> wrote: > > When processing monitor config from guest store head0 width and height > for single-head configurations. Use these when creating the > DisplaySurface in the local renderer. > > This fixes a rendering issue with wayland. Wayland rounds up the > framebuffer width and height to a multiple of 64, so with odd > resolutions (800x600 for example) the framebuffer is larger than the > actual screen. The monitor config has the actual screen size though. > > This fixes guest display for anything using the local renderer > (non-spice UI, screendump monitor command). > > Signed-off-by: Gerd Hoffmann <kra...@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lur...@redhat.com> > --- > hw/display/qxl.h | 2 ++ > hw/display/qxl-render.c | 18 ++++++++++-------- > hw/display/qxl.c | 12 ++++++++++++ > 3 files changed, 24 insertions(+), 8 deletions(-) > > diff --git a/hw/display/qxl.h b/hw/display/qxl.h > index 6eacba080d..dd9c0522b7 100644 > --- a/hw/display/qxl.h > +++ b/hw/display/qxl.h > @@ -78,6 +78,8 @@ typedef struct PCIQXLDevice { > QXLPHYSICAL guest_cursor; > > QXLPHYSICAL guest_monitors_config; > + uint32_t guest_head0_width; > + uint32_t guest_head0_height; > > QemuMutex track_lock; > > diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c > index c62b9a5e75..6debe8fc11 100644 > --- a/hw/display/qxl-render.c > +++ b/hw/display/qxl-render.c > @@ -98,6 +98,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice > *qxl) > { > VGACommonState *vga = &qxl->vga; > DisplaySurface *surface; > + int width = qxl->guest_head0_width ?: qxl->guest_primary.surface.width; > + int height = qxl->guest_head0_height ?: > qxl->guest_primary.surface.height; > int i; > > if (qxl->guest_primary.resized) { > @@ -111,8 +113,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice > *qxl) > qxl_set_rect_to_surface(qxl, &qxl->dirty[0]); > qxl->num_dirty_rects = 1; > trace_qxl_render_guest_primary_resized( > - qxl->guest_primary.surface.width, > - qxl->guest_primary.surface.height, > + width, > + height, > qxl->guest_primary.qxl_stride, > qxl->guest_primary.bytes_pp, > qxl->guest_primary.bits_pp); > @@ -120,15 +122,15 @@ static void > qxl_render_update_area_unlocked(PCIQXLDevice *qxl) > pixman_format_code_t format = > qemu_default_pixman_format(qxl->guest_primary.bits_pp, true); > surface = qemu_create_displaysurface_from > - (qxl->guest_primary.surface.width, > - qxl->guest_primary.surface.height, > + (width, > + height, > format, > qxl->guest_primary.abs_stride, > qxl->guest_primary.data); > } else { > surface = qemu_create_displaysurface > - (qxl->guest_primary.surface.width, > - qxl->guest_primary.surface.height); > + (width, > + height); > } > dpy_gfx_replace_surface(vga->con, surface); > } > @@ -144,8 +146,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice > *qxl) > qxl->dirty[i].top < 0 || > qxl->dirty[i].left > qxl->dirty[i].right || > qxl->dirty[i].top > qxl->dirty[i].bottom || > - qxl->dirty[i].right > qxl->guest_primary.surface.width || > - qxl->dirty[i].bottom > qxl->guest_primary.surface.height) { > + qxl->dirty[i].right > width || > + qxl->dirty[i].bottom > height) { > continue; > } > qxl_blit(qxl, qxl->dirty+i); > diff --git a/hw/display/qxl.c b/hw/display/qxl.c > index 8e9135d9c6..747986478f 100644 > --- a/hw/display/qxl.c > +++ b/hw/display/qxl.c > @@ -259,6 +259,8 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, > qxl_async_io async) > > static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay) > { > + QXLMonitorsConfig *cfg; > + > trace_qxl_spice_monitors_config(qxl->id); > if (replay) { > /* > @@ -286,6 +288,16 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice > *qxl, int replay) > (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO, > QXL_IO_MONITORS_CONFIG_ASYNC)); > } > + > + cfg = qxl_phys2virt(qxl, qxl->guest_monitors_config, > MEMSLOT_GROUP_GUEST); > + if (cfg->count == 1) { > + qxl->guest_primary.resized = 1; > + qxl->guest_head0_width = cfg->heads[0].width; > + qxl->guest_head0_height = cfg->heads[0].height; > + } else { > + qxl->guest_head0_width = 0; > + qxl->guest_head0_height = 0; > + } > } > > void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) > -- > 2.9.3 > > -- Marc-André Lureau