From e8b1320f91838a29891c6a5b377160e27a0adcf5 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 4 Aug 2024 20:27:26 +0200 Subject: Add option to choose render api (glx or egl) in window creation --- src/gl.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 27 deletions(-) (limited to 'src/gl.c') diff --git a/src/gl.c b/src/gl.c index 4ac022a..77e867a 100644 --- a/src/gl.c +++ b/src/gl.c @@ -1,6 +1,7 @@ #include "../include/mgl/gl.h" #include #include +#include typedef struct { void **func; @@ -18,22 +19,8 @@ static void* dlsym_print_fail(void *handle, const char *name, int required) { return sym; } -int mgl_gl_load(mgl_gl *self) { - const char *glx_path = "libGL.so.1"; - self->handle = dlopen(glx_path, RTLD_LAZY); - if(!self->handle) { - fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", glx_path); - return -1; - } - - dlsym_assign required_dlsym[] = { - { (void**)&self->glXCreateNewContext, "glXCreateNewContext" }, - { (void**)&self->glXMakeContextCurrent, "glXMakeContextCurrent" }, - { (void**)&self->glXDestroyContext, "glXDestroyContext" }, - { (void**)&self->glXSwapBuffers, "glXSwapBuffers" }, - { (void**)&self->glXChooseFBConfig, "glXChooseFBConfig" }, - { (void**)&self->glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig" }, - +static int mgl_gl_load_gl(mgl_gl *self) { + const dlsym_assign required_dlsym[] = { { (void**)&self->glViewport, "glViewport" }, { (void**)&self->glScissor, "glScissor" }, { (void**)&self->glClearColor, "glClearColor" }, @@ -98,32 +85,133 @@ int mgl_gl_load(mgl_gl *self) { }; for(int i = 0; required_dlsym[i].func; ++i) { - *required_dlsym[i].func = dlsym_print_fail(self->handle, required_dlsym[i].name, 1); - if(!*required_dlsym[i].func) { - mgl_gl_unload(self); + *required_dlsym[i].func = dlsym_print_fail(self->gl_library, required_dlsym[i].name, 1); + if(!*required_dlsym[i].func) return -1; - } } const dlsym_assign optional_dlsym[] = { - { (void**)&self->glXSwapIntervalEXT, "glXSwapIntervalEXT" }, - { (void**)&self->glXSwapIntervalMESA, "glXGetSwapIntervalMESA" }, - { (void**)&self->glXSwapIntervalSGI, "glXSwapIntervalSGI" }, { (void**)&self->glGenerateMipmap, "glGenerateMipmap" }, { NULL, NULL } }; for(int i = 0; optional_dlsym[i].func; ++i) { - *optional_dlsym[i].func = dlsym_print_fail(self->handle, optional_dlsym[i].name, 0); + *optional_dlsym[i].func = dlsym_print_fail(self->gl_library, optional_dlsym[i].name, 0); + } + + return 0; +} + +static int mgl_gl_load_glx(mgl_gl *self) { + const dlsym_assign required_dlsym[] = { + { (void**)&self->glXGetProcAddress, "glXGetProcAddress" }, + { (void**)&self->glXCreateNewContext, "glXCreateNewContext" }, + { (void**)&self->glXMakeContextCurrent, "glXMakeContextCurrent" }, + { (void**)&self->glXDestroyContext, "glXDestroyContext" }, + { (void**)&self->glXSwapBuffers, "glXSwapBuffers" }, + { (void**)&self->glXChooseFBConfig, "glXChooseFBConfig" }, + { (void**)&self->glXGetVisualFromFBConfig, "glXGetVisualFromFBConfig" }, + + { NULL, NULL } + }; + + for(int i = 0; required_dlsym[i].func; ++i) { + *required_dlsym[i].func = dlsym_print_fail(self->glx_library, required_dlsym[i].name, 1); + if(!*required_dlsym[i].func) + return -1; + } + + self->glXSwapIntervalEXT = (FUNC_glXSwapIntervalEXT)self->glXGetProcAddress((const unsigned char*)"glXSwapIntervalEXT"); + self->glXSwapIntervalMESA = (FUNC_glXSwapIntervalMESA)self->glXGetProcAddress((const unsigned char*)"glXSwapIntervalMESA"); + self->glXSwapIntervalSGI = (FUNC_glXSwapIntervalSGI)self->glXGetProcAddress((const unsigned char*)"glXSwapIntervalSGI"); + + return 0; +} + +static int mgl_gl_load_egl(mgl_gl *self) { + const dlsym_assign required_dlsym[] = { + { (void**)&self->eglGetDisplay, "eglGetDisplay" }, + { (void**)&self->eglInitialize, "eglInitialize" }, + { (void**)&self->eglTerminate, "eglTerminate" }, + { (void**)&self->eglChooseConfig, "eglChooseConfig" }, + { (void**)&self->eglCreateWindowSurface, "eglCreateWindowSurface" }, + { (void**)&self->eglCreateContext, "eglCreateContext" }, + { (void**)&self->eglMakeCurrent, "eglMakeCurrent" }, + { (void**)&self->eglDestroyContext, "eglDestroyContext" }, + { (void**)&self->eglDestroySurface, "eglDestroySurface" }, + { (void**)&self->eglSwapInterval, "eglSwapInterval" }, + { (void**)&self->eglSwapBuffers, "eglSwapBuffers" }, + { (void**)&self->eglBindAPI, "eglBindAPI" }, + { (void**)&self->eglGetConfigAttrib, "eglGetConfigAttrib" }, + + { NULL, NULL } + }; + + for(int i = 0; required_dlsym[i].func; ++i) { + *required_dlsym[i].func = dlsym_print_fail(self->egl_library, required_dlsym[i].name, 1); + if(!*required_dlsym[i].func) + return -1; + } + + return 0; +} + +int mgl_gl_load(mgl_gl *self) { + memset(self, 0, sizeof(*self)); + + self->gl_library = dlopen("libGL.so.1", RTLD_LAZY); + if(!self->gl_library) { + fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", "libGL.so.1"); + mgl_gl_unload(self); + return -1; + } + + self->glx_library = dlopen("libGLX.so.0", RTLD_LAZY); + if(!self->glx_library) { + fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", "libGLX.so.0"); + mgl_gl_unload(self); + return -1; + } + + self->egl_library = dlopen("libEGL.so.1", RTLD_LAZY); + if(!self->egl_library) { + fprintf(stderr, "mgl error:dlopen(\"%s\", RTLD_LAZY) failed\n", "libEGL.so.1"); + mgl_gl_unload(self); + return -1; + } + + if(mgl_gl_load_gl(self) != 0) { + mgl_gl_unload(self); + return -1; + } + + if(mgl_gl_load_glx(self) != 0) { + mgl_gl_unload(self); + return -1; + } + + if(mgl_gl_load_egl(self) != 0) { + mgl_gl_unload(self); + return -1; } return 0; } void mgl_gl_unload(mgl_gl *self) { - if(self->handle) { - dlclose(self->handle); - self->handle = NULL; + if(self->egl_library) { + dlclose(self->egl_library); + self->egl_library = NULL; + } + + if(self->glx_library) { + dlclose(self->glx_library); + self->glx_library = NULL; + } + + if(self->gl_library) { + dlclose(self->gl_library); + self->gl_library = NULL; } } -- cgit v1.2.3