Pass function ptr to resolve glFunctions to initGL

Summary:
KWin still resolves some OpenGL function pointers. For that it needs to
use either eglGetProcAddress or glxGetProcAddress. With other words the
method to resolve needs to know whether it is egl or glx and needs both
a dependency to egl and glx. Especially the dependency to glx is ugly as
that pulls in XLib into our library.

The way so far was to pass an enum value to the initGL method to know
whether it's EGL or GLX. With this change the enum value is removed and
replaced by a function pointer to resolve the methods.

This simplifies the resolve code and allows to completely remove the glx
variant we still had in the library. Thus kwinglutils library is now glx
and XLib free.

Test Plan: nested KWin with OpenGL/EGL still works

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D3336
This commit is contained in:
Martin Gräßlin 2016-11-11 09:16:23 +01:00
parent 6184278bec
commit d7fa827644
7 changed files with 20 additions and 44 deletions

View file

@ -107,6 +107,12 @@ bool AbstractEglBackend::initEglAPI()
return true;
}
typedef void (*eglFuncPtr)();
static eglFuncPtr getProcAddress(const char* name)
{
return eglGetProcAddress(name);
}
void AbstractEglBackend::initKWinGL()
{
initEGL();
@ -116,7 +122,7 @@ void AbstractEglBackend::initKWinGL()
if (options->glPreferBufferSwap() == Options::AutoSwapStrategy)
options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen
glPlatform->printResults();
initGL(EglPlatformInterface);
initGL(&getProcAddress);
}
void AbstractEglBackend::initBufferAge()

View file

