b38b0f
From 1b209dbf4eba1f7cdd456a809a2a8576e66a1464 Mon Sep 17 00:00:00 2001
b38b0f
From: Gerd Hoffmann <kraxel@redhat.com>
b38b0f
Date: Tue, 13 Aug 2019 11:20:45 +0100
b38b0f
Subject: [PATCH 01/10] vnc: detect and optimize pageflips
b38b0f
MIME-Version: 1.0
b38b0f
Content-Type: text/plain; charset=UTF-8
b38b0f
Content-Transfer-Encoding: 8bit
b38b0f
b38b0f
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
b38b0f
Message-id: <20190813112045.3887-2-kraxel@redhat.com>
b38b0f
Patchwork-id: 89956
b38b0f
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 1/1] vnc: detect and optimize pageflips
b38b0f
Bugzilla: 1727033
b38b0f
RH-Acked-by: John Snow <jsnow@redhat.com>
b38b0f
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
b38b0f
RH-Acked-by: Thomas Huth <thuth@redhat.com>
b38b0f
b38b0f
When size and format of the display surface stays the same we can just
b38b0f
tag the guest display as dirty and be done with it.
b38b0f
b38b0f
There is no need need to resize the vnc server display or to touch the
b38b0f
vnc client dirty bits.  On the next refresh cycle
b38b0f
vnc_refresh_server_surface() will check for actual display content
b38b0f
changes and update the client dirty bits as needed.
b38b0f
b38b0f
The desktop resize and framebuffer format notifications to the vnc
b38b0f
client will be skipped too.
b38b0f
b38b0f
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
b38b0f
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
b38b0f
Message-id: 20190116101049.8929-1-kraxel@redhat.com
b38b0f
(cherry picked from commit 61e77a5f0c788495566aecb437bcf6b2cf9cda97)
b38b0f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
b38b0f
---
b38b0f
 ui/vnc.c | 25 ++++++++++++++++++++++---
b38b0f
 1 file changed, 22 insertions(+), 3 deletions(-)
b38b0f
b38b0f
diff --git a/ui/vnc.c b/ui/vnc.c
b38b0f
index 86c6762..0bd44f1 100644
b38b0f
--- a/ui/vnc.c
b38b0f
+++ b/ui/vnc.c
b38b0f
@@ -743,6 +743,17 @@ static void vnc_update_server_surface(VncDisplay *vd)
b38b0f
                        width, height);
b38b0f
 }
b38b0f
 
b38b0f
+static bool vnc_check_pageflip(DisplaySurface *s1,
b38b0f
+                               DisplaySurface *s2)
b38b0f
+{
b38b0f
+    return (s1 != NULL &&
b38b0f
+            s2 != NULL &&
b38b0f
+            surface_width(s1) == surface_width(s2) &&
b38b0f
+            surface_height(s1) == surface_height(s2) &&
b38b0f
+            surface_format(s1) == surface_format(s2));
b38b0f
+
b38b0f
+}
b38b0f
+
b38b0f
 static void vnc_dpy_switch(DisplayChangeListener *dcl,
b38b0f
                            DisplaySurface *surface)
b38b0f
 {
b38b0f
@@ -750,6 +761,7 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
b38b0f
         "Display output is not active.";
b38b0f
     static DisplaySurface *placeholder;
b38b0f
     VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
b38b0f
+    bool pageflip = vnc_check_pageflip(vd->ds, surface);
b38b0f
     VncState *vs;
b38b0f
 
b38b0f
     if (surface == NULL) {
b38b0f
@@ -762,14 +774,21 @@ static void vnc_dpy_switch(DisplayChangeListener *dcl,
b38b0f
     vnc_abort_display_jobs(vd);
b38b0f
     vd->ds = surface;
b38b0f
 
b38b0f
-    /* server surface */
b38b0f
-    vnc_update_server_surface(vd);
b38b0f
-
b38b0f
     /* guest surface */
b38b0f
     qemu_pixman_image_unref(vd->guest.fb);
b38b0f
     vd->guest.fb = pixman_image_ref(surface->image);
b38b0f
     vd->guest.format = surface->format;
b38b0f
 
b38b0f
+    if (pageflip) {
b38b0f
+        vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
b38b0f
+                           surface_width(surface),
b38b0f
+                           surface_height(surface));
b38b0f
+        return;
b38b0f
+    }
b38b0f
+
b38b0f
+    /* server surface */
b38b0f
+    vnc_update_server_surface(vd);
b38b0f
+
b38b0f
     QTAILQ_FOREACH(vs, &vd->clients, next) {
b38b0f
         vnc_colordepth(vs);
b38b0f
         vnc_desktop_resize(vs);
b38b0f
-- 
b38b0f
1.8.3.1
b38b0f