Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/opengl/qgl_x11.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5555#include <private/qpixmap_x11_p.h>
    5656#include <private/qimagepixmapcleanuphooks_p.h>
     57#include <private/qunicodetables_p.h>
    5758#ifdef Q_OS_HPUX
    5859// for GLXPBuffer
     
    114115#define GLX_TEXTURE_RECTANGLE_EXT          0x20DD
    115116#define GLX_FRONT_LEFT_EXT                 0x20DE
     117#endif
     118
     119#ifndef GLX_ARB_create_context
     120#define GLX_CONTEXT_DEBUG_BIT_ARB          0x00000001
     121#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
     122#define GLX_CONTEXT_MAJOR_VERSION_ARB      0x2091
     123#define GLX_CONTEXT_MINOR_VERSION_ARB      0x2092
     124#define GLX_CONTEXT_FLAGS_ARB              0x2094
     125#endif
     126
     127#ifndef GLX_ARB_create_context_profile
     128#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB   0x00000001
     129#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
     130#define GLX_CONTEXT_PROFILE_MASK_ARB       0x9126
    116131#endif
    117132
     
    400415        find_trans_colors();
    401416    return trans_colors.size() > 0;
     417}
     418
     419static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice,
     420                      int bufDepth, bool onlyFBConfig = false)
     421{
     422    int i = 0;
     423    spec[i++] = GLX_LEVEL;
     424    spec[i++] = f.plane();
     425    const QX11Info *xinfo = qt_x11Info(paintDevice);
     426    bool useFBConfig = onlyFBConfig;
     427
     428#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX)
     429    /*
     430      HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
     431      Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
     432     */
     433    QWidget* widget = 0;
     434    if (paintDevice->devType() == QInternal::Widget)
     435        widget = static_cast<QWidget*>(paintDevice);
     436
     437    // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual
     438    if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender)
     439        useFBConfig = true;
     440#endif
     441
     442#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
     443    static bool useTranspExt = false;
     444    static bool useTranspExtChecked = false;
     445    if (f.plane() && !useTranspExtChecked && paintDevice) {
     446        QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
     447        useTranspExt = extensions.match("GLX_EXT_visual_info");
     448        //# (A bit simplistic; that could theoretically be a substring)
     449        if (useTranspExt) {
     450            QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
     451            useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
     452            if (useTranspExt) {
     453                // bug workaround - some systems (eg. FireGL) refuses to return an overlay
     454                // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if
     455                // the implementation supports transparent overlays
     456                int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
     457                                  f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
     458                                  XNone };
     459                XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec);
     460                if (!vinf) {
     461                    useTranspExt = false;
     462                }
     463            }
     464        }
     465
     466        useTranspExtChecked = true;
     467    }
     468    if (f.plane() && useTranspExt && !useFBConfig) {
     469        // Required to avoid non-transparent overlay visual(!) on some systems
     470        spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
     471        spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
     472    }
     473#endif
     474
     475#if defined(GLX_VERSION_1_3)  && !defined(Q_OS_HPUX)
     476    // GLX_RENDER_TYPE is only in glx >=1.3
     477    if (useFBConfig) {
     478        spec[i++] = GLX_RENDER_TYPE;
     479        spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
     480    }
     481#endif
     482
     483    if (f.doubleBuffer())
     484        spec[i++] = GLX_DOUBLEBUFFER;
     485        if (useFBConfig)
     486            spec[i++] = True;
     487    if (f.depth()) {
     488        spec[i++] = GLX_DEPTH_SIZE;
     489        spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
     490    }
     491    if (f.stereo()) {
     492        spec[i++] = GLX_STEREO;
     493        if (useFBConfig)
     494            spec[i++] = True;
     495    }
     496    if (f.stencil()) {
     497        spec[i++] = GLX_STENCIL_SIZE;
     498        spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
     499    }
     500    if (f.rgba()) {
     501        if (!useFBConfig)
     502            spec[i++] = GLX_RGBA;
     503        spec[i++] = GLX_RED_SIZE;
     504        spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
     505        spec[i++] = GLX_GREEN_SIZE;
     506        spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
     507        spec[i++] = GLX_BLUE_SIZE;
     508        spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
     509        if (f.alpha()) {
     510            spec[i++] = GLX_ALPHA_SIZE;
     511            spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
     512        }
     513        if (f.accum()) {
     514            spec[i++] = GLX_ACCUM_RED_SIZE;
     515            spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
     516            spec[i++] = GLX_ACCUM_GREEN_SIZE;
     517            spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
     518            spec[i++] = GLX_ACCUM_BLUE_SIZE;
     519            spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
     520            if (f.alpha()) {
     521                spec[i++] = GLX_ACCUM_ALPHA_SIZE;
     522                spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
     523            }
     524        }
     525    } else {
     526        spec[i++] = GLX_BUFFER_SIZE;
     527        spec[i++] = bufDepth;
     528    }
     529
     530    if (f.sampleBuffers()) {
     531        spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
     532        spec[i++] = 1;
     533        spec[i++] = GLX_SAMPLES_ARB;
     534        spec[i++] = f.samples() == -1 ? 4 : f.samples();
     535    }
     536
     537#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     538    if (useFBConfig) {
     539        spec[i++] = GLX_DRAWABLE_TYPE;
     540        switch(paintDevice->devType()) {
     541        case QInternal::Pixmap:
     542            spec[i++] = GLX_PIXMAP_BIT;
     543            break;
     544        case QInternal::Pbuffer:
     545            spec[i++] = GLX_PBUFFER_BIT;
     546            break;
     547        default:
     548            qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType());
     549            // Fall-through & assume it's a window
     550        case QInternal::Widget:
     551            spec[i++] = GLX_WINDOW_BIT;
     552            break;
     553        };
     554    }
     555#endif
     556
     557    spec[i] = XNone;
     558    return useFBConfig;
    402559}
    403560
     
    494651    }
    495652
     653    const int major = d->reqFormat.majorVersion();
     654    const int minor = d->reqFormat.minorVersion();
     655    const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile
     656        ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
     657        : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
     658
    496659    d->cx = 0;
    497     if (shareContext) {
     660
     661#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
     662    /*
     663      HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
     664      Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
     665     */
     666    if ((major == 3 && minor >= 2) || major > 3) {
     667        QGLTemporaryContext *tmpContext = 0;
     668        if (!QGLContext::currentContext())
     669            tmpContext = new QGLTemporaryContext;
     670
     671        int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major,
     672                             GLX_CONTEXT_MINOR_VERSION_ARB, minor,
     673                             GLX_CONTEXT_PROFILE_MASK_ARB, profile,
     674                             0 };
     675
     676        typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC)
     677            (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
     678
     679
     680        Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
     681            (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB");
     682
     683        if (glXCreateContextAttribs) {
     684            int spec[45];
     685            glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res);
     686            buildSpec(spec, format(), d->paintDevice, res, true);
     687
     688            GLXFBConfig *configs;
     689            int configCount = 0;
     690            configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount);
     691
     692            if (configs && configCount > 0) {
     693                d->cx = glXCreateContextAttribs(disp, configs[0],
     694                    shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes);
     695                if (!d->cx && shareContext) {
     696                    shareContext = 0;
     697                    d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes);
     698                }
     699                d->screen = ((XVisualInfo*)d->vi)->screen;
     700            }
     701            XFree(configs);
     702        } else {
     703            qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor);
     704        }
     705
     706        if (tmpContext)
     707            delete tmpContext;
     708    }
     709#else
     710    Q_UNUSED(major);
     711    Q_UNUSED(minor);
     712    Q_UNUSED(profile);
     713#endif
     714
     715    if (!d->cx && shareContext) {
    498716        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,
    499717                               (GLXContext)shareContext->d_func()->cx, direct);
    500718        d->screen = ((XVisualInfo*)d->vi)->screen;
    501         if (d->cx) {
    502             QGLContext *share = const_cast<QGLContext *>(shareContext);
    503             d->sharing = true;
    504             share->d_func()->sharing = true;
    505         }
    506719    }
    507720    if (!d->cx) {
    508721        d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);
    509722        d->screen = ((XVisualInfo*)d->vi)->screen;
    510     }
     723        shareContext = 0;
     724    }
     725
     726    if (shareContext && d->cx) {
     727        QGLContext *share = const_cast<QGLContext *>(shareContext);
     728        d->sharing = true;
     729        share->d_func()->sharing = true;
     730    }
     731
    511732    if (!d->cx)
    512733        return false;
     
    607828    Q_D(QGLContext);
    608829    int spec[45];
    609     int i = 0;
    610     spec[i++] = GLX_LEVEL;
    611     spec[i++] = f.plane();
    612830    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
    628 
    629 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
    630     static bool useTranspExt = false;
    631     static bool useTranspExtChecked = false;
    632     if (f.plane() && !useTranspExtChecked && d->paintDevice) {
    633         QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
    634         useTranspExt = extensions.match("GLX_EXT_visual_info");
    635         //# (A bit simplistic; that could theoretically be a substring)
    636         if (useTranspExt) {
    637             QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
    638             useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
    639             if (useTranspExt) {
    640                 // bug workaround - some systems (eg. FireGL) refuses to return an overlay
    641                 // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if
    642                 // the implementation supports transparent overlays
    643                 int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
    644                                   f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
    645                                   XNone };
    646                 XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec);
    647                 if (!vinf) {
    648                     useTranspExt = false;
    649                 }
    650             }
    651         }
    652 
    653         useTranspExtChecked = true;
    654     }
    655     if (f.plane() && useTranspExt && !useFBConfig) {
    656         // Required to avoid non-transparent overlay visual(!) on some systems
    657         spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
    658         spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
    659     }
    660 #endif
    661 
    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 
    670     if (f.doubleBuffer())
    671         spec[i++] = GLX_DOUBLEBUFFER;
    672         if (useFBConfig)
    673             spec[i++] = True;
    674     if (f.depth()) {
    675         spec[i++] = GLX_DEPTH_SIZE;
    676         spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
    677     }
    678     if (f.stereo()) {
    679         spec[i++] = GLX_STEREO;
    680         if (useFBConfig)
    681             spec[i++] = True;
    682     }
    683     if (f.stencil()) {
    684         spec[i++] = GLX_STENCIL_SIZE;
    685         spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
    686     }
    687     if (f.rgba()) {
    688         if (!useFBConfig)
    689             spec[i++] = GLX_RGBA;
    690         spec[i++] = GLX_RED_SIZE;
    691         spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
    692         spec[i++] = GLX_GREEN_SIZE;
    693         spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
    694         spec[i++] = GLX_BLUE_SIZE;
    695         spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
    696         if (f.alpha()) {
    697             spec[i++] = GLX_ALPHA_SIZE;
    698             spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
    699         }
    700         if (f.accum()) {
    701             spec[i++] = GLX_ACCUM_RED_SIZE;
    702             spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
    703             spec[i++] = GLX_ACCUM_GREEN_SIZE;
    704             spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
    705             spec[i++] = GLX_ACCUM_BLUE_SIZE;
    706             spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
    707             if (f.alpha()) {
    708                 spec[i++] = GLX_ACCUM_ALPHA_SIZE;
    709                 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
    710             }
    711         }
    712     } else {
    713         spec[i++] = GLX_BUFFER_SIZE;
    714         spec[i++] = bufDepth;
    715     }
    716 
    717     if (f.sampleBuffers()) {
    718         spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
    719         spec[i++] = 1;
    720         spec[i++] = GLX_SAMPLES_ARB;
    721         spec[i++] = f.samples() == -1 ? 4 : f.samples();
    722     }
    723 
    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 
    744     spec[i] = XNone;
    745 
     831    bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false);
    746832
    747833    XVisualInfo* chosenVisualInfo = 0;
     
    756842            break; // fallback to trying glXChooseVisual
    757843
    758         for (i = 0; i < configCount; ++i) {
     844        for (int i = 0; i < configCount; ++i) {
    759845            XVisualInfo* vi;
    760846            vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]);
     
    844930        ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx);
    845931    } else if (d->paintDevice->devType() == QInternal::Widget) {
    846         ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->winId(), (GLXContext)d->cx);
     932        ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx);
    847933    }
    848934    if (!ok)
     
    16721758
    16731759
    1674 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, const qint64 key,
     1760QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
    16751761                                                           QGLContext::BindOptions options)
    16761762{
     
    16781764    return 0;
    16791765#else
     1766
     1767    // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap
     1768    int majorVersion = 0;
     1769    int minorVersion = 0;
     1770    glXQueryVersion(X11->display, &majorVersion, &minorVersion);
     1771    if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3))
     1772        return 0;
     1773
    16801774    Q_Q(QGLContext);
    16811775
    1682     Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
     1776    QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
     1777    Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
     1778
     1779    // We can't use TFP if the pixmap has a separate X11 mask
     1780    if (pixmapData->x11_mask)
     1781        return 0;
    16831782
    16841783    if (!qt_resolveTextureFromPixmap(paintDevice))
    16851784        return 0;
    16861785
    1687     QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
    16881786    const QX11Info &x11Info = pixmapData->xinfo;
    16891787
     
    17541852            return 0;
    17551853
    1756         pixmapData->gl_surface = (Qt::HANDLE)glxPixmap;
     1854        pixmapData->gl_surface = (void*)glxPixmap;
    17571855
    17581856        // Make sure the cleanup hook gets called so we can delete the glx pixmap
     
    17661864
    17671865    glBindTexture(GL_TEXTURE_2D, textureId);
     1866    GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST;
     1867    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
     1868    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
    17681869
    17691870    if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
Note: See TracChangeset for help on using the changeset viewer.