diff options
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/spu_loader/choosevisual.c')
-rw-r--r-- | src/VBox/GuestHost/OpenGL/spu_loader/choosevisual.c | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/src/VBox/GuestHost/OpenGL/spu_loader/choosevisual.c b/src/VBox/GuestHost/OpenGL/spu_loader/choosevisual.c new file mode 100644 index 00000000..1dc797e1 --- /dev/null +++ b/src/VBox/GuestHost/OpenGL/spu_loader/choosevisual.c @@ -0,0 +1,329 @@ + +#include "chromium.h" +#include "cr_spu.h" +#include "cr_error.h" +#include "cr_string.h" + + +/** + * Wrappers for glXChooseVisual/etc. + * + * By using this function, the fake GLX, render SPU, tilesort SPU, + * etc can be assured of getting the same GLX visual for a set of CR_*_BIT + * visual flags. This helps ensure that render_to_app_window will work + * properly. + */ + + +#if defined(WINDOWS) +int +crChooseVisual(const crOpenGLInterface *ws, int visBits) +{ + /* placeholder */ + return 0; +} +#endif + + +#if defined(DARWIN) +int +crChooseVisual(const crOpenGLInterface *ws, int visBits) +{ + /* placeholder */ + return 0; +} +#endif + + +#if defined(GLX) + +XVisualInfo * +crChooseVisual(const crOpenGLInterface *ws, Display *dpy, int screen, + GLboolean directColor, int visBits) +{ + XVisualInfo *vis; + int errorBase, eventBase; + + if (ws->glXQueryExtension(dpy, &errorBase, &eventBase)) + { + + if (ws->glXChooseVisual) + { + /* Use the real OpenGL's glXChooseVisual function */ + int attribList[100]; + int i = 0; + + /* Build the attribute list */ + if (visBits & CR_RGB_BIT) + { + attribList[i++] = GLX_RGBA; + attribList[i++] = GLX_RED_SIZE; + attribList[i++] = 1; + attribList[i++] = GLX_GREEN_SIZE; + attribList[i++] = 1; + attribList[i++] = GLX_BLUE_SIZE; + attribList[i++] = 1; + } + + if (visBits & CR_ALPHA_BIT) + { + attribList[i++] = GLX_ALPHA_SIZE; + attribList[i++] = 1; + } + + if (visBits & CR_DOUBLE_BIT) + { + attribList[i++] = GLX_DOUBLEBUFFER; + } + + if (visBits & CR_STEREO_BIT) + { + attribList[i++] = GLX_STEREO; + } + + if (visBits & CR_DEPTH_BIT) + { + attribList[i++] = GLX_DEPTH_SIZE; + attribList[i++] = 1; + } + + if (visBits & CR_STENCIL_BIT) + { + attribList[i++] = GLX_STENCIL_SIZE; + attribList[i++] = 1; + } + + if (visBits & CR_ACCUM_BIT) + { + attribList[i++] = GLX_ACCUM_RED_SIZE; + attribList[i++] = 1; + attribList[i++] = GLX_ACCUM_GREEN_SIZE; + attribList[i++] = 1; + attribList[i++] = GLX_ACCUM_BLUE_SIZE; + attribList[i++] = 1; + if (visBits & CR_ALPHA_BIT) + { + attribList[i++] = GLX_ACCUM_ALPHA_SIZE; + attribList[i++] = 1; + } + } + + if (visBits & CR_MULTISAMPLE_BIT) + { + attribList[i++] = GLX_SAMPLE_BUFFERS_SGIS; + attribList[i++] = 1; + attribList[i++] = GLX_SAMPLES_SGIS; + attribList[i++] = 4; + } + + if (visBits & CR_OVERLAY_BIT) + { + attribList[i++] = GLX_LEVEL; + attribList[i++] = 1; + } + + if (directColor) + { + /* + * See if we have have GLX_EXT_visual_info so we + * can grab a Direct Color visual + */ +#ifdef GLX_EXT_visual_info + if (crStrstr(ws->glXQueryExtensionsString(dpy, screen), + "GLX_EXT_visual_info")) + { + attribList[i++] = GLX_X_VISUAL_TYPE_EXT; + attribList[i++] = GLX_DIRECT_COLOR_EXT; + } +#endif + } + + /* End the list */ + attribList[i++] = None; + + vis = ws->glXChooseVisual(dpy, screen, attribList); + return vis; + } + else + { + /* Don't use glXChooseVisual, use glXGetConfig. + * + * Here's the deal: + * Some (all?) versions of the libGL.so that's shipped with ATI's + * drivers aren't built with the -Bsymbolic flag. That's bad. + * + * If we call the glXChooseVisual() function that's built into ATI's + * libGL, it in turn calls the glXGetConfig() function. Now, there's + * a glXGetConfig function in libGL.so **AND** there's a glXGetConfig + * function in Chromium's libcrfaker.so library. Unfortunately, the + * later one gets called instead of the former. At this point, things + * go haywire. If -Bsymbolic were used, this would not happen. + */ + XVisualInfo templateVis; + long templateFlags; + int count, i, visType; + + visType = directColor ? DirectColor : TrueColor; + + /* Get list of candidate visuals */ + templateFlags = VisualScreenMask | VisualClassMask; + templateVis.screen = screen; +#if defined(__cplusplus) || defined(c_plusplus) + templateVis.c_class = visType; +#else + templateVis.class = visType; +#endif + + vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count); + /* find first visual that's good enough */ + for (i = 0; i < count; i++) + { + int val; + + /* Need exact match on RGB, DOUBLEBUFFER, STEREO, LEVEL, MULTISAMPLE */ + ws->glXGetConfig(dpy, vis + i, GLX_RGBA, &val); + if (((visBits & CR_RGB_BIT) && !val) || + (((visBits & CR_RGB_BIT) == 0) && val)) + { + continue; + } + + ws->glXGetConfig(dpy, vis + i, GLX_DOUBLEBUFFER, &val); + if (((visBits & CR_DOUBLE_BIT) && !val) || + (((visBits & CR_DOUBLE_BIT) == 0) && val)) + { + continue; + } + + ws->glXGetConfig(dpy, vis + i, GLX_STEREO, &val); + if (((visBits & CR_STEREO_BIT) && !val) || + (((visBits & CR_STEREO_BIT) == 0) && val)) + { + continue; + } + + ws->glXGetConfig(dpy, vis + i, GLX_LEVEL, &val); + if (((visBits & CR_OVERLAY_BIT) && !val) || + (((visBits & CR_OVERLAY_BIT) == 0) && val)) + { + continue; + } + + ws->glXGetConfig(dpy, vis + i, GLX_SAMPLE_BUFFERS_SGIS, &val); + if (visBits & CR_MULTISAMPLE_BIT) + { + if (!val) + continue; + ws->glXGetConfig(dpy, vis + i, GLX_SAMPLES_SGIS, &val); + if (val < 4) + continue; + } + else { + /* don't want multisample */ + if (val) + continue; + } + + /* Need good enough for ALPHA, DEPTH, STENCIL, ACCUM */ + if (visBits & CR_ALPHA_BIT) + { + ws->glXGetConfig(dpy, vis + i, GLX_ALPHA_SIZE, &val); + if (!val) + continue; + } + + if (visBits & CR_DEPTH_BIT) + { + ws->glXGetConfig(dpy, vis + i, GLX_DEPTH_SIZE, &val); + if (!val) + continue; + } + + if (visBits & CR_STENCIL_BIT) + { + ws->glXGetConfig(dpy, vis + i, GLX_STENCIL_SIZE, &val); + if (!val) + continue; + } + + if (visBits & CR_ACCUM_BIT) + { + ws->glXGetConfig(dpy, vis + i, GLX_ACCUM_RED_SIZE, &val); + if (!val) + continue; + if (visBits & CR_ALPHA_BIT) + { + ws->glXGetConfig(dpy, vis + i, GLX_ACCUM_ALPHA_SIZE, &val); + if (!val) + continue; + } + } + + /* If we get here, we found a good visual. + * Now, we need to get a new XVisualInfo pointer in case the caller + * calls XFree on it. + */ + templateFlags = VisualScreenMask | VisualIDMask; + templateVis.screen = screen; + templateVis.visualid = vis[i].visual->visualid; + XFree(vis); /* free the list */ + vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count); + return vis; + } + + /* if we get here, we failed to find a sufficient visual */ + return NULL; + } + } + else + { + /* use Xlib instead of GLX */ + XVisualInfo templateVis, *best; + long templateFlags; + int i, count, visType; + + if (visBits & CR_RGB_BIT) + visType = directColor ? DirectColor : TrueColor; + else + visType = PseudoColor; + + /* Get list of candidate visuals */ + templateFlags = VisualScreenMask | VisualClassMask; + templateVis.screen = screen; +#if defined(__cplusplus) || defined(c_plusplus) + templateVis.c_class = visType; +#else + templateVis.class = visType; +#endif + + vis = XGetVisualInfo(dpy, templateFlags, &templateVis, &count); + if (!vis) + return NULL; + + /* okay, select the RGB visual with the most depth */ + best = vis + 0; + for (i = 1; i < count; i++) + { + if (vis[i].depth > best->depth && + vis[i].bits_per_rgb > best->bits_per_rgb ) + best = vis + i; + } + + if (best) + { + /* If we get here, we found a good visual. + * Now, we need to get a new XVisualInfo pointer in case the caller + * calls XFree on it. + */ + templateFlags = VisualScreenMask | VisualIDMask; + templateVis.screen = screen; + templateVis.visualid = best->visualid; + XFree(vis); /* free the list */ + best = XGetVisualInfo(dpy, templateFlags, &templateVis, &count); + } + + return best; + } +} + +#endif /* GLX */ |