Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/usermode optimize rfb updates by allowing queueing ...
details: https://anonhg.NetBSD.org/src/rev/579cdf1dc443
branches: trunk
changeset: 772330:579cdf1dc443
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Dec 30 09:36:01 2011 +0000
description:
optimize rfb updates by allowing queueing of multiple update messages,
dropping duplicates, and transmitting them in batches
diffstat:
sys/arch/usermode/include/thunk.h | 8 +-
sys/arch/usermode/usermode/thunk.c | 110 ++++++++++++++++++++++++------------
2 files changed, 78 insertions(+), 40 deletions(-)
diffs (192 lines):
diff -r 2d253bc15c13 -r 579cdf1dc443 sys/arch/usermode/include/thunk.h
--- a/sys/arch/usermode/include/thunk.h Fri Dec 30 09:31:44 2011 +0000
+++ b/sys/arch/usermode/include/thunk.h Fri Dec 30 09:36:01 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.h,v 1.47 2011/12/29 21:22:49 jmcneill Exp $ */
+/* $NetBSD: thunk.h,v 1.48 2011/12/30 09:36:01 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -191,10 +191,11 @@
} thunk_rfb_event_t;
typedef struct {
- bool pending;
uint16_t x, y, w, h;
} thunk_rfb_update_t;
+#define THUNK_RFB_QUEUELEN 128
+
typedef struct {
int sockfd;
int clientfd;
@@ -207,7 +208,8 @@
uint8_t depth;
char name[64];
uint8_t *framebuf;
- thunk_rfb_update_t update;
+ thunk_rfb_update_t update[THUNK_RFB_QUEUELEN];
+ unsigned int nupdates;
} thunk_rfb_t;
int thunk_rfb_open(thunk_rfb_t *, uint16_t);
diff -r 2d253bc15c13 -r 579cdf1dc443 sys/arch/usermode/usermode/thunk.c
--- a/sys/arch/usermode/usermode/thunk.c Fri Dec 30 09:31:44 2011 +0000
+++ b/sys/arch/usermode/usermode/thunk.c Fri Dec 30 09:36:01 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.c,v 1.56 2011/12/29 21:22:49 jmcneill Exp $ */
+/* $NetBSD: thunk.c,v 1.57 2011/12/30 09:36:02 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifdef __NetBSD__
-__RCSID("$NetBSD: thunk.c,v 1.56 2011/12/29 21:22:49 jmcneill Exp $");
+__RCSID("$NetBSD: thunk.c,v 1.57 2011/12/30 09:36:02 jmcneill Exp $");
#endif
#include <sys/types.h>
@@ -970,44 +970,68 @@
static void
thunk_rfb_send_pending(thunk_rfb_t *rfb)
{
+ thunk_rfb_update_t *update;
uint8_t rfb_update[16];
- uint8_t *p = rfb_update;
- uint16_t x, y, w, h;
+ uint8_t *p;
+ unsigned int n;
ssize_t len;
- if (rfb->connected == false || rfb->update.pending == false)
+ if (rfb->connected == false || rfb->nupdates == 0)
return;
- x = rfb->update.x;
- y = rfb->update.y;
- w = rfb->update.w;
- h = rfb->update.h;
- rfb->update.pending = false;
+ /* If we have too many updates queued, just send a single update */
+ if (rfb->nupdates >= __arraycount(rfb->update)) {
+ rfb->nupdates = 1;
+ rfb->update[0].x = 0;
+ rfb->update[0].y = 0;
+ rfb->update[0].w = rfb->width;
+ rfb->update[0].h = rfb->height;
+ }
+#ifdef RFB_DEBUG
+ fprintf(stdout, "rfb: sending %d updates\n", rfb->nupdates);
+#endif
+
+ p = rfb_update;
*(uint8_t *)p = 0; p += 1; /* FramebufferUpdate */
*(uint8_t *)p = 0; p += 1; /* padding */
- *(uint16_t *)p = htons(1); p += 2; /* # rects */
- *(uint16_t *)p = htons(x); p += 2;
- *(uint16_t *)p = htons(y); p += 2;
- *(uint16_t *)p = htons(w); p += 2;
- *(uint16_t *)p = htons(h); p += 2;
- *(uint32_t *)p = htonl(0); p += 4; /* Raw encoding */
+ *(uint16_t *)p = htons(rfb->nupdates); p += 2; /* # rects */
- len = send(rfb->clientfd, rfb_update, sizeof(rfb_update),
- MSG_NOSIGNAL);
+ len = send(rfb->clientfd, rfb_update, 4, MSG_NOSIGNAL);
if (len <= 0)
goto disco;
- p = rfb->framebuf + (y * rfb->width * (rfb->depth / 8)) +
- (x * (rfb->depth / 8));
- while (h-- > 0) {
- len = send(rfb->clientfd, p, w * (rfb->depth / 8),
- MSG_NOSIGNAL);
+ for (n = 0; n < rfb->nupdates; n++) {
+ p = rfb_update;
+ update = &rfb->update[n];
+ *(uint16_t *)p = htons(update->x); p += 2;
+ *(uint16_t *)p = htons(update->y); p += 2;
+ *(uint16_t *)p = htons(update->w); p += 2;
+ *(uint16_t *)p = htons(update->h); p += 2;
+ *(uint32_t *)p = htonl(0); p += 4; /* Raw enc */
+
+#ifdef RFB_DEBUG
+ fprintf(stdout, "rfb: [%u] x=%d y=%d w=%d h=%d\n",
+ n, update->x, update->y, update->w, update->h);
+#endif
+
+ len = send(rfb->clientfd, rfb_update, 12, MSG_NOSIGNAL);
if (len <= 0)
goto disco;
- p += rfb->width * (rfb->depth / 8);
+
+ p = rfb->framebuf + (update->y * rfb->width * (rfb->depth / 8))
+ + (update->x * (rfb->depth / 8));
+ while (update->h-- > 0) {
+ len = send(rfb->clientfd, p,
+ update->w * (rfb->depth / 8), MSG_NOSIGNAL);
+ if (len <= 0)
+ goto disco;
+ p += rfb->width * (rfb->depth / 8);
+ }
}
+ rfb->nupdates = 0;
+
return;
disco:
@@ -1059,6 +1083,7 @@
}
rfb->connected = true;
+ rfb->nupdates = 0;
thunk_rfb_update(rfb, 0, 0, rfb->width, rfb->height);
}
@@ -1124,18 +1149,29 @@
void
thunk_rfb_update(thunk_rfb_t *rfb, int x, int y, int w, int h)
{
- if (rfb->update.pending) {
- /* pending update, just redraw the whole screen */
- rfb->update.x = 0;
- rfb->update.y = 0;
- rfb->update.w = rfb->width;
- rfb->update.h = rfb->height;
- } else {
- /* try to only update the requested rectangle */
- rfb->update.x = x;
- rfb->update.y = y;
- rfb->update.w = w;
- rfb->update.h = h;
+ thunk_rfb_update_t *update = NULL;
+ unsigned int n;
+
+ /* if the queue is full, just return */
+ if (rfb->nupdates >= __arraycount(rfb->update))
+ return;
+
+ /* no sense in queueing duplicate updates */
+ for (n = 0; n < rfb->nupdates; n++) {
+ if (rfb->update[n].x == x && rfb->update[n].y == y &&
+ rfb->update[n].w == w && rfb->update[n].h == h)
+ return;
}
- rfb->update.pending = true;
+
+#ifdef RFB_DEBUG
+ fprintf(stdout, "rfb: queue slot %d, x=%d y=%d w=%d h=%d\n",
+ rfb->nupdates, x, y, w, h);
+#endif
+
+ /* add the update request to the queue */
+ update = &rfb->update[rfb->nupdates++];
+ update->x = x;
+ update->y = y;
+ update->w = w;
+ update->h = h;
}
Home |
Main Index |
Thread Index |
Old Index