src/opengl/qgl_x11.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
child 30 5dc02b23752f
--- a/src/opengl/qgl_x11.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/opengl/qgl_x11.cpp	Wed Mar 31 11:06:36 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -549,7 +549,7 @@
     bool triedDouble = false;
     bool triedSample = false;
     if (fmt.sampleBuffers())
-        fmt.setSampleBuffers(QGLExtensions::glExtensions & QGLExtensions::SampleBuffers);
+        fmt.setSampleBuffers(QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers);
     while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {
         if (!fmt.rgba() && bufDepths[i] > 1) {
             i++;
@@ -825,7 +825,7 @@
     d->valid = false;
     d->transpColor = QColor();
     d->initDone = false;
-    qgl_share_reg()->removeShare(this);
+    QGLContextGroup::removeShare(this);
 }
 
 
@@ -1132,6 +1132,71 @@
     return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data()));
 }
 
+/*
+    QGLTemporaryContext implementation
+*/
+
+class QGLTemporaryContextPrivate {
+public:
+    bool initialized;
+    Window drawable;
+    GLXContext context;
+    GLXDrawable oldDrawable;
+    GLXContext oldContext;
+};
+
+QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
+    : d(new QGLTemporaryContextPrivate)
+{
+    d->initialized = false;
+    d->oldDrawable = 0;
+    d->oldContext = 0;
+    int screen = 0;
+
+    int attribs[] = {GLX_RGBA, XNone};
+    XVisualInfo *vi = glXChooseVisual(X11->display, screen, attribs);
+    if (!vi) {
+        qWarning("QGLTempContext: No GL capable X visuals available.");
+        return;
+    }
+
+    int useGL;
+    glXGetConfig(X11->display, vi, GLX_USE_GL, &useGL);
+    if (!useGL) {
+        XFree(vi);
+        return;
+    }
+
+    d->oldDrawable = glXGetCurrentDrawable();
+    d->oldContext = glXGetCurrentContext();
+
+    XSetWindowAttributes a;
+    a.colormap = qt_gl_choose_cmap(X11->display, vi);
+    d->drawable = XCreateWindow(X11->display, RootWindow(X11->display, screen),
+                                0, 0, 1, 1, 0,
+                                vi->depth, InputOutput, vi->visual,
+                                CWColormap, &a);
+    d->context = glXCreateContext(X11->display, vi, 0, True);
+    if (d->context && glXMakeCurrent(X11->display, d->drawable, d->context)) {
+        d->initialized = true;
+    } else {
+        qWarning("QGLTempContext: Unable to create GL context.");
+        XDestroyWindow(X11->display, d->drawable);
+    }
+    XFree(vi);
+}
+
+QGLTemporaryContext::~QGLTemporaryContext()
+{
+    if (d->initialized) {
+        glXMakeCurrent(X11->display, 0, 0);
+        glXDestroyContext(X11->display, d->context);
+        XDestroyWindow(X11->display, d->drawable);
+    }
+    if (d->oldDrawable && d->oldContext)
+        glXMakeCurrent(X11->display, d->oldDrawable, d->oldContext);
+}
+
 /*****************************************************************************
   QGLOverlayWidget (Internal overlay class for X11)
  *****************************************************************************/
@@ -1566,28 +1631,6 @@
     delete [] cmw;
 }
 
-void QGLExtensions::init()
-{
-    static bool init_done = false;
-
-    if (init_done)
-        return;
-    init_done = true;
-
-    QGLWidget dmy;
-    dmy.makeCurrent();
-    init_extensions();
-
-    // nvidia 9x.xx unix drivers contain a bug which requires us to call glFinish before releasing an fbo
-    // to avoid painting artifacts
-    const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
-    const int pos = versionString.indexOf("NVIDIA");
-    if (pos >= 0) {
-        const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat();
-        nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0;
-    }
-}
-
 // Solaris defines glXBindTexImageEXT as part of the GL library
 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
@@ -1603,14 +1646,21 @@
         resolvedTextureFromPixmap = true;
 
         // Check to see if we have NPOT texture support
-        if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) &&
+        if ( !(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures) &&
              !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
         {
             return false; // Can't use TFP without NPOT
         }
+
         const QX11Info *xinfo = qt_x11Info(paintDevice);
-        QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
-        if (extensions.match("GLX_EXT_texture_from_pixmap")) {
+        Display *display = xinfo ? xinfo->display() : X11->display;
+        int screen = xinfo ? xinfo->screen() : X11->defaultScreen;
+
+        QGLExtensionMatcher serverExtensions(glXQueryExtensionsString(display, screen));
+        QGLExtensionMatcher clientExtensions(glXGetClientString(display, GLX_EXTENSIONS));
+        if (serverExtensions.match("GLX_EXT_texture_from_pixmap")
+            && clientExtensions.match("GLX_EXT_texture_from_pixmap"))
+        {
             glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
             glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
         }