summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp814
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.h249
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp307
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h128
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp147
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp54
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsopenglcontext.h89
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp146
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h52
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp59
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h31
-rw-r--r--src/plugins/platforms/windows/windows.pri7
14 files changed, 1841 insertions, 259 deletions
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index d5ca06bb3f..6ceddf865c 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,23 +46,282 @@
#include <QtCore/QDebug>
#include <QtGui/QOpenGLContext>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
QT_BEGIN_NAMESPACE
/*!
\class QWindowsEGLStaticContext
\brief Static data for QWindowsEGLContext.
- Keeps the display. The class is shared via
- QSharedPointer in the windows, the contexts
- and in QWindowsIntegration. The display will
- be closed if the last instance is deleted.
+ Keeps the display. The class is shared via QSharedPointer in the windows, the
+ contexts and in QWindowsIntegration. The display will be closed if the last instance
+ is deleted.
+
+ No EGL or OpenGL functions are called directly. Instead, they are resolved
+ dynamically. This works even if the plugin links directly to libegl/libglesv2 so
+ there is no need to differentiate between dynamic or Angle-only builds in here.
\internal
\ingroup qt-lighthouse-win
*/
+QWindowsLibEGL QWindowsEGLStaticContext::libEGL;
+QWindowsLibGLESv2 QWindowsEGLStaticContext::libGLESv2;
+
+#ifdef Q_CC_MINGW
+static void *resolveFunc(HMODULE lib, const char *name)
+{
+ QString baseNameStr = QString::fromLatin1(name);
+ QString nameStr;
+ void *proc = 0;
+
+ // Play nice with 32-bit mingw: Try func first, then func@0, func@4,
+ // func@8, func@12, ..., func@64. The def file does not provide any aliases
+ // in libEGL and libGLESv2 in these builds which results in exporting
+ // function names like eglInitialize@12. This cannot be fixed without
+ // breaking binary compatibility. So be flexible here instead.
+
+ int argSize = -1;
+ while (!proc && argSize <= 64) {
+ nameStr = baseNameStr;
+ if (argSize >= 0)
+ nameStr += QLatin1Char('@') + QString::number(argSize);
+ argSize = argSize < 0 ? 0 : argSize + 4;
+ proc = (void *) ::GetProcAddress(lib, nameStr.toLatin1().constData());
+ }
+ return proc;
+}
+#else
+static void *resolveFunc(HMODULE lib, const char *name)
+{
+# ifndef Q_OS_WINCE
+ return (void *) ::GetProcAddress(lib, name);
+# else
+ return (void *) ::GetProcAddress(lib, (const wchar_t *) QString::fromLatin1(name).utf16());
+# endif // Q_OS_WINCE
+}
+#endif // Q_CC_MINGW
+
+void *QWindowsLibEGL::resolve(const char *name)
+{
+ void *proc = m_lib ? resolveFunc(m_lib, name) : 0;
+ if (!proc)
+ qErrnoWarning(::GetLastError(), "Failed to resolve EGL function %s", name);
+
+ return proc;
+}
+
+bool QWindowsLibEGL::init()
+{
+#ifdef QT_DEBUG
+ const char dllName[] = "libEGLd.dll";
+#else
+ const char dllName[] = "libEGL.dll";
+#endif
+
+ qCDebug(lcQpaGl) << "Qt: Using EGL from" << dllName;
+
+ m_lib = ::LoadLibraryW((const wchar_t *) QString::fromLatin1(dllName).utf16());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", dllName);
+ return false;
+ }
+
+ eglGetError = reinterpret_cast<EGLint (EGLAPIENTRY *)(void)>(resolve("eglGetError"));
+ eglGetDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)>(resolve("eglGetDisplay"));
+ eglInitialize = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)>(resolve("eglInitialize"));
+ eglTerminate = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay)>(resolve("eglTerminate"));
+ eglChooseConfig = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)>(resolve("eglChooseConfig"));
+ eglGetConfigAttrib = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLint, EGLint *)>(resolve("eglGetConfigAttrib"));
+ eglCreateWindowSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint *)>(resolve("eglCreateWindowSurface"));
+ eglCreatePbufferSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay , EGLConfig, const EGLint *)>(resolve("eglCreatePbufferSurface"));
+ eglDestroySurface = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface )>(resolve("eglDestroySurface"));
+ eglBindAPI = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLenum )>(resolve("eglBindAPI"));
+ eglSwapInterval = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLint )>(resolve("eglSwapInterval"));
+ eglCreateContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(EGLDisplay , EGLConfig , EGLContext , const EGLint *)>(resolve("eglCreateContext"));
+ eglDestroyContext = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLContext)>(resolve("eglDestroyContext"));
+ eglMakeCurrent = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLSurface , EGLContext )>(resolve("eglMakeCurrent"));
+ eglGetCurrentContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(void)>(resolve("eglGetCurrentContext"));
+ eglGetCurrentSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLint )>(resolve("eglGetCurrentSurface"));
+ eglGetCurrentDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(void)>(resolve("eglGetCurrentDisplay"));
+ eglSwapBuffers = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)>(resolve("eglSwapBuffers"));
+ eglGetProcAddress = reinterpret_cast<__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)>(resolve("eglGetProcAddress"));
+
+ return eglGetError && eglGetDisplay && eglInitialize;
+}
+
+void *QWindowsLibGLESv2::resolve(const char *name)
+{
+ void *proc = m_lib ? resolveFunc(m_lib, name) : 0;
+ if (!proc)
+ qWarning() << "Failed to resolve OpenGL ES function" << name;
+
+ return proc;
+}
+
+bool QWindowsLibGLESv2::init()
+{
+#ifdef QT_DEBUG
+ const char dllName[] = "libGLESv2d.dll";
+#else
+ const char dllName[] = "libGLESv2.dll";
+#endif
+
+ qCDebug(lcQpaGl) << "Qt: Using OpenGL ES 2.0 from" << dllName;
+
+ m_lib = ::LoadLibraryW((const wchar_t *) QString::fromLatin1(dllName).utf16());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", dllName);
+ return false;
+ }
+
+ glBindTexture = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glBindTexture"));
+ glBlendFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolve("glBlendFunc"));
+ glClear = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolve("glClear"));
+ glClearColor = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolve("glClearColor"));
+ glClearStencil = reinterpret_cast<void (APIENTRY *)(GLint )>(resolve("glClearStencil"));
+ glColorMask = reinterpret_cast<void (APIENTRY *)(GLboolean , GLboolean , GLboolean , GLboolean )>(resolve("glColorMask"));
+ glCopyTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLsizei , GLint )>(resolve("glCopyTexImage2D"));
+ glCopyTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei )>(resolve("glCopyTexSubImage2D"));
+ glCullFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glCullFace"));
+ glDeleteTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *)>(resolve("glDeleteTextures"));
+ glDepthFunc = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glDepthFunc"));
+ glDepthMask = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolve("glDepthMask"));
+ glDisable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glDisable"));
+ glDrawArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLsizei )>(resolve("glDrawArrays"));
+ glDrawElements = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , GLenum , const GLvoid *)>(resolve("glDrawElements"));
+ glEnable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glEnable"));
+ glFinish = reinterpret_cast<void (APIENTRY *)()>(resolve("glFinish"));
+ glFlush = reinterpret_cast<void (APIENTRY *)()>(resolve("glFlush"));
+ glFrontFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glFrontFace"));
+ glGenTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolve("glGenTextures"));
+ glGetBooleanv = reinterpret_cast<void (APIENTRY *)(GLenum , GLboolean *)>(resolve("glGetBooleanv"));
+ glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
+ glGetFloatv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolve("glGetFloatv"));
+ glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
+ glGetString = reinterpret_cast<const GLubyte * (APIENTRY *)(GLenum )>(resolve("glGetString"));
+ glGetTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolve("glGetTexParameterfv"));
+ glGetTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolve("glGetTexParameteriv"));
+ glHint = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolve("glHint"));
+ glIsEnabled = reinterpret_cast<GLboolean (APIENTRY *)(GLenum )>(resolve("glIsEnabled"));
+ glIsTexture = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsTexture"));
+ glLineWidth = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolve("glLineWidth"));
+ glPixelStorei = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolve("glPixelStorei"));
+ glPolygonOffset = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolve("glPolygonOffset"));
+ glReadPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , GLvoid *)>(resolve("glReadPixels"));
+ glScissor = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolve("glScissor"));
+ glStencilFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLuint )>(resolve("glStencilFunc"));
+ glStencilMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glStencilMask"));
+ glStencilOp = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum )>(resolve("glStencilOp"));
+ glTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolve("glTexImage2D"));
+ glTexParameterf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolve("glTexParameterf"));
+ glTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolve("glTexParameterfv"));
+ glTexParameteri = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolve("glTexParameteri"));
+ glTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolve("glTexParameteriv"));
+ glTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolve("glTexSubImage2D"));
+ glViewport = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolve("glViewport"));
+
+ glActiveTexture = reinterpret_cast<void (APIENTRY *)(GLenum)>(resolve("glActiveTexture"));
+ glAttachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolve("glAttachShader"));
+ glBindAttribLocation = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , const GLchar* )>(resolve("glBindAttribLocation"));
+ glBindBuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glBindBuffer"));
+ glBindFramebuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glBindFramebuffer"));
+ glBindRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glBindRenderbuffer"));
+ glBlendColor = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf , GLclampf , GLclampf )>(resolve("glBlendColor"));
+ glBlendEquation = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glBlendEquation"));
+ glBlendEquationSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolve("glBlendEquationSeparate"));
+ glBlendFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolve("glBlendFuncSeparate"));
+ glBufferData = reinterpret_cast<void (APIENTRY *)(GLenum , qopengl_GLsizeiptr , const GLvoid* , GLenum )>(resolve("glBufferData"));
+ glBufferSubData = reinterpret_cast<void (APIENTRY *)(GLenum , qopengl_GLintptr , qopengl_GLsizeiptr , const GLvoid* )>(resolve("glBufferSubData"));
+ glCheckFramebufferStatus = reinterpret_cast<GLenum (APIENTRY *)(GLenum )>(resolve("glCheckFramebufferStatus"));
+ glCompileShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glCompileShader"));
+ glCompressedTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLsizei , GLsizei, GLint, GLsizei, const GLvoid* )>(resolve("glCompressedTexImage2D"));
+ glCompressedTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid* )>(resolve("glCompressedTexSubImage2D"));
+ glCreateProgram = reinterpret_cast<GLuint (APIENTRY *)(void)>(resolve("glCreateProgram"));
+ glCreateShader = reinterpret_cast<GLuint (APIENTRY *)(GLenum )>(resolve("glCreateShader"));
+ glDeleteBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*)>(resolve("glDeleteBuffers"));
+ glDeleteFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolve("glDeleteFramebuffers"));
+ glDeleteProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glDeleteProgram"));
+ glDeleteRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolve("glDeleteRenderbuffers"));
+ glDeleteShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glDeleteShader"));
+ glDetachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolve("glDetachShader"));
+ glDisableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glDisableVertexAttribArray"));
+ glEnableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glEnableVertexAttribArray"));
+ glFramebufferRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint )>(resolve("glFramebufferRenderbuffer"));
+ glFramebufferTexture2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint , GLint )>(resolve("glFramebufferTexture2D"));
+ glGenBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolve("glGenBuffers"));
+ glGenerateMipmap = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glGenerateMipmap"));
+ glGenFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolve("glGenFramebuffers"));
+ glGenRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolve("glGenRenderbuffers"));
+ glGetActiveAttrib = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolve("glGetActiveAttrib"));
+ glGetActiveUniform = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolve("glGetActiveUniform"));
+ glGetAttachedShaders = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLuint* )>(resolve("glGetAttachedShaders"));
+ glGetAttribLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolve("glGetAttribLocation"));
+ glGetBufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolve("glGetBufferParameteriv"));
+ glGetFramebufferAttachmentParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum, GLenum , GLint* )>(resolve("glGetFramebufferAttachmentParameteriv"));
+ glGetProgramiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolve("glGetProgramiv"));
+ glGetProgramInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolve("glGetProgramInfoLog"));
+ glGetRenderbufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolve("glGetRenderbufferParameteriv"));
+ glGetShaderiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolve("glGetShaderiv"));
+ glGetShaderInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLchar*)>(resolve("glGetShaderInfoLog"));
+ glGetShaderPrecisionFormat = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* , GLint* )>(resolve("glGetShaderPrecisionFormat"));
+ glGetShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolve("glGetShaderSource"));
+ glGetUniformfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLfloat*)>(resolve("glGetUniformfv"));
+ glGetUniformiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLint*)>(resolve("glGetUniformiv"));
+ glGetUniformLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolve("glGetUniformLocation"));
+ glGetVertexAttribfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLfloat* )>(resolve("glGetVertexAttribfv"));
+ glGetVertexAttribiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolve("glGetVertexAttribiv"));
+ glGetVertexAttribPointerv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLvoid** pointer)>(resolve("glGetVertexAttribPointerv"));
+ glIsBuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsBuffer"));
+ glIsFramebuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsFramebuffer"));
+ glIsProgram = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsProgram"));
+ glIsRenderbuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsRenderbuffer"));
+ glIsShader = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsShader"));
+ glLinkProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glLinkProgram"));
+ glReleaseShaderCompiler = reinterpret_cast<void (APIENTRY *)(void)>(resolve("glReleaseShaderCompiler"));
+ glRenderbufferStorage = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLsizei , GLsizei )>(resolve("glRenderbufferStorage"));
+ glSampleCoverage = reinterpret_cast<void (APIENTRY *)(GLclampf , GLboolean )>(resolve("glSampleCoverage"));
+ glShaderBinary = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*, GLenum , const GLvoid* , GLsizei )>(resolve("glShaderBinary"));
+ glShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , const GLchar* *, const GLint* )>(resolve("glShaderSource"));
+ glStencilFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint , GLuint )>(resolve("glStencilFuncSeparate"));
+ glStencilMaskSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glStencilMaskSeparate"));
+ glStencilOpSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolve("glStencilOpSeparate"));
+ glUniform1f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat )>(resolve("glUniform1f"));
+ glUniform1fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolve("glUniform1fv"));
+ glUniform1i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolve("glUniform1i"));
+ glUniform1iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolve("glUniform1iv"));
+ glUniform2f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat )>(resolve("glUniform2f"));
+ glUniform2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolve("glUniform2fv"));
+ glUniform2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolve("glUniform2i"));
+ glUniform2iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolve("glUniform2iv"));
+ glUniform3f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat )>(resolve("glUniform3f"));
+ glUniform3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolve("glUniform3fv"));
+ glUniform3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolve("glUniform3i"));
+ glUniform3iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolve("glUniform3iv"));
+ glUniform4f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolve("glUniform4f"));
+ glUniform4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolve("glUniform4fv"));
+ glUniform4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint , GLint )>(resolve("glUniform4i"));
+ glUniform4iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolve("glUniform4iv"));
+ glUniformMatrix2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolve("glUniformMatrix2fv"));
+ glUniformMatrix3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolve("glUniformMatrix3fv"));
+ glUniformMatrix4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolve("glUniformMatrix4fv"));
+ glUseProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glUseProgram"));
+ glValidateProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glValidateProgram"));
+ glVertexAttrib1f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat )>(resolve("glVertexAttrib1f"));
+ glVertexAttrib1fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolve("glVertexAttrib1fv"));
+ glVertexAttrib2f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat )>(resolve("glVertexAttrib2f"));
+ glVertexAttrib2fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolve("glVertexAttrib2fv"));
+ glVertexAttrib3f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat )>(resolve("glVertexAttrib3f"));
+ glVertexAttrib3fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolve("glVertexAttrib3fv"));
+ glVertexAttrib4f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolve("glVertexAttrib4f"));
+ glVertexAttrib4fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolve("glVertexAttrib4fv"));
+ glVertexAttribPointer = reinterpret_cast<void (APIENTRY *)(GLuint , GLint, GLenum, GLboolean, GLsizei, const GLvoid* )>(resolve("glVertexAttribPointer"));
+
+ glClearDepthf = reinterpret_cast<void (APIENTRY *)(GLclampf )>(resolve("glClearDepthf"));
+ glDepthRangef = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf )>(resolve("glDepthRangef"));
+
+ return glBindTexture && glCreateShader && glClearDepthf;
+}
+
QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int version)
: m_display(display), m_version(version)
{
@@ -76,7 +335,16 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
return 0;
}
- EGLDisplay display = eglGetDisplay((EGLNativeDisplayType)dc);
+ if (!libEGL.init()) {
+ qWarning("%s: Failed to load and resolve libEGL functions", Q_FUNC_INFO);
+ return 0;
+ }
+ if (!libGLESv2.init()) {
+ qWarning("%s: Failed to load and resolve libGLESv2 functions", Q_FUNC_INFO);
+ return 0;
+ }
+
+ EGLDisplay display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc);
if (!display) {
qWarning("%s: Could not obtain EGL display", Q_FUNC_INFO);
return 0;
@@ -84,9 +352,11 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
EGLint major;
EGLint minor;
- if (!eglInitialize(display, &major, &minor)) {
- qWarning("%s: Could not initialize egl display: error %d\n",
- Q_FUNC_INFO, eglGetError());
+ if (!libEGL.eglInitialize(display, &major, &minor)) {
+ int err = libEGL.eglGetError();
+ qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err);
+ if (err == 0x3001)
+ qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", Q_FUNC_INFO);
return 0;
}
@@ -97,7 +367,70 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
QWindowsEGLStaticContext::~QWindowsEGLStaticContext()
{
qCDebug(lcQpaGl) << __FUNCTION__ << "Releasing EGL display " << m_display;
- eglTerminate(m_display);
+ libEGL.eglTerminate(m_display);
+}
+
+QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *context)
+{
+ return new QWindowsEGLContext(this, context->format(), context->shareHandle());
+}
+
+void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig)
+{
+ EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, (EGLConfig) nativeConfig,
+ (EGLNativeWindowType) nativeWindow, 0);
+ if (surface == EGL_NO_SURFACE)
+ qWarning("%s: Could not create the EGL window surface: 0x%x\n", Q_FUNC_INFO, libEGL.eglGetError());
+
+ return surface;
+}
+
+void QWindowsEGLStaticContext::destroyWindowSurface(void *nativeSurface)
+{
+ libEGL.eglDestroySurface(m_display, (EGLSurface) nativeSurface);
+}
+
+QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EGLConfig config,
+ const QSurfaceFormat &referenceFormat)
+{
+ QSurfaceFormat format;
+ EGLint redSize = 0;
+ EGLint greenSize = 0;
+ EGLint blueSize = 0;
+ EGLint alphaSize = 0;
+ EGLint depthSize = 0;
+ EGLint stencilSize = 0;
+ EGLint sampleCount = 0;
+
+ libEGL.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
+ libEGL.eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
+
+ format.setRenderableType(QSurfaceFormat::OpenGLES);
+ format.setVersion(referenceFormat.majorVersion(), referenceFormat.minorVersion());
+ format.setProfile(referenceFormat.profile());
+ format.setOptions(referenceFormat.options());
+
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ format.setAlphaBufferSize(alphaSize);
+ format.setDepthBufferSize(depthSize);
+ format.setStencilBufferSize(stencilSize);
+ format.setSamples(sampleCount);
+ format.setStereo(false);
+ format.setSwapInterval(referenceFormat.swapInterval());
+
+ // Clear the EGL error state because some of the above may
+ // have errored out because the attribute is not applicable
+ // to the surface type. Such errors don't matter.
+ libEGL.eglGetError();
+
+ return format;
}
/*!
@@ -121,40 +454,465 @@ QWindowsEGLStaticContext::~QWindowsEGLStaticContext()
\ingroup qt-lighthouse-win
*/
-QWindowsEGLContext::QWindowsEGLContext(const QWindowsEGLStaticContextPtr &staticContext,
+QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
const QSurfaceFormat &format,
QPlatformOpenGLContext *share)
- : QEGLPlatformContext(format, share, staticContext->display())
- , m_staticContext(staticContext)
+ : m_staticContext(staticContext)
+ , m_eglDisplay(staticContext->display())
+ , m_api(EGL_OPENGL_ES_API)
+ , m_swapInterval(-1)
{
+ if (!m_staticContext)
+ return;
+
+ m_eglConfig = chooseConfig(format);
+ m_format = m_staticContext->formatFromConfig(m_eglDisplay, m_eglConfig, format);
+ m_shareContext = share ? static_cast<QWindowsEGLContext *>(share)->m_eglContext : 0;
+
+ QVector<EGLint> contextAttrs;
+ contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ contextAttrs.append(m_format.majorVersion());
+ contextAttrs.append(EGL_NONE);
+
+ QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
+ m_eglContext = QWindowsEGLStaticContext::libEGL.eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData());
+ if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) {
+ m_shareContext = 0;
+ m_eglContext = QWindowsEGLStaticContext::libEGL.eglCreateContext(m_eglDisplay, m_eglConfig, 0, contextAttrs.constData());
+ }
+
+ if (m_eglContext == EGL_NO_CONTEXT) {
+ qWarning("QWindowsEGLContext: eglError: %x, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ return;
+ }
+
+ // Make the context current to ensure the GL version query works. This needs a surface too.
+ const EGLint pbufferAttributes[] = {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_LARGEST_PBUFFER, EGL_FALSE,
+ EGL_NONE
+ };
+ EGLSurface pbuffer = QWindowsEGLStaticContext::libEGL.eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttributes);
+ if (pbuffer == EGL_NO_SURFACE)
+ return;
+
+ if (QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, pbuffer, pbuffer, m_eglContext)) {
+ const GLubyte *s = QWindowsEGLStaticContext::libGLESv2.glGetString(GL_VERSION);
+ if (s) {
+ QByteArray version = QByteArray(reinterpret_cast<const char *>(s));
+ int major, minor;
+ if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) {
+ m_format.setMajorVersion(major);
+ m_format.setMinorVersion(minor);
+ }
+ }
+ m_format.setProfile(QSurfaceFormat::NoProfile);
+ m_format.setOptions(QSurfaceFormat::FormatOptions());
+ QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ }
+ QWindowsEGLStaticContext::libEGL.eglDestroySurface(m_eglDisplay, pbuffer);
}
QWindowsEGLContext::~QWindowsEGLContext()
{
+ if (m_eglContext != EGL_NO_CONTEXT) {
+ QWindowsEGLStaticContext::libEGL.eglDestroyContext(m_eglDisplay, m_eglContext);
+ m_eglContext = EGL_NO_CONTEXT;
+ }
}
-bool QWindowsEGLContext::hasThreadedOpenGLCapability()
+bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
{
- return false;
+ Q_ASSERT(surface->surface()->supportsOpenGL());
+
+ QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
+
+ QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
+ EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig));
+ Q_ASSERT(eglSurface);
+
+ // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation
+ if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext &&
+ QWindowsEGLStaticContext::libEGL.eglGetCurrentDisplay() == m_eglDisplay &&
+ QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_READ) == eglSurface &&
+ QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_DRAW) == eglSurface) {
+ return true;
+ }
+
+ const bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
+ if (ok) {
+ const int requestedSwapInterval = surface->format().swapInterval();
+ if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) {
+ m_swapInterval = requestedSwapInterval;
+ QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval);
+ }
+ } else {
+ qWarning("QWindowsEGLContext::makeCurrent: eglError: %x, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+ }
+
+ return ok;
}
-EGLSurface QWindowsEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+void QWindowsEGLContext::doneCurrent()
{
- const QWindowsWindow *window = static_cast<const QWindowsWindow *>(surface);
- return window->eglSurfaceHandle();
+ QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
+ bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (!ok)
+ qWarning("QWindowsEGLContext::doneCurrent: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
}
-bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
+void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface)
{
- bool ok = false;
+ QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
QWindowsWindow *window = static_cast<QWindowsWindow *>(surface);
- if (EGLSurface eglSurface = window->ensureEglSurfaceHandle(m_staticContext, eglConfig())) {
- ok = eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext());
- if (!ok)
- qWarning("%s: eglMakeCurrent() failed, eglError: 0x%x, this: %p \n",
- Q_FUNC_INFO, eglGetError(), this);
+ EGLSurface eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig));
+ Q_ASSERT(eglSurface);
+
+ bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface);
+ if (!ok)
+ qWarning("QWindowsEGLContext::swapBuffers: eglError: %d, this: %p \n", QWindowsEGLStaticContext::libEGL.eglGetError(), this);
+}
+
+QFunctionPointer QWindowsEGLContext::getProcAddress(const QByteArray &procName)
+{
+ // We support AllGLFunctionsQueryable, which means this function must be able to
+ // return a function pointer for standard GLES2 functions too. These are not
+ // guaranteed to be queryable via eglGetProcAddress().
+ static struct StdFunc {
+ const char *name;
+ void *func;
+ } standardFuncs[] = {
+ { "glBindTexture", (void *) QWindowsEGLStaticContext::libGLESv2.glBindTexture },
+ { "glBlendFunc", (void *) QWindowsEGLStaticContext::libGLESv2.glBlendFunc },
+ { "glClear", (void *) QWindowsEGLStaticContext::libGLESv2.glClear },
+ { "glClearColor", (void *) QWindowsEGLStaticContext::libGLESv2.glClearColor },
+ { "glClearStencil", (void *) QWindowsEGLStaticContext::libGLESv2.glClearStencil },
+ { "glColorMask", (void *) QWindowsEGLStaticContext::libGLESv2.glColorMask },
+ { "glCopyTexImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glCopyTexImage2D },
+ { "glCopyTexSubImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glCopyTexSubImage2D },
+ { "glCullFace", (void *) QWindowsEGLStaticContext::libGLESv2.glCullFace },
+ { "glDeleteTextures", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteTextures },
+ { "glDepthFunc", (void *) QWindowsEGLStaticContext::libGLESv2.glDepthFunc },
+ { "glDepthMask", (void *) QWindowsEGLStaticContext::libGLESv2.glDepthMask },
+ { "glDisable", (void *) QWindowsEGLStaticContext::libGLESv2.glDisable },
+ { "glDrawArrays", (void *) QWindowsEGLStaticContext::libGLESv2.glDrawArrays },
+ { "glDrawElements", (void *) QWindowsEGLStaticContext::libGLESv2.glDrawElements },
+ { "glEnable", (void *) QWindowsEGLStaticContext::libGLESv2.glEnable },
+ { "glFinish", (void *) QWindowsEGLStaticContext::libGLESv2.glFinish },
+ { "glFlush", (void *) QWindowsEGLStaticContext::libGLESv2.glFlush },
+ { "glFrontFace", (void *) QWindowsEGLStaticContext::libGLESv2.glFrontFace },
+ { "glGenTextures", (void *) QWindowsEGLStaticContext::libGLESv2.glGenTextures },
+ { "glGetBooleanv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetBooleanv },
+ { "glGetError", (void *) QWindowsEGLStaticContext::libGLESv2.glGetError },
+ { "glGetFloatv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetFloatv },
+ { "glGetIntegerv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetIntegerv },
+ { "glGetString", (void *) QWindowsEGLStaticContext::libGLESv2.glGetString },
+ { "glGetTexParameterfv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetTexParameterfv },
+ { "glGetTexParameteriv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetTexParameteriv },
+ { "glHint", (void *) QWindowsEGLStaticContext::libGLESv2.glHint },
+ { "glIsEnabled", (void *) QWindowsEGLStaticContext::libGLESv2.glIsEnabled },
+ { "glIsTexture", (void *) QWindowsEGLStaticContext::libGLESv2.glIsTexture },
+ { "glLineWidth", (void *) QWindowsEGLStaticContext::libGLESv2.glLineWidth },
+ { "glPixelStorei", (void *) QWindowsEGLStaticContext::libGLESv2.glPixelStorei },
+ { "glPolygonOffset", (void *) QWindowsEGLStaticContext::libGLESv2.glPolygonOffset },
+ { "glReadPixels", (void *) QWindowsEGLStaticContext::libGLESv2.glReadPixels },
+ { "glScissor", (void *) QWindowsEGLStaticContext::libGLESv2.glScissor },
+ { "glStencilFunc", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilFunc },
+ { "glStencilMask", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilMask },
+ { "glStencilOp", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilOp },
+ { "glTexImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glTexImage2D },
+ { "glTexParameterf", (void *) QWindowsEGLStaticContext::libGLESv2.glTexParameterf },
+ { "glTexParameterfv", (void *) QWindowsEGLStaticContext::libGLESv2.glTexParameterfv },
+ { "glTexParameteri", (void *) QWindowsEGLStaticContext::libGLESv2.glTexParameteri },
+ { "glTexParameteriv", (void *) QWindowsEGLStaticContext::libGLESv2.glTexParameteriv },
+ { "glTexSubImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glTexSubImage2D },
+ { "glViewport", (void *) QWindowsEGLStaticContext::libGLESv2.glViewport },
+
+ { "glActiveTexture", (void *) QWindowsEGLStaticContext::libGLESv2.glActiveTexture },
+ { "glAttachShader", (void *) QWindowsEGLStaticContext::libGLESv2.glAttachShader },
+ { "glBindAttribLocation", (void *) QWindowsEGLStaticContext::libGLESv2.glBindAttribLocation },
+ { "glBindBuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glBindBuffer },
+ { "glBindFramebuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glBindFramebuffer },
+ { "glBindRenderbuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glBindRenderbuffer },
+ { "glBlendColor", (void *) QWindowsEGLStaticContext::libGLESv2.glBlendColor },
+ { "glBlendEquation", (void *) QWindowsEGLStaticContext::libGLESv2.glBlendEquation },
+ { "glBlendEquationSeparate", (void *) QWindowsEGLStaticContext::libGLESv2.glBlendEquationSeparate },
+ { "glBlendFuncSeparate", (void *) QWindowsEGLStaticContext::libGLESv2.glBlendFuncSeparate },
+ { "glBufferData", (void *) QWindowsEGLStaticContext::libGLESv2.glBufferData },
+ { "glBufferSubData", (void *) QWindowsEGLStaticContext::libGLESv2.glBufferSubData },
+ { "glCheckFramebufferStatus", (void *) QWindowsEGLStaticContext::libGLESv2.glCheckFramebufferStatus },
+ { "glCompileShader", (void *) QWindowsEGLStaticContext::libGLESv2.glCompileShader },
+ { "glCompressedTexImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glCompressedTexImage2D },
+ { "glCompressedTexSubImage2D", (void *) QWindowsEGLStaticContext::libGLESv2.glCompressedTexSubImage2D },
+ { "glCreateProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glCreateProgram },
+ { "glCreateShader", (void *) QWindowsEGLStaticContext::libGLESv2.glCreateShader },
+ { "glDeleteBuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteBuffers },
+ { "glDeleteFramebuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteFramebuffers },
+ { "glDeleteProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteProgram },
+ { "glDeleteRenderbuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteRenderbuffers },
+ { "glDeleteShader", (void *) QWindowsEGLStaticContext::libGLESv2.glDeleteShader },
+ { "glDetachShader", (void *) QWindowsEGLStaticContext::libGLESv2.glDetachShader },
+ { "glDisableVertexAttribArray", (void *) QWindowsEGLStaticContext::libGLESv2.glDisableVertexAttribArray },
+ { "glEnableVertexAttribArray", (void *) QWindowsEGLStaticContext::libGLESv2.glEnableVertexAttribArray },
+ { "glFramebufferRenderbuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glFramebufferRenderbuffer },
+ { "glFramebufferTexture2D", (void *) QWindowsEGLStaticContext::libGLESv2.glFramebufferTexture2D },
+ { "glGenBuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glGenBuffers },
+ { "glGenerateMipmap", (void *) QWindowsEGLStaticContext::libGLESv2.glGenerateMipmap },
+ { "glGenFramebuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glGenFramebuffers },
+ { "glGenRenderbuffers", (void *) QWindowsEGLStaticContext::libGLESv2.glGenRenderbuffers },
+ { "glGetActiveAttrib", (void *) QWindowsEGLStaticContext::libGLESv2.glGetActiveAttrib },
+ { "glGetActiveUniform", (void *) QWindowsEGLStaticContext::libGLESv2.glGetActiveUniform },
+ { "glGetAttachedShaders", (void *) QWindowsEGLStaticContext::libGLESv2.glGetAttachedShaders },
+ { "glGetAttribLocation", (void *) QWindowsEGLStaticContext::libGLESv2.glGetAttribLocation },
+ { "glGetBufferParameteriv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetBufferParameteriv },
+ { "glGetFramebufferAttachmentParameteriv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetFramebufferAttachmentParameteriv },
+ { "glGetProgramiv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetProgramiv },
+ { "glGetProgramInfoLog", (void *) QWindowsEGLStaticContext::libGLESv2.glGetProgramInfoLog },
+ { "glGetRenderbufferParameteriv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetRenderbufferParameteriv },
+ { "glGetShaderiv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetShaderiv },
+ { "glGetShaderInfoLog", (void *) QWindowsEGLStaticContext::libGLESv2.glGetShaderInfoLog },
+ { "glGetShaderPrecisionFormat", (void *) QWindowsEGLStaticContext::libGLESv2.glGetShaderPrecisionFormat },
+ { "glGetShaderSource", (void *) QWindowsEGLStaticContext::libGLESv2.glGetShaderSource },
+ { "glGetUniformfv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetUniformfv },
+ { "glGetUniformiv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetUniformiv },
+ { "glGetUniformLocation", (void *) QWindowsEGLStaticContext::libGLESv2.glGetUniformLocation },
+ { "glGetVertexAttribfv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetVertexAttribfv },
+ { "glGetVertexAttribiv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetVertexAttribiv },
+ { "glGetVertexAttribPointerv", (void *) QWindowsEGLStaticContext::libGLESv2.glGetVertexAttribPointerv },
+ { "glIsBuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glIsBuffer },
+ { "glIsFramebuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glIsFramebuffer },
+ { "glIsProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glIsProgram },
+ { "glIsRenderbuffer", (void *) QWindowsEGLStaticContext::libGLESv2.glIsRenderbuffer },
+ { "glIsShader", (void *) QWindowsEGLStaticContext::libGLESv2.glIsShader },
+ { "glLinkProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glLinkProgram },
+ { "glReleaseShaderCompiler", (void *) QWindowsEGLStaticContext::libGLESv2.glReleaseShaderCompiler },
+ { "glRenderbufferStorage", (void *) QWindowsEGLStaticContext::libGLESv2.glRenderbufferStorage },
+ { "glSampleCoverage", (void *) QWindowsEGLStaticContext::libGLESv2.glSampleCoverage },
+ { "glShaderBinary", (void *) QWindowsEGLStaticContext::libGLESv2.glShaderBinary },
+ { "glShaderSource", (void *) QWindowsEGLStaticContext::libGLESv2.glShaderSource },
+ { "glStencilFuncSeparate", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilFuncSeparate },
+ { "glStencilMaskSeparate", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilMaskSeparate },
+ { "glStencilOpSeparate", (void *) QWindowsEGLStaticContext::libGLESv2.glStencilOpSeparate },
+ { "glUniform1f", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform1f },
+ { "glUniform1fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform1fv },
+ { "glUniform1i", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform1i },
+ { "glUniform1iv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform1iv },
+ { "glUniform2f", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform2f },
+ { "glUniform2fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform2fv },
+ { "glUniform2i", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform2i },
+ { "glUniform2iv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform2iv },
+ { "glUniform3f", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform3f },
+ { "glUniform3fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform3fv },
+ { "glUniform3i", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform3i },
+ { "glUniform3iv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform3iv },
+ { "glUniform4f", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform4f },
+ { "glUniform4fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform4fv },
+ { "glUniform4i", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform4i },
+ { "glUniform4iv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniform4iv },
+ { "glUniformMatrix2fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniformMatrix2fv },
+ { "glUniformMatrix3fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniformMatrix3fv },
+ { "glUniformMatrix4fv", (void *) QWindowsEGLStaticContext::libGLESv2.glUniformMatrix4fv },
+ { "glUseProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glUseProgram },
+ { "glValidateProgram", (void *) QWindowsEGLStaticContext::libGLESv2.glValidateProgram },
+ { "glVertexAttrib1f", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib1f },
+ { "glVertexAttrib1fv", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib1fv },
+ { "glVertexAttrib2f", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib2f },
+ { "glVertexAttrib2fv", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib2fv },
+ { "glVertexAttrib3f", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib3f },
+ { "glVertexAttrib3fv", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib3fv },
+ { "glVertexAttrib4f", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib4f },
+ { "glVertexAttrib4fv", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttrib4fv },
+ { "glVertexAttribPointer", (void *) QWindowsEGLStaticContext::libGLESv2.glVertexAttribPointer },
+
+ { "glClearDepthf", (void *) QWindowsEGLStaticContext::libGLESv2.glClearDepthf },
+ { "glDepthRangef", (void *) QWindowsEGLStaticContext::libGLESv2.glDepthRangef }
+ };
+ for (size_t i = 0; i < sizeof(standardFuncs) / sizeof(StdFunc); ++i)
+ if (procName == standardFuncs[i].name)
+ return reinterpret_cast<QFunctionPointer>(standardFuncs[i].func);
+
+ QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api);
+ QFunctionPointer procAddress = reinterpret_cast<QFunctionPointer>(QWindowsEGLStaticContext::libEGL.eglGetProcAddress(procName.constData()));
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << procName << QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() << "returns" << procAddress;
+ if (!procAddress)
+ qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
+ return procAddress;
+}
+
+static QVector<EGLint> createConfigAttributesFromFormat(const QSurfaceFormat &format)
+{
+ int redSize = format.redBufferSize();
+ int greenSize = format.greenBufferSize();
+ int blueSize = format.blueBufferSize();
+ int alphaSize = format.alphaBufferSize();
+ int depthSize = format.depthBufferSize();
+ int stencilSize = format.stencilBufferSize();
+ int sampleCount = format.samples();
+
+ QVector<EGLint> configAttributes;
+ configAttributes.reserve(16);
+
+ configAttributes.append(EGL_RED_SIZE);
+ configAttributes.append(redSize > 0 ? redSize : 0);
+
+ configAttributes.append(EGL_GREEN_SIZE);
+ configAttributes.append(greenSize > 0 ? greenSize : 0);
+
+ configAttributes.append(EGL_BLUE_SIZE);
+ configAttributes.append(blueSize > 0 ? blueSize : 0);
+
+ configAttributes.append(EGL_ALPHA_SIZE);
+ configAttributes.append(alphaSize > 0 ? alphaSize : 0);
+
+ configAttributes.append(EGL_DEPTH_SIZE);
+ configAttributes.append(depthSize > 0 ? depthSize : 0);
+
+ configAttributes.append(EGL_STENCIL_SIZE);
+ configAttributes.append(stencilSize > 0 ? stencilSize : 0);
+
+ configAttributes.append(EGL_SAMPLES);
+ configAttributes.append(sampleCount > 0 ? sampleCount : 0);
+
+ configAttributes.append(EGL_SAMPLE_BUFFERS);
+ configAttributes.append(sampleCount > 0);
+
+ return configAttributes;
+}
+
+static bool reduceConfigAttributes(QVector<EGLint> *configAttributes)
+{
+ int i = -1;
+
+ i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
}
- return ok;
+
+ i = configAttributes->indexOf(EGL_BUFFER_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i+1) == 16) {
+ configAttributes->remove(i,2);
+ return true;
+ }
+ }
+
+ i = configAttributes->indexOf(EGL_SAMPLES);
+ if (i >= 0) {
+ EGLint value = configAttributes->value(i+1, 0);
+ if (value > 1)
+ configAttributes->replace(i+1, qMin(EGLint(16), value / 2));
+ else
+ configAttributes->remove(i, 2);
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_ALPHA_SIZE);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
+ i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
+ if (i >= 0) {
+ configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
+ configAttributes->replace(i+1,true);
+
+ }
+#endif
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_STENCIL_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i + 1) > 1)
+ configAttributes->replace(i + 1, 1);
+ else
+ configAttributes->remove(i, 2);
+ return true;
+ }
+
+ i = configAttributes->indexOf(EGL_DEPTH_SIZE);
+ if (i >= 0) {
+ if (configAttributes->at(i + 1) > 1)
+ configAttributes->replace(i + 1, 1);
+ else
+ configAttributes->remove(i, 2);
+ return true;
+ }
+#ifdef EGL_BIND_TO_TEXTURE_RGB
+ i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
+ if (i >= 0) {
+ configAttributes->remove(i,2);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format)
+{
+ QVector<EGLint> configureAttributes = createConfigAttributesFromFormat(format);
+ configureAttributes.append(EGL_SURFACE_TYPE);
+ configureAttributes.append(EGL_WINDOW_BIT);
+ configureAttributes.append(EGL_RENDERABLE_TYPE);
+ configureAttributes.append(EGL_OPENGL_ES2_BIT);
+ configureAttributes.append(EGL_NONE);
+
+ EGLDisplay display = m_staticContext->display();
+ EGLConfig cfg = 0;
+ do {
+ // Get the number of matching configurations for this set of properties.
+ EGLint matching = 0;
+ if (!QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), 0, 0, &matching) || !matching)
+ continue;
+
+ // Fetch all of the matching configurations and find the
+ // first that matches the pixel format we wanted.
+ int i = configureAttributes.indexOf(EGL_RED_SIZE);
+ int confAttrRed = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_GREEN_SIZE);
+ int confAttrGreen = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_BLUE_SIZE);
+ int confAttrBlue = configureAttributes.at(i+1);
+ i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
+ int confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1);
+
+ QVector<EGLConfig> configs(matching);
+ QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), configs.data(), configs.size(), &matching);
+ if (!cfg && matching > 0)
+ cfg = configs.first();
+
+ EGLint red = 0;
+ EGLint green = 0;
+ EGLint blue = 0;
+ EGLint alpha = 0;
+ for (int i = 0; i < configs.size(); ++i) {
+ if (confAttrRed)
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_RED_SIZE, &red);
+ if (confAttrGreen)
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_GREEN_SIZE, &green);
+ if (confAttrBlue)
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_BLUE_SIZE, &blue);
+ if (confAttrAlpha)
+ QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &alpha);
+
+ if (red == confAttrRed && green == confAttrGreen
+ && blue == confAttrBlue && alpha == confAttrAlpha)
+ return configs[i];
+ }
+ } while (reduceConfigAttributes(&configureAttributes));
+
+ if (!cfg)
+ qWarning("Cannot find EGLConfig, returning null config");
+
+ return cfg;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h
index 33653b2f2e..813c605396 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.h
+++ b/src/plugins/platforms/windows/qwindowseglcontext.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,20 +42,229 @@
#ifndef QWINDOWSEGLCONTEXT_H
#define QWINDOWSEGLCONTEXT_H
-#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
-#include <QSharedPointer>
+#include "qwindowsopenglcontext.h"
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class QWindowsEGLStaticContext
+struct QWindowsLibEGL
+{
+ bool init();
+
+ EGLint (EGLAPIENTRY * eglGetError)(void);
+ EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id);
+ EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy);
+ EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config);
+ EGLBoolean (EGLAPIENTRY * eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value);
+ EGLSurface (EGLAPIENTRY * eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+ EGLSurface (EGLAPIENTRY * eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean (EGLAPIENTRY * eglBindAPI)(EGLenum api);
+ EGLBoolean (EGLAPIENTRY * eglSwapInterval)(EGLDisplay dpy, EGLint interval);
+ EGLContext (EGLAPIENTRY * eglCreateContext)(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+ EGLBoolean (EGLAPIENTRY * eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
+ EGLContext (EGLAPIENTRY * eglGetCurrentContext)(void);
+ EGLSurface (EGLAPIENTRY * eglGetCurrentSurface)(EGLint readdraw);
+ EGLDisplay (EGLAPIENTRY * eglGetCurrentDisplay)(void);
+ EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+ __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * eglGetProcAddress)(const char *procname);
+
+private:
+ void *resolve(const char *name);
+ HMODULE m_lib;
+};
+
+struct QWindowsLibGLESv2
+{
+ bool init();
+ void *moduleHandle() const { return m_lib; }
+
+ // GL1+GLES2 common
+ void (APIENTRY * glBindTexture)(GLenum target, GLuint texture);
+ void (APIENTRY * glBlendFunc)(GLenum sfactor, GLenum dfactor);
+ void (APIENTRY * glClear)(GLbitfield mask);
+ void (APIENTRY * glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (APIENTRY * glClearStencil)(GLint s);
+ void (APIENTRY * glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void (APIENTRY * glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void (APIENTRY * glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * glCullFace)(GLenum mode);
+ void (APIENTRY * glDeleteTextures)(GLsizei n, const GLuint* textures);
+ void (APIENTRY * glDepthFunc)(GLenum func);
+ void (APIENTRY * glDepthMask)(GLboolean flag);
+ void (APIENTRY * glDisable)(GLenum cap);
+ void (APIENTRY * glDrawArrays)(GLenum mode, GLint first, GLsizei count);
+ void (APIENTRY * glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+ void (APIENTRY * glEnable)(GLenum cap);
+ void (APIENTRY * glFinish)();
+ void (APIENTRY * glFlush)();
+ void (APIENTRY * glFrontFace)(GLenum mode);
+ void (APIENTRY * glGenTextures)(GLsizei n, GLuint* textures);
+ void (APIENTRY * glGetBooleanv)(GLenum pname, GLboolean* params);
+ GLenum (APIENTRY * glGetError)();
+ void (APIENTRY * glGetFloatv)(GLenum pname, GLfloat* params);
+ void (APIENTRY * glGetIntegerv)(GLenum pname, GLint* params);
+ const GLubyte * (APIENTRY * glGetString)(GLenum name);
+ void (APIENTRY * glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params);
+ void (APIENTRY * glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * glHint)(GLenum target, GLenum mode);
+ GLboolean (APIENTRY * glIsEnabled)(GLenum cap);
+ GLboolean (APIENTRY * glIsTexture)(GLuint texture);
+ void (APIENTRY * glLineWidth)(GLfloat width);
+ void (APIENTRY * glPixelStorei)(GLenum pname, GLint param);
+ void (APIENTRY * glPolygonOffset)(GLfloat factor, GLfloat units);
+ void (APIENTRY * glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+ void (APIENTRY * glScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * glStencilFunc)(GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * glStencilMask)(GLuint mask);
+ void (APIENTRY * glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+ void (APIENTRY * glTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params);
+ void (APIENTRY * glTexParameteri)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * glTexParameteriv)(GLenum target, GLenum pname, const GLint* params);
+ void (APIENTRY * glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+ void (APIENTRY * glViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+
+ // GLES2
+ void (APIENTRY * glActiveTexture)(GLenum texture);
+ void (APIENTRY * glAttachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * glBindAttribLocation)(GLuint program, GLuint index, const char* name);
+ void (APIENTRY * glBindBuffer)(GLenum target, GLuint buffer);
+ void (APIENTRY * glBindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (APIENTRY * glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (APIENTRY * glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (APIENTRY * glBlendEquation)(GLenum mode);
+ void (APIENTRY * glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (APIENTRY * glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (APIENTRY * glBufferData)(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage);
+ void (APIENTRY * glBufferSubData)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data);
+ GLenum (APIENTRY * glCheckFramebufferStatus)(GLenum target);
+ void (APIENTRY * glCompileShader)(GLuint shader);
+ void (APIENTRY * glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+ void (APIENTRY * glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+ GLuint (APIENTRY * glCreateProgram)();
+ GLuint (APIENTRY * glCreateShader)(GLenum type);
+ void (APIENTRY * glDeleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (APIENTRY * glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (APIENTRY * glDeleteProgram)(GLuint program);
+ void (APIENTRY * glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (APIENTRY * glDeleteShader)(GLuint shader);
+ void (APIENTRY * glDetachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * glDisableVertexAttribArray)(GLuint index);
+ void (APIENTRY * glEnableVertexAttribArray)(GLuint index);
+ void (APIENTRY * glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void (APIENTRY * glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void (APIENTRY * glGenBuffers)(GLsizei n, GLuint* buffers);
+ void (APIENTRY * glGenerateMipmap)(GLenum target);
+ void (APIENTRY * glGenFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (APIENTRY * glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (APIENTRY * glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (APIENTRY * glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+ void (APIENTRY * glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ GLint (APIENTRY * glGetAttribLocation)(GLuint program, const char* name);
+ void (APIENTRY * glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (APIENTRY * glGetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (APIENTRY * glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (APIENTRY * glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * glGetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (APIENTRY * glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+ void (APIENTRY * glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (APIENTRY * glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+ void (APIENTRY * glGetUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (APIENTRY * glGetUniformiv)(GLuint program, GLint location, GLint* params);
+ GLint (APIENTRY * glGetUniformLocation)(GLuint program, const char* name);
+ void (APIENTRY * glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (APIENTRY * glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (APIENTRY * glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer);
+ GLboolean (APIENTRY * glIsBuffer)(GLuint buffer);
+ GLboolean (APIENTRY * glIsFramebuffer)(GLuint framebuffer);
+ GLboolean (APIENTRY * glIsProgram)(GLuint program);
+ GLboolean (APIENTRY * glIsRenderbuffer)(GLuint renderbuffer);
+ GLboolean (APIENTRY * glIsShader)(GLuint shader);
+ void (APIENTRY * glLinkProgram)(GLuint program);
+ void (APIENTRY * glReleaseShaderCompiler)();
+ void (APIENTRY * glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (APIENTRY * glSampleCoverage)(GLclampf value, GLboolean invert);
+ void (APIENTRY * glShaderBinary)(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length);
+ void (APIENTRY * glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length);
+ void (APIENTRY * glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * glStencilMaskSeparate)(GLenum face, GLuint mask);
+ void (APIENTRY * glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * glUniform1f)(GLint location, GLfloat x);
+ void (APIENTRY * glUniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * glUniform1i)(GLint location, GLint x);
+ void (APIENTRY * glUniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * glUniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (APIENTRY * glUniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * glUniform2i)(GLint location, GLint x, GLint y);
+ void (APIENTRY * glUniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * glUniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * glUniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (APIENTRY * glUniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * glUniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * glUniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * glUseProgram)(GLuint program);
+ void (APIENTRY * glValidateProgram)(GLuint program);
+ void (APIENTRY * glVertexAttrib1f)(GLuint indx, GLfloat x);
+ void (APIENTRY * glVertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (APIENTRY * glVertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * glVertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * glVertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+
+ // ES only
+ void (APIENTRY * glClearDepthf)(GLclampf depth);
+ void (APIENTRY * glDepthRangef)(GLclampf nearVal, GLclampf farVal);
+
+private:
+ void *resolve(const char *name);
+ HMODULE m_lib;
+};
+
+class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext
{
Q_DISABLE_COPY(QWindowsEGLStaticContext)
+
public:
static QWindowsEGLStaticContext *create();
~QWindowsEGLStaticContext();
EGLDisplay display() const { return m_display; }
+ QWindowsOpenGLContext *createContext(QOpenGLContext *context);
+ void *moduleHandle() const { return libGLESv2.moduleHandle(); }
+ QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGLES; }
+
+ void *createWindowSurface(void *nativeWindow, void *nativeConfig) Q_DECL_OVERRIDE;
+ void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE;
+
+ QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat);
+
+ static QWindowsLibEGL libEGL;
+ static QWindowsLibGLESv2 libGLESv2;
+
private:
QWindowsEGLStaticContext(EGLDisplay display, int version);
@@ -63,26 +272,38 @@ private:
const int m_version; //! majorVersion<<8 + minorVersion
};
-class QWindowsEGLContext : public QEGLPlatformContext
+class QWindowsEGLContext : public QWindowsOpenGLContext
{
public:
- typedef QSharedPointer<QWindowsEGLStaticContext> QWindowsEGLStaticContextPtr;
-
- QWindowsEGLContext(const QWindowsEGLStaticContextPtr& staticContext,
+ QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
const QSurfaceFormat &format,
QPlatformOpenGLContext *share);
-
~QWindowsEGLContext();
- static bool hasThreadedOpenGLCapability();
+ bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void doneCurrent() Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
- bool makeCurrent(QPlatformSurface *surface);
+ QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
+ bool isSharing() const Q_DECL_OVERRIDE { return m_shareContext != EGL_NO_CONTEXT; }
+ bool isValid() const Q_DECL_OVERRIDE { return m_eglContext != EGL_NO_CONTEXT; }
-protected:
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+ void *nativeContext() const Q_DECL_OVERRIDE { return m_eglContext; }
+ void *nativeDisplay() const Q_DECL_OVERRIDE { return m_eglDisplay; }
+ void *nativeConfig() const Q_DECL_OVERRIDE { return m_eglConfig; }
private:
- const QWindowsEGLStaticContextPtr m_staticContext;
+ EGLConfig chooseConfig(const QSurfaceFormat &format);
+
+ QWindowsEGLStaticContext *m_staticContext;
+ EGLContext m_eglContext;
+ EGLContext m_shareContext;
+ EGLDisplay m_eglDisplay;
+ EGLConfig m_eglConfig;
+ QSurfaceFormat m_format;
+ EGLenum m_api;
+ int m_swapInterval;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index eaa4eca84e..b1152de854 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -144,6 +144,131 @@
QT_BEGIN_NAMESPACE
+QWindowsOpengl32DLL QOpenGLStaticContext::opengl32;
+
+void *QWindowsOpengl32DLL::resolve(const char *name)
+{
+#ifndef Q_OS_WINCE
+ void *proc = m_lib ? (void *) ::GetProcAddress(m_lib, name) : 0;
+#else
+ void *proc = m_lib ? (void *) ::GetProcAddress(m_lib, (const wchar_t *) QString::fromLatin1(name).utf16()) : 0;
+#endif
+ if (!proc)
+ qErrnoWarning(::GetLastError(), "Failed to resolve OpenGL function %s", name);
+
+ return proc;
+}
+
+bool QWindowsOpengl32DLL::init(bool softwareRendering)
+{
+ const QByteArray opengl32 = QByteArrayLiteral("opengl32.dll");
+ const QByteArray swopengl = QByteArrayLiteral("QtSoftwareOpenGL.dll");
+
+ QByteArray openglDll = qgetenv("QT_OPENGL_DLL");
+ if (openglDll.isEmpty())
+ openglDll = softwareRendering ? swopengl : opengl32;
+
+ openglDll = openglDll.toLower();
+ m_nonOpengl32 = openglDll != opengl32;
+
+ qCDebug(lcQpaGl) << "Qt: Using WGL and OpenGL from" << openglDll;
+
+ m_lib = ::LoadLibraryA(openglDll.constData());
+ if (!m_lib) {
+ qErrnoWarning(::GetLastError(), "Failed to load %s", openglDll.constData());
+ return false;
+ }
+
+ if (moduleIsNotOpengl32()) {
+ // Load opengl32.dll always. GDI functions like ChoosePixelFormat do
+ // GetModuleHandle for opengl32.dll and behave differently (and call back into
+ // opengl32) when the module is present. This is fine for dummy contexts and windows.
+ ::LoadLibraryA("opengl32.dll");
+ }
+
+ wglCreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolve("wglCreateContext"));
+ wglDeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(resolve("wglDeleteContext"));
+ wglGetCurrentContext = reinterpret_cast<HGLRC (WINAPI *)()>(resolve("wglGetCurrentContext"));
+ wglGetCurrentDC = reinterpret_cast<HDC (WINAPI *)()>(resolve("wglGetCurrentDC"));
+ wglGetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(resolve("wglGetProcAddress"));
+ wglMakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(resolve("wglMakeCurrent"));
+ wglShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolve("wglShareLists"));
+ wglSwapBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC)>(resolve("wglSwapBuffers"));
+ wglSetPixelFormat = reinterpret_cast<BOOL (WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)>(resolve("wglSetPixelFormat"));
+
+ glBindTexture = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolve("glBindTexture"));
+ glBlendFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolve("glBlendFunc"));
+ glClear = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolve("glClear"));
+ glClearColor = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolve("glClearColor"));
+ glClearStencil = reinterpret_cast<void (APIENTRY *)(GLint )>(resolve("glClearStencil"));
+ glColorMask = reinterpret_cast<void (APIENTRY *)(GLboolean , GLboolean , GLboolean , GLboolean )>(resolve("glColorMask"));
+ glCopyTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLsizei , GLint )>(resolve("glCopyTexImage2D"));
+ glCopyTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei )>(resolve("glCopyTexSubImage2D"));
+ glCullFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glCullFace"));
+ glDeleteTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *)>(resolve("glDeleteTextures"));
+ glDepthFunc = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glDepthFunc"));
+ glDepthMask = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolve("glDepthMask"));
+ glDisable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glDisable"));
+ glDrawArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLsizei )>(resolve("glDrawArrays"));
+ glDrawElements = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , GLenum , const GLvoid *)>(resolve("glDrawElements"));
+ glEnable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glEnable"));
+ glFinish = reinterpret_cast<void (APIENTRY *)()>(resolve("glFinish"));
+ glFlush = reinterpret_cast<void (APIENTRY *)()>(resolve("glFlush"));
+ glFrontFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolve("glFrontFace"));
+ glGenTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolve("glGenTextures"));
+ glGetBooleanv = reinterpret_cast<void (APIENTRY *)(GLenum , GLboolean *)>(resolve("glGetBooleanv"));
+ glGetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolve("glGetError"));
+ glGetFloatv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolve("glGetFloatv"));
+ glGetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolve("glGetIntegerv"));
+ glGetString = reinterpret_cast<const GLubyte * (APIENTRY *)(GLenum )>(resolve("glGetString"));
+ glGetTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolve("glGetTexParameterfv"));
+ glGetTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolve("glGetTexParameteriv"));
+ glHint = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolve("glHint"));
+ glIsEnabled = reinterpret_cast<GLboolean (APIENTRY *)(GLenum )>(resolve("glIsEnabled"));
+ glIsTexture = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolve("glIsTexture"));
+ glLineWidth = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolve("glLineWidth"));
+ glPixelStorei = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolve("glPixelStorei"));
+ glPolygonOffset = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolve("glPolygonOffset"));
+ glReadPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , GLvoid *)>(resolve("glReadPixels"));
+ glScissor = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolve("glScissor"));
+ glStencilFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLuint )>(resolve("glStencilFunc"));
+ glStencilMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolve("glStencilMask"));
+ glStencilOp = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum )>(resolve("glStencilOp"));
+ glTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolve("glTexImage2D"));
+ glTexParameterf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolve("glTexParameterf"));
+ glTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolve("glTexParameterfv"));
+ glTexParameteri = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolve("glTexParameteri"));
+ glTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolve("glTexParameteriv"));
+ glTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolve("glTexSubImage2D"));
+ glViewport = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolve("glViewport"));
+
+ glClearDepth = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolve("glClearDepth"));
+ glDepthRange = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolve("glDepthRange"));
+
+ return wglCreateContext && glBindTexture && glClearDepth;
+}
+
+BOOL QWindowsOpengl32DLL::swapBuffers(HDC dc)
+{
+ if (moduleIsNotOpengl32())
+ return wglSwapBuffers(dc);
+ else
+ return SwapBuffers(dc);
+}
+
+BOOL QWindowsOpengl32DLL::setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd)
+{
+ if (moduleIsNotOpengl32())
+ return wglSetPixelFormat(dc, pf, pfd);
+ else
+ return SetPixelFormat(dc, pf, pfd);
+}
+
+QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *context)
+{
+ return new QWindowsGLContext(this, context);
+}
+
template <class MaskType, class FlagType> inline bool testFlag(MaskType mask, FlagType flag)
{
return (mask & MaskType(flag)) != 0;
@@ -210,10 +335,11 @@ static inline bool
bool ignoreGLSupport = false) // ARB format may not contain it.
{
const bool pixmapRequested = testFlag(additional.formatFlags, QWindowsGLRenderToPixmap);
- return (ignoreGLSupport || testFlag(pfd.dwFlags, PFD_SUPPORT_OPENGL))
- && testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP) == pixmapRequested
- && hasGLOverlay(pfd) == testFlag(additional.formatFlags, QWindowsGLOverlay)
- && (!pixmapRequested || pfd.cColorBits == additional.pixmapDepth);
+ const bool pixmapOk = !pixmapRequested || testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP);
+ const bool colorOk = !pixmapRequested || pfd.cColorBits == additional.pixmapDepth;
+ const bool glOk = ignoreGLSupport || testFlag(pfd.dwFlags, PFD_SUPPORT_OPENGL);
+ const bool overlayOk = hasGLOverlay(pfd) == testFlag(additional.formatFlags, QWindowsGLOverlay);
+ return pixmapOk && glOk && overlayOk && colorOk;
}
static void describeFormats(HDC hdc)
@@ -299,10 +425,23 @@ static PIXELFORMATDESCRIPTOR
// over the available formats to find the best one.
// Note: As of Windows 7, it seems direct-rendering is handled, so,
// the code might be obsolete?
+//
+// NB! When using an implementation with a name different than opengl32.dll
+// this code path should not be used since it will result in a mess due to GDI
+// relying on and possibly calling back into functions in opengl32.dll (and not
+// the one we are using). This is not a problem usually since for Mesa, which
+// we are most likely to ship with a name other than opengl32.dll, the ARB code
+// path should work. Hence the early bail out below.
+//
static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
const QWindowsOpenGLAdditionalFormat &additional,
PIXELFORMATDESCRIPTOR *obtainedPfd)
{
+ if (QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()) {
+ qWarning("%s: Attempted to use GDI functions with a non-opengl32.dll library", Q_FUNC_INFO);
+ return 0;
+ }
+
// 1) Try ChoosePixelFormat().
PIXELFORMATDESCRIPTOR requestedPfd = qPixelFormatFromSurfaceFormat(format, QWindowsGLDirectRendering);
initPixelFormatDescriptor(obtainedPfd);
@@ -352,12 +491,12 @@ static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
static inline HGLRC createContext(HDC hdc, HGLRC shared)
{
- HGLRC result = wglCreateContext(hdc);
+ HGLRC result = QOpenGLStaticContext::opengl32.wglCreateContext(hdc);
if (!result) {
qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
return 0;
}
- if (shared && !wglShareLists(shared, result))
+ if (shared && !QOpenGLStaticContext::opengl32.wglShareLists(shared, result))
qErrnoWarning("%s: wglShareLists() failed.", __FUNCTION__);
return result;
}
@@ -623,7 +762,7 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
if (!result) {
QString message;
QDebug(&message).nospace() << __FUNCTION__ << ": wglCreateContextAttribsARB() failed (GL error code: 0x"
- << hex << glGetError() << dec << ") for format: " << format << ", shared context: " << shared;
+ << hex << staticContext.opengl32.glGetError() << dec << ") for format: " << format << ", shared context: " << shared;
qErrnoWarning("%s", qPrintable(message));
}
return result;
@@ -648,16 +787,17 @@ static inline HGLRC createDummyGLContext(HDC dc)
initPixelFormatDescriptor(&pixelFormDescriptor);
pixelFormDescriptor.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
pixelFormDescriptor.iPixelType = PFD_TYPE_RGBA;
+ // Use the GDI variant, for the dummy this is fine, even when using something other than opengl32.dll.
const int pixelFormat = ChoosePixelFormat(dc, &pixelFormDescriptor);
if (!pixelFormat) {
qErrnoWarning("%s: ChoosePixelFormat failed.", __FUNCTION__);
return 0;
}
- if (!SetPixelFormat(dc, pixelFormat, &pixelFormDescriptor)) {
+ if (!QOpenGLStaticContext::opengl32.setPixelFormat(dc, pixelFormat, &pixelFormDescriptor)) {
qErrnoWarning("%s: SetPixelFormat failed.", __FUNCTION__);
return 0;
}
- HGLRC rc = wglCreateContext(dc);
+ HGLRC rc = QOpenGLStaticContext::opengl32.wglCreateContext(dc);
if (!rc) {
qErrnoWarning("%s: wglCreateContext failed.", __FUNCTION__);
return 0;
@@ -668,8 +808,8 @@ static inline HGLRC createDummyGLContext(HDC dc)
static inline QOpenGLContextData currentOpenGLContextData()
{
QOpenGLContextData result;
- result.hdc = wglGetCurrentDC();
- result.renderingContext = wglGetCurrentContext();
+ result.hdc = QOpenGLStaticContext::opengl32.wglGetCurrentDC();
+ result.renderingContext = QOpenGLStaticContext::opengl32.wglGetCurrentContext();
return result;
}
@@ -721,7 +861,7 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
}
// v3 onwards
GLint value = 0;
- glGetIntegerv(GL_CONTEXT_FLAGS, &value);
+ QOpenGLStaticContext::opengl32.glGetIntegerv(GL_CONTEXT_FLAGS, &value);
if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
result.options |= QSurfaceFormat::DeprecatedFunctions;
if (value & GL_CONTEXT_FLAG_DEBUG_BIT)
@@ -730,7 +870,7 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
return result;
// v3.2 onwards: Profiles
value = 0;
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ QOpenGLStaticContext::opengl32.glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
if (value & GL_CONTEXT_CORE_PROFILE_BIT)
result.profile = QSurfaceFormat::CoreProfile;
else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
@@ -784,15 +924,15 @@ QOpenGLTemporaryContext::QOpenGLTemporaryContext() :
m_previous(currentOpenGLContextData()),
m_current(createDummyWindowOpenGLContextData())
{
- wglMakeCurrent(m_current.hdc, m_current.renderingContext);
+ QOpenGLStaticContext::opengl32.wglMakeCurrent(m_current.hdc, m_current.renderingContext);
}
QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
{
- wglMakeCurrent(m_previous.hdc, m_previous.renderingContext);
+ QOpenGLStaticContext::opengl32.wglMakeCurrent(m_previous.hdc, m_previous.renderingContext);
ReleaseDC(m_current.hwnd, m_current.hdc);
DestroyWindow(m_current.hwnd);
- wglDeleteContext(m_current.renderingContext);
+ QOpenGLStaticContext::opengl32.wglDeleteContext(m_current.renderingContext);
}
/*!
@@ -807,6 +947,11 @@ QOpenGLTemporaryContext::~QOpenGLTemporaryContext()
Functions pending integration in the next version of OpenGL are post-fixed ARB.
+ No WGL or OpenGL functions are called directly from the windows plugin. Instead, the
+ static context loads opengl32.dll and resolves the necessary functions. This allows
+ building the plugin without linking to opengl32 and enables QT_OPENGL_DYNAMIC builds
+ where both the EGL and WGL (this) based implementation of the context are built.
+
\note Initialization requires an active context (see create()).
\sa QWindowsGLContext
@@ -822,11 +967,11 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
extensionNames(QOpenGLStaticContext::getGlString(GL_EXTENSIONS)),
extensions(0),
defaultFormat(QWindowsOpenGLContextFormat::current()),
- wglGetPixelFormatAttribIVARB((WglGetPixelFormatAttribIVARB)wglGetProcAddress("wglGetPixelFormatAttribivARB")),
- wglChoosePixelFormatARB((WglChoosePixelFormatARB)wglGetProcAddress("wglChoosePixelFormatARB")),
- wglCreateContextAttribsARB((WglCreateContextAttribsARB)wglGetProcAddress("wglCreateContextAttribsARB")),
- wglSwapInternalExt((WglSwapInternalExt)wglGetProcAddress("wglSwapIntervalEXT")),
- wglGetSwapInternalExt((WglGetSwapInternalExt)wglGetProcAddress("wglGetSwapIntervalEXT"))
+ wglGetPixelFormatAttribIVARB((WglGetPixelFormatAttribIVARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetPixelFormatAttribivARB")),
+ wglChoosePixelFormatARB((WglChoosePixelFormatARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglChoosePixelFormatARB")),
+ wglCreateContextAttribsARB((WglCreateContextAttribsARB)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglCreateContextAttribsARB")),
+ wglSwapInternalExt((WglSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglSwapIntervalEXT")),
+ wglGetSwapInternalExt((WglGetSwapInternalExt)QOpenGLStaticContext::opengl32.wglGetProcAddress("wglGetSwapIntervalEXT"))
{
if (extensionNames.startsWith(SAMPLE_BUFFER_EXTENSION " ")
|| extensionNames.indexOf(" " SAMPLE_BUFFER_EXTENSION " ") != -1)
@@ -835,16 +980,21 @@ QOpenGLStaticContext::QOpenGLStaticContext() :
QByteArray QOpenGLStaticContext::getGlString(unsigned int which)
{
- if (const GLubyte *s = glGetString(which))
+ if (const GLubyte *s = opengl32.glGetString(which))
return QByteArray((const char*)s);
return QByteArray();
}
-QOpenGLStaticContext *QOpenGLStaticContext::create()
+QOpenGLStaticContext *QOpenGLStaticContext::create(bool softwareRendering)
{
+ if (!opengl32.init(softwareRendering)) {
+ qWarning("%s: Failed to load and resolve WGL/OpenGL functions", Q_FUNC_INFO);
+ return 0;
+ }
+
// We need a current context for wglGetProcAdress()/getGLString() to work.
QScopedPointer<QOpenGLTemporaryContext> temporaryContext;
- if (!wglGetCurrentContext())
+ if (!QOpenGLStaticContext::opengl32.wglGetCurrentContext())
temporaryContext.reset(new QOpenGLTemporaryContext);
QOpenGLStaticContext *result = new QOpenGLStaticContext;
qCDebug(lcQpaGl) << __FUNCTION__ << *result;
@@ -881,7 +1031,7 @@ QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
\ingroup qt-lighthouse-win
*/
-QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
+QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
QOpenGLContext *context) :
m_staticContext(staticContext),
m_context(context),
@@ -890,6 +1040,9 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
m_extensionsUsed(false),
m_swapInterval(-1)
{
+ if (!m_staticContext) // Something went very wrong. Stop here, isValid() will return false.
+ return;
+
QSurfaceFormat format = context->format();
if (format.renderableType() == QSurfaceFormat::DefaultRenderableType)
format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -901,7 +1054,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
static bool opengl32dll = false;
if (!opengl32dll) {
GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
+ staticContext->opengl32.glGetIntegerv(GL_DEPTH_BITS, &params);
opengl32dll = true;
}
@@ -954,7 +1107,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
qWarning("%s: Unable find a suitable pixel format.", __FUNCTION__);
break;
}
- if (!SetPixelFormat(hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ if (!QOpenGLStaticContext::opengl32.setPixelFormat(hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
qErrnoWarning("SetPixelFormat failed.");
break;
}
@@ -978,7 +1131,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
}
// Query obtained parameters and apply swap interval.
- if (!wglMakeCurrent(hdc, m_renderingContext)) {
+ if (!QOpenGLStaticContext::opengl32.wglMakeCurrent(hdc, m_renderingContext)) {
qWarning("Failed to make context current.");
break;
}
@@ -988,7 +1141,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
if (m_staticContext->wglGetSwapInternalExt)
obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
- wglMakeCurrent(0, 0);
+ QOpenGLStaticContext::opengl32.wglMakeCurrent(0, 0);
} while (false);
if (hdc)
ReleaseDC(dummyWindow, hdc);
@@ -1006,7 +1159,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
QWindowsGLContext::~QWindowsGLContext()
{
if (m_renderingContext)
- wglDeleteContext(m_renderingContext);
+ QOpenGLStaticContext::opengl32.wglDeleteContext(m_renderingContext);
releaseDCs();
}
@@ -1043,11 +1196,11 @@ void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
{
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaGl) << __FUNCTION__ << surface;
- if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface))) {
- SwapBuffers(contextData->hdc);
- } else {
+
+ if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface)))
+ QOpenGLStaticContext::opengl32.swapBuffers(contextData->hdc);
+ else
qWarning("%s: Cannot find window %p", __FUNCTION__, handleOf(surface));
- }
}
bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
@@ -1066,11 +1219,11 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
// Repeated calls to wglMakeCurrent when vsync is enabled in the driver will
// often result in 100% cpuload. This check is cheap and avoids the problem.
// This is reproducable on NVidia cards and Intel onboard chips.
- if (wglGetCurrentContext() == contextData->renderingContext
- && wglGetCurrentDC() == contextData->hdc) {
+ if (QOpenGLStaticContext::opengl32.wglGetCurrentContext() == contextData->renderingContext
+ && QOpenGLStaticContext::opengl32.wglGetCurrentDC() == contextData->hdc) {
return true;
}
- return wglMakeCurrent(contextData->hdc, contextData->renderingContext);
+ return QOpenGLStaticContext::opengl32.wglMakeCurrent(contextData->hdc, contextData->renderingContext);
}
// Create a new entry.
const QOpenGLContextData newContext(m_renderingContext, hwnd, GetDC(hwnd));
@@ -1079,7 +1232,7 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
// Initialize pixel format first time. This will apply to
// the HWND as well and must be done only once.
if (!window->testFlag(QWindowsWindow::OpenGlPixelFormatInitialized)) {
- if (!SetPixelFormat(newContext.hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
+ if (!QOpenGLStaticContext::opengl32.setPixelFormat(newContext.hdc, m_pixelFormat, &m_obtainedPixelFormatDescriptor)) {
qErrnoWarning("%s: SetPixelFormat() failed", __FUNCTION__);
ReleaseDC(newContext.hwnd, newContext.hdc);
return false;
@@ -1090,7 +1243,7 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
}
m_windowContexts.append(newContext);
- bool success = wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+ bool success = QOpenGLStaticContext::opengl32.wglMakeCurrent(newContext.hdc, newContext.renderingContext);
// Set the swap interval
if (m_staticContext->wglSwapInternalExt) {
@@ -1110,16 +1263,82 @@ void QWindowsGLContext::doneCurrent()
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts";
#endif // DEBUG_GL
- wglMakeCurrent(0, 0);
+ QOpenGLStaticContext::opengl32.wglMakeCurrent(0, 0);
releaseDCs();
}
-QWindowsGLContext::GL_Proc QWindowsGLContext::getProcAddress(const QByteArray &procName)
+QFunctionPointer QWindowsGLContext::getProcAddress(const QByteArray &procName)
{
- // TODO: Will that work with the calling conventions?
- GL_Proc procAddress = reinterpret_cast<GL_Proc>(wglGetProcAddress(procName.constData()));
+ // We support AllGLFunctionsQueryable, which means this function must be able to
+ // return a function pointer even for functions that are in GL.h and exported
+ // normally from opengl32.dll. wglGetProcAddress() is not guaranteed to work for such
+ // functions, however in QT_OPENGL_DYNAMIC builds QOpenGLFunctions will just blindly
+ // call into here for _any_ OpenGL function. Hence the need to handle these specially
+ // here. The list has to match QOpenGLFunctions. See
+ // QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *).
+ static struct StdFunc {
+ const char *name;
+ void *func;
+ } standardFuncs[] = {
+ { "glBindTexture", (void *) QOpenGLStaticContext::opengl32.glBindTexture },
+ { "glBlendFunc", (void *) QOpenGLStaticContext::opengl32.glBlendFunc },
+ { "glClear", (void *) QOpenGLStaticContext::opengl32.glClear },
+ { "glClearColor", (void *) QOpenGLStaticContext::opengl32.glClearColor },
+ { "glClearStencil", (void *) QOpenGLStaticContext::opengl32.glClearStencil },
+ { "glColorMask", (void *) QOpenGLStaticContext::opengl32.glColorMask },
+ { "glCopyTexImage2D", (void *) QOpenGLStaticContext::opengl32.glCopyTexImage2D },
+ { "glCopyTexSubImage2D", (void *) QOpenGLStaticContext::opengl32.glCopyTexSubImage2D },
+ { "glCullFace", (void *) QOpenGLStaticContext::opengl32.glCullFace },
+ { "glDeleteTextures", (void *) QOpenGLStaticContext::opengl32.glDeleteTextures },
+ { "glDepthFunc", (void *) QOpenGLStaticContext::opengl32.glDepthFunc },
+ { "glDepthMask", (void *) QOpenGLStaticContext::opengl32.glDepthMask },
+ { "glDisable", (void *) QOpenGLStaticContext::opengl32.glDisable },
+ { "glDrawArrays", (void *) QOpenGLStaticContext::opengl32.glDrawArrays },
+ { "glDrawElements", (void *) QOpenGLStaticContext::opengl32.glDrawElements },
+ { "glEnable", (void *) QOpenGLStaticContext::opengl32.glEnable },
+ { "glFinish", (void *) QOpenGLStaticContext::opengl32.glFinish },
+ { "glFlush", (void *) QOpenGLStaticContext::opengl32.glFlush },
+ { "glFrontFace", (void *) QOpenGLStaticContext::opengl32.glFrontFace },
+ { "glGenTextures", (void *) QOpenGLStaticContext::opengl32.glGenTextures },
+ { "glGetBooleanv", (void *) QOpenGLStaticContext::opengl32.glGetBooleanv },
+ { "glGetError", (void *) QOpenGLStaticContext::opengl32.glGetError },
+ { "glGetFloatv", (void *) QOpenGLStaticContext::opengl32.glGetFloatv },
+ { "glGetIntegerv", (void *) QOpenGLStaticContext::opengl32.glGetIntegerv },
+ { "glGetString", (void *) QOpenGLStaticContext::opengl32.glGetString },
+ { "glGetTexParameterfv", (void *) QOpenGLStaticContext::opengl32.glGetTexParameterfv },
+ { "glGetTexParameteriv", (void *) QOpenGLStaticContext::opengl32.glGetTexParameteriv },
+ { "glHint", (void *) QOpenGLStaticContext::opengl32.glHint },
+ { "glIsEnabled", (void *) QOpenGLStaticContext::opengl32.glIsEnabled },
+ { "glIsTexture", (void *) QOpenGLStaticContext::opengl32.glIsTexture },
+ { "glLineWidth", (void *) QOpenGLStaticContext::opengl32.glLineWidth },
+ { "glPixelStorei", (void *) QOpenGLStaticContext::opengl32.glPixelStorei },
+ { "glPolygonOffset", (void *) QOpenGLStaticContext::opengl32.glPolygonOffset },
+ { "glReadPixels", (void *) QOpenGLStaticContext::opengl32.glReadPixels },
+ { "glScissor", (void *) QOpenGLStaticContext::opengl32.glScissor },
+ { "glStencilFunc", (void *) QOpenGLStaticContext::opengl32.glStencilFunc },
+ { "glStencilMask", (void *) QOpenGLStaticContext::opengl32.glStencilMask },
+ { "glStencilOp", (void *) QOpenGLStaticContext::opengl32.glStencilOp },
+ { "glTexImage2D", (void *) QOpenGLStaticContext::opengl32.glTexImage2D },
+ { "glTexParameterf", (void *) QOpenGLStaticContext::opengl32.glTexParameterf },
+ { "glTexParameterfv", (void *) QOpenGLStaticContext::opengl32.glTexParameterfv },
+ { "glTexParameteri", (void *) QOpenGLStaticContext::opengl32.glTexParameteri },
+ { "glTexParameteriv", (void *) QOpenGLStaticContext::opengl32.glTexParameteriv },
+ { "glTexSubImage2D", (void *) QOpenGLStaticContext::opengl32.glTexSubImage2D },
+ { "glViewport", (void *) QOpenGLStaticContext::opengl32.glViewport },
+
+ { "glClearDepth", (void *) QOpenGLStaticContext::opengl32.glClearDepth },
+ { "glDepthRange", (void *) QOpenGLStaticContext::opengl32.glDepthRange },
+ };
+ for (size_t i = 0; i < sizeof(standardFuncs) / sizeof(StdFunc); ++i)
+ if (procName == standardFuncs[i].name)
+ return reinterpret_cast<QFunctionPointer>(standardFuncs[i].func);
+
+ // Even though we use QFunctionPointer, it does not mean the function can be called.
+ // It will need to be cast to the proper function type with the correct calling
+ // convention. QFunctionPointer is nothing more than a glorified void* here.
+ QFunctionPointer procAddress = reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.wglGetProcAddress(procName.constData()));
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaGl) << __FUNCTION__ << procName << wglGetCurrentContext() << "returns" << procAddress;
+ qCDebug(lcQpaGl) << __FUNCTION__ << procName << QOpenGLStaticContext::opengl32.wglGetCurrentContext() << "returns" << procAddress;
if (!procAddress)
qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
return procAddress;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index c6b477128a..dcc31c6197 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -44,10 +44,9 @@
#include "array.h"
#include "qtwindows_additional.h"
+#include "qwindowsopenglcontext.h"
-#include <qpa/qplatformopenglcontext.h>
#include <QtGui/QOpenGLContext>
-#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -81,6 +80,8 @@ struct QOpenGLContextData
HDC hdc;
};
+class QOpenGLStaticContext;
+
struct QWindowsOpenGLContextFormat
{
QWindowsOpenGLContextFormat();
@@ -94,7 +95,87 @@ struct QWindowsOpenGLContextFormat
QDebug operator<<(QDebug d, const QWindowsOpenGLContextFormat &);
-class QOpenGLStaticContext
+struct QWindowsOpengl32DLL
+{
+ bool init(bool softwareRendering);
+ void *moduleHandle() const { return m_lib; }
+ bool moduleIsNotOpengl32() const { return m_nonOpengl32; }
+
+ // Wrappers. Always use these instead of SwapBuffers/wglSwapBuffers/etc.
+ BOOL swapBuffers(HDC dc);
+ BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+
+ // WGL
+ HGLRC (WINAPI * wglCreateContext)(HDC dc);
+ BOOL (WINAPI * wglDeleteContext)(HGLRC context);
+ HGLRC (WINAPI * wglGetCurrentContext)();
+ HDC (WINAPI * wglGetCurrentDC)();
+ PROC (WINAPI * wglGetProcAddress)(LPCSTR name);
+ BOOL (WINAPI * wglMakeCurrent)(HDC dc, HGLRC context);
+ BOOL (WINAPI * wglShareLists)(HGLRC context1, HGLRC context2);
+
+ // GL1+GLES2 common
+ void (APIENTRY * glBindTexture)(GLenum target, GLuint texture);
+ void (APIENTRY * glBlendFunc)(GLenum sfactor, GLenum dfactor);
+ void (APIENTRY * glClear)(GLbitfield mask);
+ void (APIENTRY * glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (APIENTRY * glClearStencil)(GLint s);
+ void (APIENTRY * glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void (APIENTRY * glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void (APIENTRY * glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * glCullFace)(GLenum mode);
+ void (APIENTRY * glDeleteTextures)(GLsizei n, const GLuint* textures);
+ void (APIENTRY * glDepthFunc)(GLenum func);
+ void (APIENTRY * glDepthMask)(GLboolean flag);
+ void (APIENTRY * glDisable)(GLenum cap);
+ void (APIENTRY * glDrawArrays)(GLenum mode, GLint first, GLsizei count);
+ void (APIENTRY * glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+ void (APIENTRY * glEnable)(GLenum cap);
+ void (APIENTRY * glFinish)();
+ void (APIENTRY * glFlush)();
+ void (APIENTRY * glFrontFace)(GLenum mode);
+ void (APIENTRY * glGenTextures)(GLsizei n, GLuint* textures);
+ void (APIENTRY * glGetBooleanv)(GLenum pname, GLboolean* params);
+ GLenum (APIENTRY * glGetError)();
+ void (APIENTRY * glGetFloatv)(GLenum pname, GLfloat* params);
+ void (APIENTRY * glGetIntegerv)(GLenum pname, GLint* params);
+ const GLubyte * (APIENTRY * glGetString)(GLenum name);
+ void (APIENTRY * glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params);
+ void (APIENTRY * glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * glHint)(GLenum target, GLenum mode);
+ GLboolean (APIENTRY * glIsEnabled)(GLenum cap);
+ GLboolean (APIENTRY * glIsTexture)(GLuint texture);
+ void (APIENTRY * glLineWidth)(GLfloat width);
+ void (APIENTRY * glPixelStorei)(GLenum pname, GLint param);
+ void (APIENTRY * glPolygonOffset)(GLfloat factor, GLfloat units);
+ void (APIENTRY * glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+ void (APIENTRY * glScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * glStencilFunc)(GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * glStencilMask)(GLuint mask);
+ void (APIENTRY * glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+ void (APIENTRY * glTexParameterf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params);
+ void (APIENTRY * glTexParameteri)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * glTexParameteriv)(GLenum target, GLenum pname, const GLint* params);
+ void (APIENTRY * glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+ void (APIENTRY * glViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+
+ // GL only
+ void (APIENTRY * glClearDepth)(GLdouble depth);
+ void (APIENTRY * glDepthRange)(GLdouble zNear, GLdouble zFar);
+
+private:
+ void *resolve(const char *name);
+ HMODULE m_lib;
+ bool m_nonOpengl32;
+
+ // For Mesa llvmpipe shipped with a name other than opengl32.dll
+ BOOL (WINAPI * wglSwapBuffers)(HDC dc);
+ BOOL (WINAPI * wglSetPixelFormat)(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd);
+};
+
+class QOpenGLStaticContext : public QWindowsStaticOpenGLContext
{
Q_DISABLE_COPY(QOpenGLStaticContext)
QOpenGLStaticContext();
@@ -125,9 +206,17 @@ public:
bool hasExtensions() const
{ return wglGetPixelFormatAttribIVARB && wglChoosePixelFormatARB && wglCreateContextAttribsARB; }
- static QOpenGLStaticContext *create();
+ static QOpenGLStaticContext *create(bool softwareRendering = false);
static QByteArray getGlString(unsigned int which);
+ QWindowsOpenGLContext *createContext(QOpenGLContext *context);
+ void *moduleHandle() const { return opengl32.moduleHandle(); }
+ QOpenGLContext::OpenGLModuleType moduleType() const { return QOpenGLContext::LibGL; }
+
+ // For a regular opengl32.dll report the ThreadedOpenGL capability.
+ // For others, which are likely to be software-only, don't.
+ bool supportsThreadedOpenGL() const { return !opengl32.moduleIsNotOpengl32(); }
+
const QByteArray vendor;
const QByteArray renderer;
const QByteArray extensionNames;
@@ -139,37 +228,38 @@ public:
WglCreateContextAttribsARB wglCreateContextAttribsARB;
WglSwapInternalExt wglSwapInternalExt;
WglGetSwapInternalExt wglGetSwapInternalExt;
+
+ static QWindowsOpengl32DLL opengl32;
};
QDebug operator<<(QDebug d, const QOpenGLStaticContext &);
-class QWindowsGLContext : public QPlatformOpenGLContext
+class QWindowsGLContext : public QWindowsOpenGLContext
{
public:
- typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
-
- explicit QWindowsGLContext(const QOpenGLStaticContextPtr &staticContext,
- QOpenGLContext *context);
+ explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context);
virtual ~QWindowsGLContext();
- bool isSharing() const { return m_context->shareHandle(); }
- bool isValid() const { return m_renderingContext; }
- virtual QSurfaceFormat format() const { return m_obtainedFormat; }
+ bool isSharing() const Q_DECL_OVERRIDE { return m_context->shareHandle(); }
+ bool isValid() const Q_DECL_OVERRIDE { return m_renderingContext; }
+ virtual QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_obtainedFormat; }
- virtual void swapBuffers(QPlatformSurface *surface);
+ virtual void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- virtual bool makeCurrent(QPlatformSurface *surface);
- virtual void doneCurrent();
+ virtual bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ virtual void doneCurrent() Q_DECL_OVERRIDE;
typedef void (*GL_Proc) ();
- virtual GL_Proc getProcAddress(const QByteArray &procName);
+ virtual QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE;
+
+ HGLRC renderingContext() const { return m_renderingContext; }
- HGLRC renderingContext() const { return m_renderingContext; }
+ void *nativeContext() const Q_DECL_OVERRIDE { return m_renderingContext; }
private:
inline void releaseDCs();
- const QOpenGLStaticContextPtr m_staticContext;
+ QOpenGLStaticContext *m_staticContext;
QOpenGLContext *m_context;
QSurfaceFormat m_obtainedFormat;
HGLRC m_renderingContext;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index fc59302bf3..529dd75ed5 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,19 +43,7 @@
#include "qwindowsintegration.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
-
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-# include "qwindowseglcontext.h"
-# include <QtGui/QOpenGLContext>
-#endif
-
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
-# include "qwindowsglcontext.h"
-#endif
-
-#if !defined(QT_NO_OPENGL)
-# include <QtGui/QOpenGLFunctions>
-#endif
+#include "qwindowsopenglcontext.h"
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
@@ -91,6 +79,17 @@
#include <limits.h>
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+# include "qwindowseglcontext.h"
+#endif
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+# include "qwindowsglcontext.h"
+#endif
+
+#ifndef Q_OS_WINCE
+# include "qwindowsopengltester.h"
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -136,15 +135,9 @@ QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate
{
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- typedef QSharedPointer<QWindowsEGLStaticContext> QEGLStaticContextPtr;
-#endif
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
- typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
-#endif
-
explicit QWindowsIntegrationPrivate(const QStringList &paramList);
~QWindowsIntegrationPrivate();
+ bool ensureStaticOpenGLContext();
unsigned m_options;
QWindowsContext m_context;
@@ -155,12 +148,9 @@ struct QWindowsIntegrationPrivate
QWindowsDrag m_drag;
# endif
#endif
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- QEGLStaticContextPtr m_staticEGLContext;
-#endif
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
- QOpenGLStaticContextPtr m_staticOpenGLContext;
-#endif
+#ifndef QT_NO_OPENGL
+ QSharedPointer<QWindowsStaticOpenGLContext> m_staticOpenGLContext;
+#endif // QT_NO_OPENGL
QScopedPointer<QPlatformInputContext> m_inputContext;
#ifndef QT_NO_ACCESSIBILITY
QWindowsAccessibility m_accessibility;
@@ -273,12 +263,7 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
case OpenGL:
return true;
case ThreadedOpenGL:
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- return QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL
- ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true;
-# else
- return true;
-# endif // QT_OPENGL_ES_2
+ return d->ensureStaticOpenGLContext() ? d->m_staticOpenGLContext->supportsThreadedOpenGL() : false;
#endif // !QT_NO_OPENGL
case WindowMasks:
return true;
@@ -288,6 +273,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return true;
case RasterGLSurface:
return true;
+ case AllGLFunctionsQueryable:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
@@ -304,8 +291,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
if (customMarginsV.isValid())
requested.customMargins = qvariant_cast<QMargins>(customMarginsV);
- const QWindowsWindowData obtained
- = QWindowsWindowData::create(window, requested, window->title());
+ QWindowsWindowData obtained = QWindowsWindowData::create(window, requested, window->title());
qCDebug(lcQpaWindows).nospace()
<< __FUNCTION__ << '<' << window
<< "\n Requested: " << requested.geometry << "frame incl.: "
@@ -323,6 +309,11 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
}
+#ifndef QT_NO_OPENGL
+ d->ensureStaticOpenGLContext();
+ obtained.staticOpenGLContext = d->m_staticOpenGLContext;
+#endif // QT_NO_OPENGL
+
return obtained;
}
@@ -334,32 +325,80 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
}
#ifndef QT_NO_OPENGL
-QPlatformOpenGLContext
- *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0;
+
+QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create()
{
- qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) {
- if (d->m_staticEGLContext.isNull()) {
- QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
- if (!staticContext)
- return 0;
- d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
+ QWindowsStaticOpenGLContext *ctx = 0;
+
+#if defined(QT_OPENGL_DYNAMIC)
+ const QByteArray requested = qgetenv("QT_OPENGL"); // angle, desktop, software
+ const bool angleRequested = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES) || requested == QByteArrayLiteral("angle");
+ const bool desktopRequested = QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL) || requested == QByteArrayLiteral("desktop");
+ const bool softwareRequested = QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL) || requested == QByteArrayLiteral("software");
+
+ // If ANGLE is requested, use it, don't try anything else.
+ if (angleRequested) {
+ ctx = QWindowsEGLStaticContext::create();
+ } else {
+ // If opengl32.dll seems to be OpenGL 2.x capable, or desktop OpenGL is requested, use it.
+ if (!softwareRequested && (desktopRequested || QWindowsOpenGLTester::testDesktopGL()))
+ ctx = QOpenGLStaticContext::create();
+ // If failed and desktop OpenGL is not explicitly requested, try ANGLE.
+ if (!ctx && !desktopRequested && !softwareRequested)
+ ctx = QWindowsEGLStaticContext::create();
+ // Try software.
+ if (!ctx) {
+ ctx = QOpenGLStaticContext::create(true);
+ // If software was explicitly requested but failed, try the regular one.
+ if (!ctx && softwareRequested && QWindowsOpenGLTester::testDesktopGL())
+ ctx = QOpenGLStaticContext::create();
}
- return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
}
+#elif defined(QT_OPENGL_ES_2)
+ ctx = QWindowsEGLStaticContext::create();
+#elif !defined(QT_NO_OPENGL)
+ ctx = QOpenGLStaticContext::create();
#endif
-#if !defined(QT_OPENGL_ES_2)
- if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
- if (d->m_staticOpenGLContext.isNull())
- d->m_staticOpenGLContext =
- QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
- QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
- return result->isValid() ? result.take() : 0;
+
+ q_staticOpenGLContext = ctx;
+
+ return ctx;
+}
+
+bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext()
+{
+ if (m_staticOpenGLContext.isNull())
+ m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create());
+ return !m_staticOpenGLContext.isNull();
+}
+
+QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
+ if (d->ensureStaticOpenGLContext()) {
+ QScopedPointer<QWindowsOpenGLContext> result(d->m_staticOpenGLContext->createContext(context));
+ if (result->isValid())
+ return result.take();
}
-#endif // !QT_OPENGL_ES_2
return 0;
}
+
+QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType()
+{
+#if defined(QT_OPENGL_ES_2)
+ return QOpenGLContext::LibGLES;
+#elif !defined(QT_OPENGL_DYNAMIC)
+ return QOpenGLContext::LibGL;
+#else
+ return d->ensureStaticOpenGLContext() ? d->m_staticOpenGLContext->moduleType() : QOpenGLContext::LibGL;
+#endif
+}
+
+QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext()
+{
+ return q_staticOpenGLContext;
+}
#endif // !QT_NO_OPENGL
/* Workaround for QTBUG-24205: In 'Auto', pick the FreeType engine for
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 0f417c8239..a5bf5718c1 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate;
struct QWindowsWindowData;
class QWindowsWindow;
+class QWindowsStaticOpenGLContext;
class QWindowsIntegration : public QPlatformIntegration
{
@@ -74,6 +75,8 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const;
#ifndef QT_NO_OPENGL
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QOpenGLContext::OpenGLModuleType openGLModuleType();
+ static QWindowsStaticOpenGLContext *staticOpenGLContext();
#endif
virtual QAbstractEventDispatcher *createEventDispatcher() const;
void initialize() Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index 06c0122bbb..7d274f330f 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,21 +42,11 @@
#include "qwindowsnativeinterface.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
-
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-# include "qwindowseglcontext.h"
-# include <QtGui/QOpenGLContext>
-#endif
-
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
-# include "qwindowsglcontext.h"
-#endif
-
-#if !defined(QT_NO_OPENGL)
-# include <QtGui/QOpenGLFunctions>
-#endif
+#include "qwindowsopenglcontext.h"
+#include "qwindowsintegration.h"
#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
QT_BEGIN_NAMESPACE
@@ -117,6 +107,16 @@ QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) c
return result;
}
+void *QWindowsNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
+{
+#ifndef QT_NO_OPENGL
+ if (resource == QByteArrayLiteral("glhandle"))
+ return QWindowsIntegration::staticOpenGLContext()->moduleHandle();
+#endif
+
+ return 0;
+}
+
#ifndef QT_NO_OPENGL
void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
@@ -124,24 +124,14 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour
qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
return 0;
}
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) {
- QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("eglDisplay"))
- return windowsEglContext->eglDisplay();
- if (resource == QByteArrayLiteral("eglContext"))
- return windowsEglContext->eglContext();
- if (resource == QByteArrayLiteral("eglConfig"))
- return windowsEglContext->eglConfig();
- }
-#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
-#if !defined(QT_OPENGL_ES_2)
- if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
- QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("renderingContext"))
- return windowsContext->renderingContext();
- }
-#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
+
+ QWindowsOpenGLContext *glcontext = static_cast<QWindowsOpenGLContext *>(context->handle());
+ if (resource == QByteArrayLiteral("renderingContext") || resource == QByteArrayLiteral("eglContext"))
+ return glcontext->nativeContext();
+ if (resource == QByteArrayLiteral("eglDisplay"))
+ return glcontext->nativeDisplay();
+ if (resource == QByteArrayLiteral("eglConfig"))
+ return glcontext->nativeConfig();
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
return 0;
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index 20100d0f49..a8fbf4fd2c 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -66,11 +66,13 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
{
Q_OBJECT
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
+
public:
+ void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
- virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
#endif
- virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
const QString &windowName,
@@ -83,10 +85,10 @@ public:
bool asyncExpose() const;
void setAsyncExpose(bool value);
- QVariantMap windowProperties(QPlatformWindow *window) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
- void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
+ QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE;
+ void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h
new file mode 100644
index 0000000000..555af72f37
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSOPENGLCONTEXT_H
+#define QWINDOWSOPENGLCONTEXT_H
+
+#include <QtGui/QOpenGLContext>
+#include <qpa/qplatformopenglcontext.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_OPENGL
+
+class QWindowsOpenGLContext;
+
+class QWindowsStaticOpenGLContext
+{
+public:
+ static QWindowsStaticOpenGLContext *create();
+ virtual ~QWindowsStaticOpenGLContext() { }
+
+ virtual QWindowsOpenGLContext *createContext(QOpenGLContext *context) = 0;
+ virtual void *moduleHandle() const = 0;
+ virtual QOpenGLContext::OpenGLModuleType moduleType() const = 0;
+ virtual bool supportsThreadedOpenGL() const { return false; }
+
+ // If the windowing system interface needs explicitly created window surfaces (like EGL),
+ // reimplement these.
+ virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; }
+ virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
+};
+
+class QWindowsOpenGLContext : public QPlatformOpenGLContext
+{
+public:
+ virtual ~QWindowsOpenGLContext() { }
+
+ // Returns the native context handle (e.g. HGLRC for WGL, EGLContext for EGL).
+ virtual void *nativeContext() const = 0;
+
+ // These should be implemented only for some winsys interfaces, for example EGL.
+ // For others, like WGL, they are not relevant.
+ virtual void *nativeDisplay() const { return 0; }
+ virtual void *nativeConfig() const { return 0; }
+};
+
+#endif // QT_NO_OPENGL
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSOPENGLCONTEXT_H
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
new file mode 100644
index 0000000000..9ee62e6d56
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsopengltester.h"
+#include "qt_windows.h"
+#include "qwindowscontext.h"
+
+QT_BEGIN_NAMESPACE
+
+bool QWindowsOpenGLTester::testDesktopGL()
+{
+ HMODULE lib = 0;
+ HWND wnd = 0;
+ HDC dc = 0;
+ HGLRC context = 0;
+ LPCTSTR className = L"qtopengltest";
+
+ HGLRC (WINAPI * CreateContext)(HDC dc) = 0;
+ BOOL (WINAPI * DeleteContext)(HGLRC context) = 0;
+ BOOL (WINAPI * MakeCurrent)(HDC dc, HGLRC context) = 0;
+ PROC (WINAPI * WGL_GetProcAddress)(LPCSTR name) = 0;
+
+ bool result = false;
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+ lib = LoadLibraryA("opengl32.dll");
+ if (lib) {
+ CreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(::GetProcAddress(lib, "wglCreateContext"));
+ if (!CreateContext)
+ goto cleanup;
+ DeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(::GetProcAddress(lib, "wglDeleteContext"));
+ if (!DeleteContext)
+ goto cleanup;
+ MakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(::GetProcAddress(lib, "wglMakeCurrent"));
+ if (!MakeCurrent)
+ goto cleanup;
+ WGL_GetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(::GetProcAddress(lib, "wglGetProcAddress"));
+ if (!WGL_GetProcAddress)
+ goto cleanup;
+
+ WNDCLASS wclass;
+ wclass.cbClsExtra = 0;
+ wclass.cbWndExtra = 0;
+ wclass.hInstance = (HINSTANCE) GetModuleHandle(0);
+ wclass.hIcon = 0;
+ wclass.hCursor = 0;
+ wclass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND);
+ wclass.lpszMenuName = 0;
+ wclass.lpfnWndProc = DefWindowProc;
+ wclass.lpszClassName = className;
+ wclass.style = CS_OWNDC;
+ if (!RegisterClass(&wclass))
+ goto cleanup;
+ wnd = CreateWindow(className, L"qtopenglproxytest", WS_OVERLAPPED,
+ 0, 0, 640, 480, 0, 0, wclass.hInstance, 0);
+ if (!wnd)
+ goto cleanup;
+ dc = GetDC(wnd);
+ if (!dc)
+ goto cleanup;
+
+ PIXELFORMATDESCRIPTOR pfd;
+ memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ // Use the GDI functions. Under the hood this will call the wgl variants in opengl32.dll.
+ int pixelFormat = ChoosePixelFormat(dc, &pfd);
+ if (!pixelFormat)
+ goto cleanup;
+ if (!SetPixelFormat(dc, pixelFormat, &pfd))
+ goto cleanup;
+ context = CreateContext(dc);
+ if (!context)
+ goto cleanup;
+ if (!MakeCurrent(dc, context))
+ goto cleanup;
+
+ // Now that there is finally a context current, try doing something useful.
+ if (WGL_GetProcAddress("glCreateShader")) {
+ result = true;
+ qCDebug(lcQpaGl, "OpenGL 2.0 entry points available");
+ } else {
+ qCDebug(lcQpaGl, "OpenGL 2.0 entry points not found");
+ }
+ } else {
+ qCDebug(lcQpaGl, "Failed to load opengl32.dll");
+ }
+
+cleanup:
+ if (MakeCurrent)
+ MakeCurrent(0, 0);
+ if (context)
+ DeleteContext(context);
+ if (dc && wnd)
+ ReleaseDC(wnd, dc);
+ if (wnd) {
+ DestroyWindow(wnd);
+ UnregisterClass(className, GetModuleHandle(0));
+ }
+ // No FreeLibrary. Some implementations, Mesa in particular, deadlock when trying to unload.
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
new file mode 100644
index 0000000000..f7cd7e3005
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtwindowsglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsOpenGLTester
+{
+public:
+ static bool testDesktopGL();
+};
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 2a221e71ca..56f9119459 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -48,15 +48,11 @@
# include "qwindowscursor.h"
#endif
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-# include "qwindowseglcontext.h"
-# include <QtGui/QOpenGLFunctions>
-#endif
-
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtGui/QRegion>
+#include <QtGui/QOpenGLContext>
#include <private/qsystemlibrary_p.h>
#include <private/qwindow_p.h>
#include <private/qguiapplication_p.h>
@@ -867,15 +863,13 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
m_opacity(1.0),
m_dropTarget(0),
m_savedStyle(0),
- m_format(aWindow->format()),
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- m_eglSurface(0),
-#endif
+ m_format(aWindow->requestedFormat()),
#ifdef Q_OS_WINCE
m_previouslyHidden(false),
#endif
m_iconSmall(0),
- m_iconBig(0)
+ m_iconBig(0),
+ m_surface(0)
{
// Clear the creation context as the window can be found in QWindowsContext's map.
QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>());
@@ -883,13 +877,14 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
const Qt::WindowType type = aWindow->type();
if (type == Qt::Desktop)
return; // No further handling for Qt::Desktop
+#ifndef QT_NO_OPENGL
if (aWindow->surfaceType() == QWindow::OpenGLSurface) {
- setFlag(OpenGLSurface);
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL)
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL)
+ setFlag(OpenGLSurface);
+ else
setFlag(OpenGL_ES2);
-#endif
}
+#endif // QT_NO_OPENGL
updateDropSite();
#ifndef Q_OS_WINCE
@@ -953,13 +948,10 @@ void QWindowsWindow::destroyWindow()
if (hasMouseCapture())
setMouseGrabEnabled(false);
setDropSiteEnabled(false);
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- if (m_eglSurface) {
- qCDebug(lcQpaGl) << __FUNCTION__ << "Freeing EGL surface " << m_eglSurface << window();
- eglDestroySurface(m_staticEglContext->display(), m_eglSurface);
- m_eglSurface = 0;
+ if (m_surface) {
+ m_data.staticOpenGLContext->destroyWindowSurface(m_surface);
+ m_surface = 0;
}
-#endif
#ifdef Q_OS_WINCE
if ((m_windowState & Qt::WindowFullScreen) && !m_previouslyHidden) {
HWND handle = FindWindow(L"HHTaskBar", L"");
@@ -2144,23 +2136,6 @@ void QWindowsWindow::setEnabled(bool enabled)
setStyle(newStyle);
}
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindowsEGLStaticContextPtr &staticContext, EGLConfig config)
-{
- if (!m_eglSurface) {
- m_staticEglContext = staticContext;
- m_eglSurface = eglCreateWindowSurface(staticContext->display(), config, (EGLNativeWindowType)m_data.hwnd, NULL);
- if (m_eglSurface == EGL_NO_SURFACE)
- qWarning("%s: Could not create the egl surface for %s/'%s' (eglCreateWindowSurface failed): error = 0x%x\n",
- Q_FUNC_INFO, window()->metaObject()->className(),
- qPrintable(window()->objectName()), eglGetError());
-
- qCDebug(lcQpaGl) << __FUNCTION__<<"Created EGL surface "<< m_eglSurface <<window();
- }
- return m_eglSurface;
-}
-#endif // QT_OPENGL_ES_2
-
QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
{
const int iwf = int(wf);
@@ -2272,4 +2247,12 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
}
}
+void *QWindowsWindow::surface(void *nativeConfig)
+{
+ if (!m_surface)
+ m_surface = m_data.staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig);
+
+ return m_surface;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index cb437b76d0..d6d671a3e4 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -47,23 +47,15 @@
# include "qplatformfunctions_wince.h"
#endif
#include "qwindowscursor.h"
+#include "qwindowsopenglcontext.h"
#include <qpa/qplatformwindow.h>
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-# include <QtCore/QSharedPointer>
-# include <EGL/egl.h>
-#endif
-
QT_BEGIN_NAMESPACE
class QWindowsOleDropTarget;
class QDebug;
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
-class QWindowsEGLStaticContext;
-#endif
-
struct QWindowsGeometryHint
{
QWindowsGeometryHint() {}
@@ -121,6 +113,9 @@ struct QWindowsWindowData
QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
HWND hwnd;
bool embedded;
+#ifndef QT_NO_OPENGL
+ QSharedPointer<QWindowsStaticOpenGLContext> staticOpenGLContext;
+#endif // QT_NO_OPENGL
static QWindowsWindowData create(const QWindow *w,
const QWindowsWindowData &parameters,
@@ -130,10 +125,6 @@ struct QWindowsWindowData
class QWindowsWindow : public QPlatformWindow
{
public:
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- typedef QSharedPointer<QWindowsEGLStaticContext> QWindowsEGLStaticContextPtr;
-#endif
-
enum Flags
{
AutoMouseCapture = 0x1, //! Automatic mouse capture on button press.
@@ -207,11 +198,6 @@ public:
QMargins customMargins() const { return m_data.customMargins; }
void setCustomMargins(const QMargins &m);
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- EGLSurface eglSurfaceHandle() const { return m_eglSurface;}
- EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config);
-#endif
-
inline unsigned style() const
{ return GetWindowLongPtr(m_data.hwnd, GWL_STYLE); }
void setStyle(unsigned s) const;
@@ -263,6 +249,8 @@ public:
bool isEnabled() const;
void setWindowIcon(const QIcon &icon);
+ void *surface(void *nativeConfig);
+
#ifndef Q_OS_WINCE
void setAlertState(bool enabled);
bool isAlertState() const { return testFlag(AlertState); }
@@ -302,15 +290,12 @@ private:
unsigned m_savedStyle;
QRect m_savedFrameGeometry;
const QSurfaceFormat m_format;
-#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
- EGLSurface m_eglSurface;
- QSharedPointer<QWindowsEGLStaticContext> m_staticEglContext;
-#endif
#ifdef Q_OS_WINCE
bool m_previouslyHidden;
#endif
HICON m_iconSmall;
HICON m_iconBig;
+ void *m_surface;
};
// Debug
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 13799ba1ba..fec9af2645 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -66,8 +66,12 @@ HEADERS += \
$$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h
+!wince: HEADERS += $$PWD/qwindowsopengltester.h
+
INCLUDEPATH += $$PWD
+contains(QT_CONFIG,opengl): HEADERS += $$PWD/qwindowsopenglcontext.h
+
contains(QT_CONFIG, opengles2) {
SOURCES += $$PWD/qwindowseglcontext.cpp
HEADERS += $$PWD/qwindowseglcontext.h
@@ -78,7 +82,8 @@ contains(QT_CONFIG, opengles2) {
# Dynamic GL needs both WGL and EGL
contains(QT_CONFIG,dynamicgl) {
- SOURCES += $$PWD/qwindowseglcontext.cpp
+ SOURCES += $$PWD/qwindowseglcontext.cpp \
+ $$PWD/qwindowsopengltester.cpp
HEADERS += $$PWD/qwindowseglcontext.h
}