gllindrv.cpp revision 648f4eb3997820a317f8aa900598a4b7fe425c23
b614993b942a5222f6d88ae5e9974334484d74f2nd * VBox OpenGL
b614993b942a5222f6d88ae5e9974334484d74f2nd * Simple buffered OpenGL functions
031b91a62d25106ae69d4693475c79618dd5e884fielding * Contributor: Alexander Eichner
031b91a62d25106ae69d4693475c79618dd5e884fielding * Copyright (C) 2006-2007 innotek GmbH
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * This file is part of VirtualBox Open Source Edition (OSE), as
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * available from http://www.virtualbox.org. This file is free software;
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * you can redistribute it and/or modify it under the terms of the GNU
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * General Public License as published by the Free Software Foundation,
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * distribution. VirtualBox OSE is distributed in the hope that it will
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * be useful, but WITHOUT ANY WARRANTY of any kind.
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * If you received this file as part of a commercial VirtualBox
816bc7965d58c92c0d02fd42d6ea58090f70c6bdnd * distribution, then only the terms of your commercial VirtualBox
7db9f691a00ead175b03335457ca296a33ddf31bnd * license agreement apply instead of the previous paragraph.
b614993b942a5222f6d88ae5e9974334484d74f2nd/*static int (*X_handler)(Display *, XErrorEvent *) = NULL;
b614993b942a5222f6d88ae5e9974334484d74f2ndstatic int x_errhandler(Display *d, XErrorEvent *e)
b614993b942a5222f6d88ae5e9974334484d74f2nd return (X_handler(d, e));
b614993b942a5222f6d88ae5e9974334484d74f2ndstatic int (*XIO_handler)(Display *) = NULL;
b614993b942a5222f6d88ae5e9974334484d74f2ndstatic int xio_errhandler(Display *d)
b614993b942a5222f6d88ae5e9974334484d74f2nd return (XIO_handler(d));
b614993b942a5222f6d88ae5e9974334484d74f2ndstatic Bool WaitForNotify( Display *dpy, XEvent *event, XPointer arg ) {
b614993b942a5222f6d88ae5e9974334484d74f2nd return (event->type == MapNotify) && (event->xmap.window == (Window) arg);
b614993b942a5222f6d88ae5e9974334484d74f2ndGLboolean vboxglCheckExtension(Display *dpy, int screenNum, char *extName )
b614993b942a5222f6d88ae5e9974334484d74f2nd ** Search for extName in the extensions string. Use of strstr()
b614993b942a5222f6d88ae5e9974334484d74f2nd ** is not sufficient because extension names can be prefixes of
b614993b942a5222f6d88ae5e9974334484d74f2nd ** other extension names. Could use strtok() but the constant
b614993b942a5222f6d88ae5e9974334484d74f2nd ** string returned by glGetString can be in read-only memory.
b614993b942a5222f6d88ae5e9974334484d74f2nd char *p = (char *) glXQueryExtensionsString(dpy, screenNum);
b614993b942a5222f6d88ae5e9974334484d74f2nd while (p < end) {
b614993b942a5222f6d88ae5e9974334484d74f2nd if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) {
b614993b942a5222f6d88ae5e9974334484d74f2nd p += (n + 1);
b614993b942a5222f6d88ae5e9974334484d74f2nd * Print parameters for a GLXFBConfig to stdout.
b614993b942a5222f6d88ae5e9974334484d74f2nd * Input: dpy - the X display
b614993b942a5222f6d88ae5e9974334484d74f2nd * screen - the X screen number
b614993b942a5222f6d88ae5e9974334484d74f2nd * fbConfig - the fbconfig handle
b614993b942a5222f6d88ae5e9974334484d74f2nd * horizFormat - if true, print in horizontal format
b614993b942a5222f6d88ae5e9974334484d74f2ndPrintFBConfigInfo(Display *dpy, int screen, GLXFBConfig config)
b614993b942a5222f6d88ae5e9974334484d74f2nd int accumRedSize, accumBlueSize, accumGreenSize, accumAlphaSize;
b614993b942a5222f6d88ae5e9974334484d74f2nd /* do queries using the GLX 1.3 tokens (same as the SGIX tokens) */
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_BUFFER_SIZE, &bufferSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_DOUBLEBUFFER, &doubleBuffer);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_AUX_BUFFERS, &auxBuffers);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_RED_SIZE, &redSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_GREEN_SIZE, &greenSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_BLUE_SIZE, &blueSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_ALPHA_SIZE, &alphaSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_DEPTH_SIZE, &depthSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_STENCIL_SIZE, &stencilSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_ACCUM_RED_SIZE, &accumRedSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_ACCUM_GREEN_SIZE, &accumGreenSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_ACCUM_BLUE_SIZE, &accumBlueSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_ACCUM_ALPHA_SIZE, &accumAlphaSize);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_SAMPLE_BUFFERS, &sampleBuffers);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_SAMPLES, &samples);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_DRAWABLE_TYPE, &drawableType);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_RENDER_TYPE, &renderType);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_X_RENDERABLE, &xRenderable);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXGetFBConfigAttrib(dpy, config, GLX_X_VISUAL_TYPE, &xVisual);
b614993b942a5222f6d88ae5e9974334484d74f2nd if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX))
b614993b942a5222f6d88ae5e9974334484d74f2nd printf(" Double Buffer: %s\n", doubleBuffer ? "yes" : "no");
b614993b942a5222f6d88ae5e9974334484d74f2nd if (renderType & GLX_COLOR_INDEX_BIT_SGIX) printf("CI ");
b614993b942a5222f6d88ae5e9974334484d74f2nd printf(" X Renderable: %s\n", xRenderable ? "yes" : "no");
b614993b942a5222f6d88ae5e9974334484d74f2nd * Global init of VBox OpenGL for windows
b614993b942a5222f6d88ae5e9974334484d74f2nd * @returns VBox error code
b614993b942a5222f6d88ae5e9974334484d74f2nd /*vboxInitOpenGLExtensions();*/
b614993b942a5222f6d88ae5e9974334484d74f2nd * Enable OpenGL
b614993b942a5222f6d88ae5e9974334484d74f2nd * @returns VBox error code
b614993b942a5222f6d88ae5e9974334484d74f2nd * @param pClient Client context
b614993b942a5222f6d88ae5e9974334484d74f2nd static int attribs[] = {
b614993b942a5222f6d88ae5e9974334484d74f2nd GLX_DOUBLEBUFFER, True, /* Request a double-buffered color buffer with */
b614993b942a5222f6d88ae5e9974334484d74f2nd GLX_RED_SIZE, 1, /* the maximum number of bits per component */
b614993b942a5222f6d88ae5e9974334484d74f2nd unsigned long mask;
b614993b942a5222f6d88ae5e9974334484d74f2nd /* we have to set up a rendering context to be able to use glGetString
b614993b942a5222f6d88ae5e9974334484d74f2nd * a window is created but is not mapped to screen (so it's not visible')
b614993b942a5222f6d88ae5e9974334484d74f2nd * and a GLXContext is bound to it */
b614993b942a5222f6d88ae5e9974334484d74f2nd pClient->enable.fbConfig = pClient->glxChooseFBConfig(pClient->dpy, screen_num, attribs, &returnedFBConfigs);
b614993b942a5222f6d88ae5e9974334484d74f2nd Log(("vboxglGetString: returned FBConfigs: %d\n", returnedFBConfigs));
b614993b942a5222f6d88ae5e9974334484d74f2nd pClient->enable.visinfo = pClient->glxGetVisualFromFBConfig(pClient->dpy, fbConfig[0]);
b614993b942a5222f6d88ae5e9974334484d74f2nd /* Create Window */
b614993b942a5222f6d88ae5e9974334484d74f2nd attr.colormap = XCreateColormap(pClient->dpy, RootWindow(dpy, screen_num), visinfo->visual, AllocNone);
b614993b942a5222f6d88ae5e9974334484d74f2nd mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
b614993b942a5222f6d88ae5e9974334484d74f2nd pClient->enable.win = XCreateWindow(pClient->dpy, RootWindow(pClient->dpy, screen_num), 0, 0, 100, 100,
b614993b942a5222f6d88ae5e9974334484d74f2nd /* Create Context */
b614993b942a5222f6d88ae5e9974334484d74f2nd pClient->enable.ctx = pClient->glxCreateNewContext(pClient->dpy, fbConfig[0], GLX_RGBA_TYPE, NULL, True);
b614993b942a5222f6d88ae5e9974334484d74f2nd glXMakeCurrent(pClient->dpy, pClient->enable.win, pClient->enable.ctx);
return VINF_SUCCESS;
glFlush();
return VINF_SUCCESS;
if (pClient->glxChooseFBConfig && pClient->glxGetVisualFromFBConfig && pClient->glxCreateNewContext)
return rc;
#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
return VINF_SUCCESS;
unsigned long mask;
int screen_num;
#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
if (!fbConfig) {
int returnedNumFBConfigs;
static int attribs[] = {
returnedFBConfigs = pClient->glxChooseFBConfig(pClient->dpy, screen_num, attribs, &returnedNumFBConfigs);
if (!returnedNumFBConfigs) {
attr.colormap = XCreateColormap(pClient->dpy, RootWindow(pClient->dpy, screen_num ), visinfo->visual, AllocNone);
pClient->glxContext = pClient->glxCreateNewContext(pClient->dpy, fbConfig, GLX_RGBA_TYPE, NULL, True);
AssertFailed();
glrc = 0;
#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
AssertFailed();
glXCopyContext(pClient->dpy, VBOX_OGL_GUEST_TO_HOST_HDC(hglrc), VBOX_OGL_GUEST_TO_HOST_HDC(hglrc), mask);
#ifdef VBOX_OGL_DEBUG_WINDOW_OUTPUT
AssertFailed();
int screen_num;
if (glxReturnValue)
return pfnProc;