16 #include <GL/glxtokens.h>
18 #include <GL/glxext.h>
24 typedef void (*BindEXTFunc)(Display *, GLXDrawable, int, const int *);
25 typedef void (*ReleaseEXTFunc)(Display *, GLXDrawable, int);
28 void (*screen_paint)(d_screen_t *sc);
29 void (*screen_root_pixmap_change)(d_screen_t *sc);
30 void (*window_show)(d_window_t *w);
31 void (*window_zombie_dead)(d_window_t *w);
32 void (*window_resize)(d_window_t *w);
33 void (*window_reshape)(d_window_t *w);
39 GLXFBConfig fbconfig[MAX_DEPTH + 1];
43 BindEXTFunc bind_func;
44 ReleaseEXTFunc release_func;
52 static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d);
54 static void glxrender_paint(d_screen_t *sc);
55 static void glxrender_root_pixmap_change(d_screen_t *sc);
56 static void paint_root(d_screen_t *sc, data_t *d);
57 static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
58 gboolean opaque, int x, int y, int width,
59 int height, int bwidth);
60 static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
61 int x, int y, int width, int height, int bwidth);
62 static void glxrender_update_window_pixmap(d_window_t *w, data_t *d,
64 static void glxrender_free_window_pixmap(d_window_t *w, data_t *d,
66 static void glxrender_update_root_pixmap(d_screen_t *sc, data_t *d);
68 static void glxrender_window_show(d_window_t *window);
69 static void glxrender_window_zombie_dead(d_window_t *window);
70 static void glxrender_window_resize(d_window_t *window);
71 static void glxrender_window_reshape(d_window_t *window);
74 glxrender_init(d_screen_t *sc, int id)
76 static int context_visual_config[] = {
87 d = malloc(sizeof(data_t));
88 d->screen_paint = sc->screen_paint;
89 d->screen_root_pixmap_change = sc->screen_root_pixmap_change;
90 d->window_show = sc->window_show;
91 d->window_zombie_dead = sc->window_zombie_dead;
92 d->window_resize = sc->window_resize;
93 d->window_reshape = sc->window_reshape;
94 screen_add_plugin_data(sc, plugin_id, d);
96 sc->screen_paint = glxrender_paint;
97 sc->screen_root_pixmap_change = glxrender_root_pixmap_change;
98 sc->window_show = glxrender_window_show;
99 sc->window_zombie_dead = glxrender_window_zombie_dead;
100 sc->window_resize = glxrender_window_resize;
101 sc->window_reshape = glxrender_window_reshape;
103 d->shadowalpha = 0x3333; /* 20% */
107 vi = glXChooseVisual(sc->dpy->xlib_dpy, sc->num, context_visual_config);
109 printf("unable to find a valid double buffered GL context to use\n");
113 d->context = glXCreateContext(sc->dpy->xlib_dpy, vi, NULL, GL_TRUE);
114 glXMakeCurrent(sc->dpy->xlib_dpy, sc->overlay, d->context);
117 if (!(glxrender_find_fb_config(sc, d))) {
118 printf("unable to find FB configs\n");
122 glViewport(0, 0, sc->super->width_in_pixels, sc->super->height_in_pixels);
123 glMatrixMode(GL_PROJECTION);
125 glOrtho(0, sc->super->width_in_pixels, sc->super->height_in_pixels, 0,
127 glMatrixMode(GL_MODELVIEW);
129 glEnable(GL_TEXTURE_2D);
131 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
132 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
135 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
136 glClear(GL_COLOR_BUFFER_BIT);
137 glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
139 d->bind_func = (BindEXTFunc)
140 glXGetProcAddress((const guchar*)"glXBindTexImageEXT");
141 d->release_func = (ReleaseEXTFunc)
142 glXGetProcAddress((const guchar*)"glXReleaseTexImageEXT");
146 glxrender_find_fb_config(d_screen_t *sc, data_t *d)
148 static const int drawable_tfp_attrs[] = {
149 GLX_CONFIG_CAVEAT, GLX_NONE,
150 GLX_DOUBLEBUFFER, FALSE,
156 GLX_RENDER_TYPE, GLX_RGBA_BIT,
157 GLX_BIND_TO_TEXTURE_RGBA_EXT, TRUE, /* For TextureFromPixmap */
160 int db, stencil, depth, numfb, i;
162 XVisualInfo tvis, *visinfo;
164 fbcons = glXChooseFBConfig(sc->dpy->xlib_dpy, sc->num,
165 drawable_tfp_attrs, &numfb);
166 if (!fbcons) return FALSE;
168 for (i = 0; i <= MAX_DEPTH; i++) {
178 printf("looking for depth %d\n", i);
181 visinfo = XGetVisualInfo(sc->dpy->xlib_dpy, VisualDepthMask,
183 /* pick the nicest visual for the depth */
184 for (j = 0; j < count; j++) {
185 glXGetConfig(sc->dpy->xlib_dpy, &visinfo[j], GLX_USE_GL, &value);
189 glXGetConfig(sc->dpy->xlib_dpy, &visinfo[j], GLX_DOUBLEBUFFER,
195 glXGetConfig(sc->dpy->xlib_dpy, &visinfo[j], GLX_STENCIL_SIZE,
201 glXGetConfig(sc->dpy->xlib_dpy, &visinfo[j], GLX_DEPTH_SIZE,
207 /* use this visual */
208 vid = visinfo[j].visualid;
213 /* look for an fbconfig for this visual */
214 for (j = 0; j < numfb; ++j) {
215 glXGetFBConfigAttrib(sc->dpy->xlib_dpy, fbcons[j],
216 GLX_VISUAL_ID, &value);
217 if ((unsigned)value == vid) {
218 d->fbconfig[i] = fbcons[j];
220 printf("found visual 0x%x fbconfig 0x%x for depth %d\n",
221 (uint32_t)vid, (uint32_t)fbcons[j], i);
232 glxrender_free(d_screen_t *sc)
234 data_t *d = screen_find_plugin_data(sc, plugin_id);
236 screen_remove_plugin_data(sc, plugin_id);
240 glxrender_next_timeout(struct d_screen *sc, struct timeval *tv)
248 glxrender_timeout(struct d_screen *sc, const struct timeval *now)
254 glxrender_window_free_data(d_window_t *w, data_t *d, window_data_t *wd)
256 glxrender_free_window_pixmap(w, d, wd);
257 glDeleteTextures(1, &wd->texname);
262 glxrender_window_show(d_window_t *w)
267 d = screen_find_plugin_data(w->sc, plugin_id);
272 wd = window_find_plugin_data(w, plugin_id);
274 glxrender_window_free_data(w, d, wd);
276 wd = malloc(sizeof(window_data_t));
277 glGenTextures(1, &wd->texname);
278 wd->glpixmap = XCB_NONE;
280 window_add_plugin_data(w, plugin_id, wd);
284 glxrender_window_zombie_dead(d_window_t *w)
289 d = screen_find_plugin_data(w->sc, plugin_id);
290 wd = window_find_plugin_data(w, plugin_id);
292 glxrender_window_free_data(w, d, wd);
293 window_remove_plugin_data(w, plugin_id);
297 d->window_zombie_dead(w);
301 glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
303 /* this might cause an error, oh well */
305 glBindTexture(GL_TEXTURE_2D, wd->texname);
310 1 CARD8 opcode (X assigned)
311 1 16 GLX opcode (glXVendorPrivate)
313 4 1331 vendor specific opcode
315 4 GLX_DRAWABLE drawable
319 unsigned int len = (2 + 0) * sizeof(uint32_t);
324 xcb_glx_vendor_private(w->sc->dpy->conn,
327 len, (uint8_t*)data);
329 d->release_func(w->sc->dpy->xlib_dpy,
330 wd->glpixmap, GLX_FRONT_LEFT_EXT);
333 glBindTexture(GL_TEXTURE_2D, 0);
335 //xcb_glx_destroy_pixmap(w->sc->dpy->conn, wd->glpixmap);
336 glXDestroyPixmap(w->sc->dpy->xlib_dpy, wd->glpixmap);
337 wd->glpixmap = XCB_NONE;
342 glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
347 static int attrs[] = {
348 GLX_TEXTURE_FORMAT_EXT,
353 px = window_get_pixmap(w);
354 depth = window_get_depth(w);
358 //printf("%x %d %x\n", px, depth, d->fbconfig[depth]);
359 if (!d->fbconfig[depth]) {
360 printf("no GL visual for depth %d\n", depth);
364 if (window_is_argb(w))
365 attrs[1] = GLX_TEXTURE_FORMAT_RGBA_EXT;
367 attrs[1] = GLX_TEXTURE_FORMAT_RGB_EXT;
370 wd->glpixmap = xcb_generate_id(w->sc->dpy->conn);
371 printf("bind config 0x%x screen %d pixmap 0x%x glpixmap 0x%x "
373 d->fbconfig[depth], w->sc->num, px, wd->glpixmap,
374 sizeof(attrs)/sizeof(attrs[0]));
375 xcb_void_cookie_t ck =
376 xcb_glx_create_pixmap_checked(w->sc->dpy->conn, w->sc->num,
379 sizeof(attrs)/sizeof(attrs[0] - 1),
381 xcb_generic_error_t *err = xcb_request_check(w->sc->dpy->conn, ck);
383 display_error(w->sc->dpy, err);
385 wd->glpixmap = XCB_NONE;
389 wd->glpixmap = glXCreatePixmap(w->sc->dpy->xlib_dpy,
394 glBindTexture(GL_TEXTURE_2D, wd->texname);
399 1 CARD8 opcode (X assigned)
400 1 16 GLX opcode (glXVendorPrivate)
402 4 1330 vendor specific opcode
404 4 GLX_DRAWABLE drawable
406 4 CARD32 num_attributes
407 4*n LISTofATTRIBUTE_PAIR attribute, value pairs.
410 unsigned int len = (3 + 0) * sizeof(uint32_t);
416 xcb_glx_vendor_private(w->sc->dpy->conn,
419 len, (uint8_t*)data);
421 d->bind_func(w->sc->dpy->xlib_dpy,
422 wd->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
428 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
429 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
430 //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
432 glBindTexture(GL_TEXTURE_2D, 0);
436 glxrender_update_root_pixmap(d_screen_t *sc, data_t *d)
440 px = screen_get_root_pixmap(sc);
446 glxrender_window_resize(d_window_t *w)
451 d = screen_find_plugin_data(w->sc, plugin_id);
452 wd = window_find_plugin_data(w, plugin_id);
458 glxrender_free_window_pixmap(w, d, wd);
462 glxrender_window_reshape(d_window_t *w)
467 d = screen_find_plugin_data(w->sc, plugin_id);
468 wd = window_find_plugin_data(w, plugin_id);
471 d->window_reshape(w);
474 glxrender_free_window_pixmap(w, d, wd);
478 glxrender_root_pixmap_change(d_screen_t *sc)
482 d = screen_find_plugin_data(sc, plugin_id);
483 int a; /* XXX free things here */
484 //if (d->root_picture) {
485 // xcb_render_free_picture(sc->dpy->conn, d->root_picture);
486 // d->root_picture = XCB_NONE;
490 d->screen_root_pixmap_change(sc);
494 glxrender_paint(d_screen_t *sc)
496 data_t *d = screen_find_plugin_data(sc, plugin_id);
499 //printf("painting\n");
503 for (it = list_bottom(sc->stacking); it; it = it->prev) {
504 d_window_t *w = it->data;
506 if (!window_is_input_only(w) &&
507 (window_is_mapped(w) || window_is_zombie(w)))
509 int x, y, width, height, bwidth;
513 window_get_area(w, &x, &y, &width, &height, &bwidth);
515 if (!(x < sc->super->width_in_pixels &&
516 y < sc->super->height_in_pixels &&
517 (x + width > 0 || x + width + d->xshadowoff > 0) &&
518 (y + height > 0 || y + height + d->yshadowoff > 0)))
523 opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
525 wd = window_find_plugin_data(w, plugin_id);
527 paint_shadow(w, d, wd, x, y, width, height, bwidth);
528 paint_window(w, d, wd, opaque, x, y, width, height, bwidth);
532 //xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
533 glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
535 /* call the function we replaced in the chain */
540 paint_root(d_screen_t *sc, data_t *d)
542 //if (!d->root_picture)
543 glxrender_update_root_pixmap(sc, d);
545 glClear(GL_COLOR_BUFFER_BIT);
549 paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
550 int x, int y, int width, int height, int bwidth)
552 uint16_t o = window_get_opacity(w);
555 glxrender_update_window_pixmap(w, d, wd);
557 glBindTexture(GL_TEXTURE_2D, wd->texname);
562 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
563 glColor4us(o, o, o, o);
569 glVertex2i(x + width + bwidth, y);
571 glVertex2i(x + width + bwidth,
572 y + height + bwidth);
574 glVertex2i(x, y + height + bwidth);
578 glBindTexture(GL_TEXTURE_2D, 0);
581 glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
582 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
588 paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
589 int x, int y, int width, int height, int bwidth)
592 xcb_render_composite(w->sc->dpy->conn,
593 XCB_RENDER_PICT_OP_OVER,
598 x+d->xshadowoff, y+d->yshadowoff,
599 width + bwidth*2, height + bwidth *2);