Better cleanup if OpenGL initialization fails
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c
index 39d94da..ccfb92e 100644
--- a/src/video/SDL_egl.c
+++ b/src/video/SDL_egl.c
@@ -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;
}
}
@@ -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);
@@ -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());
@@ -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);
@@ -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");
}
@@ -424,4 +428,4 @@ SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface)
#endif /* SDL_VIDEO_OPENGL_EGL */
/* vi: set ts=4 sw=4 expandtab: */
-
\ No newline at end of file
+
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 201ba53..613bf4c 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -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);
}
diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c
index 3cc6737..20d9913 100644
--- a/src/video/windows/SDL_windowsopengl.c
+++ b/src/video/windows/SDL_windowsopengl.c
@@ -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 */
@@ -81,8 +82,7 @@ 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");
@@ -90,23 +90,15 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
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();
}
@@ -114,21 +106,20 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
/* 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");
}
@@ -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 */