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