From e35f40730d3d79ebc1870c5716c14f821a67a5ef Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 22 Feb 2017 12:36:23 +0100 Subject: [PATCH 05/24] ui/vnc: fix vmware VGA incompatiblities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Gerd Hoffmann Message-id: <1487766986-6329-6-git-send-email-kraxel@redhat.com> Patchwork-id: 73976 O-Subject: [RHEL-7.4 qemu-kvm PATCH 5/8] ui/vnc: fix vmware VGA incompatiblities Bugzilla: 1377977 RH-Acked-by: Thomas Huth RH-Acked-by: Marc-André Lureau RH-Acked-by: Laurent Vivier From: Peter Lieven this fixes invalid rectangle updates observed after commit 12b316d with the vmware VGA driver. The issues occured because the server and client surface update seems to be out of sync at some points and the max width of the surface is not dividable by VNC_DIRTY_BITS_PER_PIXEL (16). Reported-by: Serge Hallyn Signed-off-by: Peter Lieven Signed-off-by: Gerd Hoffmann (cherry picked from commit 2f487a3d40faff1772e14da6b921900915501f9a) Signed-off-by: Miroslav Rezanina --- hw/display/vmware_vga.c | 3 ++- ui/vnc.c | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index df76aec..8e334c0 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -24,6 +24,7 @@ #include "hw/hw.h" #include "hw/loader.h" #include "ui/console.h" +#include "ui/vnc.h" #include "hw/pci/pci.h" #undef VERBOSE @@ -209,7 +210,7 @@ enum { /* These values can probably be changed arbitrarily. */ #define SVGA_SCRATCH_SIZE 0x8000 -#define SVGA_MAX_WIDTH 2360 +#define SVGA_MAX_WIDTH ROUND_UP(2360, VNC_DIRTY_PIXELS_PER_BIT) #define SVGA_MAX_HEIGHT 1770 #ifdef VERBOSE diff --git a/ui/vnc.c b/ui/vnc.c index 2540261..51f95be 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -898,7 +898,7 @@ static int vnc_update_client(VncState *vs, int has_dirty) VncDisplay *vd = vs->vd; VncJob *job; int y; - int height; + int height, width; int n = 0; if (vs->output.offset && !vs->audio_cap && !vs->force_update) @@ -917,6 +917,7 @@ static int vnc_update_client(VncState *vs, int has_dirty) job = vnc_job_new(vs); height = MIN(pixman_image_get_height(vd->server), vs->client_height); + width = MIN(pixman_image_get_width(vd->server), vs->client_width); y = 0; for (;;) { @@ -935,8 +936,11 @@ static int vnc_update_client(VncState *vs, int has_dirty) VNC_DIRTY_BPL(vs), x); bitmap_clear(vs->dirty[y], x, x2 - x); h = find_and_clear_dirty_height(vs, y, x, x2, height); - n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y, - (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h); + x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT); + if (x2 > x) { + n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y, + (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h); + } } vnc_job_push(job); -- 1.8.3.1