Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/opengl/qgl_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtOpenGL module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5353#include <private/qfontengine_ft_p.h>
    5454#include <private/qt_x11_p.h>
     55#include <private/qpixmap_x11_p.h>
     56#include <private/qimagepixmapcleanuphooks_p.h>
    5557#ifdef Q_OS_HPUX
    5658// for GLXPBuffer
    5759#include <private/qglpixelbuffer_p.h>
    5860#endif
     61
     62// We always define GLX_EXT_texture_from_pixmap ourselves because
     63// we can't trust system headers to do it properly
     64#define GLX_EXT_texture_from_pixmap 1
    5965
    6066#define INT8  dummy_INT8
     
    6369#undef  INT8
    6470#undef  INT32
     71
    6572#include <X11/Xlib.h>
    6673#include <X11/Xutil.h>
    6774#include <X11/Xos.h>
     75#ifdef Q_OS_VXWORS
     76#  ifdef open
     77#    undef open
     78#  endif
     79#  ifdef getpid
     80#    undef getpid
     81#  endif
     82#endif // Q_OS_VXWORKS
    6883#include <X11/Xatom.h>
    6984
     
    8095#define GLX_SAMPLE_BUFFERS_ARB  100000
    8196#define GLX_SAMPLES_ARB         100001
     97#endif
     98
     99#ifndef GLX_TEXTURE_2D_BIT_EXT
     100#define GLX_TEXTURE_2D_BIT_EXT             0x00000002
     101#define GLX_TEXTURE_RECTANGLE_BIT_EXT      0x00000004
     102#define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
     103#define GLX_BIND_TO_TEXTURE_RGBA_EXT       0x20D1
     104#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT     0x20D2
     105#define GLX_BIND_TO_TEXTURE_TARGETS_EXT    0x20D3
     106#define GLX_Y_INVERTED_EXT                 0x20D4
     107#define GLX_TEXTURE_FORMAT_EXT             0x20D5
     108#define GLX_TEXTURE_TARGET_EXT             0x20D6
     109#define GLX_MIPMAP_TEXTURE_EXT             0x20D7
     110#define GLX_TEXTURE_FORMAT_NONE_EXT        0x20D8
     111#define GLX_TEXTURE_FORMAT_RGB_EXT         0x20D9
     112#define GLX_TEXTURE_FORMAT_RGBA_EXT        0x20DA
     113#define GLX_TEXTURE_2D_EXT                 0x20DC
     114#define GLX_TEXTURE_RECTANGLE_EXT          0x20DD
     115#define GLX_FRONT_LEFT_EXT                 0x20DE
    82116#endif
    83117
     
    130164    GLCMapHash *qglcmap_hash;
    131165};
    132 Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler);
     166Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler)
    133167
    134168static void cleanup_cmaps()
     
    298332  QGLFormat UNIX/GLX-specific code
    299333 *****************************************************************************/
     334
     335void* qglx_getProcAddress(const char* procName)
     336{
     337    // On systems where the GL driver is pluggable (like Mesa), we have to use
     338    // the glXGetProcAddressARB extension to resolve other function pointers as
     339    // the symbols wont be in the GL library, but rather in a plugin loaded by
     340    // the GL library.
     341    typedef void* (*qt_glXGetProcAddressARB)(const char *);
     342    static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
     343    static bool triedResolvingGlxGetProcAddress = false;
     344    if (!triedResolvingGlxGetProcAddress) {
     345        triedResolvingGlxGetProcAddress = true;
     346        QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
     347        if (extensions.match("GLX_ARB_get_proc_address")) {
     348#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
     349            void *handle = dlopen(NULL, RTLD_LAZY);
     350            if (handle) {
     351                glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
     352                dlclose(handle);
     353            }
     354            if (!glXGetProcAddressARB)
     355#endif
     356            {
     357#if !defined(QT_NO_LIBRARY)
     358                extern const QString qt_gl_library_name();
     359                QLibrary lib(qt_gl_library_name());
     360                glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
     361#endif
     362            }
     363        }
     364    }
     365
     366    void *procAddress = 0;
     367    if (glXGetProcAddressARB)
     368        procAddress = glXGetProcAddressARB(procName);
     369
     370    // If glXGetProcAddress didn't work, try looking the symbol up in the GL library
     371#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
     372    if (!procAddress) {
     373        void *handle = dlopen(NULL, RTLD_LAZY);
     374        if (handle) {
     375            procAddress = dlsym(handle, procName);
     376            dlclose(handle);
     377        }
     378    }
     379#endif
     380#if !defined(QT_NO_LIBRARY)
     381    if (!procAddress) {
     382        extern const QString qt_gl_library_name();
     383        QLibrary lib(qt_gl_library_name());
     384        procAddress = lib.resolve(procName);
     385    }
     386#endif
     387
     388    return procAddress;
     389}
    300390
    301391bool QGLFormat::hasOpenGL()
     
    434524            return false;
    435525    }
    436     QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));
    437     if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
     526    QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
     527    if (extensions.match("GLX_SGI_video_sync")) {
    438528        if (d->glFormat.swapInterval() == -1)
    439529            d->glFormat.setSwapInterval(0);
     
    444534}
    445535
    446 
    447 /*!
    448   \bold{X11 only:} This virtual function tries to find a
    449   visual that matches the format, reducing the demands if the original
    450   request cannot be met.
    451 
    452   The algorithm for reducing the demands of the format is quite
    453   simple-minded, so override this method in your subclass if your
    454   application has spcific requirements on visual selection.
    455 
    456   \sa chooseContext()
    457 */
    458 
     536/*
     537  See qgl.cpp for qdoc comment.
     538 */
    459539void *QGLContext::chooseVisual()
    460540{
     
    520600}
    521601
    522 
    523 /*!
    524   \internal
    525 
    526   \bold{X11 only:} This virtual function chooses a visual
    527   that matches the OpenGL \link format() format\endlink. Reimplement this
    528   function in a subclass if you need a custom visual.
    529 
    530   \sa chooseContext()
    531 */
    532 
     602/*
     603  See qgl.cpp for qdoc comment.
     604 */
    533605void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
    534606{
    535607    Q_D(QGLContext);
    536     int spec[40];
     608    int spec[45];
    537609    int i = 0;
    538610    spec[i++] = GLX_LEVEL;
    539611    spec[i++] = f.plane();
    540612    const QX11Info *xinfo = qt_x11Info(d->paintDevice);
     613    bool useFBConfig = false;
     614
     615#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX)
     616    /*
     617      HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
     618      Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
     619     */
     620    QWidget* widget = 0;
     621    if (d->paintDevice->devType() == QInternal::Widget)
     622        widget = static_cast<QWidget*>(d->paintDevice);
     623
     624    // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual
     625    if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender)
     626        useFBConfig = true;
     627#endif
    541628
    542629#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
     
    544631    static bool useTranspExtChecked = false;
    545632    if (f.plane() && !useTranspExtChecked && d->paintDevice) {
    546         QByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
    547         useTranspExt = estr.contains("GLX_EXT_visual_info");
     633        QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
     634        useTranspExt = extensions.match("GLX_EXT_visual_info");
    548635        //# (A bit simplistic; that could theoretically be a substring)
    549636        if (useTranspExt) {
     
    566653        useTranspExtChecked = true;
    567654    }
    568     if (f.plane() && useTranspExt) {
     655    if (f.plane() && useTranspExt && !useFBConfig) {
    569656        // Required to avoid non-transparent overlay visual(!) on some systems
    570657        spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
     
    573660#endif
    574661
     662#if defined(GLX_VERSION_1_3)  && !defined(Q_OS_HPUX)
     663    // GLX_RENDER_TYPE is only in glx >=1.3
     664    if (useFBConfig) {
     665        spec[i++] = GLX_RENDER_TYPE;
     666        spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
     667    }
     668#endif
     669
    575670    if (f.doubleBuffer())
    576671        spec[i++] = GLX_DOUBLEBUFFER;
     672        if (useFBConfig)
     673            spec[i++] = True;
    577674    if (f.depth()) {
    578675        spec[i++] = GLX_DEPTH_SIZE;
     
    581678    if (f.stereo()) {
    582679        spec[i++] = GLX_STEREO;
     680        if (useFBConfig)
     681            spec[i++] = True;
    583682    }
    584683    if (f.stencil()) {
     
    587686    }
    588687    if (f.rgba()) {
    589         spec[i++] = GLX_RGBA;
     688        if (!useFBConfig)
     689            spec[i++] = GLX_RGBA;
    590690        spec[i++] = GLX_RED_SIZE;
    591691        spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
     
    622722    }
    623723
     724#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     725    if (useFBConfig) {
     726        spec[i++] = GLX_DRAWABLE_TYPE;
     727        switch(d->paintDevice->devType()) {
     728        case QInternal::Pixmap:
     729            spec[i++] = GLX_PIXMAP_BIT;
     730            break;
     731        case QInternal::Pbuffer:
     732            spec[i++] = GLX_PBUFFER_BIT;
     733            break;
     734        default:
     735            qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType());
     736            // Fall-through & assume it's a window
     737        case QInternal::Widget:
     738            spec[i++] = GLX_WINDOW_BIT;
     739            break;
     740        };
     741    }
     742#endif
     743
    624744    spec[i] = XNone;
    625     return glXChooseVisual(xinfo->display(), xinfo->screen(), spec);
     745
     746
     747    XVisualInfo* chosenVisualInfo = 0;
     748
     749#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     750    while (useFBConfig) {
     751        GLXFBConfig *configs;
     752        int configCount = 0;
     753        configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount);
     754
     755        if (!configs)
     756            break; // fallback to trying glXChooseVisual
     757
     758        for (i = 0; i < configCount; ++i) {
     759            XVisualInfo* vi;
     760            vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]);
     761            if (!vi)
     762                continue;
     763
     764#if !defined(QT_NO_XRENDER)
     765            QWidget* w = 0;
     766            if (d->paintDevice->devType() == QInternal::Widget)
     767                w = static_cast<QWidget*>(d->paintDevice);
     768
     769            if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) {
     770                // Attempt to find a config who's visual has a proper alpha channel
     771                XRenderPictFormat *pictFormat;
     772                pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual);
     773
     774                if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) {
     775                    // The pict format for the visual matching the FBConfig indicates ARGB
     776                    if (chosenVisualInfo)
     777                        XFree(chosenVisualInfo);
     778                    chosenVisualInfo = vi;
     779                    break;
     780                }
     781            } else
     782#endif //QT_NO_XRENDER
     783            if (chosenVisualInfo) {
     784                // If we've got a visual we can use and we're not trying to find one with a
     785                // real alpha channel, we might as well just use the one we've got
     786                break;
     787            }
     788
     789            if (!chosenVisualInfo)
     790                chosenVisualInfo = vi; // Have something to fall back to
     791            else
     792                XFree(vi);
     793        }
     794
     795        XFree(configs);
     796        break;
     797    }
     798#endif // defined(GLX_VERSION_1_3)
     799
     800    if (!chosenVisualInfo)
     801        chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec);
     802
     803    return chosenVisualInfo;
    626804}
    627805
     
    671849        qWarning("QGLContext::makeCurrent(): Failed.");
    672850
    673     if (ok) {
    674         if (!qgl_context_storage.hasLocalData() && QThread::currentThread())
    675             qgl_context_storage.setLocalData(new QGLThreadContext);
    676         if (qgl_context_storage.hasLocalData())
    677             qgl_context_storage.localData()->context = this;
    678         currentCtx = this;
    679     }
     851    if (ok)
     852        QGLContextPrivate::setCurrentContext(this);
    680853}
    681854
     
    684857    Q_D(QGLContext);
    685858    glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0);
    686     if (qgl_context_storage.hasLocalData())
    687         qgl_context_storage.localData()->context = 0;
    688     currentCtx = 0;
     859    QGLContextPrivate::setCurrentContext(0);
    689860}
    690861
     
    704875            static bool resolved = false;
    705876            if (!resolved) {
    706                 QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));
    707                 if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
    708 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
    709                     void *handle = dlopen(NULL, RTLD_LAZY);
    710                     if (handle) {
    711                         glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI");
    712                         glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI");
    713                         dlclose(handle);
    714                     }
    715                     if (!glXGetVideoSyncSGI)
    716 #endif
    717                     {
    718                         extern const QString qt_gl_library_name();
    719                         QLibrary lib(qt_gl_library_name());
    720                         glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI");
    721                         glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI");
    722                     }
     877                const QX11Info *xinfo = qt_x11Info(d->paintDevice);
     878                QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
     879                if (extensions.match("GLX_SGI_video_sync")) {
     880                    glXGetVideoSyncSGI =  (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
     881                    glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
    723882                }
    724883                resolved = true;
     
    9491108        return 0;
    9501109    if (!glXGetProcAddressARB) {
    951         QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));
    952         if (glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) {
     1110        QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
     1111        if (extensions.match("GLX_ARB_get_proc_address")) {
    9531112#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
    9541113            void *handle = dlopen(NULL, RTLD_LAZY);
     
    9601119#endif
    9611120            {
     1121#if !defined(QT_NO_LIBRARY)
    9621122                extern const QString qt_gl_library_name();
    9631123                QLibrary lib(qt_gl_library_name());
    9641124                glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
     1125#endif
    9651126            }
    9661127        }
     
    11841345    d->glcx = context;
    11851346
    1186 
    11871347    if (parentWidget()) {
    11881348        // force creation of delay-created widgets
     
    11911351            d_func()->xinfo = parentWidget()->d_func()->xinfo;
    11921352    }
     1353
     1354    // If the application has set WA_TranslucentBackground and not explicitly set
     1355    // the alpha buffer size to zero, modify the format so it have an alpha channel
     1356    QGLFormat& fmt = d->glcx->d_func()->glFormat;
     1357    if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1)
     1358        fmt.setAlphaBufferSize(1);
    11931359
    11941360    bool createFailed = false;
     
    14231589}
    14241590
     1591// Solaris defines glXBindTexImageEXT as part of the GL library
     1592#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     1593typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
     1594typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
     1595static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
     1596static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
     1597
     1598static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
     1599{
     1600    static bool resolvedTextureFromPixmap = false;
     1601
     1602    if (!resolvedTextureFromPixmap) {
     1603        resolvedTextureFromPixmap = true;
     1604
     1605        // Check to see if we have NPOT texture support
     1606        if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) &&
     1607             !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
     1608        {
     1609            return false; // Can't use TFP without NPOT
     1610        }
     1611        const QX11Info *xinfo = qt_x11Info(paintDevice);
     1612        QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
     1613        if (extensions.match("GLX_EXT_texture_from_pixmap")) {
     1614            glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
     1615            glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
     1616        }
     1617    }
     1618
     1619    return glXBindTexImageEXT && glXReleaseTexImageEXT;
     1620}
     1621#endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     1622
     1623
     1624QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, const qint64 key,
     1625                                                           QGLContext::BindOptions options)
     1626{
     1627#if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
     1628    return 0;
     1629#else
     1630    Q_Q(QGLContext);
     1631
     1632    Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
     1633
     1634    if (!qt_resolveTextureFromPixmap(paintDevice))
     1635        return 0;
     1636
     1637    QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
     1638    const QX11Info &x11Info = pixmapData->xinfo;
     1639
     1640    // Store the configs (Can be static because configs aren't dependent on current context)
     1641    static GLXFBConfig glxRGBPixmapConfig = 0;
     1642    static bool RGBConfigInverted = false;
     1643    static GLXFBConfig glxRGBAPixmapConfig = 0;
     1644    static bool RGBAConfigInverted = false;
     1645
     1646    bool hasAlpha = pixmapData->hasAlphaChannel();
     1647
     1648    // Check to see if we need a config
     1649    if ( (hasAlpha && !glxRGBAPixmapConfig) || (!hasAlpha && !glxRGBPixmapConfig) ) {
     1650        GLXFBConfig    *configList = 0;
     1651        int             configCount = 0;
     1652
     1653        int configAttribs[] = {
     1654            hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True,
     1655            GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
     1656            GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
     1657            // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can:
     1658            GLX_Y_INVERTED_EXT, options & QGLContext::CanFlipNativePixmapBindOption ? GLX_DONT_CARE : False,
     1659            XNone
     1660        };
     1661        configList = glXChooseFBConfig(x11Info.display(), x11Info.screen(), configAttribs, &configCount);
     1662        if (!configList)
     1663            return 0;
     1664
     1665        int yInv;
     1666        glXGetFBConfigAttrib(x11Info.display(), configList[0], GLX_Y_INVERTED_EXT, &yInv);
     1667
     1668        if (hasAlpha) {
     1669            glxRGBAPixmapConfig = configList[0];
     1670            RGBAConfigInverted = yInv;
     1671        }
     1672        else {
     1673            glxRGBPixmapConfig = configList[0];
     1674            RGBConfigInverted = yInv;
     1675        }
     1676
     1677        XFree(configList);
     1678    }
     1679
     1680    // Check to see if the surface is still valid
     1681    if (pixmapData->gl_surface &&
     1682        hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
     1683    {
     1684        // Surface is invalid!
     1685        destroyGlSurfaceForPixmap(pixmapData);
     1686    }
     1687
     1688    // Check to see if we need a surface
     1689    if (!pixmapData->gl_surface) {
     1690        GLXPixmap glxPixmap;
     1691        int pixmapAttribs[] = {
     1692            GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
     1693            GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
     1694            GLX_MIPMAP_TEXTURE_EXT, False, // Maybe needs to be don't care
     1695            XNone
     1696        };
     1697
     1698        // Wrap the X Pixmap into a GLXPixmap:
     1699        glxPixmap = glXCreatePixmap(x11Info.display(),
     1700                                    hasAlpha ? glxRGBAPixmapConfig : glxRGBPixmapConfig,
     1701                                    pixmapData->handle(), pixmapAttribs);
     1702
     1703        if (!glxPixmap)
     1704            return 0;
     1705
     1706        pixmapData->gl_surface = (Qt::HANDLE)glxPixmap;
     1707
     1708        // Make sure the cleanup hook gets called so we can delete the glx pixmap
     1709        QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData);
     1710    }
     1711
     1712    GLuint textureId;
     1713    glGenTextures(1, &textureId);
     1714    glBindTexture(GL_TEXTURE_2D, textureId);
     1715    glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0);
     1716
     1717    glBindTexture(GL_TEXTURE_2D, textureId);
     1718
     1719    if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
     1720        options &= ~QGLContext::InvertedYBindOption;
     1721
     1722    QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
     1723    if (texture->options & QGLContext::InvertedYBindOption)
     1724        pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;
     1725
     1726    // We assume the cost of bound pixmaps is zero
     1727    QGLTextureCache::instance()->insert(q, key, texture, 0);
     1728
     1729    return texture;
     1730#endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
     1731}
     1732
     1733
     1734void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd)
     1735{
     1736#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     1737    Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
     1738    QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
     1739    if (pixmapData->gl_surface) {
     1740        glXDestroyPixmap(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface);
     1741        pixmapData->gl_surface = 0;
     1742    }
     1743#endif
     1744}
     1745
     1746void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd)
     1747{
     1748#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     1749    Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
     1750    Q_ASSERT(QGLContext::currentContext());
     1751    QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
     1752    if (pixmapData->gl_surface)
     1753        glXReleaseTexImageEXT(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT);
     1754#endif
     1755}
     1756
    14251757QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.