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