From: Dana Jansens Date: Mon, 10 Mar 2008 04:00:02 +0000 (-0400) Subject: find the visuals to use, and the fbconfig we want to use for all available depths X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=740af05e4a6317352566fd948e156238640d0d57;p=dana%2Fdcompmgr.git find the visuals to use, and the fbconfig we want to use for all available depths --- diff --git a/glxrender.c b/glxrender.c index d9fdf69..1a4a8da 100644 --- a/glxrender.c +++ b/glxrender.c @@ -15,6 +15,8 @@ #include #include +#define MAX_DEPTH 32 + static int plugin_id; typedef struct { @@ -29,6 +31,8 @@ typedef struct { int xshadowoff; int yshadowoff; + uint32_t fbconfig[MAX_DEPTH + 1]; + xcb_glx_context_t context; xcb_glx_context_tag_t context_tag; } data_t; @@ -38,7 +42,10 @@ typedef struct { xcb_glx_pixmap_t glpixmap; } window_data_t; +static uint32_t glxrender_visual_info(uint32_t *props, int vis, int numprops, + uint32_t name); static gboolean glxrender_check_visual(d_screen_t *sc); +static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d); static void glxrender_paint(d_screen_t *sc); static void glxrender_root_pixmap_change(d_screen_t *sc); @@ -93,6 +100,11 @@ glxrender_init(d_screen_t *sc, int id) exit(1); } + if (!(glxrender_find_fb_config(sc, d))) { + printf("unable to find FB configs\n"); + exit(1); + } + d->context = xcb_generate_id(sc->dpy->conn); ck = xcb_glx_create_context_checked(sc->dpy->conn, d->context, sc->overlay_visual, sc->num, @@ -136,6 +148,35 @@ glxrender_init(d_screen_t *sc, int id) */ } +static uint32_t +glxrender_visual_info(uint32_t *props, int vis, int numprops, uint32_t name) +{ + int s; + + assert(numprops > 14); + + /* + for (s = vis * numprops; s < vis*numprops + numprops; ++s) + printf("%x ", props[s]); + printf("\n"); + */ + + s = vis * numprops; + switch (name) { + case GLX_VISUAL_ID: return props[s+0]; /* id number */ + case GLX_X_VISUAL_TYPE: return props[s+1]; /* XCB_CLASS_TRUE_COLOR etc */ + case GLX_USE_GL: return props[s+2]; /* boolean */ + case GLX_RED_SIZE: return props[s+3]; /* number */ + case GLX_GREEN_SIZE: return props[s+4]; /* number */ + case GLX_BLUE_SIZE: return props[s+5]; /* number */ + case GLX_ALPHA_SIZE: return props[s+6]; /* number */ + case GLX_DOUBLEBUFFER: return props[s+11]; /* boolean */ + case GLX_DEPTH_SIZE: return props[s+14]; /* number */ + case GLX_STENCIL_SIZE: return props[s+15]; /* number */ + default: assert(0); + } +} + static gboolean glxrender_check_visual(d_screen_t *sc) { @@ -146,10 +187,8 @@ glxrender_check_visual(d_screen_t *sc) ck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num); rep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, ck, NULL); if (rep) { - uint32_t *list; - unsigned int i, j; - int len; - gboolean depth, doublebuffer, rgba; + uint32_t *props; + unsigned int i, nprops; /* static int config[] = { @@ -160,49 +199,23 @@ glxrender_check_visual(d_screen_t *sc) }; */ - list = xcb_glx_get_visual_configs_property_list(rep); - len = xcb_glx_get_visual_configs_property_list_length(rep); - printf("got %d %d, %d\n", rep->num_visuals, rep->num_properties, len); + props = xcb_glx_get_visual_configs_property_list(rep); + nprops = rep->num_properties; for (i = 0; i < rep->num_visuals; ++i) { - const int - ID = 0, - CLASS = 1, - USE_GL = 2, - RED_DEPTH = 3, - BLUE_DEPTH = 4, - GREEN_DEPTH = 5, - ALPHA_DEPTH = 6, - DOUBLE_BUFFER = 11, - DEPTH_SIZE = 14; - int s = i * rep->num_properties; - - depth = doublebuffer = rgba = FALSE; - /* look for the overlay's visual */ - if (list[s+ID] != sc->overlay_visual) continue; - - printf("0x%x ", list[s+ID]); - printf("%d ", list[s+CLASS]); - printf("%s ", list[s+USE_GL] ? "yes" : "no"); - printf("%d ", list[s+RED_DEPTH]); - printf("%d ", list[s+GREEN_DEPTH]); - printf("%d ", list[s+BLUE_DEPTH]); - printf("%d ", list[s+ALPHA_DEPTH]); - printf("%s ", list[s+DOUBLE_BUFFER] ? "yes" : "no"); - printf("%d ", list[s+DEPTH_SIZE]); - - printf("\n"); - for (j = 0; j < rep->num_properties; ++j) - printf("%d ", list[i*rep->num_properties+j]); - printf("\n"); - - if (!list[s+USE_GL]) { + if (glxrender_visual_info(props, i, nprops, GLX_VISUAL_ID) != + sc->overlay_visual) + { + continue; + } + + if (!glxrender_visual_info(props, i, nprops, GLX_USE_GL)) { printf("overlay visual does not support GL\n"); break; } - if (!list[s+DOUBLE_BUFFER]) { + if (!glxrender_visual_info(props, i, nprops, GLX_DOUBLEBUFFER)) { printf("overlay visual is not double buffered\n"); break; } @@ -215,6 +228,165 @@ glxrender_check_visual(d_screen_t *sc) return ok; } +static uint32_t +glxrender_fbconfig_info(uint32_t *props, int con, int numprops, uint32_t name) +{ + int i; + + for (i = 0; i < numprops; ++i) { + if (props[i*2 + con*numprops*2] == name) + return props[i*2 + con*numprops*2 + 1]; + } + return 0; +} + +static gboolean +glxrender_find_fb_config(d_screen_t *sc, data_t *d) +{ + xcb_glx_get_visual_configs_cookie_t vck; + xcb_glx_get_visual_configs_reply_t *vrep; + xcb_glx_get_fb_configs_cookie_t fbck; + xcb_glx_get_fb_configs_reply_t *fbrep; + xcb_depth_iterator_t depth_it; + uint32_t fbcon = FALSE; + unsigned int i, nvprops, nfbprops; + uint32_t *vprops, *fbprops; + uint32_t db, stencil, depthsize; + + vck = xcb_glx_get_visual_configs_unchecked(sc->dpy->conn, sc->num); + vrep = xcb_glx_get_visual_configs_reply(sc->dpy->conn, vck, NULL); + if (!vrep) return FALSE; + + fbck = xcb_glx_get_fb_configs(sc->dpy->conn, sc->num); + fbrep = xcb_glx_get_fb_configs_reply(sc->dpy->conn, fbck, NULL); + if (!fbrep) return FALSE; + + vprops = xcb_glx_get_visual_configs_property_list(vrep); + nvprops = vrep->num_properties; + fbprops = xcb_glx_get_fb_configs_property_list(fbrep); + nfbprops = fbrep->num_properties; + + for (i = 0; i <= MAX_DEPTH; ++i) + d->fbconfig[i] = 0; + + db = 32767; + stencil = 32767; + depthsize = 32767; + depth_it = xcb_screen_allowed_depths_iterator(&sc->super); + for (; depth_it.rem; xcb_depth_next(&depth_it)) { + uint32_t vid; + int j; + unsigned int k; + xcb_visualtype_t *visuals; + int nvisuals; + + vid = 0; + if (depth_it.data->depth > MAX_DEPTH) continue; + + visuals = xcb_depth_visuals(depth_it.data); + nvisuals = xcb_depth_visuals_length(depth_it.data); + + /* pick the nicest visual for the depth */ + for (j = 0; j < nvisuals; ++j) { + uint32_t val; + + /* find the visual's properties */ + for (k = 0; k < vrep->num_visuals; ++k) + if (glxrender_visual_info(vprops, k, nvprops, GLX_VISUAL_ID) + == visuals[j].visual_id) + { + break; + } + if (k == vrep->num_visuals) continue; + + val = glxrender_visual_info(vprops, k, nvprops, GLX_USE_GL); + if (!val) continue; + + val = glxrender_visual_info(vprops, k, nvprops, GLX_DOUBLEBUFFER); + if (!val > db) continue; + db = val; + + val = glxrender_visual_info(vprops, k, nvprops, GLX_STENCIL_SIZE); + if (!val > stencil) continue; + stencil = val; + + val = glxrender_visual_info(vprops, k, nvprops, GLX_DEPTH_SIZE); + if (!val > depthsize) continue; + depthsize = val; + + /* use this visual */ + vid = visuals[j].visual_id; + } + + if (!vid) continue; + + printf("found visual for depth %d\n", i); + + for (k = 0; k < fbrep->num_FB_configs; ++k) { + uint32_t val; + + printf("root visual 0x%x\n", sc->super.root_visual); + printf("overlay visual 0x%x\n", sc->overlay_visual); + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_VISUAL_ID); + printf("x visual 0x%x\n", val); + if (val != vid) continue; + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_DOUBLEBUFFER); + printf("dbl buffer %s\n", val ? "yes" : "no"); + if (db) continue; + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_DEPTH_SIZE); + printf("depth size %d\n", val); + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_RED_SIZE); + printf("red size %d\n", val); + if (!val) continue; + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_GREEN_SIZE); + printf("green size %d\n", val); + if (!val) continue; + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_BLUE_SIZE); + printf("blue size %d\n", val); + if (!val) continue; + + val = glxrender_fbconfig_info(fbprops, k, nfbprops, + GLX_ALPHA_SIZE); + printf("alpha size %d\n", val); + if (!val) continue; + + val = glxrender_fbconfig_info(fbprops, j, nfbprops, + GLX_RENDER_TYPE); + printf("rgba bit %s\n", val & GLX_RGBA_BIT ? "yes" : "no"); + if (!(val & GLX_RGBA_BIT)) continue; + + val = glxrender_fbconfig_info(fbprops, j, nfbprops, + GLX_CONFIG_CAVEAT); + printf("caveat 0x%x\n", val); + + val = glxrender_fbconfig_info(fbprops, j, nfbprops, + GLX_BIND_TO_TEXTURE_RGBA_EXT); + printf("bind ext %s\n", val ? "yes" : "no"); + if (!val) continue; + + d->fbconfig[depth_it.data->depth] = + glxrender_fbconfig_info(fbprops, i, nfbprops, GLX_FBCONFIG_ID); + break; + } + } + + free(vrep); + free(fbrep); + return TRUE; +} + void glxrender_free(d_screen_t *sc) {