Better cleanup if OpenGL initialization fails
authorSam Lantinga <slouken@libsdl.org>
Mon, 21 Oct 2013 00:15:24 -0700
changeset 7865f2a42ca4ddf0
parent 7864 fdada7e3b3e7
child 7866 42da269b7977
Better cleanup if OpenGL initialization fails
src/video/SDL_egl.c
src/video/SDL_video.c
src/video/windows/SDL_windowsopengl.c
     1.1 --- a/src/video/SDL_egl.c	Sun Oct 20 23:52:02 2013 -0700
     1.2 +++ b/src/video/SDL_egl.c	Mon Oct 21 00:15:24 2013 -0700
     1.3 @@ -91,17 +91,23 @@
     1.4  void
     1.5  SDL_EGL_UnloadLibrary(_THIS)
     1.6  {
     1.7 -    if ((_this->egl_data) && (_this->gl_config.driver_loaded)) {
     1.8 -        _this->egl_data->eglTerminate(_this->egl_data->egl_display);
     1.9 -        
    1.10 -        dlclose(_this->gl_config.dll_handle);
    1.11 -        dlclose(_this->egl_data->egl_dll_handle);
    1.12 +    if (_this->egl_data) {
    1.13 +        if (_this->egl_data->egl_display) {
    1.14 +            _this->egl_data->eglTerminate(_this->egl_data->egl_display);
    1.15 +            _this->egl_data->egl_display = NULL;
    1.16 +        }
    1.17 +
    1.18 +        if (_this->gl_config.dll_handle) {
    1.19 +            dlclose(_this->gl_config.dll_handle);
    1.20 +            _this->gl_config.dll_handle = NULL;
    1.21 +        }
    1.22 +        if (_this->egl_data->egl_dll_handle) {
    1.23 +            dlclose(_this->egl_data->egl_dll_handle);
    1.24 +            _this->egl_data->egl_dll_handle = NULL;
    1.25 +        }
    1.26          
    1.27          SDL_free(_this->egl_data);
    1.28          _this->egl_data = NULL;
    1.29 -        
    1.30 -        _this->gl_config.dll_handle = NULL;
    1.31 -        _this->gl_config.driver_loaded = 0;
    1.32      }
    1.33  }
    1.34  
    1.35 @@ -115,16 +121,18 @@
    1.36      if (_this->egl_data) {
    1.37          return SDL_SetError("OpenGL ES context already created");
    1.38      }
    1.39 -    
    1.40 -    /* Unload the old driver and reset the pointers */
    1.41 -    SDL_EGL_UnloadLibrary(_this);
    1.42 -    
    1.43 -    #ifdef RTLD_GLOBAL
    1.44 +
    1.45 +    _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
    1.46 +    if (!_this->egl_data) {
    1.47 +        return SDL_OutOfMemory();
    1.48 +    }
    1.49 +
    1.50 +#ifdef RTLD_GLOBAL
    1.51      dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
    1.52 -    #else
    1.53 +#else
    1.54      dlopen_flags = RTLD_LAZY;
    1.55 -    #endif
    1.56 -    
    1.57 +#endif
    1.58 +
    1.59      /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
    1.60      path = getenv("SDL_VIDEO_GL_DRIVER");
    1.61      egl_dll_handle = dlopen(path, dlopen_flags);
    1.62 @@ -141,6 +149,7 @@
    1.63              }
    1.64          }
    1.65      }
    1.66 +    _this->egl_data->egl_dll_handle = egl_dll_handle;
    1.67  
    1.68      if (egl_dll_handle == NULL) {
    1.69          return SDL_SetError("Could not initialize OpenGL ES library: %s", dlerror());
    1.70 @@ -157,16 +166,12 @@
    1.71          }
    1.72          dll_handle = dlopen(path, dlopen_flags);
    1.73      }
    1.74 -    
    1.75 +    _this->gl_config.dll_handle = dll_handle;
    1.76 +
    1.77      if (dll_handle == NULL) {
    1.78          return SDL_SetError("Could not load EGL library: %s", dlerror());
    1.79      }
    1.80  
    1.81 -    _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
    1.82 -    if (!_this->egl_data) {
    1.83 -        return SDL_OutOfMemory();
    1.84 -    }
    1.85 -    
    1.86      /* Load new function pointers */
    1.87      LOAD_FUNC(eglGetDisplay);
    1.88      LOAD_FUNC(eglInitialize);
    1.89 @@ -185,7 +190,6 @@
    1.90      LOAD_FUNC(eglWaitGL);
    1.91      
    1.92      _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
    1.93 -    
    1.94      if (!_this->egl_data->egl_display) {
    1.95          return SDL_SetError("Could not get EGL display");
    1.96      }
    1.97 @@ -424,4 +428,4 @@
    1.98  #endif /* SDL_VIDEO_OPENGL_EGL */
    1.99  
   1.100  /* vi: set ts=4 sw=4 expandtab: */
   1.101 -    
   1.102 \ No newline at end of file
   1.103 +    
     2.1 --- a/src/video/SDL_video.c	Sun Oct 20 23:52:02 2013 -0700
     2.2 +++ b/src/video/SDL_video.c	Mon Oct 21 00:15:24 2013 -0700
     2.3 @@ -2333,12 +2333,16 @@
     2.4          retval = 0;
     2.5      } else {
     2.6          if (!_this->GL_LoadLibrary) {
     2.7 -            return  SDL_SetError("No dynamic GL support in video driver");
     2.8 +            return SDL_SetError("No dynamic GL support in video driver");
     2.9          }
    2.10          retval = _this->GL_LoadLibrary(_this, path);
    2.11      }
    2.12      if (retval == 0) {
    2.13          ++_this->gl_config.driver_loaded;
    2.14 +    } else {
    2.15 +        if (_this->GL_UnloadLibrary) {
    2.16 +            _this->GL_UnloadLibrary(_this);
    2.17 +        }
    2.18      }
    2.19      return (retval);
    2.20  }
     3.1 --- a/src/video/windows/SDL_windowsopengl.c	Sun Oct 20 23:52:02 2013 -0700
     3.2 +++ b/src/video/windows/SDL_windowsopengl.c	Mon Oct 21 00:15:24 2013 -0700
     3.3 @@ -23,6 +23,7 @@
     3.4  #if SDL_VIDEO_DRIVER_WINDOWS
     3.5  
     3.6  #include "SDL_assert.h"
     3.7 +#include "SDL_loadso.h"
     3.8  #include "SDL_windowsvideo.h"
     3.9  
    3.10  /* WGL implementation of SDL OpenGL support */
    3.11 @@ -81,8 +82,7 @@
    3.12  int
    3.13  WIN_GL_LoadLibrary(_THIS, const char *path)
    3.14  {
    3.15 -    LPTSTR wpath;
    3.16 -    HANDLE handle;
    3.17 +    void *handle;
    3.18  
    3.19      if (path == NULL) {
    3.20          path = SDL_getenv("SDL_OPENGL_LIBRARY");
    3.21 @@ -90,23 +90,15 @@
    3.22      if (path == NULL) {
    3.23          path = DEFAULT_OPENGL;
    3.24      }
    3.25 -    wpath = WIN_UTF8ToString(path);
    3.26 -    _this->gl_config.dll_handle = LoadLibrary(wpath);
    3.27 -    SDL_free(wpath);
    3.28 +    _this->gl_config.dll_handle = SDL_LoadObject(path);
    3.29      if (!_this->gl_config.dll_handle) {
    3.30 -        char message[1024];
    3.31 -        SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
    3.32 -                     path);
    3.33 -        return WIN_SetError(message);
    3.34 +        return -1;
    3.35      }
    3.36      SDL_strlcpy(_this->gl_config.driver_path, path,
    3.37                  SDL_arraysize(_this->gl_config.driver_path));
    3.38  
    3.39      /* Allocate OpenGL memory */
    3.40 -    _this->gl_data =
    3.41 -        (struct SDL_GLDriverData *) SDL_calloc(1,
    3.42 -                                               sizeof(struct
    3.43 -                                                      SDL_GLDriverData));
    3.44 +    _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData));
    3.45      if (!_this->gl_data) {
    3.46          return SDL_OutOfMemory();
    3.47      }
    3.48 @@ -114,21 +106,20 @@
    3.49      /* Load function pointers */
    3.50      handle = _this->gl_config.dll_handle;
    3.51      _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
    3.52 -        GetProcAddress(handle, "wglGetProcAddress");
    3.53 +        SDL_LoadFunction(handle, "wglGetProcAddress");
    3.54      _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
    3.55 -        GetProcAddress(handle, "wglCreateContext");
    3.56 +        SDL_LoadFunction(handle, "wglCreateContext");
    3.57      _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
    3.58 -        GetProcAddress(handle, "wglDeleteContext");
    3.59 +        SDL_LoadFunction(handle, "wglDeleteContext");
    3.60      _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
    3.61 -        GetProcAddress(handle, "wglMakeCurrent");
    3.62 +        SDL_LoadFunction(handle, "wglMakeCurrent");
    3.63      _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
    3.64 -        GetProcAddress(handle, "wglShareLists");
    3.65 +        SDL_LoadFunction(handle, "wglShareLists");
    3.66  
    3.67      if (!_this->gl_data->wglGetProcAddress ||
    3.68          !_this->gl_data->wglCreateContext ||
    3.69          !_this->gl_data->wglDeleteContext ||
    3.70          !_this->gl_data->wglMakeCurrent) {
    3.71 -        SDL_UnloadObject(handle);
    3.72          return SDL_SetError("Could not retrieve OpenGL functions");
    3.73      }
    3.74  
    3.75 @@ -152,7 +143,7 @@
    3.76  void
    3.77  WIN_GL_UnloadLibrary(_THIS)
    3.78  {
    3.79 -    FreeLibrary((HMODULE) _this->gl_config.dll_handle);
    3.80 +    SDL_UnloadObject(_this->gl_config.dll_handle);
    3.81      _this->gl_config.dll_handle = NULL;
    3.82  
    3.83      /* Free OpenGL memory */