diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2012-01-25 18:27:50 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-27 11:01:14 +0100 |
commit | 7f9b624e12731afc21f332c081b9c9a9e2a8c55e (patch) | |
tree | 8e9e3a8b2745801bbc1c44f6ef648d72057e8ec9 /src/platformsupport/glxconvenience/qglxconvenience.cpp | |
parent | 2d39471897f0a3a769406ec9c2b39558ebd45af3 (diff) |
Fall back on glXChooseVisual() if glXChooseFBConfig() doesn't work.
Some older drivers don't fully support glXChooseFBConfig(). As a bonus,
fix some memory leaks here and there.
Task-number: QTBUG-21880
Change-Id: Ie306dee27f616927a6aa55fd71601569b828afcc
Reviewed-by: Uli Schlachter <psychon@znc.in>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/platformsupport/glxconvenience/qglxconvenience.cpp')
-rw-r--r-- | src/platformsupport/glxconvenience/qglxconvenience.cpp | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index ea433f5a33..0d48c4e16a 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -42,6 +42,7 @@ #include "qglxconvenience_p.h" #include <QtCore/QVector> +#include <QtCore/QVarLengthArray> #ifndef QT_NO_XRENDER #include <X11/extensions/Xrender.h> @@ -131,14 +132,19 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize); if (alphaSize > 0) { XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig); + bool hasAlpha = false; + #if !defined(QT_NO_XRENDER) XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual); - if (pictFormat->direct.alphaMask > 0) - break; + hasAlpha = pictFormat->direct.alphaMask > 0; #else - if (visual->depth == 32) - break; + hasAlpha = visual->depth == 32; #endif + + XFree(visual); + + if (hasAlpha) + break; } } else { break; // Just choose the first in the list if there's no alpha requested @@ -150,16 +156,59 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced); } - if (!chosenConfig) - qWarning("Warning: no suitable glx confiuration found"); - return chosenConfig; } XVisualInfo *qglx_findVisualInfo(Display *display, int screen, const QSurfaceFormat &format) { + XVisualInfo *visualInfo = 0; + GLXFBConfig config = qglx_findConfig(display,screen,format); - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display,config); + if (config) + visualInfo = glXGetVisualFromFBConfig(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()); + + reducedFormat = qglx_reduceSurfaceFormat(reducedFormat, &reduced); + } + return visualInfo; } @@ -208,7 +257,13 @@ QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *redu QSurfaceFormat retFormat = format; *reduced = true; - if (retFormat.samples() > 1) { + if (retFormat.redBufferSize() > 1) { + retFormat.setRedBufferSize(1); + } else if (retFormat.greenBufferSize() > 1) { + retFormat.setGreenBufferSize(1); + } else if (retFormat.blueBufferSize() > 1) { + retFormat.setBlueBufferSize(1); + } else if (retFormat.samples() > 1) { retFormat.setSamples(0); } else if (retFormat.stereo()) { retFormat.setStereo(false); @@ -218,6 +273,8 @@ QSurfaceFormat qglx_reduceSurfaceFormat(const QSurfaceFormat &format, bool *redu retFormat.setAlphaBufferSize(0); }else if (retFormat.depthBufferSize() > 0) { retFormat.setDepthBufferSize(0); + }else if (retFormat.swapBehavior() != QSurfaceFormat::SingleBuffer) { + retFormat.setSwapBehavior(QSurfaceFormat::SingleBuffer); }else{ *reduced = false; } |