summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp197
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h28
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h10
4 files changed, 156 insertions, 91 deletions
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 27669da392..1685adccec 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -545,49 +545,6 @@ static QSurfaceFormat
if (iValues[11])
additionalIn->formatFlags |= QWindowsGLOverlay;
}
- // Check version. Known to fail for some drivers
- if (staticContext.majorVersion > 1) {
- i = 0;
- iAttributes[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; // 0
- iAttributes[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; // 1
- if (staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
- iAttributes, iValues)) {
- result.setMajorVersion(iValues[0]);
- result.setMinorVersion(iValues[1]);
- } else {
- qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for version.", __FUNCTION__);
- }
- }
- // Query flags from 3.2 onwards
- if (staticContext.majorVersion > 3) {
- i = 0;
- iAttributes[i++] = WGL_CONTEXT_FLAGS_ARB; // 0
- if (staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
- iAttributes, iValues)) {
- if (iValues[0] & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
- result.setOption(QSurfaceFormat::DeprecatedFunctions);
- if (iValues[0] & WGL_CONTEXT_DEBUG_BIT_ARB)
- result.setOption(QSurfaceFormat::DebugContext);
- } else {
- qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for context flags.", __FUNCTION__);
- }
- }
- // Query profile from 3.2 onwards. Known to fail for some drivers
- if ((staticContext.majorVersion == 3 && staticContext.minorVersion >= 2)
- || staticContext.majorVersion > 3) {
- i = 0;
- iAttributes[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; // 0
- if (staticContext.wglGetPixelFormatAttribIVARB(hdc, pixelFormat, 0, i,
- iAttributes, iValues)) {
- if (iValues[0] & WGL_CONTEXT_CORE_PROFILE_BIT_ARB) {
- result.setProfile(QSurfaceFormat::CoreProfile);
- } else if (iValues[0] & WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
- result.setProfile(QSurfaceFormat::CompatibilityProfile);
- }
- } else {
- qErrnoWarning("%s: wglGetPixelFormatAttribIVARB() failed for profile mask.", __FUNCTION__);
- }
- }
return result;
}
@@ -604,22 +561,14 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
int attributes[attribSize];
int attribIndex = 0;
qFill(attributes, attributes + attribSize, int(0));
-
- const int formatMajorVersion = format.majorVersion();
- const int formatMinorVersion = format.minorVersion();
- const bool versionRequested = formatMajorVersion != 1 || formatMinorVersion != 1;
- const int majorVersion = versionRequested ?
- formatMajorVersion : staticContext.majorVersion;
- const int minorVersion = versionRequested ?
- formatMinorVersion : staticContext.minorVersion;
-
- if (majorVersion > 1) {
+ const int requestedVersion = (format.majorVersion() << 8) + format.minorVersion();
+ if (requestedVersion > 0x0101) {
attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
- attributes[attribIndex++] = majorVersion;
+ attributes[attribIndex++] = format.majorVersion();
attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
- attributes[attribIndex++] = minorVersion;
+ attributes[attribIndex++] = format.minorVersion();
}
- if (majorVersion >= 3) {
+ if (requestedVersion >= 0x0300) {
attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
attributes[attribIndex] = 0;
if (format.testOption(QSurfaceFormat::DeprecatedFunctions))
@@ -628,8 +577,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
attributes[attribIndex++] |= WGL_CONTEXT_DEBUG_BIT_ARB;
attribIndex++;
}
- if ((majorVersion == 3 && minorVersion >= 2)
- || majorVersion > 3) {
+ if (requestedVersion >= 0x0302) {
switch (format.profile()) {
case QSurfaceFormat::NoProfile:
break;
@@ -645,7 +593,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
}
if (QWindowsContext::verboseGL)
qDebug("%s: Creating context version %d.%d with %d attributes",
- __FUNCTION__, majorVersion, minorVersion, attribIndex / 2);
+ __FUNCTION__, format.majorVersion(), format.minorVersion(), attribIndex / 2);
const HGLRC result =
staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
@@ -708,6 +656,85 @@ static inline QOpenGLContextData createDummyWindowOpenGLContextData()
}
/*!
+ \class QOpenGLContextFormat
+ \brief Format options that are related to the context (not pixelformats)
+
+ Provides utility function to retrieve from currently active
+ context and to apply to a QSurfaceFormat.
+
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsOpenGLContextFormat::QWindowsOpenGLContextFormat() :
+ profile(QSurfaceFormat::NoProfile),
+ version(0),
+ options(0)
+{
+}
+
+QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
+{
+ QWindowsOpenGLContextFormat result;
+ const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
+ const int majorDot = version.indexOf('.');
+ if (majorDot != -1) {
+ int minorDot = version.indexOf('.', majorDot + 1);
+ if (minorDot == -1)
+ minorDot = version.size();
+ result.version = (version.mid(0, majorDot).toInt() << 8)
+ + version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
+ }
+ if (result.version < 0x0300) {
+ result.profile = QSurfaceFormat::NoProfile;
+ result.options |= QSurfaceFormat::DeprecatedFunctions;
+ return result;
+ }
+ // v3 onwards
+ GLint value = 0;
+ glGetIntegerv(GL_CONTEXT_FLAGS, &value);
+ if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
+ result.options |= QSurfaceFormat::DeprecatedFunctions;
+ if (value & WGL_CONTEXT_DEBUG_BIT_ARB)
+ result.options |= QSurfaceFormat::DebugContext;
+ if (result.version < 0x0302)
+ return result;
+ // v3.2 onwards: Profiles
+ value = 0;
+ glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ switch (value) {
+ case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
+ result.profile = QSurfaceFormat::CoreProfile;
+ break;
+ case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ result.profile = QSurfaceFormat::CompatibilityProfile;
+ break;
+ default:
+ result.profile = QSurfaceFormat::NoProfile;
+ break;
+ }
+ return result;
+}
+
+void QWindowsOpenGLContextFormat::apply(QSurfaceFormat *format) const
+{
+ format->setMajorVersion(version >> 8);
+ format->setMinorVersion(version & 0xFF);
+ format->setProfile(profile);
+ if (options & QSurfaceFormat::DebugContext)
+ format->setOption(QSurfaceFormat::DebugContext);
+ if (options & QSurfaceFormat::DeprecatedFunctions)
+ format->setOption(QSurfaceFormat::DeprecatedFunctions);
+}
+
+QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &f)
+{
+ d.nospace() << "ContextFormat: v" << (f.version >> 8) << '.'
+ << (f.version & 0xFF) << " profile: " << f.profile
+ << " options: " << f.options;
+ return d;
+}
+
+/*!
\class QOpenGLTemporaryContext
\brief A temporary context that can be instantiated on the stack.
@@ -768,29 +795,17 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
vendor(QOpenGLStaticContext::getGlString(GL_VENDOR)),
renderer(QOpenGLStaticContext::getGlString(GL_RENDERER)),
extensionNames(QOpenGLStaticContext::getGlString(GL_EXTENSIONS)),
- majorVersion(0), minorVersion(0),
extensions(0),
+ defaultFormat(QWindowsOpenGLContextFormat::current()),
wglGetPixelFormatAttribIVARB((WglGetPixelFormatAttribIVARB)wglGetProcAddress("wglGetPixelFormatAttribivARB")),
wglChoosePixelFormatARB((WglChoosePixelFormatARB)wglGetProcAddress("wglChoosePixelFormatARB")),
- wglCreateContextAttribsARB((WglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB"))
+ wglCreateContextAttribsARB((WglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB")),
+ wglSwapInternalExt((WglSwapInternalExt)wglGetProcAddress("wglSwapIntervalEXT")),
+ wglGetSwapInternalExt((WglGetSwapInternalExt)wglGetProcAddress("wglGetSwapIntervalEXT"))
{
if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION" ")
|| extensionNames.indexOf(" "SAMPLE_BUFFER_EXTENSION" ") != -1)
extensions |= SampleBuffers;
- // Get version
- do {
- const QByteArray version = QOpenGLStaticContext::getGlString(GL_VERSION);
- if (version.isEmpty())
- break;
- const int majorDot = version.indexOf('.');
- if (majorDot == -1)
- break;
- int minorDot = version.indexOf('.', majorDot + 1);
- if (minorDot == -1)
- minorDot = version.size();
- majorVersion = version.mid(0, majorDot).toInt();
- minorVersion = version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
- } while (false);
}
QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
@@ -815,13 +830,15 @@ QOpenGLStaticContext *QOpenGLStaticContext::create()
QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
{
QDebug nsp = d.nospace();
- nsp << "OpenGL: " << s.vendor << ',' << s.renderer << ",v"
- << s.majorVersion << '.' << s.minorVersion;
+ nsp << "OpenGL: " << s.vendor << ',' << s.renderer << " default "
+ << s.defaultFormat;
if (s.extensions & QOpenGLStaticContext::SampleBuffers)
nsp << ",SampleBuffers";
if (s.hasExtensions())
nsp << ", Extension-API present";
- nsp << "\nExtensions: " << s.extensionNames;
+ nsp << "\nExtensions: " << (s.extensionNames.count(' ') + 1);
+ if (QWindowsContext::verboseGL > 1)
+ nsp << s.extensionNames;
return d;
}
@@ -872,6 +889,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
HWND dummyWindow = 0;
HDC hdc = 0;
bool tryExtensions = false;
+ int obtainedSwapInternal = -1;
do {
dummyWindow = createDummyGLWindow();
if (!dummyWindow)
@@ -934,6 +952,21 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
qWarning("Unable to create a GL Context.");
break;
}
+
+ // Query obtained parameters and apply swap interval.
+ if (!wglMakeCurrent(hdc, m_renderingContext)) {
+ qWarning("Failed to make context current.");
+ break;
+ }
+
+ QWindowsOpenGLContextFormat::current().apply(&m_obtainedFormat);
+
+ if (requestedAdditional.swapInterval != -1 && m_staticContext->wglSwapInternalExt) {
+ m_staticContext->wglSwapInternalExt(requestedAdditional.swapInterval);
+ if (m_staticContext->wglGetSwapInternalExt)
+ obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
+ }
+ wglMakeCurrent(0, 0);
} while (false);
if (hdc)
ReleaseDC(dummyWindow, hdc);
@@ -945,6 +978,8 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
<< " requested: " << context->format()
<< "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI")
<< m_obtainedFormat << "\n " << m_obtainedPixelFormatDescriptor
+ << " swap interval: " << obtainedSwapInternal
+ << "\n default: " << m_staticContext->defaultFormat
<< "\n HGLRC=" << m_renderingContext;
}
@@ -1012,13 +1047,15 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
return false;
// Initialize pixel format first time. This will apply to
// the HWND as well and must be done only once.
- if (!window->testFlag(QWindowsWindow::PixelFormatInitialized)) {
+ if (!window->testFlag(QWindowsWindow::OpenGlPixelFormatInitialized)) {
if (!SetPixelFormat(newContext.hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
qErrnoWarning("%s: SetPixelFormat() failed", __FUNCTION__);
ReleaseDC(newContext.hwnd, newContext.hdc);
return false;
}
- window->setFlag(QWindowsWindow::PixelFormatInitialized);
+ window->setFlag(QWindowsWindow::OpenGlPixelFormatInitialized);
+ if (m_obtainedFormat.swapBehavior() == QSurfaceFormat::DoubleBuffer)
+ window->setFlag(QWindowsWindow::OpenGLDoubleBuffered);
}
m_windowContexts.append(newContext);
return wglMakeCurrent(newContext.hdc, newContext.renderingContext);
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index aa839d1fcd..f2784f3d9b 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -64,10 +64,11 @@ enum QWindowsGLFormatFlags
// Additional format information for Windows.
struct QWindowsOpenGLAdditionalFormat
{
- QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0) :
- formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn) {}
+ QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0, unsigned swapIntervalIn = -1) :
+ formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn), swapInterval(swapIntervalIn) {}
unsigned formatFlags; // QWindowsGLFormatFlags.
unsigned pixmapDepth; // for QWindowsGLRenderToPixmap
+ int swapInterval;
};
// Per-window data for active OpenGL contexts.
@@ -81,6 +82,19 @@ struct QOpenGLContextData
HDC hdc;
};
+struct QWindowsOpenGLContextFormat
+{
+ QWindowsOpenGLContextFormat();
+ static QWindowsOpenGLContextFormat current();
+ void apply(QSurfaceFormat *format) const;
+
+ QSurfaceFormat::OpenGLContextProfile profile;
+ int version; //! majorVersion<<8 + minorVersion
+ QSurfaceFormat::FormatOptions options;
+};
+
+QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &);
+
class QOpenGLStaticContext
{
Q_DISABLE_COPY(QOpenGLStaticContext)
@@ -104,6 +118,11 @@ public:
typedef HGLRC
(APIENTRY *WglCreateContextAttribsARB)(HDC, HGLRC, const int *);
+ typedef BOOL
+ (APIENTRY *WglSwapInternalExt)(int interval);
+ typedef int
+ (APIENTRY *WglGetSwapInternalExt)(void);
+
bool hasExtensions() const
{ return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; }
@@ -113,13 +132,14 @@ public:
const QByteArray vendor;
const QByteArray renderer;
const QByteArray extensionNames;
- int majorVersion;
- int minorVersion;
unsigned extensions;
+ const QWindowsOpenGLContextFormat defaultFormat;
WglGetPixelFormatAttribIVARB wglGetPixelFormatAttribIVARB;
WglChoosePixelFormatARB wglChoosePixelFormatARB;
WglCreateContextAttribsARB wglCreateContextAttribsARB;
+ WglSwapInternalExt wglSwapInternalExt;
+ WglGetSwapInternalExt wglGetSwapInternalExt;
};
QDebug operator<<(QDebug d, const QOpenGLStaticContext &);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 4b03fe6c9e..ef5c2ae246 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -617,7 +617,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
m_dropTarget(0)
{
if (aWindow->surfaceType() == QWindow::OpenGLSurface)
- setFlag(OpenGL_Surface);
+ setFlag(OpenGLSurface);
QWindowsContext::instance()->addWindow(m_data.hwnd, this);
if (aWindow->isTopLevel()) {
switch (aWindow->windowType()) {
@@ -779,9 +779,14 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
parentHWND = parentW->handle();
}
+
const bool wasTopLevel = window()->isTopLevel();
const bool isTopLevel = parentHWND == 0;
+
+ setFlag(WithinSetParent);
SetParent(m_data.hwnd, parentHWND);
+ clearFlag(WithinSetParent);
+
// WS_CHILD/WS_POPUP must be manually set/cleared in addition
// to dialog frames, etc (see SetParent() ) if the top level state changes.
if (wasTopLevel != isTopLevel) {
@@ -841,7 +846,8 @@ void QWindowsWindow::setGeometry(const QRect &rect)
void QWindowsWindow::handleMoved()
{
- if (!IsIconic(m_data.hwnd)) // Minimize can send nonsensical move events.
+ // Minimize/Set parent can send nonsensical move events.
+ if (!IsIconic(m_data.hwnd) && !testFlag(WithinSetParent))
handleGeometryChange();
}
@@ -940,7 +946,7 @@ void QWindowsWindow::handleWmPaint(HWND hwnd, UINT,
WPARAM, LPARAM)
{
PAINTSTRUCT ps;
- if (testFlag(OpenGL_Surface)) {
+ if (testFlag(OpenGLSurface)) {
BeginPaint(hwnd, &ps); // WM_ERASEBKGND needs to be handled.
EndPaint(hwnd, &ps);
} else {
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 42fff8b362..2aaf722277 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -95,10 +95,12 @@ class QWindowsWindow : public QPlatformWindow
public:
enum Flags
{
- OpenGL_Surface = 0x1,
- WithinWmPaint = 0x2,
- PixelFormatInitialized = 0x4,
- FrameDirty = 0x8 //! Frame outdated by setStyle, recalculate in next query.
+ WithinWmPaint = 0x1,
+ WithinSetParent = 0x2,
+ FrameDirty = 0x4, //! Frame outdated by setStyle, recalculate in next query.
+ OpenGLSurface = 0x10,
+ OpenGLDoubleBuffered = 0x20,
+ OpenGlPixelFormatInitialized = 0x40
};
struct WindowData