# HG changeset patch
# User Christian Limpach <Christian.Limpach@xxxxxxxxxxxxx>
# Node ID 7706696ff53203c1c42e39b44f4755f8cc1989fd
# Parent 317e8516d464a47d3aa0eba6f01e14448df8159a
[qemu patches] Update patches for changeset 11562:449dcaff2551.
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxxx>
---
tools/ioemu/patches/series | 1
tools/ioemu/patches/vnc-backoff-screen-scan | 227 ++++++++++++++++++++++++++++
tools/ioemu/patches/vnc-start-vncviewer | 9 -
3 files changed, 232 insertions(+), 5 deletions(-)
diff -r 317e8516d464 -r 7706696ff532 tools/ioemu/patches/series
--- a/tools/ioemu/patches/series Thu Sep 21 19:28:35 2006 +0100
+++ b/tools/ioemu/patches/series Thu Sep 21 19:33:07 2006 +0100
@@ -36,6 +36,7 @@ vnc-title-domain-name
vnc-title-domain-name
vnc-access-monitor-vt
vnc-display-find-unused
+vnc-backoff-screen-scan
xenstore-block-device-config
xenstore-write-vnc-port
qemu-allow-disable-sdl
diff -r 317e8516d464 -r 7706696ff532 tools/ioemu/patches/vnc-start-vncviewer
--- a/tools/ioemu/patches/vnc-start-vncviewer Thu Sep 21 19:28:35 2006 +0100
+++ b/tools/ioemu/patches/vnc-start-vncviewer Thu Sep 21 19:33:07 2006 +0100
@@ -1,8 +1,8 @@ Index: ioemu/vnc.c
Index: ioemu/vnc.c
===================================================================
---- ioemu.orig/vnc.c 2006-09-21 19:10:45.000000000 +0100
-+++ ioemu/vnc.c 2006-09-21 19:10:53.000000000 +0100
-@@ -1173,3 +1173,25 @@
+--- ioemu.orig/vnc.c 2006-09-21 19:26:38.000000000 +0100
++++ ioemu/vnc.c 2006-09-21 19:29:58.000000000 +0100
+@@ -1174,3 +1174,25 @@
vnc_dpy_resize(vs->ds, 640, 400);
}
@@ -20,7 +20,7 @@ Index: ioemu/vnc.c
+ exit(1);
+
+ case 0: /* child */
-+ execlp("vncviewer", "vncviewer", s, 0);
++ execlp("vncviewer", "vncviewer", s, NULL);
+ fprintf(stderr, "vncviewer execlp failed\n");
+ exit(1);
+
@@ -30,8 +30,8 @@ Index: ioemu/vnc.c
+}
Index: ioemu/vl.c
===================================================================
---- ioemu.orig/vl.c 2006-09-21 19:08:38.000000000 +0100
-+++ ioemu/vl.c 2006-09-21 19:10:53.000000000 +0100
+--- ioemu.orig/vl.c 2006-09-21 19:26:24.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:29:50.000000000 +0100
@@ -120,6 +120,7 @@
int bios_size;
static DisplayState display_state;
@@ -93,8 +93,8 @@ Index: ioemu/vl.c
sdl_display_init(ds, full_screen);
Index: ioemu/vl.h
===================================================================
---- ioemu.orig/vl.h 2006-09-21 19:08:38.000000000 +0100
-+++ ioemu/vl.h 2006-09-21 19:10:53.000000000 +0100
+--- ioemu.orig/vl.h 2006-09-21 19:26:24.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:29:50.000000000 +0100
@@ -786,6 +786,7 @@
/* vnc.c */
diff -r 317e8516d464 -r 7706696ff532 tools/ioemu/patches/vnc-backoff-screen-scan
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/patches/vnc-backoff-screen-scan Thu Sep 21 19:33:07
2006 +0100
@@ -0,0 +1,381 @@
+Index: ioemu/vnc.c
+===================================================================
+--- ioemu.orig/vnc.c 2006-09-21 19:31:03.000000000 +0100
++++ ioemu/vnc.c 2006-09-21 19:32:23.000000000 +0100
+@@ -27,7 +27,19 @@
+ #include "vl.h"
+ #include "qemu_socket.h"
+
+-#define VNC_REFRESH_INTERVAL (1000 / 30)
++/* The refresh interval starts at BASE. If we scan the buffer and
++ find no change, we increase by INC, up to MAX. If the mouse moves
++ or we get a keypress, the interval is set back to BASE. If we find
++ an update, halve the interval.
++
++ All times in milliseconds. */
++#define VNC_REFRESH_INTERVAL_BASE 30
++#define VNC_REFRESH_INTERVAL_INC 50
++#define VNC_REFRESH_INTERVAL_MAX 2000
++
++/* Wait at most one second between updates, so that we can detect a
++ minimised vncviewer reasonably quickly. */
++#define VNC_MAX_UPDATE_INTERVAL 5000
+
+ #include "vnc_keysym.h"
+ #include "keymaps.c"
+@@ -64,10 +76,11 @@
+ struct VncState
+ {
+ QEMUTimer *timer;
++ int timer_interval;
++ int64_t last_update_time;
+ int lsock;
+ int csock;
+ DisplayState *ds;
+- int need_update;
+ int width;
+ int height;
+ uint64_t *dirty_row; /* screen regions which are possibly dirty */
+@@ -98,8 +111,6 @@
+ int visible_w;
+ int visible_h;
+
+- int slow_client;
+-
+ int ctl_keys; /* Ctrl+Alt starts calibration */
+ };
+
+@@ -380,7 +391,7 @@
+ int y = 0;
+ int pitch = ds->linesize;
+ VncState *vs = ds->opaque;
+- int updating_client = !vs->slow_client;
++ int updating_client = 1;
+
+ if (src_x < vs->visible_x || src_y < vs->visible_y ||
+ dst_x < vs->visible_x || dst_y < vs->visible_y ||
+@@ -390,11 +401,6 @@
+ (dst_y + h) > (vs->visible_y + vs->visible_h))
+ updating_client = 0;
+
+- if (updating_client) {
+- vs->need_update = 1;
+- _vnc_update_client(vs);
+- }
+-
+ if (dst_y > src_y) {
+ y = h - 1;
+ pitch = -pitch;
+@@ -445,110 +451,145 @@
+ static void _vnc_update_client(void *opaque)
+ {
+ VncState *vs = opaque;
+- int64_t now = qemu_get_clock(rt_clock);
+-
+- if (vs->need_update && vs->csock != -1) {
+- int y;
+- char *row;
+- char *old_row;
+- uint64_t width_mask;
+- int n_rectangles;
+- int saved_offset;
+- int maxx, maxy;
+- int tile_bytes = vs->depth * DP2X(vs, 1);
++ int64_t now;
++ int y;
++ char *row;
++ char *old_row;
++ uint64_t width_mask;
++ int n_rectangles;
++ int saved_offset;
++ int maxx, maxy;
++ int tile_bytes = vs->depth * DP2X(vs, 1);
+
+- qemu_mod_timer(vs->timer, now + VNC_REFRESH_INTERVAL);
++ if (vs->csock == -1)
++ return;
+
+- if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
+- width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
+- else
+- width_mask = ~(0ULL);
++ now = qemu_get_clock(rt_clock);
+
+- /* Walk through the dirty map and eliminate tiles that
+- really aren't dirty */
+- row = vs->ds->data;
+- old_row = vs->old_data;
+-
+- for (y = 0; y < vs->ds->height; y++) {
+- if (vs->dirty_row[y] & width_mask) {
+- int x;
+- char *ptr, *old_ptr;
+-
+- ptr = row;
+- old_ptr = old_row;
+-
+- for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
+- if (vs->dirty_row[y] & (1ULL << x)) {
+- if (memcmp(old_ptr, ptr, tile_bytes)) {
+- vs->has_update = 1;
+- vs->update_row[y] |= (1ULL << x);
+- memcpy(old_ptr, ptr, tile_bytes);
+- }
+- vs->dirty_row[y] &= ~(1ULL << x);
+- }
++ if (vs->width != DP2X(vs, DIRTY_PIXEL_BITS))
++ width_mask = (1ULL << X2DP_UP(vs, vs->ds->width)) - 1;
++ else
++ width_mask = ~(0ULL);
+
+- ptr += tile_bytes;
+- old_ptr += tile_bytes;
+- }
+- }
++ /* Walk through the dirty map and eliminate tiles that really
++ aren't dirty */
++ row = vs->ds->data;
++ old_row = vs->old_data;
+
+- row += vs->ds->linesize;
+- old_row += vs->ds->linesize;
+- }
++ for (y = 0; y < vs->ds->height; y++) {
++ if (vs->dirty_row[y] & width_mask) {
++ int x;
++ char *ptr, *old_ptr;
+
+- if (!vs->has_update || vs->visible_y >= vs->ds->height ||
+- vs->visible_x >= vs->ds->width)
+- return;
++ ptr = row;
++ old_ptr = old_row;
+
+- /* Count rectangles */
+- n_rectangles = 0;
+- vnc_write_u8(vs, 0); /* msg id */
+- vnc_write_u8(vs, 0);
+- saved_offset = vs->output.offset;
+- vnc_write_u16(vs, 0);
++ for (x = 0; x < X2DP_UP(vs, vs->ds->width); x++) {
++ if (vs->dirty_row[y] & (1ULL << x)) {
++ if (memcmp(old_ptr, ptr, tile_bytes)) {
++ vs->has_update = 1;
++ vs->update_row[y] |= (1ULL << x);
++ memcpy(old_ptr, ptr, tile_bytes);
++ }
++ vs->dirty_row[y] &= ~(1ULL << x);
++ }
+
+- maxy = vs->visible_y + vs->visible_h;
+- if (maxy > vs->ds->height)
+- maxy = vs->ds->height;
+- maxx = vs->visible_x + vs->visible_w;
+- if (maxx > vs->ds->width)
+- maxx = vs->ds->width;
++ ptr += tile_bytes;
++ old_ptr += tile_bytes;
++ }
++ }
++
++ row += vs->ds->linesize;
++ old_row += vs->ds->linesize;
++ }
+
+- for (y = vs->visible_y; y < maxy; y++) {
+- int x;
+- int last_x = -1;
+- for (x = X2DP_DOWN(vs, vs->visible_x);
+- x < X2DP_UP(vs, maxx); x++) {
+- if (vs->update_row[y] & (1ULL << x)) {
+- if (last_x == -1)
+- last_x = x;
+- vs->update_row[y] &= ~(1ULL << x);
+- } else {
+- if (last_x != -1) {
+- int h = find_update_height(vs, y, maxy, last_x, x);
++ if (!vs->has_update || vs->visible_y >= vs->ds->height ||
++ vs->visible_x >= vs->ds->width)
++ goto backoff;
++
++ /* Count rectangles */
++ n_rectangles = 0;
++ vnc_write_u8(vs, 0); /* msg id */
++ vnc_write_u8(vs, 0);
++ saved_offset = vs->output.offset;
++ vnc_write_u16(vs, 0);
++
++ maxy = vs->visible_y + vs->visible_h;
++ if (maxy > vs->ds->height)
++ maxy = vs->ds->height;
++ maxx = vs->visible_x + vs->visible_w;
++ if (maxx > vs->ds->width)
++ maxx = vs->ds->width;
++
++ for (y = vs->visible_y; y < maxy; y++) {
++ int x;
++ int last_x = -1;
++ for (x = X2DP_DOWN(vs, vs->visible_x);
++ x < X2DP_UP(vs, maxx); x++) {
++ if (vs->update_row[y] & (1ULL << x)) {
++ if (last_x == -1)
++ last_x = x;
++ vs->update_row[y] &= ~(1ULL << x);
++ } else {
++ if (last_x != -1) {
++ int h = find_update_height(vs, y, maxy, last_x, x);
++ if (h != 0) {
+ send_framebuffer_update(vs, DP2X(vs, last_x), y,
+ DP2X(vs, (x - last_x)), h);
+ n_rectangles++;
+ }
+- last_x = -1;
+ }
++ last_x = -1;
+ }
+- if (last_x != -1) {
+- int h = find_update_height(vs, y, maxy, last_x, x);
++ }
++ if (last_x != -1) {
++ int h = find_update_height(vs, y, maxy, last_x, x);
++ if (h != 0) {
+ send_framebuffer_update(vs, DP2X(vs, last_x), y,
+ DP2X(vs, (x - last_x)), h);
+ n_rectangles++;
+ }
+ }
+- vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
+- vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
++ }
++ vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
++ vs->output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
+
+- vs->has_update = 0;
+- vs->need_update = 0;
+- vnc_flush(vs);
+- vs->slow_client = 0;
+- } else
+- vs->slow_client = 1;
++ if (n_rectangles == 0)
++ goto backoff;
++
++ vs->has_update = 0;
++ vnc_flush(vs);
++ vs->last_update_time = now;
++
++ vs->timer_interval /= 2;
++ if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE)
++ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
++
++ return;
++
++ backoff:
++ /* No update -> back off a bit */
++ vs->timer_interval += VNC_REFRESH_INTERVAL_INC;
++ if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) {
++ vs->timer_interval = VNC_REFRESH_INTERVAL_MAX;
++ if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) {
++ /* Send a null update. If the client is no longer
++ interested (e.g. minimised) it'll ignore this, and we
++ can stop scanning the buffer until it sends another
++ update request. */
++ /* Note that there are bugs in xvncviewer which prevent
++ this from actually working. Leave the code in place
++ for correct clients. */
++ vnc_write_u8(vs, 0);
++ vnc_write_u8(vs, 0);
++ vnc_write_u16(vs, 0);
++ vnc_flush(vs);
++ vs->last_update_time = now;
++ return;
++ }
++ }
++ qemu_mod_timer(vs->timer, now + vs->timer_interval);
++ return;
+ }
+
+ static void vnc_update_client(void *opaque)
+@@ -561,8 +602,10 @@
+
+ static void vnc_timer_init(VncState *vs)
+ {
+- if (vs->timer == NULL)
++ if (vs->timer == NULL) {
+ vs->timer = qemu_new_timer(rt_clock, vnc_update_client, vs);
++ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
++ }
+ }
+
+ static void vnc_dpy_refresh(DisplayState *ds)
+@@ -622,7 +665,6 @@
+ vs->csock = -1;
+ buffer_reset(&vs->input);
+ buffer_reset(&vs->output);
+- vs->need_update = 0;
+ return 0;
+ }
+ return ret;
+@@ -892,7 +934,6 @@
+ int x_position, int y_position,
+ int w, int h)
+ {
+- vs->need_update = 1;
+ if (!incremental)
+ framebuffer_set_updated(vs, x_position, y_position, w, h);
+ vs->visible_x = x_position;
+@@ -1015,6 +1056,7 @@
+ {
+ int i;
+ uint16_t limit;
++ int64_t now;
+
+ switch (data[0]) {
+ case 0:
+@@ -1054,12 +1096,18 @@
+ if (len == 1)
+ return 8;
+
++ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
++ qemu_advance_timer(vs->timer,
++ qemu_get_clock(rt_clock) + vs->timer_interval);
+ key_event(vs, read_u8(data, 1), read_u32(data, 4));
+ break;
+ case 5:
+ if (len == 1)
+ return 6;
+
++ vs->timer_interval = VNC_REFRESH_INTERVAL_BASE;
++ qemu_advance_timer(vs->timer,
++ qemu_get_clock(rt_clock) + vs->timer_interval);
+ pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data,
4));
+ break;
+ case 6:
+Index: ioemu/vl.c
+===================================================================
+--- ioemu.orig/vl.c 2006-09-21 19:31:03.000000000 +0100
++++ ioemu/vl.c 2006-09-21 19:32:23.000000000 +0100
+@@ -725,6 +725,12 @@
+ }
+ }
+
++void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time)
++{
++ if (ts->expire_time > expire_time)
++ qemu_mod_timer(ts, expire_time);
++}
++
+ /* modify the current timer so that it will be fired when current_time
+ >= expire_time. The corresponding callback will be called. */
+ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
+Index: ioemu/vl.h
+===================================================================
+--- ioemu.orig/vl.h 2006-09-21 19:31:03.000000000 +0100
++++ ioemu/vl.h 2006-09-21 19:32:23.000000000 +0100
+@@ -405,6 +405,7 @@
+ void qemu_free_timer(QEMUTimer *ts);
+ void qemu_del_timer(QEMUTimer *ts);
+ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
++void qemu_advance_timer(QEMUTimer *ts, int64_t expire_time);
+ int qemu_timer_pending(QEMUTimer *ts);
+
+ extern int64_t ticks_per_sec;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|