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