diff --git a/include/SDL_video.h b/include/SDL_video.h index 878c053f0..7e3ef3897 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -183,6 +183,7 @@ typedef enum SDL_GL_RETAINED_BACKING, SDL_GL_CONTEXT_MAJOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_PROFILE_MASK } SDL_GLattr; diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 679be4bf8..61faa7c49 100755 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -272,6 +272,7 @@ struct SDL_VideoDevice int minor_version; int flags; int profile_mask; + int use_egl; int retained_backing; int driver_loaded; char driver_path[256]; @@ -288,7 +289,7 @@ struct SDL_VideoDevice void *driverdata; struct SDL_GLDriverData *gl_data; -#if SDL_VIDEO_OPENGL_ES +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 struct SDL_PrivateGLESData *gles_data; #endif diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 61941d3d2..dfcac7382 100755 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -493,12 +493,15 @@ SDL_VideoInit(const char *driver_name) #if SDL_VIDEO_OPENGL _this->gl_config.major_version = 2; _this->gl_config.minor_version = 1; + _this->gl_config.use_egl = 0; #elif SDL_VIDEO_OPENGL_ES _this->gl_config.major_version = 1; _this->gl_config.minor_version = 1; + _this->gl_config.use_egl = 1; #elif SDL_VIDEO_OPENGL_ES2 _this->gl_config.major_version = 2; _this->gl_config.minor_version = 0; + _this->gl_config.use_egl = 1; #endif _this->gl_config.flags = 0; _this->gl_config.profile_mask = 0; @@ -2302,6 +2305,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) case SDL_GL_CONTEXT_MINOR_VERSION: _this->gl_config.minor_version = value; break; + case SDL_GL_CONTEXT_EGL: + _this->gl_config.use_egl = value; + break; case SDL_GL_CONTEXT_FLAGS: _this->gl_config.flags = value; break; @@ -2454,6 +2460,11 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) *value = _this->gl_config.minor_version; return 0; } + case SDL_GL_CONTEXT_EGL: + { + *value = _this->gl_config.use_egl; + return 0; + } case SDL_GL_CONTEXT_FLAGS: { *value = _this->gl_config.flags; diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 1f62fd1a4..b10dab23d 100755 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -29,6 +29,7 @@ #if SDL_VIDEO_OPENGL_GLX #include "SDL_loadso.h" +#include "SDL_x11opengles.h" #if defined(__IRIX__) /* IRIX doesn't have a GL library versioning system */ @@ -122,6 +123,28 @@ X11_GL_LoadLibrary(_THIS, const char *path) { void *handle; + if (_this->gl_data) { + SDL_SetError("OpenGL context already created"); + return -1; + } + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + /* If SDL_GL_CONTEXT_EGL has been changed to 1, switch over to X11_GLES functions */ + if (_this->gl_config.use_egl == 1) { + _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, path); + } +#endif + + /* Load the OpenGL library */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); diff --git a/src/video/x11/SDL_x11opengles.c b/src/video/x11/SDL_x11opengles.c index 3fe2d1cb3..7269bcb00 100755 --- a/src/video/x11/SDL_x11opengles.c +++ b/src/video/x11/SDL_x11opengles.c @@ -24,6 +24,7 @@ #include "SDL_x11video.h" #include "SDL_x11opengles.h" +#include "SDL_x11opengl.h" #define DEFAULT_EGL "libEGL.so" #define DEFAULT_OGL_ES2 "libGLESv2.so" @@ -71,22 +72,14 @@ X11_GLES_GetProcAddress(_THIS, const char *proc) void X11_GLES_UnloadLibrary(_THIS) { - if (_this->gl_config.driver_loaded) { + if ((_this->gles_data) && (_this->gl_config.driver_loaded)) { _this->gles_data->eglTerminate(_this->gles_data->egl_display); dlclose(_this->gl_config.dll_handle); dlclose(_this->gles_data->egl_dll_handle); - _this->gles_data->eglGetProcAddress = NULL; - _this->gles_data->eglChooseConfig = NULL; - _this->gles_data->eglCreateContext = NULL; - _this->gles_data->eglCreateWindowSurface = NULL; - _this->gles_data->eglDestroyContext = NULL; - _this->gles_data->eglDestroySurface = NULL; - _this->gles_data->eglMakeCurrent = NULL; - _this->gles_data->eglSwapBuffers = NULL; - _this->gles_data->eglGetDisplay = NULL; - _this->gles_data->eglTerminate = NULL; + SDL_free(_this->gles_data); + _this->gles_data = NULL; _this->gl_config.dll_handle = NULL; _this->gl_config.driver_loaded = 0; @@ -101,10 +94,27 @@ X11_GLES_LoadLibrary(_THIS, const char *path) SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - if (_this->gles_data->egl_active) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context already created"); return -1; } + +#if SDL_VIDEO_OPENGL_GLX + /* If SDL_GL_CONTEXT_EGL has been changed to 0, switch over to X11_GL functions */ + if (_this->gl_config.use_egl == 0) { + _this->GL_LoadLibrary = X11_GL_LoadLibrary; + _this->GL_GetProcAddress = X11_GL_GetProcAddress; + _this->GL_UnloadLibrary = X11_GL_UnloadLibrary; + _this->GL_CreateContext = X11_GL_CreateContext; + _this->GL_MakeCurrent = X11_GL_MakeCurrent; + _this->GL_SetSwapInterval = X11_GL_SetSwapInterval; + _this->GL_GetSwapInterval = X11_GL_GetSwapInterval; + _this->GL_SwapWindow = X11_GL_SwapWindow; + _this->GL_DeleteContext = X11_GL_DeleteContext; + return X11_GL_LoadLibrary(_this, path); + } +#endif + #ifdef RTLD_GLOBAL dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; #else @@ -130,6 +140,12 @@ X11_GLES_LoadLibrary(_THIS, const char *path) /* Unload the old driver and reset the pointers */ X11_GLES_UnloadLibrary(_this); + _this->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); + if (!_this->gles_data) { + SDL_OutOfMemory(); + return -1; + } + /* Load new function pointers */ LOAD_FUNC(eglGetDisplay); LOAD_FUNC(eglInitialize); @@ -204,12 +220,9 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) VisualID visual_id; int i; - /* load the gl driver from a default path */ - if (!_this->gl_config.driver_loaded) { - /* no driver has been loaded, use default (ourselves) */ - if (X11_GLES_LoadLibrary(_this, NULL) < 0) { - return NULL; - } + if (!_this->gles_data) { + /* The EGL library wasn't loaded, SDL_GetError() should have info */ + return NULL; } i = 0; @@ -324,7 +337,6 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) return NULL; } - _this->gles_data->egl_active = 1; _this->gles_data->egl_swapinterval = 0; if (X11_GLES_MakeCurrent(_this, window, context) < 0) { @@ -359,7 +371,7 @@ X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) int X11_GLES_SetSwapInterval(_THIS, int interval) { - if (_this->gles_data->egl_active != 1) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context not active"); return -1; } @@ -378,7 +390,7 @@ X11_GLES_SetSwapInterval(_THIS, int interval) int X11_GLES_GetSwapInterval(_THIS) { - if (_this->gles_data->egl_active != 1) { + if (_this->gles_data) { SDL_SetError("OpenGL ES context not active"); return -1; } @@ -397,30 +409,31 @@ void X11_GLES_DeleteContext(_THIS, SDL_GLContext context) { /* Clean up GLES and EGL */ - if (_this->gles_data->egl_context != EGL_NO_CONTEXT || - _this->gles_data->egl_surface != EGL_NO_SURFACE) { - _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); + if (_this->gles_data) { + if (_this->gles_data->egl_context != EGL_NO_CONTEXT || + _this->gles_data->egl_surface != EGL_NO_SURFACE) { + _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display, + EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); - if (_this->gles_data->egl_context != EGL_NO_CONTEXT) { - _this->gles_data->eglDestroyContext(_this->gles_data->egl_display, - _this->gles_data-> - egl_context); - _this->gles_data->egl_context = EGL_NO_CONTEXT; + if (_this->gles_data->egl_context != EGL_NO_CONTEXT) { + _this->gles_data->eglDestroyContext(_this->gles_data->egl_display, + _this->gles_data-> + egl_context); + _this->gles_data->egl_context = EGL_NO_CONTEXT; + } + + if (_this->gles_data->egl_surface != EGL_NO_SURFACE) { + _this->gles_data->eglDestroySurface(_this->gles_data->egl_display, + _this->gles_data-> + egl_surface); + _this->gles_data->egl_surface = EGL_NO_SURFACE; + } } - if (_this->gles_data->egl_surface != EGL_NO_SURFACE) { - _this->gles_data->eglDestroySurface(_this->gles_data->egl_display, - _this->gles_data-> - egl_surface); - _this->gles_data->egl_surface = EGL_NO_SURFACE; - } + /* crappy fix */ + X11_GLES_UnloadLibrary(_this); } - _this->gles_data->egl_active = 0; - -/* crappy fix */ - X11_GLES_UnloadLibrary(_this); } diff --git a/src/video/x11/SDL_x11opengles.h b/src/video/x11/SDL_x11opengles.h index a9c2a2dc8..3806b93aa 100755 --- a/src/video/x11/SDL_x11opengles.h +++ b/src/video/x11/SDL_x11opengles.h @@ -18,7 +18,12 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#include "SDL_config.h" +#ifndef _SDL_x11opengles_h +#define _SDL_x11opengles_h + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 #include #include #include @@ -30,7 +35,6 @@ typedef struct SDL_PrivateGLESData { - int egl_active; /* to stop switching drivers while we have a valid context */ XVisualInfo *egl_visualinfo; void *egl_dll_handle; EGLDisplay egl_display; @@ -92,3 +96,9 @@ extern int X11_GLES_SetSwapInterval(_THIS, int interval); extern int X11_GLES_GetSwapInterval(_THIS); extern void X11_GLES_SwapWindow(_THIS, SDL_Window * window); extern void X11_GLES_DeleteContext(_THIS, SDL_GLContext context); + +#endif /* SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 */ + +#endif /* _SDL_x11opengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index dec4173cf..d8b417ecd 100755 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -111,9 +111,6 @@ X11_DeleteDevice(SDL_VideoDevice * device) } SDL_free(data->windowlist); SDL_free(device->driverdata); -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - SDL_free(device->gles_data); -#endif SDL_free(device); SDL_X11_UnloadSymbols(); @@ -144,29 +141,6 @@ X11_CreateDevice(int devindex) } device->driverdata = data; - /* In case GL and GLES/GLES2 is compiled in, we default to GL, but use - * GLES if SDL_VIDEO_X11_GLES is set. - */ -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 -#if SDL_VIDEO_OPENGL_GLX - data->gles = SDL_getenv("SDL_VIDEO_X11_GLES") != NULL; -#else - data->gles = SDL_TRUE; -#endif -#endif - -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (data->gles) { - device->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); - if (!device->gles_data) { - SDL_OutOfMemory(); - SDL_free(device->driverdata); - SDL_free(device); - return NULL; - } - } -#endif - /* FIXME: Do we need this? if ( (SDL_strncmp(XDisplayName(display), ":", 1) == 0) || (SDL_strncmp(XDisplayName(display), "unix:", 5) == 0) ) { @@ -190,9 +164,6 @@ X11_CreateDevice(int devindex) } #endif if (data->display == NULL) { -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - SDL_free(device->gles_data); -#endif SDL_free(device->driverdata); SDL_free(device); SDL_SetError("Couldn't open X11 display"); @@ -237,30 +208,25 @@ X11_CreateDevice(int devindex) device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape; #if SDL_VIDEO_OPENGL_GLX - if (!data->gles) { - device->GL_LoadLibrary = X11_GL_LoadLibrary; - device->GL_GetProcAddress = X11_GL_GetProcAddress; - device->GL_UnloadLibrary = X11_GL_UnloadLibrary; - device->GL_CreateContext = X11_GL_CreateContext; - device->GL_MakeCurrent = X11_GL_MakeCurrent; - device->GL_SetSwapInterval = X11_GL_SetSwapInterval; - device->GL_GetSwapInterval = X11_GL_GetSwapInterval; - device->GL_SwapWindow = X11_GL_SwapWindow; - device->GL_DeleteContext = X11_GL_DeleteContext; - } -#endif -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (data->gles) { - device->GL_LoadLibrary = X11_GLES_LoadLibrary; - device->GL_GetProcAddress = X11_GLES_GetProcAddress; - device->GL_UnloadLibrary = X11_GLES_UnloadLibrary; - device->GL_CreateContext = X11_GLES_CreateContext; - device->GL_MakeCurrent = X11_GLES_MakeCurrent; - device->GL_SetSwapInterval = X11_GLES_SetSwapInterval; - device->GL_GetSwapInterval = X11_GLES_GetSwapInterval; - device->GL_SwapWindow = X11_GLES_SwapWindow; - device->GL_DeleteContext = X11_GLES_DeleteContext; - } + device->GL_LoadLibrary = X11_GL_LoadLibrary; + device->GL_GetProcAddress = X11_GL_GetProcAddress; + device->GL_UnloadLibrary = X11_GL_UnloadLibrary; + device->GL_CreateContext = X11_GL_CreateContext; + device->GL_MakeCurrent = X11_GL_MakeCurrent; + device->GL_SetSwapInterval = X11_GL_SetSwapInterval; + device->GL_GetSwapInterval = X11_GL_GetSwapInterval; + device->GL_SwapWindow = X11_GL_SwapWindow; + device->GL_DeleteContext = X11_GL_DeleteContext; +#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + device->GL_LoadLibrary = X11_GLES_LoadLibrary; + device->GL_GetProcAddress = X11_GLES_GetProcAddress; + device->GL_UnloadLibrary = X11_GLES_UnloadLibrary; + device->GL_CreateContext = X11_GLES_CreateContext; + device->GL_MakeCurrent = X11_GLES_MakeCurrent; + device->GL_SetSwapInterval = X11_GLES_SetSwapInterval; + device->GL_GetSwapInterval = X11_GLES_GetSwapInterval; + device->GL_SwapWindow = X11_GLES_SwapWindow; + device->GL_DeleteContext = X11_GLES_DeleteContext; #endif device->SetClipboardText = X11_SetClipboardText; diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index c3935cd15..59234296f 100755 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -92,9 +92,7 @@ typedef struct SDL_VideoData Atom UTF8_STRING; SDL_Scancode key_layout[256]; - SDL_bool selection_waiting; - - SDL_bool gles; + SDL_bool selection_waiting; } SDL_VideoData; extern SDL_bool X11_UseDirectColorVisuals(void); diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 90557d109..f4482d2e0 100755 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -273,15 +273,16 @@ X11_CreateWindow(_THIS, SDL_Window * window) if (window->flags & SDL_WINDOW_OPENGL) { XVisualInfo *vinfo; -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (data->gles) { +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + if (_this->gl_config.use_egl == 1) { vinfo = X11_GLES_GetVisual(_this, display, screen); } else #endif { +#if SDL_VIDEO_OPENGL_GLX vinfo = X11_GL_GetVisual(_this, display, screen); +#endif } - if (!vinfo) { return -1; } @@ -390,7 +391,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) return -1; } #if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if (data->gles && window->flags & SDL_WINDOW_OPENGL) { + if (window->flags & SDL_WINDOW_OPENGL) { /* Create the GLES window surface */ _this->gles_data->egl_surface = _this->gles_data->eglCreateWindowSurface(_this->gles_data->