summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-06-23 16:45:11 +0200
committerLaszlo Agocs <laszlo.agocs@digia.com>2014-07-07 12:55:16 +0200
commite7056a8969cf9445ff84c7362137f792ef207ae2 (patch)
treef1e5ced5d3d22cd5db9376cd01f362d2b3dad87c /src/plugins
parentd8103d0e629f1d8f6c2b9d5b0dcc95b6ff20b99d (diff)
Add context adoption support for WGL
This is trickier than the GLX and EGL implementations due to the way pixel formats, windows and contexts work. Apart from some restrictions, it should be fully functional nonetheless. Add also some proper documentation. Change-Id: Ia6e3eb1ab2701e439b8621b9092c2b0934ff2151 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp82
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h2
2 files changed, 72 insertions, 12 deletions
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index b1152de854..e336c6414e 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -48,6 +48,7 @@
#include <QtCore/QSysInfo>
#include <QtGui/QGuiApplication>
#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformHeaders/QWGLNativeContext>
#include <algorithm>
@@ -1038,11 +1039,54 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
m_renderingContext(0),
m_pixelFormat(0),
m_extensionsUsed(false),
- m_swapInterval(-1)
+ m_swapInterval(-1),
+ m_ownsContext(true)
{
if (!m_staticContext) // Something went very wrong. Stop here, isValid() will return false.
return;
+ QVariant nativeHandle = context->nativeHandle();
+ if (!nativeHandle.isNull()) {
+ // Adopt and existing context.
+ if (!nativeHandle.canConvert<QWGLNativeContext>()) {
+ qWarning("QWindowsGLContext: Requires a QWGLNativeContext");
+ return;
+ }
+ QWGLNativeContext handle = nativeHandle.value<QWGLNativeContext>();
+ HGLRC wglcontext = handle.context();
+ HWND wnd = handle.window();
+ if (!wglcontext || !wnd) {
+ qWarning("QWindowsGLContext: No context and window given");
+ return;
+ }
+
+ HDC dc = GetDC(wnd);
+ // A window with an associated pixel format is mandatory.
+ // When no SetPixelFormat() call has been made, the following will fail.
+ m_pixelFormat = GetPixelFormat(dc);
+ bool ok = m_pixelFormat != 0;
+ if (!ok)
+ qWarning("QWindowsGLContext: Failed to get pixel format");
+ ok = DescribePixelFormat(dc, m_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &m_obtainedPixelFormatDescriptor);
+ if (!ok) {
+ qWarning("QWindowsGLContext: Failed to describe pixel format");
+ } else {
+ QWindowsOpenGLAdditionalFormat obtainedAdditional;
+ m_obtainedFormat = GDI::qSurfaceFormatFromPixelFormat(m_obtainedPixelFormatDescriptor, &obtainedAdditional);
+ m_renderingContext = wglcontext;
+ ok = updateObtainedParams(dc);
+ }
+
+ ReleaseDC(wnd, dc);
+
+ if (ok)
+ m_ownsContext = false;
+ else
+ m_renderingContext = 0;
+
+ return;
+ }
+
QSurfaceFormat format = context->format();
if (format.renderableType() == QSurfaceFormat::DefaultRenderableType)
format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -1065,7 +1109,7 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
HWND dummyWindow = 0;
HDC hdc = 0;
bool tryExtensions = false;
- int obtainedSwapInternal = -1;
+ int obtainedSwapInterval = -1;
do {
dummyWindow = createDummyGLWindow();
if (!dummyWindow)
@@ -1131,18 +1175,16 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
}
// Query obtained parameters and apply swap interval.
- if (!QOpenGLStaticContext::opengl32.wglMakeCurrent(hdc, m_renderingContext)) {
- qWarning("Failed to make context current.");
+ if (!updateObtainedParams(hdc, &obtainedSwapInterval))
break;
- }
- QWindowsOpenGLContextFormat::current().apply(&m_obtainedFormat);
+ } while (false);
- if (m_staticContext->wglGetSwapInternalExt)
- obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
+ // Make the HGLRC retrievable via QOpenGLContext::nativeHandle().
+ // Do not provide the window since it is the dummy one and it is about to disappear.
+ if (m_renderingContext)
+ context->setNativeHandle(QVariant::fromValue<QWGLNativeContext>(QWGLNativeContext(m_renderingContext, 0)));
- QOpenGLStaticContext::opengl32.wglMakeCurrent(0, 0);
- } while (false);
if (hdc)
ReleaseDC(dummyWindow, hdc);
if (dummyWindow)
@@ -1151,18 +1193,34 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
qCDebug(lcQpaGl) << __FUNCTION__ << this << (tryExtensions ? "ARB" : "GDI")
<< " requested: " << context->format()
<< "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI") << m_obtainedFormat
- << "\n " << m_obtainedPixelFormatDescriptor << " swap interval: " << obtainedSwapInternal
+ << "\n " << m_obtainedPixelFormatDescriptor << " swap interval: " << obtainedSwapInterval
<< "\n default: " << m_staticContext->defaultFormat
<< "\n HGLRC=" << m_renderingContext;
}
QWindowsGLContext::~QWindowsGLContext()
{
- if (m_renderingContext)
+ if (m_renderingContext && m_ownsContext)
QOpenGLStaticContext::opengl32.wglDeleteContext(m_renderingContext);
releaseDCs();
}
+bool QWindowsGLContext::updateObtainedParams(HDC hdc, int *obtainedSwapInterval)
+{
+ if (!QOpenGLStaticContext::opengl32.wglMakeCurrent(hdc, m_renderingContext)) {
+ qWarning("Failed to make context current.");
+ return false;
+ }
+
+ QWindowsOpenGLContextFormat::current().apply(&m_obtainedFormat);
+
+ if (m_staticContext->wglGetSwapInternalExt && obtainedSwapInterval)
+ *obtainedSwapInterval = m_staticContext->wglGetSwapInternalExt();
+
+ QOpenGLStaticContext::opengl32.wglMakeCurrent(0, 0);
+ return true;
+}
+
void QWindowsGLContext::releaseDCs()
{
const QOpenGLContextData *end = m_windowContexts.end();
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index dcc31c6197..d92d94aa1a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -258,6 +258,7 @@ public:
private:
inline void releaseDCs();
+ bool updateObtainedParams(HDC hdc, int *obtainedSwapInterval = 0);
QOpenGLStaticContext *m_staticContext;
QOpenGLContext *m_context;
@@ -268,6 +269,7 @@ private:
int m_pixelFormat;
bool m_extensionsUsed;
int m_swapInterval;
+ bool m_ownsContext;
};
QT_END_NAMESPACE