diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-02-20 14:48:56 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-02-26 20:06:03 +0000 |
commit | 931e4ae66504f5d0be9d097565b4e9f49a92c69a (patch) | |
tree | 10647e6bb2a898624df84b53ca795a744687134d /src/platformsupport | |
parent | d5078161aadac7bb36862d8eb0d6d8c27eb58c60 (diff) |
Support windows with sRGB-capable default framebuffers in QSurfaceFormat
Backend implementation is done for GLX for now. WGL and EGL may follow
later on.
[ChangeLog][QtGui] Added support for requesting OpenGL windows with
sRGB-capable default framebuffers. While this is implicit on some
platforms, QSurfaceFormat now has the necessary flags to request
such windows in a cross-platform manner.
Task-number: QTBUG-50987
Change-Id: I4df1f786e41e63396f46920a81afdf5ecb5eedea
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/platformsupport')
-rw-r--r-- | src/platformsupport/glxconvenience/qglxconvenience.cpp | 48 | ||||
-rw-r--r-- | src/platformsupport/glxconvenience/qglxconvenience_p.h | 15 |
2 files changed, 48 insertions, 15 deletions
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 4225bebf37..c7b5470b39 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -76,7 +76,11 @@ enum { #undef FontChange #endif -QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit) +#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#endif + +QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit, int flags) { QVector<int> spec; @@ -120,6 +124,10 @@ QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit) << GLX_SAMPLES_ARB << format.samples(); + if ((flags & QGLX_SUPPORTS_SRGB) && format.colorSpace() == QSurfaceFormat::sRGBColorSpace) + spec << GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB + << True; + spec << GLX_DRAWABLE_TYPE << drawableBit @@ -179,14 +187,14 @@ template <class T> using QXlibArrayPointer = QScopedArrayPointer<T, QXlibScopedPointerDeleter<T>>; } -GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format, bool highestPixelFormat, int drawableBit) +GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format, bool highestPixelFormat, int drawableBit, int flags) { QXcbSoftwareOpenGLEnforcer softwareOpenGLEnforcer; GLXFBConfig config = 0; do { - const QVector<int> spec = qglx_buildSpec(format, drawableBit); + const QVector<int> spec = qglx_buildSpec(format, drawableBit, flags); int confcount = 0; QXlibArrayPointer<GLXFBConfig> configs(glXChooseFBConfig(display, screen, spec.constData(), &confcount)); @@ -205,6 +213,13 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format for (int i = 0; i < confcount; i++) { GLXFBConfig candidate = configs[i]; + if ((flags & QGLX_SUPPORTS_SRGB) && format.colorSpace() == QSurfaceFormat::sRGBColorSpace) { + int srgbCapable = 0; + glXGetFBConfigAttrib(display, candidate, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &srgbCapable); + if (!srgbCapable) + continue; + } + QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate)); const int actualRed = qPopulationCount(visual->red_mask); @@ -228,28 +243,28 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format return config; } -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit) +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit, int flags) { Q_ASSERT(format); XVisualInfo *visualInfo = 0; - GLXFBConfig config = qglx_findConfig(display, screen, *format, false, drawableBit); + GLXFBConfig config = qglx_findConfig(display, screen, *format, false, drawableBit, flags); if (config) visualInfo = glXGetVisualFromFBConfig(display, config); if (visualInfo) { - qglx_surfaceFormatFromGLXFBConfig(format, display, config); + qglx_surfaceFormatFromGLXFBConfig(format, display, config, flags); return visualInfo; } // attempt to fall back to glXChooseVisual do { - QVector<int> attribs = qglx_buildSpec(*format, drawableBit); + QVector<int> attribs = qglx_buildSpec(*format, drawableBit, flags); visualInfo = glXChooseVisual(display, screen, attribs.data()); if (visualInfo) { - qglx_surfaceFormatFromVisualInfo(format, display, visualInfo); + qglx_surfaceFormatFromVisualInfo(format, display, visualInfo, flags); return visualInfo; } } while (qglx_reduceFormat(format)); @@ -257,7 +272,7 @@ XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *f return visualInfo; } -void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config) +void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config, int flags) { int redSize = 0; int greenSize = 0; @@ -268,6 +283,7 @@ void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, int sampleBuffers = 0; int sampleCount = 0; int stereo = 0; + int srgbCapable = 0; glXGetFBConfigAttrib(display, config, GLX_RED_SIZE, &redSize); glXGetFBConfigAttrib(display, config, GLX_GREEN_SIZE, &greenSize); @@ -277,6 +293,8 @@ void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, glXGetFBConfigAttrib(display, config, GLX_STENCIL_SIZE, &stencilSize); glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleBuffers); glXGetFBConfigAttrib(display, config, GLX_STEREO, &stereo); + if (flags & QGLX_SUPPORTS_SRGB) + glXGetFBConfigAttrib(display, config, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &srgbCapable); format->setRedBufferSize(redSize); format->setGreenBufferSize(greenSize); @@ -288,11 +306,12 @@ void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, glXGetFBConfigAttrib(display, config, GLX_SAMPLES_ARB, &sampleCount); format->setSamples(sampleCount); } + format->setColorSpace(srgbCapable ? QSurfaceFormat::sRGBColorSpace : QSurfaceFormat::DefaultColorSpace); format->setStereo(stereo); } -void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo) +void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo, int flags) { int redSize = 0; int greenSize = 0; @@ -303,6 +322,7 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, int sampleBuffers = 0; int sampleCount = 0; int stereo = 0; + int srgbCapable = 0; glXGetConfig(display, visualInfo, GLX_RED_SIZE, &redSize); glXGetConfig(display, visualInfo, GLX_GREEN_SIZE, &greenSize); @@ -312,6 +332,8 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, glXGetConfig(display, visualInfo, GLX_STENCIL_SIZE, &stencilSize); glXGetConfig(display, visualInfo, GLX_SAMPLES_ARB, &sampleBuffers); glXGetConfig(display, visualInfo, GLX_STEREO, &stereo); + if (flags & QGLX_SUPPORTS_SRGB) + glXGetConfig(display, visualInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &srgbCapable); format->setRedBufferSize(redSize); format->setGreenBufferSize(greenSize); @@ -323,6 +345,7 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, glXGetConfig(display, visualInfo, GLX_SAMPLES_ARB, &sampleCount); format->setSamples(sampleCount); } + format->setColorSpace(srgbCapable ? QSurfaceFormat::sRGBColorSpace : QSurfaceFormat::DefaultColorSpace); format->setStereo(stereo); } @@ -391,5 +414,10 @@ bool qglx_reduceFormat(QSurfaceFormat *format) return true; } + if (format->colorSpace() == QSurfaceFormat::sRGBColorSpace) { + format->setColorSpace(QSurfaceFormat::DefaultColorSpace); + return true; + } + return false; } diff --git a/src/platformsupport/glxconvenience/qglxconvenience_p.h b/src/platformsupport/glxconvenience/qglxconvenience_p.h index d422668584..f9647bfd9a 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience_p.h +++ b/src/platformsupport/glxconvenience/qglxconvenience_p.h @@ -57,11 +57,16 @@ #include <X11/Xlib.h> #include <GL/glx.h> -QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT); -XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit = GLX_WINDOW_BIT); -GLXFBConfig qglx_findConfig(Display *display, int screen, QSurfaceFormat format, bool highestPixelFormat = false, int drawableBit = GLX_WINDOW_BIT); -void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config); -void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo); +enum QGlxFlags +{ + QGLX_SUPPORTS_SRGB = 0x01 +}; + +QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit = GLX_WINDOW_BIT, int flags = 0); +XVisualInfo *qglx_findVisualInfo(Display *display, int screen, QSurfaceFormat *format, int drawableBit = GLX_WINDOW_BIT, int flags = 0); +GLXFBConfig qglx_findConfig(Display *display, int screen, QSurfaceFormat format, bool highestPixelFormat = false, int drawableBit = GLX_WINDOW_BIT, int flags = 0); +void qglx_surfaceFormatFromGLXFBConfig(QSurfaceFormat *format, Display *display, GLXFBConfig config, int flags = 0); +void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, XVisualInfo *visualInfo, int flags = 0); bool qglx_reduceFormat(QSurfaceFormat *format); #endif // QGLXCONVENIENCE_H |