Exemplo n.º 1
0
XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format)
{
    Q_ASSERT(format);

    XVisualInfo *visualInfo = 0;

    GLXFBConfig config = qglx_findConfig(display,screen,*format);
    if (config) {
        visualInfo = glXGetVisualFromFBConfig(display, config);
        *format = qglx_surfaceFormatFromGLXFBConfig(display, config);
    }

    // attempt to fall back to glXChooseVisual
    bool reduced = true;
    QSurfaceFormat reducedFormat = *format;
    while (!visualInfo && reduced) {
        QVarLengthArray<int, 13> attribs;
        attribs.append(GLX_RGBA);

        if (reducedFormat.redBufferSize() > 0) {
            attribs.append(GLX_RED_SIZE);
            attribs.append(reducedFormat.redBufferSize());
        }

        if (reducedFormat.greenBufferSize() > 0) {
            attribs.append(GLX_GREEN_SIZE);
            attribs.append(reducedFormat.greenBufferSize());
        }

        if (reducedFormat.blueBufferSize() > 0) {
            attribs.append(GLX_BLUE_SIZE);
            attribs.append(reducedFormat.blueBufferSize());
        }

        if (reducedFormat.stencilBufferSize() > 0) {
            attribs.append(GLX_STENCIL_SIZE);
            attribs.append(reducedFormat.stencilBufferSize());
        }

        if (reducedFormat.depthBufferSize() > 0) {
            attribs.append(GLX_DEPTH_SIZE);
            attribs.append(reducedFormat.depthBufferSize());
        }

        if (reducedFormat.swapBehavior() != QSurfaceFormat::SingleBuffer)
            attribs.append(GLX_DOUBLEBUFFER);

        attribs.append(XNone);

        visualInfo = glXChooseVisual(display, screen, attribs.data());
        if (visualInfo)
            *format = reducedFormat;

        reducedFormat = qglx_reduceSurfaceFormat(reducedFormat, &reduced);
    }

    return visualInfo;
}
QT_BEGIN_NAMESPACE

QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen)
    : m_display(display)
{
    qDebug("creating XComposite-GLX context");
    GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0;
    GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_WINDOW_BIT | GLX_PIXMAP_BIT);
    XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config);
    m_context = glXCreateContext(display, visualInfo, shareContext, true);
    qglx_surfaceFormatFromGLXFBConfig(&m_format, display, config, m_context);
}
QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context)
    : d(new QOffscreenX11GLXContextData)
{
    d->x11 = x11;
    d->format = context->format();

    d->shareContext = 0;
    if (context->shareHandle())
        d->shareContext = static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context;

    GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), d->format);
    if (config) {
        d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext, true);
        if (!d->context && d->shareContext) {
            d->shareContext = 0;
            // re-try without a shared glx context
            d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, 0, true);
        }

        // Get the basic surface format details
        if (d->context)
            qglx_surfaceFormatFromGLXFBConfig(&d->format, x11->display(), config);

        // Create a temporary window so that we can make the new context current
        d->window = createDummyWindow(x11, config);
    } else {
        XVisualInfo *visualInfo = qglx_findVisualInfo(x11->display(), 0, &d->format);
        if (!visualInfo)
            qFatal("Could not initialize GLX");
        d->context = glXCreateContext(x11->display(), visualInfo, d->shareContext, true);
        if (!d->context && d->shareContext) {
            // re-try without a shared glx context
            d->shareContext = 0;
            d->context = glXCreateContext(x11->display(), visualInfo, 0, true);
        }

        d->window = createDummyWindow(x11, visualInfo);
        XFree(visualInfo);
    }
}