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