[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 03/15] vnc: refresh lossy rect after a given timeout
From: |
Corentin Chary |
Subject: |
[Qemu-devel] [PATCH 03/15] vnc: refresh lossy rect after a given timeout |
Date: |
Wed, 11 Aug 2010 07:49:33 +0200 |
If an adaptive encoding has choosen to send a lossy update
based on the result of vnc_update_freq(), then it should advertise
it with vnc_sent_lossy_rect(). This will allow to automatically refresh
this rect once it's static again.
Signed-off-by: Corentin Chary <address@hidden>
---
ui/vnc-jobs-async.c | 2 +
ui/vnc.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++---
ui/vnc.h | 3 ++
3 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c
index 6e9cf08..31f8436 100644
--- a/ui/vnc-jobs-async.c
+++ b/ui/vnc-jobs-async.c
@@ -166,6 +166,7 @@ static void vnc_async_encoding_start(VncState *orig,
VncState *local)
local->features = orig->features;
local->ds = orig->ds;
local->vd = orig->vd;
+ local->lossy_rect = orig->lossy_rect;
local->write_pixels = orig->write_pixels;
local->clientds = orig->clientds;
local->tight = orig->tight;
@@ -182,6 +183,7 @@ static void vnc_async_encoding_end(VncState *orig, VncState
*local)
orig->tight = local->tight;
orig->zlib = local->zlib;
orig->hextile = local->hextile;
+ orig->lossy_rect = local->lossy_rect;
}
static int vnc_worker_thread_loop(VncJobQueue *queue)
diff --git a/ui/vnc.c b/ui/vnc.c
index 5c3a760..f7a43e5 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1010,6 +1010,8 @@ static void vnc_disconnect_start(VncState *vs)
static void vnc_disconnect_finish(VncState *vs)
{
+ int i;
+
vnc_jobs_join(vs); /* Wait encoding jobs */
vnc_lock_output(vs);
@@ -1046,7 +1048,11 @@ static void vnc_disconnect_finish(VncState *vs)
#ifdef CONFIG_VNC_THREAD
qemu_mutex_destroy(&vs->output_mutex);
#endif
- qemu_free(vs);
+ for (i = 0; i < VNC_STAT_ROWS; ++i) {
+ qemu_free(vs->lossy_rect[i]);
+ }
+ qemu_free(vs->lossy_rect);
+ qemu_free(vs);
}
int vnc_client_io_error(VncState *vs, int ret, int last_errno)
@@ -2262,10 +2268,55 @@ static VncRectStat *vnc_stat_rect(VncDisplay *vd, int
x, int y)
return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
}
-static void vnc_update_stats(VncDisplay *vd, struct timeval * tv)
+void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
+{
+ int i, j;
+
+ w = (x + w) / VNC_STAT_RECT;
+ h = (y + h) / VNC_STAT_RECT;
+ x /= VNC_STAT_RECT;
+ y /= VNC_STAT_RECT;
+
+ for (j = y; j <= y + h; j++) {
+ for (i = x; i <= x + w; i++) {
+ vs->lossy_rect[j][i] = 1;
+ }
+ }
+}
+
+static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
+{
+ VncState *vs;
+ int sty = y / VNC_STAT_RECT;
+ int stx = x / VNC_STAT_RECT;
+ int has_dirty = 0;
+
+ y = y / VNC_STAT_RECT * VNC_STAT_RECT;
+ x = x / VNC_STAT_RECT * VNC_STAT_RECT;
+
+ QTAILQ_FOREACH(vs, &vd->clients, next) {
+ int j ;
+
+ /* kernel send buffers are full -> refresh later */
+ if (vs->output.offset)
+ continue ;
+
+ if (!vs->lossy_rect[sty][stx])
+ continue ;
+ vs->lossy_rect[sty][stx] = 0;
+ for (j = 0; j < VNC_STAT_RECT; ++j) {
+ vnc_set_bits(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16);
+ }
+ has_dirty++;
+ }
+ return has_dirty;
+}
+
+static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
{
int x, y;
struct timeval res;
+ int has_dirty = 0;
for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
@@ -2278,7 +2329,7 @@ static void vnc_update_stats(VncDisplay *vd, struct
timeval * tv)
timersub(tv, &VNC_REFRESH_STATS, &res);
if (timercmp(&vd->guest.last_freq_check, &res, >)) {
- return ;
+ return has_dirty;
}
vd->guest.last_freq_check = *tv;
@@ -2297,6 +2348,7 @@ static void vnc_update_stats(VncDisplay *vd, struct
timeval * tv)
if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
rect->freq = 0;
+ has_dirty += vnc_refresh_lossy_rect(vd, x, y);
memset(rect->times, 0, sizeof (rect->times));
continue ;
}
@@ -2310,6 +2362,7 @@ static void vnc_update_stats(VncDisplay *vd, struct
timeval * tv)
rect->freq = 1. / rect->freq;
}
}
+ return has_dirty;
}
double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
@@ -2361,7 +2414,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
struct timeval tv;
gettimeofday(&tv, NULL);
- vnc_update_stats(vd, &tv);
+ has_dirty = vnc_update_stats(vd, &tv);
/*
* Walk through the guest dirty map.
@@ -2463,7 +2516,13 @@ static void vnc_remove_timer(VncDisplay *vd)
static void vnc_connect(VncDisplay *vd, int csock)
{
VncState *vs = qemu_mallocz(sizeof(VncState));
+ int i;
+
vs->csock = csock;
+ vs->lossy_rect = qemu_mallocz(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
+ for (i = 0; i < VNC_STAT_ROWS; ++i) {
+ vs->lossy_rect[i] = qemu_mallocz(VNC_STAT_COLS * sizeof (uint8_t));
+ }
VNC_DEBUG("New client on socket %d\n", csock);
dcl->idle = 0;
diff --git a/ui/vnc.h b/ui/vnc.h
index f10fa3c..00bd21c 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -216,6 +216,8 @@ struct VncState
DisplayState *ds;
uint32_t dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
+ uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
+ * vnc-jobs-async.c */
VncDisplay *vd;
int need_update;
@@ -497,6 +499,7 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int
w, int h,
void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v);
double vnc_update_freq(VncState *vs, int x, int y, int w, int h);
+void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h);
/* Encodings */
int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
--
1.7.1
- [Qemu-devel] [PATCH 00/15] vnc: adapative tight, zrle, zywrle, and bitmap module, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 01/15] vnc: don't set the quality if lossy encoding are disabled, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 02/15] vnc: add a way to get the update frequency for a given region, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 03/15] vnc: refresh lossy rect after a given timeout,
Corentin Chary <=
- [Qemu-devel] [PATCH 04/15] vnc: tight: use the update frequency to choose between lossy and lossless, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 05/15] vnc: palette: use a pool to reduce memory allocations, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 06/15] vnc: palette: add palette_init calls, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 07/15] vnc: palette: and fill and color calls., Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 09/15] vnc: fix uint8_t comparisons with negative values, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 08/15] vnc: Add ZRLE and ZYWRLE encodings., Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 10/15] vnc: fix lossy rect refreshing, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 11/15] bitmap: add a generic bitmap and bitops library, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 12/15] vnc: use the new generic bitmap functions, Corentin Chary, 2010/08/11
- [Qemu-devel] [PATCH 13/15] vnc: don't try to send bigger updates that client height, Corentin Chary, 2010/08/11