@ -105,11 +105,6 @@ kwin4_add_glutils_backend(kwinglutils ${epoxy_INCLUDE_DIR} ${epoxy_LIBRARY})
set_target_properties(kwinglutils PROPERTIES OUTPUT_NAME ${KWIN_NAME}glutils)
target_link_libraries(kwinglutils PUBLIC ${epoxy_LIBRARY})
# -ldl used by OpenGL code
find_library(DL_LIBRARY dl)
if (DL_LIBRARY)
target_link_libraries(kwinglutils PRIVATE ${DL_LIBRARY})
endif()
install( FILES
kwinglobals.h

View file

@ -84,7 +84,7 @@ void initEGL()
eglResolveFunctions();
}
void initGL(OpenGLPlatformInterface platformInterface)
void initGL(std::function<resolveFuncPtr(const char*)> resolveFunction)
{
// Get list of supported OpenGL extensions
if (hasGLVersion(3, 0)) {
@ -99,7 +99,7 @@ void initGL(OpenGLPlatformInterface platformInterface)
glExtensions = QByteArray((const char*)glGetString(GL_EXTENSIONS)).split(' ');
// handle OpenGL extensions functions
glResolveFunctions(platformInterface);
glResolveFunctions(resolveFunction);
GLTexturePrivate::initStatic();
GLRenderTarget::initStatic();

View file

@ -51,7 +51,8 @@ class GLVertexBufferPrivate;
// Initializes OpenGL stuff. This includes resolving function pointers as
// well as checking for GL version and extensions
// Note that GL context has to be created by the time this function is called
void KWINGLUTILS_EXPORT initGL(OpenGLPlatformInterface platformInterface);
typedef void (*resolveFuncPtr)();
void KWINGLUTILS_EXPORT initGL(std::function<resolveFuncPtr(const char*)> resolveFunction);
// Initializes EGL function pointers
void KWINGLUTILS_EXPORT initEGL();
// Cleans up all resources hold by the GL Context

View file

@ -21,26 +21,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwinglutils.h"
#include "kwinglplatform.h"
#include <dlfcn.h>
#if HAVE_EPOXY_GLX
#include <epoxy/glx.h>
#endif
// Resolves given function, using getProcAddress
#define GL_RESOLVE( function ) \
if (platformInterface == GlxPlatformInterface) \
function = (function ## _func)getProcAddress( #function ); \
else if (platformInterface == EglPlatformInterface) \
function = (function ## _func)eglGetProcAddress( #function );
// Same as above but tries to use function "symbolName"
// Useful when functionality is defined in an extension with a different name
#define GL_RESOLVE_WITH_EXT( function, symbolName ) \
if (platformInterface == GlxPlatformInterface) { \
function = (function ## _func)getProcAddress( #symbolName ); \
} else if (platformInterface == EglPlatformInterface) { \
function = (function ## _func)eglGetProcAddress( #symbolName ); \
}
function = (function ## _func)resolveFunction( #symbolName );
namespace KWin
{
@ -55,24 +40,11 @@ glGetGraphicsResetStatus_func glGetGraphicsResetStatus;
glReadnPixels_func glReadnPixels;
glGetnUniformfv_func glGetnUniformfv;
typedef void (*glXFuncPtr)();
static glXFuncPtr getProcAddress(const char* name)
{
glXFuncPtr ret = nullptr;
#if HAVE_EPOXY_GLX
ret = glXGetProcAddress((const GLubyte*) name);
#endif
if (ret == nullptr)
ret = (glXFuncPtr) dlsym(RTLD_DEFAULT, name);
return ret;
}
void eglResolveFunctions()
{
}
void glResolveFunctions(OpenGLPlatformInterface platformInterface)
void glResolveFunctions(std::function<resolveFuncPtr(const char*)> resolveFunction)
{
const bool haveArbRobustness = hasGLExtension(QByteArrayLiteral("GL_ARB_robustness"));
const bool haveExtRobustness = hasGLExtension(QByteArrayLiteral("GL_EXT_robustness"));
@ -103,9 +75,9 @@ void glResolveFunctions(OpenGLPlatformInterface platformInterface)
GL_RESOLVE_WITH_EXT(glGetnUniformfv, glGetnUniformfvARB);
} else if (robustContext && haveExtRobustness) {
// See http://www.khronos.org/registry/gles/extensions/EXT/EXT_robustness.txt
glGetGraphicsResetStatus = (glGetGraphicsResetStatus_func) eglGetProcAddress("glGetGraphicsResetStatusEXT");
glReadnPixels = (glReadnPixels_func) eglGetProcAddress("glReadnPixelsEXT");
glGetnUniformfv = (glGetnUniformfv_func) eglGetProcAddress("glGetnUniformfvEXT");
glGetGraphicsResetStatus = (glGetGraphicsResetStatus_func) resolveFunction("glGetGraphicsResetStatusEXT");
glReadnPixels = (glReadnPixels_func) resolveFunction("glReadnPixelsEXT");
glGetnUniformfv = (glGetnUniformfv_func) resolveFunction("glGetnUniformfvEXT");
} else {
glGetGraphicsResetStatus = KWin::GetGraphicsResetStatus;
glReadnPixels = KWin::ReadnPixels;

View file

@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <fixx11h.h>
#include <epoxy/gl.h>
#include <functional>
// qopengl.h declares GLdouble as a typedef of float when Qt is built
// with GLES support. This conflicts with the epoxy/gl_generated.h
@ -49,7 +50,8 @@ namespace KWin
void KWINGLUTILS_EXPORT eglResolveFunctions();
void KWINGLUTILS_EXPORT glResolveFunctions(OpenGLPlatformInterface platformInterface);
typedef void (*resolveFuncPtr)();
void KWINGLUTILS_EXPORT glResolveFunctions(std::function<resolveFuncPtr(const char*)> resolveFunction);
// GL_ARB_robustness / GL_EXT_robustness
using glGetGraphicsResetStatus_func = GLenum (*)();

View file

@ -199,7 +199,7 @@ void GlxBackend::init()
if (options->glPreferBufferSwap() == Options::AutoSwapStrategy)
options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen
glPlatform->printResults();
initGL(GlxPlatformInterface);
initGL(&getProcAddress);
// Check whether certain features are supported
m_haveMESACopySubBuffer = hasExtension(QByteArrayLiteral("GLX_MESA_copy_sub_buffer"));