Add sRGB capable default framebuffer support for WGL

Not that it changes much since one tyically gets sRGB capable by default
on AMD and NVIDIA at least, but let's handle the QSurfaceFormat flag
correctly via WGL_EXT_framebuffer_sRGB.

Task-number: QTBUG-50987
Change-Id: I898c3757ab6fea51323d6c041b2511bea780c3fb
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
bb10
Laszlo Agocs 2017-02-21 13:59:24 +01:00
parent f9f9bea370
commit ffa578faf0
2 changed files with 60 additions and 19 deletions

View File

@ -145,6 +145,10 @@
#define RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define LOSE_CONTEXT_ON_RESET_ARB 0x8252
#ifndef WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
#endif
QT_BEGIN_NAMESPACE
QWindowsOpengl32DLL QOpenGLStaticContext::opengl32;
@ -489,7 +493,7 @@ static int choosePixelFormat(HDC hdc,
const QWindowsOpenGLAdditionalFormat &additional,
PIXELFORMATDESCRIPTOR *obtainedPfd)
{
enum { attribSize =40 };
enum { attribSize = 42 };
if ((additional.formatFlags & QWindowsGLRenderToPixmap) || !staticContext.hasExtensions())
return 0;
@ -570,7 +574,15 @@ static int choosePixelFormat(HDC hdc,
iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
iAttributes[i++] = FALSE;
}
// If sample buffer request cannot be satisfied, reduce request.
// must be the last
bool srgbRequested = format.colorSpace() == QSurfaceFormat::sRGBColorSpace;
int srgbValuePosition = 0;
if (srgbRequested) {
srgbValuePosition = i;
iAttributes[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT;
iAttributes[i++] = TRUE;
}
// If sample or sRGB request cannot be satisfied, reduce request.
int pixelFormat = 0;
uint numFormats = 0;
while (true) {
@ -578,20 +590,25 @@ static int choosePixelFormat(HDC hdc,
staticContext.wglChoosePixelFormatARB(hdc, iAttributes, 0, 1,
&pixelFormat, &numFormats)
&& numFormats >= 1;
if (valid || !sampleBuffersRequested)
break;
if (iAttributes[samplesValuePosition] > 1) {
iAttributes[samplesValuePosition] /= 2;
} else if (iAttributes[samplesValuePosition] == 1) {
// Fallback in case it is unable to initialize with any
// samples to avoid falling back to the GDI path
// NB: The sample attributes needs to be at the end for this
// to work correctly
iAttributes[samplesValuePosition - 1] = FALSE;
iAttributes[samplesValuePosition] = 0;
iAttributes[samplesValuePosition + 1] = 0;
} else {
if (valid || (!sampleBuffersRequested && !srgbRequested))
break;
if (srgbRequested) {
iAttributes[srgbValuePosition] = 0;
srgbRequested = false;
} else if (sampleBuffersRequested) {
if (iAttributes[samplesValuePosition] > 1) {
iAttributes[samplesValuePosition] /= 2;
} else if (iAttributes[samplesValuePosition] == 1) {
// Fallback in case it is unable to initialize with any
// samples to avoid falling back to the GDI path
// NB: The sample attributes needs to be at the end for this
// to work correctly
iAttributes[samplesValuePosition - 1] = FALSE;
iAttributes[samplesValuePosition] = 0;
iAttributes[samplesValuePosition + 1] = 0;
} else {
break;
}
}
}
// Verify if format is acceptable. Note that the returned
@ -628,7 +645,7 @@ static QSurfaceFormat
HDC hdc, int pixelFormat,
QWindowsOpenGLAdditionalFormat *additionalIn = 0)
{
enum { attribSize =40 };
enum { attribSize = 42 };
QSurfaceFormat result;
result.setRenderableType(QSurfaceFormat::OpenGL);
@ -641,6 +658,7 @@ static QSurfaceFormat
int i = 0;
const bool hasSampleBuffers = testFlag(staticContext.extensions, QOpenGLStaticContext::SampleBuffers);
const bool hasSrgbSupport = testFlag(staticContext.extensions, QOpenGLStaticContext::sRGBCapableFramebuffer);
iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
@ -658,6 +676,9 @@ static QSurfaceFormat
iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
iAttributes[i++] = WGL_SAMPLES_ARB; // 13
}
if (hasSrgbSupport)
iAttributes[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT; // 12 or 14
if (!staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
iAttributes, iValues)) {
qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for basic parameters.", __FUNCTION__);
@ -673,8 +694,14 @@ static QSurfaceFormat
if (iValues[9])
result.setOption(QSurfaceFormat::StereoBuffers);
if (hasSampleBuffers)
if (hasSampleBuffers) {
result.setSamples(iValues[13]);
if (hasSrgbSupport && iValues[14])
result.setColorSpace(QSurfaceFormat::sRGBColorSpace);
} else {
if (hasSrgbSupport && iValues[12])
result.setColorSpace(QSurfaceFormat::sRGBColorSpace);
}
if (additionalIn) {
if (iValues[7])
additionalIn->formatFlags |= QWindowsGLAccumBuffer;
@ -947,7 +974,8 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
wglChoosePixelFormatARB((WglChoosePixelFormatARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglChoosePixelFormatARB")),
wglCreateContextAttribsARB((WglCreateContextAttribsARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglCreateContextAttribsARB")),
wglSwapInternalExt((WglSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglSwapIntervalEXT")),
wglGetSwapInternalExt((WglGetSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetSwapIntervalEXT"))
wglGetSwapInternalExt((WglGetSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetSwapIntervalEXT")),
wglGetExtensionsStringARB((WglGetExtensionsStringARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetExtensionsStringARB"))
{
if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
|| extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
@ -1091,6 +1119,14 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
&& !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DisableArb);
QWindowsOpenGLAdditionalFormat obtainedAdditional;
if (tryExtensions) {
if (m_staticContext->wglGetExtensionsStringARB) {
const char *exts = m_staticContext->wglGetExtensionsStringARB(hdc);
if (exts) {
qCDebug(lcQpaGl) << __FUNCTION__ << "WGL extensions:" << exts;
if (strstr(exts, "WGL_EXT_framebuffer_sRGB"))
m_staticContext->extensions |= QOpenGLStaticContext::sRGBCapableFramebuffer;
}
}
m_pixelFormat =
ARB::choosePixelFormat(hdc, *m_staticContext, format,
requestedAdditional, &m_obtainedPixelFormatDescriptor);

View File

@ -139,7 +139,8 @@ class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
public:
enum Extensions
{
SampleBuffers = 0x1
SampleBuffers = 0x1,
sRGBCapableFramebuffer = 0x2
};
typedef bool
@ -160,6 +161,9 @@ public:
typedef int
(APIENTRY *WglGetSwapInternalExt)(void);
typedef const char *
(APIENTRY *WglGetExtensionsStringARB)(HDC);
bool hasExtensions() const
{ return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; }
@ -185,6 +189,7 @@ public:
WglCreateContextAttribsARB wglCreateContextAttribsARB;
WglSwapInternalExt wglSwapInternalExt;
WglGetSwapInternalExt wglGetSwapInternalExt;
WglGetExtensionsStringARB wglGetExtensionsStringARB;
static QWindowsOpengl32DLL opengl32;
};