src/opengl/qgl_x11.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    51 #include "qlibrary.h"
    51 #include "qlibrary.h"
    52 #include "qdebug.h"
    52 #include "qdebug.h"
    53 #include <private/qfontengine_ft_p.h>
    53 #include <private/qfontengine_ft_p.h>
    54 #include <private/qt_x11_p.h>
    54 #include <private/qt_x11_p.h>
    55 #include <private/qpixmap_x11_p.h>
    55 #include <private/qpixmap_x11_p.h>
       
    56 #include <private/qimagepixmapcleanuphooks_p.h>
    56 #ifdef Q_OS_HPUX
    57 #ifdef Q_OS_HPUX
    57 // for GLXPBuffer
    58 // for GLXPBuffer
    58 #include <private/qglpixelbuffer_p.h>
    59 #include <private/qglpixelbuffer_p.h>
    59 #endif
    60 #endif
    60 
    61 
   340     typedef void* (*qt_glXGetProcAddressARB)(const char *);
   341     typedef void* (*qt_glXGetProcAddressARB)(const char *);
   341     static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
   342     static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
   342     static bool triedResolvingGlxGetProcAddress = false;
   343     static bool triedResolvingGlxGetProcAddress = false;
   343     if (!triedResolvingGlxGetProcAddress) {
   344     if (!triedResolvingGlxGetProcAddress) {
   344         triedResolvingGlxGetProcAddress = true;
   345         triedResolvingGlxGetProcAddress = true;
   345         QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
   346         QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
   346         if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) {
   347         if (extensions.match("GLX_ARB_get_proc_address")) {
   347 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
   348 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
   348             void *handle = dlopen(NULL, RTLD_LAZY);
   349             void *handle = dlopen(NULL, RTLD_LAZY);
   349             if (handle) {
   350             if (handle) {
   350                 glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
   351                 glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
   351                 dlclose(handle);
   352                 dlclose(handle);
   520                                               qt_x11Handle(d->paintDevice));
   521                                               qt_x11Handle(d->paintDevice));
   521 #endif
   522 #endif
   522         if (!d->gpm)
   523         if (!d->gpm)
   523             return false;
   524             return false;
   524     }
   525     }
   525     QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
   526     QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
   526     if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
   527     if (extensions.match("GLX_SGI_video_sync")) {
   527         if (d->glFormat.swapInterval() == -1)
   528         if (d->glFormat.swapInterval() == -1)
   528             d->glFormat.setSwapInterval(0);
   529             d->glFormat.setSwapInterval(0);
   529     } else {
   530     } else {
   530         d->glFormat.setSwapInterval(-1);
   531         d->glFormat.setSwapInterval(-1);
   531     }
   532     }
   627 
   628 
   628 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
   629 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
   629     static bool useTranspExt = false;
   630     static bool useTranspExt = false;
   630     static bool useTranspExtChecked = false;
   631     static bool useTranspExtChecked = false;
   631     if (f.plane() && !useTranspExtChecked && d->paintDevice) {
   632     if (f.plane() && !useTranspExtChecked && d->paintDevice) {
   632         QByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
   633         QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
   633         useTranspExt = estr.contains("GLX_EXT_visual_info");
   634         useTranspExt = extensions.match("GLX_EXT_visual_info");
   634         //# (A bit simplistic; that could theoretically be a substring)
   635         //# (A bit simplistic; that could theoretically be a substring)
   635         if (useTranspExt) {
   636         if (useTranspExt) {
   636             QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
   637             QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
   637             useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
   638             useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
   638             if (useTranspExt) {
   639             if (useTranspExt) {
   871             typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
   872             typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
   872             static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
   873             static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
   873             static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
   874             static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
   874             static bool resolved = false;
   875             static bool resolved = false;
   875             if (!resolved) {
   876             if (!resolved) {
   876                 QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
   877                 const QX11Info *xinfo = qt_x11Info(d->paintDevice);
   877                 if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
   878                 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
       
   879                 if (extensions.match("GLX_SGI_video_sync")) {
   878                     glXGetVideoSyncSGI =  (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
   880                     glXGetVideoSyncSGI =  (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
   879                     glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
   881                     glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
   880                 }
   882                 }
   881                 resolved = true;
   883                 resolved = true;
   882             }
   884             }
  1103     static bool resolved = false;
  1105     static bool resolved = false;
  1104 
  1106 
  1105     if (resolved && !glXGetProcAddressARB)
  1107     if (resolved && !glXGetProcAddressARB)
  1106         return 0;
  1108         return 0;
  1107     if (!glXGetProcAddressARB) {
  1109     if (!glXGetProcAddressARB) {
  1108         QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
  1110         QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
  1109         if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) {
  1111         if (extensions.match("GLX_ARB_get_proc_address")) {
  1110 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
  1112 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
  1111             void *handle = dlopen(NULL, RTLD_LAZY);
  1113             void *handle = dlopen(NULL, RTLD_LAZY);
  1112             if (handle) {
  1114             if (handle) {
  1113                 glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
  1115                 glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
  1114                 dlclose(handle);
  1116                 dlclose(handle);
  1591 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
  1593 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
  1592 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
  1594 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
  1593 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
  1595 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
  1594 static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
  1596 static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
  1595 
  1597 
  1596 bool qt_resolveTextureFromPixmap()
  1598 static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
  1597 {
  1599 {
  1598     static bool resolvedTextureFromPixmap = false;
  1600     static bool resolvedTextureFromPixmap = false;
  1599 
  1601 
  1600     if (!resolvedTextureFromPixmap) {
  1602     if (!resolvedTextureFromPixmap) {
  1601         resolvedTextureFromPixmap = true;
  1603         resolvedTextureFromPixmap = true;
  1604         if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) &&
  1606         if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) &&
  1605              !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
  1607              !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
  1606         {
  1608         {
  1607             return false; // Can't use TFP without NPOT
  1609             return false; // Can't use TFP without NPOT
  1608         }
  1610         }
  1609 
  1611         const QX11Info *xinfo = qt_x11Info(paintDevice);
  1610         QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
  1612         QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
  1611         if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) {
  1613         if (extensions.match("GLX_EXT_texture_from_pixmap")) {
  1612             glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
  1614             glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
  1613             glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
  1615             glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
  1614         }
  1616         }
  1615     }
  1617     }
  1616 
  1618 
  1627 #else
  1629 #else
  1628     Q_Q(QGLContext);
  1630     Q_Q(QGLContext);
  1629 
  1631 
  1630     Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
  1632     Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
  1631 
  1633 
  1632     if (!qt_resolveTextureFromPixmap())
  1634     if (!qt_resolveTextureFromPixmap(paintDevice))
  1633         return 0;
  1635         return 0;
  1634 
  1636 
  1635     QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
  1637     QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
  1636     const QX11Info &x11Info = pixmapData->xinfo;
  1638     const QX11Info &x11Info = pixmapData->xinfo;
  1637 
  1639 
  1702             return 0;
  1704             return 0;
  1703 
  1705 
  1704         pixmapData->gl_surface = (Qt::HANDLE)glxPixmap;
  1706         pixmapData->gl_surface = (Qt::HANDLE)glxPixmap;
  1705 
  1707 
  1706         // Make sure the cleanup hook gets called so we can delete the glx pixmap
  1708         // Make sure the cleanup hook gets called so we can delete the glx pixmap
  1707         pixmapData->is_cached = true;
  1709         QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData);
  1708     }
  1710     }
  1709 
  1711 
  1710     GLuint textureId;
  1712     GLuint textureId;
  1711     glGenTextures(1, &textureId);
  1713     glGenTextures(1, &textureId);
  1712     glBindTexture(GL_TEXTURE_2D, textureId);
  1714     glBindTexture(GL_TEXTURE_2D, textureId);