Beispiel #1
0
void QGLContext::makeCurrent()
{
    if ( !d->valid ) {
#if defined(QT_CHECK_STATE)
	qWarning("QGLContext::makeCurrent(): Cannot make invalid context current.");
#endif
	return;
    }
    bool ok = TRUE;
    if ( deviceIsPixmap() )
	ok = glXMakeCurrent( d->paintDevice->x11Display(),
			     (GLXPixmap)gpm,
			     (GLXContext)cx );

    else
	ok = glXMakeCurrent( d->paintDevice->x11Display(),
			     ((QWidget *)d->paintDevice)->winId(),
			     (GLXContext)cx );
#if defined(QT_CHECK_NULL)
    //    qDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid );
    if ( !ok )
	qWarning("QGLContext::makeCurrent(): Failed.");
#endif
    if ( ok )
	currentCtx = this;
}
Beispiel #2
0
/* state:done?(simple version) */
bool QGLContext::chooseContext( const QGLContext* shareContext )
{
    qDebug( "qgl_win.cpp:QGLContext::chooseContext()" );
    // Some kind of workaround, to force loading of opengl module....
    // Seems to be neccessary....why?
    if ( !force_opengl_loading ) {
        GLint params;
        glGetIntegerv( GL_DEPTH_BITS, &params );
        force_opengl_loading = TRUE;
    }
    /* simple implementation:
       assumes that:
       1.colordepth is SAME as desktop
       2.RGBA pixels
       3.no alpna
       4.no acc
       5.32-bit depth buffer
       6.no aux/stencil buffers
       7.
       More correct implementation would use glGetXXX to
       for example:glGetbooleanv for GL_DOUBLEBUFFER...*/ 
    //TODO:what if setContext is NOT yet called and so dc is invalid?
    HDC aDc;
    if ( deviceIsPixmap() ) {
        win = 0;
        aDc = d->paintDevice->handle();
    } else {
        win = ( ( QWidget* ) d->paintDevice ) ->winId();
        aDc = GetDC( win ); //wglGetCurrentDC();
    }
    if ( !aDc ) { // needs a device context
#if defined(QT_CHECK_NULL)
        qWarning( "qgl_win.cpp: QGLContext::chooseContext(): Paint device cannot be null" );
#endif

        if ( win ) {
            ReleaseDC( win, aDc );
        }
        return FALSE;
    }

    PIXELFORMATDESCRIPTOR pfd;
    pixelFormatId = choosePixelFormat( &pfd, aDc );
    if ( ( !SetPixelFormat( aDc, pixelFormatId, &pfd ) ) ) {
        qglError( "qgl_win.cpp: QGLContext::choosePixelFormat()", "SetPixelFormat" );
        if ( win ) {
            ReleaseDC( win, aDc );
            return FALSE;
        }
    }
    rc = wglCreateContext( aDc );
    if ( !rc ) {
        qglError( "qgl_win.cpp: QGLContext:chooseContext()", "wglCreateContext" );
        if ( win )
            ReleaseDC( win, aDc );
        return FALSE;
    }
    return TRUE;
}
Beispiel #3
0
void QGLContext::swapBuffers() const
{
    if ( !d->valid )
	return;
    if ( !deviceIsPixmap() )
	glXSwapBuffers( d->paintDevice->x11Display(),
			((QWidget *)d->paintDevice)->winId() );
}
Beispiel #4
0
//state:done?
//must be kept in sync with chooseContext
int QGLContext::choosePixelFormat( void * pfd_void, HDC phdc )
{
    PIXELFORMATDESCRIPTOR * ppfd = ( PIXELFORMATDESCRIPTOR * ) pfd_void;
    memset( ppfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );
    ppfd->nSize = sizeof( PIXELFORMATDESCRIPTOR );
    ppfd->nVersion = 1;
    ppfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
    ppfd->iPixelType = PFD_TYPE_RGBA;          // RGBA type

    if ( deviceIsPixmap() )
        ppfd->dwFlags |= PFD_DRAW_TO_BITMAP;
    else
        ppfd->dwFlags |= PFD_DRAW_TO_WINDOW;
    if ( glFormat.doubleBuffer() && !deviceIsPixmap() )
        ppfd->dwFlags |= PFD_DOUBLEBUFFER;
    if ( glFormat.stereo() )
        ppfd->dwFlags |= PFD_STEREO;
    if ( glFormat.depth() )
        ppfd->cDepthBits = 16;
    else
        ppfd->dwFlags |= PFD_DEPTH_DONTCARE;
    if ( glFormat.rgba() ) {
        ppfd->iPixelType = PFD_TYPE_RGBA;
        if ( deviceIsPixmap() )
            ppfd->cColorBits = 16;
        else
            ppfd->cColorBits = 16;
    } else {
        ppfd->iPixelType = PFD_TYPE_COLORINDEX;
        ppfd->cColorBits = 0;
    }
    ppfd->cAlphaBits = 0;
    ppfd->cAccumBits = 0;
    ppfd->cStencilBits = 0;
    ppfd->iLayerType = PFD_MAIN_PLANE;
    int pixelFormat;
    if ( ( pixelFormat = ChoosePixelFormat( phdc, ppfd ) ) == 0 )
        qglError( "qgl_win.cpp:QGLContext::choosePixelFormat()", "ChoosePixelFormat()" );
    return pixelFormat;
}
Beispiel #5
0
void QGLContext::swapBuffers() const
{
    Q_D(const QGLContext);
    if (!d->valid)
        return;
    if (!deviceIsPixmap()) {
        int interval = d->glFormat.swapInterval();
        if (interval > 0) {
            typedef int (*qt_glXGetVideoSyncSGI)(uint *);
            typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
            static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
            static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
            static bool resolved = false;
            if (!resolved) {
                QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));
                if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
                    void *handle = dlopen(NULL, RTLD_LAZY);
                    if (handle) {
                        glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI");
                        glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI");
                        dlclose(handle);
                    }
                    if (!glXGetVideoSyncSGI)
#endif
                    {
                        extern const QString qt_gl_library_name();
                        QLibrary lib(qt_gl_library_name());
                        glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI");
                        glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI");
                    }
                }
                resolved = true;
            }
            if (glXGetVideoSyncSGI && glXWaitVideoSyncSGI) {
                uint counter;
                if (!glXGetVideoSyncSGI(&counter))
                    glXWaitVideoSyncSGI(interval + 1, (counter + interval) % (interval + 1), &counter);
            }
        }
        glXSwapBuffers(qt_x11Info(d->paintDevice)->display(),
                       static_cast<QWidget *>(d->paintDevice)->winId());
    }
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
/*****************************************************************************
  QGLContext AGL-specific code
 *****************************************************************************/
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
    Q_D(QGLContext);
    d->cx = 0;
    d->vi = chooseMacVisual(0);
    if(!d->vi)
        return false;

    AGLPixelFormat fmt = (AGLPixelFormat)d->vi;
    GLint res;
    aglDescribePixelFormat(fmt, AGL_LEVEL, &res);
    d->glFormat.setPlane(res);
    if(deviceIsPixmap())
        res = 0;
    else
        aglDescribePixelFormat(fmt, AGL_DOUBLEBUFFER, &res);
    d->glFormat.setDoubleBuffer(res);
    aglDescribePixelFormat(fmt, AGL_DEPTH_SIZE, &res);
    d->glFormat.setDepth(res);
    if (d->glFormat.depth())
        d->glFormat.setDepthBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_RGBA, &res);
    d->glFormat.setRgba(res);
    aglDescribePixelFormat(fmt, AGL_RED_SIZE, &res);
    d->glFormat.setRedBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_GREEN_SIZE, &res);
    d->glFormat.setGreenBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_BLUE_SIZE, &res);
    d->glFormat.setBlueBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_ALPHA_SIZE, &res);
    d->glFormat.setAlpha(res);
    if (d->glFormat.alpha())
        d->glFormat.setAlphaBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_ACCUM_RED_SIZE, &res);
    // Bug in Apple OpenGL (rdr://5015603), when we don't have an accumulation
    // buffer, it still claims that we have a 16-bit one (which is pretty rare).
    // So, we just assume we can never have a buffer that small.
    d->glFormat.setAccum(res > 5);
    if (d->glFormat.accum())
        d->glFormat.setAccumBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_STENCIL_SIZE, &res);
    d->glFormat.setStencil(res);
    if (d->glFormat.stencil())
        d->glFormat.setStencilBufferSize(res);
    aglDescribePixelFormat(fmt, AGL_STEREO, &res);
    d->glFormat.setStereo(res);
    aglDescribePixelFormat(fmt, AGL_SAMPLE_BUFFERS_ARB, &res);
    d->glFormat.setSampleBuffers(res);
    if (d->glFormat.sampleBuffers()) {
        aglDescribePixelFormat(fmt, AGL_SAMPLES_ARB, &res);
        d->glFormat.setSamples(res);
    }

    if(shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) {
        qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
        shareContext = 0;
    }

    // sharing between rgba and color-index will give wrong colors
    if(shareContext && (format().rgba() != shareContext->format().rgba()))
        shareContext = 0;
    AGLContext ctx = aglCreateContext(fmt, (AGLContext) (shareContext ? shareContext->d_func()->cx : 0));
    if(!ctx) {
        GLenum err = aglGetError();
        if(err == AGL_BAD_MATCH || err == AGL_BAD_CONTEXT) {
            if(shareContext && shareContext->d_func()->cx) {
                qWarning("QGLContext::chooseContext(): Context sharing mismatch!");
                if(!(ctx = aglCreateContext(fmt, 0)))
                    return false;
                shareContext = 0;
            }
        }
        if(!ctx) {
            qWarning("QGLContext::chooseContext(): Unable to create QGLContext");
            return false;
        }
    }
    d->cx = ctx;
    if (shareContext && shareContext->d_func()->cx) {
        QGLContext *share = const_cast<QGLContext *>(shareContext);
        d->sharing = true;
        share->d_func()->sharing = true;
    }
    if(deviceIsPixmap())
        updatePaintDevice();

    // vblank syncing
    GLint interval = d->reqFormat.swapInterval();
    if (interval != -1) {
        aglSetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
        if (interval != 0)
            aglEnable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
        else
            aglDisable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
    }
    aglGetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
    d->glFormat.setSwapInterval(interval);
    return true;
}