From 9e1f2cf5e938cc3d3d9205d3d03b28bce7dd852b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 16 Mar 2008 00:13:07 -0400 Subject: [PATCH] split the round trip to fetch a window's region up so that the request can be sent much earlier than we need the reply --- glxrender.c | 72 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/glxrender.c b/glxrender.c index e0c1cce..6077ccf 100644 --- a/glxrender.c +++ b/glxrender.c @@ -57,6 +57,9 @@ typedef struct { GLfloat *texcoords; GLint *vertices; int nrects; + + xcb_xfixes_fetch_region_cookie_t ck_region; + int waiting_region; } window_data_t; static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d); @@ -70,9 +73,11 @@ static void paint_shadow(data_t *d, window_data_t *wd, int x, int y, GLfloat z); static void glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd); +static void glxrender_fetch_window_region(d_window_t *w, window_data_t *wd); static void glxrender_update_window_region(d_window_t *w, window_data_t *wd); static void glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd); +static void glxrender_free_window_region(window_data_t *wd); static void glxrender_free_root_pixmap(d_screen_t *sc, data_t *d); static void glxrender_update_root_pixmap(d_screen_t *sc, data_t *d); @@ -272,6 +277,7 @@ void glxrender_window_free_data(d_window_t *w, data_t *d, window_data_t *wd) { glxrender_free_window_pixmap(w, d, wd); + glxrender_free_window_region(wd); glDeleteTextures(1, &wd->texname); free(wd); } @@ -294,11 +300,14 @@ glxrender_window_show(d_window_t *w) wd = malloc(sizeof(window_data_t)); glGenTextures(1, &wd->texname); wd->glpixmap = XCB_NONE; + wd->texcoords = NULL; + wd->vertices = NULL; wd->nrects = 0; + wd->waiting_region = FALSE; window_add_plugin_data(w, plugin_id, wd); - glxrender_update_window_pixmap(w, d, wd); + glxrender_fetch_window_region(w, wd); } static void @@ -333,9 +342,16 @@ glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd) wd->glpixmap = XCB_NONE; } +} + +static void +glxrender_free_window_region(window_data_t *wd) +{ if (wd->nrects) { free(wd->texcoords); free(wd->vertices); + wd->texcoords = NULL; + wd->vertices = NULL; wd->nrects = 0; } } @@ -403,17 +419,26 @@ glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd) glxrender_update_window_region(w, wd); } +static void +glxrender_fetch_window_region(d_window_t *w, window_data_t *wd) +{ + if (wd->waiting_region) return; + + wd->ck_region = + xcb_xfixes_fetch_region_unchecked(w->sc->dpy->conn, + window_get_region(w)); + wd->waiting_region = TRUE; + xcb_flush(w->sc->dpy->conn); +} + static void glxrender_update_window_region(d_window_t *w, window_data_t *wd) { - xcb_xfixes_region_t reg; - xcb_xfixes_fetch_region_cookie_t ck; xcb_xfixes_fetch_region_reply_t *rep; xcb_rectangle_t area, *rects; - int nrects, i, x, y, wid, hei, bwid; + int nrects, i, j, x, y, wid, hei, bwid; - reg = window_get_region(w); - ck = xcb_xfixes_fetch_region_unchecked(w->sc->dpy->conn, reg); + if (!wd->waiting_region) return; window_get_area(w, &x, &y, &wid, &hei, &bwid); area.x = x; @@ -421,7 +446,7 @@ glxrender_update_window_region(d_window_t *w, window_data_t *wd) area.width = wid + bwid * 2; area.height = hei + bwid * 2; - rep = xcb_xfixes_fetch_region_reply(w->sc->dpy->conn, ck, NULL); + rep = xcb_xfixes_fetch_region_reply(w->sc->dpy->conn, wd->ck_region, NULL); if (!rep) { rects = &area; nrects = 1; @@ -431,30 +456,33 @@ glxrender_update_window_region(d_window_t *w, window_data_t *wd) nrects = xcb_xfixes_fetch_region_rectangles_length(rep); } - wd->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * (nrects * 4)); - wd->vertices = (GLint*)malloc(sizeof(GLint) * (nrects * 4)); + wd->texcoords = (GLfloat*)realloc(wd->texcoords, + sizeof(GLfloat) * (nrects * 4)); + wd->vertices = (GLint*)realloc(wd->vertices, sizeof(GLint) * (nrects * 4)); wd->nrects = nrects; - for (i = 0; i < nrects * 4; i += 4) { + for (i = j = 0; i < nrects * 4; ++j, i += 4) { wd->texcoords[i+LEFT] = - (GLfloat)(rects[i].x - area.x) / (GLfloat)area.width; + (GLfloat)(rects[j].x - x) / (GLfloat)area.width; wd->texcoords[i+TOP] = - (GLfloat)(rects[i].y - area.y) / (GLfloat)area.height; + (GLfloat)(rects[j].y - y) / (GLfloat)area.height; wd->texcoords[i+RIGHT] = - (GLfloat)(rects[i].x - area.x + rects[i].width) / + (GLfloat)(rects[j].x - x + rects[j].width) / (GLfloat)area.width; wd->texcoords[i+BOTTOM] = - (GLfloat)(rects[i].y - area.y + rects[i].height) / + (GLfloat)(rects[j].y - y + rects[j].height) / (GLfloat)area.height; - wd->vertices[i+LEFT] = rects[i].x - x; - wd->vertices[i+TOP] = rects[i].y - y; - wd->vertices[i+RIGHT] = rects[i].x - x + rects[i].width; - wd->vertices[i+BOTTOM] = rects[i].y - y + rects[i].height; + wd->vertices[i+LEFT] = rects[j].x - x; + wd->vertices[i+TOP] = rects[j].y - y; + wd->vertices[i+RIGHT] = rects[j].x - x + rects[j].width; + wd->vertices[i+BOTTOM] = rects[j].y - y + rects[j].height; } if (rep) free(rep); + + wd->waiting_region = FALSE; } static void @@ -507,7 +535,9 @@ glxrender_window_resize(d_window_t *w) assert(wd != NULL); glxrender_free_window_pixmap(w, d, wd); - glxrender_update_window_pixmap(w, d, wd); + + glxrender_free_window_region(wd); + glxrender_fetch_window_region(w, wd); } static void @@ -524,7 +554,9 @@ glxrender_window_reshape(d_window_t *w) assert(wd != NULL); glxrender_free_window_pixmap(w, d, wd); - glxrender_update_window_pixmap(w, d, wd); + + glxrender_free_window_region(wd); + glxrender_fetch_window_region(w, wd); } static void -- 2.34.1