int X11_GL_LoadLibrary(_THIS, const char *path) { Display *display; void *handle; if (_this->gl_data) { return SDL_SetError("OpenGL context already created"); } /* Load the OpenGL library */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); } if (path == NULL) { path = DEFAULT_OPENGL; } _this->gl_config.dll_handle = GL_LoadObject(path); if (!_this->gl_config.dll_handle) { #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) SDL_SetError("Failed loading %s: %s", path, dlerror()); #endif return -1; } SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); /* Allocate OpenGL memory */ _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData)); if (!_this->gl_data) { return SDL_OutOfMemory(); } /* Load function pointers */ handle = _this->gl_config.dll_handle; _this->gl_data->glXQueryExtension = (Bool (*)(Display *, int *, int *)) GL_LoadFunction(handle, "glXQueryExtension"); _this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); _this->gl_data->glXChooseVisual = (XVisualInfo * (*)(Display *, int, int *)) X11_GL_GetProcAddress(_this, "glXChooseVisual"); _this->gl_data->glXCreateContext = (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int)) X11_GL_GetProcAddress(_this, "glXCreateContext"); _this->gl_data->glXDestroyContext = (void (*)(Display *, GLXContext)) X11_GL_GetProcAddress(_this, "glXDestroyContext"); _this->gl_data->glXMakeCurrent = (int (*)(Display *, GLXDrawable, GLXContext)) X11_GL_GetProcAddress(_this, "glXMakeCurrent"); _this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(_this, "glXSwapBuffers"); _this->gl_data->glXQueryDrawable = (void (*)(Display*,GLXDrawable,int,unsigned int*)) X11_GL_GetProcAddress(_this, "glXQueryDrawable"); if (!_this->gl_data->glXQueryExtension || !_this->gl_data->glXChooseVisual || !_this->gl_data->glXCreateContext || !_this->gl_data->glXDestroyContext || !_this->gl_data->glXMakeCurrent || !_this->gl_data->glXSwapBuffers) { return SDL_SetError("Could not retrieve OpenGL functions"); } display = ((SDL_VideoData *) _this->driverdata)->display; if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) { return SDL_SetError("GLX is not supported"); } /* Initialize extensions */ X11_GL_InitExtensions(_this); /* If SDL_GL_CONTEXT_EGL has been changed to 1, and there's * no GLX_EXT_create_context_es2_profile extension switch over to X11_GLES functions */ if (_this->gl_config.use_egl == 1) { if (_this->gl_data->HAS_GLX_EXT_create_context_es2_profile) { /* We cheat a little bit here by using GLX instead of EGL * to improve our chances of getting hardware acceleration */ _this->gl_config.use_egl = 0; _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; } else { #if SDL_VIDEO_OPENGL_EGL X11_GL_UnloadLibrary(_this); /* Better avoid conflicts! */ if (_this->gl_config.dll_handle != NULL ) { GL_UnloadObject(_this->gl_config.dll_handle); _this->gl_config.dll_handle = NULL; } _this->GL_LoadLibrary = X11_GLES_LoadLibrary; _this->GL_GetProcAddress = X11_GLES_GetProcAddress; _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; _this->GL_CreateContext = X11_GLES_CreateContext; _this->GL_MakeCurrent = X11_GLES_MakeCurrent; _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval; _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval; _this->GL_SwapWindow = X11_GLES_SwapWindow; _this->GL_DeleteContext = X11_GLES_DeleteContext; return X11_GLES_LoadLibrary(_this, NULL); #else return SDL_SetError("SDL not configured with EGL support"); #endif } } return 0; }
/* Passing a NULL path means load pointers from the application */ int X11_GL_LoadLibrary(_THIS, const char* path) { void* handle = NULL; if ( gl_active ) { SDL_SetError("OpenGL context already created"); return -1; } if ( path == NULL ) { path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); if ( path == NULL ) { path = DEFAULT_OPENGL; } } handle = GL_LoadObject(path); if ( handle == NULL ) { #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) SDL_SetError("Failed loading %s", path); #else /* SDL_LoadObject() will call SDL_SetError() for us. */ #endif return -1; } /* Unload the old driver and reset the pointers */ X11_GL_UnloadLibrary(this); /* Load new function pointers */ this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) GL_LoadFunction(handle, "glXGetProcAddressARB"); this->gl_data->glXChooseVisual = (XVisualInfo *(*)(Display *, int, int *)) GL_LoadFunction(handle, "glXChooseVisual"); this->gl_data->glXCreateContext = (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) GL_LoadFunction(handle, "glXCreateContext"); this->gl_data->glXDestroyContext = (void (*)(Display *, GLXContext)) GL_LoadFunction(handle, "glXDestroyContext"); this->gl_data->glXMakeCurrent = (int (*)(Display *, GLXDrawable, GLXContext)) GL_LoadFunction(handle, "glXMakeCurrent"); this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) GL_LoadFunction(handle, "glXSwapBuffers"); this->gl_data->glXGetConfig = (int (*)(Display *, XVisualInfo *, int, int *)) GL_LoadFunction(handle, "glXGetConfig"); this->gl_data->glXQueryExtensionsString = (const char *(*)(Display *, int)) GL_LoadFunction(handle, "glXQueryExtensionsString"); this->gl_data->glXSwapIntervalSGI = (int (*)(int)) GL_LoadFunction(handle, "glXSwapIntervalSGI"); this->gl_data->glXSwapIntervalMESA = (GLint (*)(unsigned)) GL_LoadFunction(handle, "glXSwapIntervalMESA"); this->gl_data->glXGetSwapIntervalMESA = (GLint (*)(void)) GL_LoadFunction(handle, "glXGetSwapIntervalMESA"); if ( (this->gl_data->glXChooseVisual == NULL) || (this->gl_data->glXCreateContext == NULL) || (this->gl_data->glXDestroyContext == NULL) || (this->gl_data->glXMakeCurrent == NULL) || (this->gl_data->glXSwapBuffers == NULL) || (this->gl_data->glXGetConfig == NULL) || (this->gl_data->glXQueryExtensionsString == NULL)) { SDL_SetError("Could not retrieve OpenGL functions"); return -1; } this->gl_config.dll_handle = handle; this->gl_config.driver_loaded = 1; if ( path ) { SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path)); } else { *this->gl_config.driver_path = '\0'; } return 0; }
/* Passing a NULL path means load pointers from the application */ int X11_GL_LoadLibrary(_THIS, const char* path) { void* handle; int dlopen_flags; if ( gl_active ) { SDL_SetError("OpenGL context already created"); return -1; } #ifdef RTLD_GLOBAL dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; #else dlopen_flags = RTLD_LAZY; #endif handle = dlopen(path, dlopen_flags); /* Catch the case where the application isn't linked with GL */ if ( (dlsym(handle, "glXChooseVisual") == NULL) && (path == NULL) ) { dlclose(handle); path = getenv("SDL_VIDEO_GL_DRIVER"); if ( path == NULL ) { path = DEFAULT_OPENGL; } handle = dlopen(path, dlopen_flags); } if ( handle == NULL ) { SDL_SetError("Could not load OpenGL library"); return -1; } /* Unload the old driver and reset the pointers */ X11_GL_UnloadLibrary(this); /* Load new function pointers */ this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) dlsym(handle, "glXGetProcAddressARB"); this->gl_data->glXChooseVisual = (XVisualInfo *(*)(Display *, int, int *)) dlsym(handle, "glXChooseVisual"); this->gl_data->glXCreateContext = (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) dlsym(handle, "glXCreateContext"); this->gl_data->glXDestroyContext = (void (*)(Display *, GLXContext)) dlsym(handle, "glXDestroyContext"); this->gl_data->glXMakeCurrent = (int (*)(Display *, GLXDrawable, GLXContext)) dlsym(handle, "glXMakeCurrent"); this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) dlsym(handle, "glXSwapBuffers"); this->gl_data->glXGetConfig = (int (*)(Display *, XVisualInfo *, int, int *)) dlsym(handle, "glXGetConfig"); this->gl_data->glXQueryExtensionsString = (const char *(*)(Display *, int)) dlsym(handle, "glXQueryExtensionsString"); /* We don't compare below for this in case we're not using Mesa. */ this->gl_data->glXReleaseBuffersMESA = (void (*)(Display *, GLXDrawable)) dlsym( handle, "glXReleaseBuffersMESA" ); if ( (this->gl_data->glXChooseVisual == NULL) || (this->gl_data->glXCreateContext == NULL) || (this->gl_data->glXDestroyContext == NULL) || (this->gl_data->glXMakeCurrent == NULL) || (this->gl_data->glXSwapBuffers == NULL) || (this->gl_data->glXGetConfig == NULL) || (this->gl_data->glXQueryExtensionsString == NULL)) { SDL_SetError("Could not retrieve OpenGL functions"); return -1; } this->gl_config.dll_handle = handle; this->gl_config.driver_loaded = 1; if ( path ) { strncpy(this->gl_config.driver_path, path, sizeof(this->gl_config.driver_path)-1); } else { strcpy(this->gl_config.driver_path, ""); } return 0; }