/* Sets flags to valid attributes. */ static XVisualInfo* bestVisual( Display* disp, int screen, int* flags ) { XVisualInfo* vi = chooseVisual( disp, screen, *flags ); if( ! vi ) { int valid = 0; int bit = GLV_ATTRIB_MULTISAMPLE; // Test each requested attribute separately. while( bit ) { if( *flags & bit ) { vi = chooseVisual( disp, screen, bit ); if( vi ) { XFree( vi ); valid |= bit; } } bit >>= 1; } *flags = valid; vi = chooseVisual( disp, screen, valid ); }
bool QGLContext::chooseContext( const QGLContext* shareContext ) { Display* disp = d->paintDevice->x11Display(); vi = chooseVisual(); if ( !vi ) return FALSE; if ( deviceIsPixmap() && (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() || ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) ) { XFree( vi ); XVisualInfo appVisInfo; memset( &appVisInfo, 0, sizeof(XVisualInfo) ); appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() ); appVisInfo.screen = d->paintDevice->x11Screen(); int nvis; vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis ); if ( !vi ) return FALSE; int useGL; glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL ); if ( !useGL ) return FALSE; //# Chickening out already... } int res; glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res ); glFormat.setPlane( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res ); glFormat.setDoubleBuffer( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res ); glFormat.setDepth( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res ); glFormat.setRgba( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res ); glFormat.setAlpha( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res ); glFormat.setAccum( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res ); glFormat.setStencil( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res ); glFormat.setStereo( res ); Bool direct = format().directRendering() ? True : False; if ( shareContext && ( !shareContext->isValid() || !shareContext->cx ) ) { #if defined(QT_CHECK_NULL) qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); #endif shareContext = 0; } // 1. Sharing between rgba and color-index will give wrong colors. // 2. Contexts cannot be shared btw. direct/non-direct renderers. // 3. Pixmaps cannot share contexts that are set up for direct rendering. if ( shareContext && (format().rgba() != shareContext->format().rgba() || (deviceIsPixmap() && glXIsDirect( disp, (GLXContext)shareContext->cx )))) shareContext = 0; cx = 0; if ( shareContext ) { cx = glXCreateContext( disp, (XVisualInfo *)vi, (GLXContext)shareContext->cx, direct ); if ( cx ) d->sharing = TRUE; } if ( !cx ) cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct ); if ( !cx ) return FALSE; glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) ); if ( deviceIsPixmap() ) { #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi, d->paintDevice->handle(), choose_cmap( disp, (XVisualInfo *)vi ) ); #else gpm = (Q_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi, d->paintDevice->handle() ); #endif if ( !gpm ) return FALSE; } return TRUE; }
bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); const QX11Info *xinfo = qt_x11Info(d->paintDevice); Display* disp = xinfo->display(); d->vi = chooseVisual(); if (!d->vi) return false; if (deviceIsPixmap() && (((XVisualInfo*)d->vi)->depth != xinfo->depth() || ((XVisualInfo*)d->vi)->screen != xinfo->screen())) { XFree(d->vi); XVisualInfo appVisInfo; memset(&appVisInfo, 0, sizeof(XVisualInfo)); appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual()); appVisInfo.screen = xinfo->screen(); int nvis; d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis); if (!d->vi) return false; int useGL; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL); if (!useGL) return false; //# Chickening out already... } int res; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res); d->glFormat.setPlane(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res); d->glFormat.setDoubleBuffer(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res); d->glFormat.setDepth(res); if (d->glFormat.depth()) d->glFormat.setDepthBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res); d->glFormat.setRgba(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res); d->glFormat.setRedBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res); d->glFormat.setGreenBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res); d->glFormat.setBlueBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res); d->glFormat.setAlpha(res); if (d->glFormat.alpha()) d->glFormat.setAlphaBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res); d->glFormat.setAccum(res); if (d->glFormat.accum()) d->glFormat.setAccumBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res); d->glFormat.setStencil(res); if (d->glFormat.stencil()) d->glFormat.setStencilBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res); d->glFormat.setStereo(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res); d->glFormat.setSampleBuffers(res); if (d->glFormat.sampleBuffers()) { glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res); d->glFormat.setSamples(res); } Bool direct = format().directRendering() ? True : False; if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) { qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); shareContext = 0; } // 1. Sharing between rgba and color-index will give wrong colors. // 2. Contexts cannot be shared btw. direct/non-direct renderers. // 3. Pixmaps cannot share contexts that are set up for direct rendering. // 4. If the contexts are not created on the same screen, they can't be shared if (shareContext && (format().rgba() != shareContext->format().rgba() || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx)) || (shareContext->d_func()->screen != xinfo->screen()))) { shareContext = 0; } d->cx = 0; if (shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); d->screen = ((XVisualInfo*)d->vi)->screen; if (d->cx) { QGLContext *share = const_cast<QGLContext *>(shareContext); d->sharing = true; share->d_func()->sharing = true; } } if (!d->cx) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); d->screen = ((XVisualInfo*)d->vi)->screen; } if (!d->cx) return false; d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx)); if (deviceIsPixmap()) { #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice), qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi)); #else d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice)); #endif if (!d->gpm) return false; } QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS))); if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { if (d->glFormat.swapInterval() == -1) d->glFormat.setSwapInterval(0); } else { d->glFormat.setSwapInterval(-1); } return true; }