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);
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);
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);
}
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
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;
}
}
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;
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;
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
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
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