diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2016-02-12 12:50:12 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-03-02 12:16:15 +0000 |
commit | 69f29b90322338bb7cd884a0cecdb8dd5dd2573e (patch) | |
tree | e0f9d7dd3d71b802fa25ca487bc232081179e1d0 /src/plugins/platforms/windows/qwindowsglcontext.cpp | |
parent | 6b0a577bf85845780e9a7b101260cdf72fa1d33c (diff) |
Clean up resolving of OpenGL functions on Windows
Always try both e/wglGetProcAddress and ::GetProcAddress to
resolve the methods. Like this QOpengGLContext::getProcAddress is
able to return any OpenGL entry point, and we can both simplify
the code we have in the QPA backend as well as get rid of windows
specific code paths in Qt Gui.
Task-number: QTBUG-39531
Change-Id: I1ddf1b0974f69b56b219a619655b723eb0134b14
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsglcontext.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsglcontext.cpp | 126 |
1 files changed, 12 insertions, 114 deletions
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 8eac7cca9e..cc2f05b6d1 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -156,8 +156,6 @@ void *QWindowsOpengl32DLL::resolve(const char *name) #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; } @@ -199,56 +197,11 @@ bool QWindowsOpengl32DLL::init(bool softwareRendering) 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; + + return wglCreateContext && glGetError && glGetString; } BOOL QWindowsOpengl32DLL::swapBuffers(HDC dc) @@ -1383,78 +1336,23 @@ void QWindowsGLContext::doneCurrent() QFunctionPointer QWindowsGLContext::getProcAddress(const char *procName) { + // 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)); + // 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 (!qstrcmp(procName, standardFuncs[i].name)) - return reinterpret_cast<QFunctionPointer>(standardFuncs[i].func); + // call into here for _any_ OpenGL function. + if (!procAddress || procAddress == reinterpret_cast<void *>(0x1) || procAddress == reinterpret_cast<void *>(0x2) + || procAddress == reinterpret_cast<void *>(0x3) || procAddress == reinterpret_cast<void *>(-1)) + procAddress = reinterpret_cast<QFunctionPointer>(QOpenGLStaticContext::opengl32.resolve(procName)); - // 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)); if (QWindowsContext::verbose > 1) qCDebug(lcQpaGl) << __FUNCTION__ << procName << QOpenGLStaticContext::opengl32.wglGetCurrentContext() << "returns" << procAddress; - if (!procAddress && QWindowsContext::verbose) - qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName); + return procAddress; } |