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