Skip to content

Commit

Permalink
Better cleanup if OpenGL initialization fails
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Oct 21, 2013
1 parent 5697089 commit 360c3d8
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 45 deletions.
52 changes: 28 additions & 24 deletions src/video/SDL_egl.c
Expand Up @@ -91,17 +91,23 @@ SDL_EGL_GetProcAddress(_THIS, const char *proc)
void
SDL_EGL_UnloadLibrary(_THIS)
{
if ((_this->egl_data) && (_this->gl_config.driver_loaded)) {
_this->egl_data->eglTerminate(_this->egl_data->egl_display);

dlclose(_this->gl_config.dll_handle);
dlclose(_this->egl_data->egl_dll_handle);
if (_this->egl_data) {
if (_this->egl_data->egl_display) {
_this->egl_data->eglTerminate(_this->egl_data->egl_display);
_this->egl_data->egl_display = NULL;
}

if (_this->gl_config.dll_handle) {
dlclose(_this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL;
}
if (_this->egl_data->egl_dll_handle) {
dlclose(_this->egl_data->egl_dll_handle);
_this->egl_data->egl_dll_handle = NULL;
}

SDL_free(_this->egl_data);
_this->egl_data = NULL;

_this->gl_config.dll_handle = NULL;
_this->gl_config.driver_loaded = 0;
}
}

Expand All @@ -115,16 +121,18 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
if (_this->egl_data) {
return SDL_SetError("OpenGL ES context already created");
}

/* Unload the old driver and reset the pointers */
SDL_EGL_UnloadLibrary(_this);

#ifdef RTLD_GLOBAL

_this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
if (!_this->egl_data) {
return SDL_OutOfMemory();
}

#ifdef RTLD_GLOBAL
dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
#else
#else
dlopen_flags = RTLD_LAZY;
#endif
#endif

/* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
path = getenv("SDL_VIDEO_GL_DRIVER");
egl_dll_handle = dlopen(path, dlopen_flags);
Expand All @@ -141,6 +149,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
}
}
}
_this->egl_data->egl_dll_handle = egl_dll_handle;

if (egl_dll_handle == NULL) {
return SDL_SetError("Could not initialize OpenGL ES library: %s", dlerror());
Expand All @@ -157,16 +166,12 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
}
dll_handle = dlopen(path, dlopen_flags);
}

_this->gl_config.dll_handle = dll_handle;

if (dll_handle == NULL) {
return SDL_SetError("Could not load EGL library: %s", dlerror());
}

_this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
if (!_this->egl_data) {
return SDL_OutOfMemory();
}

/* Load new function pointers */
LOAD_FUNC(eglGetDisplay);
LOAD_FUNC(eglInitialize);
Expand All @@ -185,7 +190,6 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
LOAD_FUNC(eglWaitGL);

_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);

if (!_this->egl_data->egl_display) {
return SDL_SetError("Could not get EGL display");
}
Expand Down Expand Up @@ -424,4 +428,4 @@ SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface)
#endif /* SDL_VIDEO_OPENGL_EGL */

/* vi: set ts=4 sw=4 expandtab: */


6 changes: 5 additions & 1 deletion src/video/SDL_video.c
Expand Up @@ -2333,12 +2333,16 @@ SDL_GL_LoadLibrary(const char *path)
retval = 0;
} else {
if (!_this->GL_LoadLibrary) {
return SDL_SetError("No dynamic GL support in video driver");
return SDL_SetError("No dynamic GL support in video driver");
}
retval = _this->GL_LoadLibrary(_this, path);
}
if (retval == 0) {
++_this->gl_config.driver_loaded;
} else {
if (_this->GL_UnloadLibrary) {
_this->GL_UnloadLibrary(_this);
}
}
return (retval);
}
Expand Down
31 changes: 11 additions & 20 deletions src/video/windows/SDL_windowsopengl.c
Expand Up @@ -23,6 +23,7 @@
#if SDL_VIDEO_DRIVER_WINDOWS

#include "SDL_assert.h"
#include "SDL_loadso.h"
#include "SDL_windowsvideo.h"

/* WGL implementation of SDL OpenGL support */
Expand Down Expand Up @@ -81,54 +82,44 @@ typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
int
WIN_GL_LoadLibrary(_THIS, const char *path)
{
LPTSTR wpath;
HANDLE handle;
void *handle;

if (path == NULL) {
path = SDL_getenv("SDL_OPENGL_LIBRARY");
}
if (path == NULL) {
path = DEFAULT_OPENGL;
}
wpath = WIN_UTF8ToString(path);
_this->gl_config.dll_handle = LoadLibrary(wpath);
SDL_free(wpath);
_this->gl_config.dll_handle = SDL_LoadObject(path);
if (!_this->gl_config.dll_handle) {
char message[1024];
SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
path);
return WIN_SetError(message);
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));
_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->wglGetProcAddress = (void *(WINAPI *) (const char *))
GetProcAddress(handle, "wglGetProcAddress");
SDL_LoadFunction(handle, "wglGetProcAddress");
_this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
GetProcAddress(handle, "wglCreateContext");
SDL_LoadFunction(handle, "wglCreateContext");
_this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
GetProcAddress(handle, "wglDeleteContext");
SDL_LoadFunction(handle, "wglDeleteContext");
_this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
GetProcAddress(handle, "wglMakeCurrent");
SDL_LoadFunction(handle, "wglMakeCurrent");
_this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
GetProcAddress(handle, "wglShareLists");
SDL_LoadFunction(handle, "wglShareLists");

if (!_this->gl_data->wglGetProcAddress ||
!_this->gl_data->wglCreateContext ||
!_this->gl_data->wglDeleteContext ||
!_this->gl_data->wglMakeCurrent) {
SDL_UnloadObject(handle);
return SDL_SetError("Could not retrieve OpenGL functions");
}

Expand All @@ -152,7 +143,7 @@ WIN_GL_GetProcAddress(_THIS, const char *proc)
void
WIN_GL_UnloadLibrary(_THIS)
{
FreeLibrary((HMODULE) _this->gl_config.dll_handle);
SDL_UnloadObject(_this->gl_config.dll_handle);
_this->gl_config.dll_handle = NULL;

/* Free OpenGL memory */
Expand Down

0 comments on commit 360c3d8

Please sign in to comment.