Blame 0218-spice-send-updates-only-for-changed-screen-content.patch

Hans de Goede 93b7e3
From e503ba260e585c9ee56f44ae5b8da51643776369 Mon Sep 17 00:00:00 2001
Hans de Goede 93b7e3
From: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede 93b7e3
Date: Wed, 5 Sep 2012 10:41:42 +0200
Hans de Goede 93b7e3
Subject: [PATCH 218/293] spice: send updates only for changed screen content
Hans de Goede 93b7e3
Hans de Goede 93b7e3
when creating screen updates go compare the current guest screen
Hans de Goede 93b7e3
against the mirror (which holds the most recent update sent), then
Hans de Goede 93b7e3
only create updates for the screen areas which did actually change.
Hans de Goede 93b7e3
Hans de Goede 93b7e3
[ v2: drop redundant qemu_spice_create_one_update call ]
Hans de Goede 93b7e3
Hans de Goede 93b7e3
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede 93b7e3
---
Hans de Goede 93b7e3
 ui/spice-display.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
Hans de Goede 93b7e3
 1 file changed, 55 insertions(+), 1 deletion(-)
Hans de Goede 93b7e3
Hans de Goede 93b7e3
diff --git a/ui/spice-display.c b/ui/spice-display.c
Hans de Goede 93b7e3
index 973cd53..d062765 100644
Hans de Goede 93b7e3
--- a/ui/spice-display.c
Hans de Goede 93b7e3
+++ b/ui/spice-display.c
Hans de Goede 93b7e3
@@ -239,6 +239,13 @@ static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
 static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
Hans de Goede 93b7e3
 {
Hans de Goede 93b7e3
+    static const int blksize = 32;
Hans de Goede 93b7e3
+    int blocks = (ds_get_width(ssd->ds) + blksize - 1) / blksize;
Hans de Goede 93b7e3
+    int dirty_top[blocks];
Hans de Goede 93b7e3
+    int y, yoff, x, xoff, blk, bw;
Hans de Goede 93b7e3
+    int bpp = ds_get_bytes_per_pixel(ssd->ds);
Hans de Goede 93b7e3
+    uint8_t *guest, *mirror;
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
     if (qemu_spice_rect_is_empty(&ssd->dirty)) {
Hans de Goede 93b7e3
         return;
Hans de Goede 93b7e3
     };
Hans de Goede 93b7e3
@@ -253,7 +260,54 @@ static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
Hans de Goede 93b7e3
         ssd->ds_mirror = g_malloc0(size);
Hans de Goede 93b7e3
     }
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
-    qemu_spice_create_one_update(ssd, &ssd->dirty);
Hans de Goede 93b7e3
+    for (blk = 0; blk < blocks; blk++) {
Hans de Goede 93b7e3
+        dirty_top[blk] = -1;
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+    guest = ds_get_data(ssd->ds);
Hans de Goede 93b7e3
+    mirror = ssd->ds_mirror;
Hans de Goede 93b7e3
+    for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
Hans de Goede 93b7e3
+        yoff = y * ds_get_linesize(ssd->ds);
Hans de Goede 93b7e3
+        for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
Hans de Goede 93b7e3
+            xoff = x * bpp;
Hans de Goede 93b7e3
+            blk = x / blksize;
Hans de Goede 93b7e3
+            bw = MIN(blksize, ssd->dirty.right - x);
Hans de Goede 93b7e3
+            if (memcmp(guest + yoff + xoff,
Hans de Goede 93b7e3
+                       mirror + yoff + xoff,
Hans de Goede 93b7e3
+                       bw * bpp) == 0) {
Hans de Goede 93b7e3
+                if (dirty_top[blk] != -1) {
Hans de Goede 93b7e3
+                    QXLRect update = {
Hans de Goede 93b7e3
+                        .top    = dirty_top[blk],
Hans de Goede 93b7e3
+                        .bottom = y,
Hans de Goede 93b7e3
+                        .left   = x,
Hans de Goede 93b7e3
+                        .right  = x + bw,
Hans de Goede 93b7e3
+                    };
Hans de Goede 93b7e3
+                    qemu_spice_create_one_update(ssd, &update);
Hans de Goede 93b7e3
+                    dirty_top[blk] = -1;
Hans de Goede 93b7e3
+                }
Hans de Goede 93b7e3
+            } else {
Hans de Goede 93b7e3
+                if (dirty_top[blk] == -1) {
Hans de Goede 93b7e3
+                    dirty_top[blk] = y;
Hans de Goede 93b7e3
+                }
Hans de Goede 93b7e3
+            }
Hans de Goede 93b7e3
+        }
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
+    for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
Hans de Goede 93b7e3
+        blk = x / blksize;
Hans de Goede 93b7e3
+        bw = MIN(blksize, ssd->dirty.right - x);
Hans de Goede 93b7e3
+        if (dirty_top[blk] != -1) {
Hans de Goede 93b7e3
+            QXLRect update = {
Hans de Goede 93b7e3
+                .top    = dirty_top[blk],
Hans de Goede 93b7e3
+                .bottom = ssd->dirty.bottom,
Hans de Goede 93b7e3
+                .left   = x,
Hans de Goede 93b7e3
+                .right  = x + bw,
Hans de Goede 93b7e3
+            };
Hans de Goede 93b7e3
+            qemu_spice_create_one_update(ssd, &update);
Hans de Goede 93b7e3
+            dirty_top[blk] = -1;
Hans de Goede 93b7e3
+        }
Hans de Goede 93b7e3
+    }
Hans de Goede 93b7e3
+
Hans de Goede 93b7e3
     memset(&ssd->dirty, 0, sizeof(ssd->dirty));
Hans de Goede 93b7e3
 }
Hans de Goede 93b7e3
 
Hans de Goede 93b7e3
-- 
Hans de Goede 93b7e3
1.7.12
Hans de Goede 93b7e3