aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkraxel <kraxel>2007-05-16 12:47:48 +0000
committerkraxel <kraxel>2007-05-16 12:47:48 +0000
commitd4f83cad7b67bd8d98e1e94d23fa3607e777e5ab (patch)
tree10ccf627e745352535b04c913de5411379fbc692
parent63f9c3be3b98a2c03af38185614cf9ccc1d960f8 (diff)
downloadxenwatch-d4f83cad7b67bd8d98e1e94d23fa3607e777e5ab.tar.gz
optimize/fix screen updates
-rw-r--r--vnc.c76
1 files changed, 64 insertions, 12 deletions
diff --git a/vnc.c b/vnc.c
index 10bfaf1..7f9c957 100644
--- a/vnc.c
+++ b/vnc.c
@@ -65,7 +65,8 @@ struct vnc_window {
int have_gl;
GLuint tex;
int tex_max;
- void *tex_data;
+ unsigned char *tex_data;
+ unsigned int dirty_y1, dirty_y2;
/* config */
int fullscreen;
@@ -175,7 +176,7 @@ static void gl_resize_window(struct vnc_window *vnc)
vnc->redraw++;
}
-static void gl_blit(struct vnc_window *vnc)
+static void gl_blit(struct vnc_window *vnc, int y1, int y2)
{
Window win = gdk_x11_drawable_get_xid(vnc->draw->window);
float x,y;
@@ -184,12 +185,18 @@ static void gl_blit(struct vnc_window *vnc)
if (!vnc->tex)
return;
+
+ if (y1 > vnc->vncdpy.h)
+ y1 = vnc->vncdpy.h;
+ if (y2 > vnc->vncdpy.h)
+ y2 = vnc->vncdpy.h;
+
glBindTexture(GL_TEXTURE_2D, vnc->tex);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0,0, vnc->vncdpy.w, vnc->vncdpy.h,
+ 0,y1, vnc->vncdpy.w, y2 - y1,
GL_BGRA_EXT /* GL_RGB */,
GL_UNSIGNED_BYTE,
- vnc->tex_data);
+ vnc->tex_data + y1 * 4 * vnc->vncdpy.w);
x = (float)vnc->vncdpy.w / vnc->texture.w;
y = (float)vnc->vncdpy.h / vnc->texture.h;
@@ -205,9 +212,34 @@ static void gl_blit(struct vnc_window *vnc)
glDisable(GL_TEXTURE_2D);
}
+static void gl_update_vnc(struct vnc_window *vnc,
+ int x, int y, int w, int h)
+{
+ if (vnc->dirty_y1 > y)
+ vnc->dirty_y1 = y;
+ if (vnc->dirty_y2 < y+h)
+ vnc->dirty_y2 = y+h;
+ vnc->updates++;
+}
+
+static void gl_update_win(struct vnc_window *vnc,
+ int x, int y, int w, int h)
+{
+ vnc->dirty_y1 = 0;
+ vnc->dirty_y2 = vnc->vncdpy.h;
+ vnc->updates++;
+}
+
static void gl_flush(struct vnc_window *vnc)
{
- gl_blit(vnc);
+ if (vnc->redraw) {
+ vnc->dirty_y1 = 0;
+ vnc->dirty_y2 = vnc->vncdpy.h;
+ }
+ gl_blit(vnc, vnc->dirty_y1, vnc->dirty_y2);
+
+ vnc->dirty_y1 = 99999;
+ vnc->dirty_y2 = 0;
vnc->updates = 0;
vnc->redraw = 0;
}
@@ -251,7 +283,8 @@ static void x11_update(struct vnc_window *vnc,
static void x11_flush(struct vnc_window *vnc)
{
- x11_update(vnc, 0, 0, vnc->vncdpy.w, vnc->vncdpy.w);
+ if (vnc->redraw)
+ x11_update(vnc, 0, 0, vnc->vncdpy.w, vnc->vncdpy.w);
vnc->updates = 0;
vnc->redraw = 0;
}
@@ -259,8 +292,9 @@ static void x11_flush(struct vnc_window *vnc)
/* ------------------------------------------------------------------ */
/* x11/gl wrappers */
-static void dpy_update(struct vnc_window *vnc,
- int x, int y, int w, int h)
+/* vnc display coordinates */
+static void dpy_update_vnc(struct vnc_window *vnc,
+ int x, int y, int w, int h)
{
if (vnc->debug)
fprintf(stderr, "%s: mode%s%s, %dx%d+%d+%d\n", __FUNCTION__,
@@ -270,7 +304,22 @@ static void dpy_update(struct vnc_window *vnc,
if (vnc->ximage)
x11_update(vnc, x, y, w, h);
if (vnc->tex)
- vnc->updates++;
+ gl_update_vnc(vnc, x, y, w, h);
+}
+
+/* app window coordinates */
+static void dpy_update_win(struct vnc_window *vnc,
+ int x, int y, int w, int h)
+{
+ if (vnc->debug)
+ fprintf(stderr, "%s: mode%s%s, %dx%d+%d+%d\n", __FUNCTION__,
+ vnc->tex ? " GL" : "",
+ vnc->ximage ? " X11" : "",
+ w, h, x, y);
+ if (vnc->ximage)
+ x11_update(vnc, x, y, w, h);
+ if (vnc->tex)
+ gl_update_win(vnc, x, y, w, h);
}
static void dpy_redraw(struct vnc_window *vnc)
@@ -557,7 +606,7 @@ static void vnc_update(rfbClient* cl, int x, int y, int w, int h)
if (!GTK_WIDGET_DRAWABLE(vnc->draw))
return;
- dpy_update(vnc, x,y, w,h);
+ dpy_update_vnc(vnc, x,y, w,h);
}
#ifdef HAVE_VNC_TEXT
@@ -676,8 +725,8 @@ static gboolean expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer dat
{
struct vnc_window *vnc = data;
- dpy_update(vnc, event->area.x, event->area.y,
- event->area.width, event->area.height);
+ dpy_update_win(vnc, event->area.x, event->area.y,
+ event->area.width, event->area.height);
if (0 == event->count)
dpy_flush(vnc, __FUNCTION__);
return TRUE;
@@ -944,8 +993,11 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags,
vnc->viewonly = (flags & VNC_FLAG_VIEW_ONLY);
vnc->debug = debug_level;
debug_libvnc = debug_level;
+
snprintf(vnc->display, sizeof(vnc->display),
"%s:%d", hostname, tcpport - 5900);
+ vnc->dirty_y1 = 99999;
+ vnc->dirty_y2 = 0;
/* x11 */
vnc->dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default());