--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_x11opengles.c Wed Jun 10 13:54:13 2009 +0000
@@ -0,0 +1,366 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2009 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with _this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+
+ Open Pandora SDL driver
+ Copyright (C) 2009 David Carré
+ (cpasjuste@gmail.com)
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_OPENGL_ES
+
+#include "SDL_x11video.h"
+#include "SDL_x11opengles.h"
+
+#define DEFAULT_OPENGL "/usr/lib/libGLES_CM.so"
+
+#define LOAD_FUNC(NAME) \
+ *((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
+ if (!_this->gles_data->NAME) \
+ { \
+ SDL_SetError("Could not retrieve EGL function " #NAME); \
+ return -1; \
+ }
+
+/* GLES implementation of SDL OpenGL support */
+
+void *
+X11_GLES_GetProcAddress(_THIS, const char *proc)
+{
+ static char procname[1024];
+ void *handle;
+ void *retval;
+
+ handle = _this->gl_config.dll_handle;
+ if (_this->gles_data->eglGetProcAddress) {
+ retval = _this->gles_data->eglGetProcAddress(proc);
+ if (retval) {
+ return retval;
+ }
+ }
+#if defined(__OpenBSD__) && !defined(__ELF__)
+#undef dlsym(x,y);
+#endif
+ retval = dlsym(handle, proc);
+ if (!retval && strlen(proc) <= 1022) {
+ procname[0] = '_';
+ strcpy(procname + 1, proc);
+ retval = dlsym(handle, procname);
+ }
+ return retval;
+}
+
+void
+X11_GLES_UnloadLibrary(_THIS)
+{
+ if (_this->gl_config.driver_loaded) {
+ _this->gles_data->eglTerminate(_this->gles_data->egl_display);
+
+ dlclose(_this->gl_config.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;
+
+ _this->gl_config.dll_handle = NULL;
+ _this->gl_config.driver_loaded = 0;
+ }
+}
+
+int
+X11_GLES_LoadLibrary(_THIS, const char *path)
+{
+ void *handle;
+ int dlopen_flags;
+
+ SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
+
+ if (_this->gles_data->egl_active) {
+ SDL_SetError("OpenGL ES 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 EGL */
+ if ((dlsym(handle, "eglChooseConfig") == 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 ES/EGL library");
+ return -1;
+ }
+
+ /* Unload the old driver and reset the pointers */
+ X11_GLES_UnloadLibrary(_this);
+
+ /* Load new function pointers */
+ LOAD_FUNC(eglGetDisplay);
+ LOAD_FUNC(eglInitialize);
+ LOAD_FUNC(eglTerminate);
+ LOAD_FUNC(eglGetProcAddress);
+ LOAD_FUNC(eglChooseConfig);
+ LOAD_FUNC(eglGetConfigAttrib);
+ LOAD_FUNC(eglCreateContext);
+ LOAD_FUNC(eglDestroyContext);
+ LOAD_FUNC(eglCreateWindowSurface);
+ LOAD_FUNC(eglDestroySurface);
+ LOAD_FUNC(eglMakeCurrent);
+ LOAD_FUNC(eglSwapBuffers);
+
+ _this->gles_data->egl_display =
+ _this->gles_data->eglGetDisplay((NativeDisplayType) data->display);
+
+ if (!_this->gles_data->egl_display) {
+ SDL_SetError("Could not get EGL display");
+ return -1;
+ }
+
+ if (_this->gles_data->
+ eglInitialize(_this->gles_data->egl_display, NULL,
+ NULL) != EGL_TRUE) {
+ SDL_SetError("Could not initialize EGL");
+ 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;
+}
+
+XVisualInfo *
+X11_GLES_GetVisual(_THIS, Display * display, int screen)
+{
+ /* 64 seems nice. */
+ EGLint attribs[64];
+ EGLint found_configs = 0;
+ 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;
+ }
+ }
+
+ i = 0;
+ attribs[i++] = EGL_RED_SIZE;
+ attribs[i++] = _this->gl_config.red_size;
+ attribs[i++] = EGL_GREEN_SIZE;
+ attribs[i++] = _this->gl_config.green_size;
+ attribs[i++] = EGL_BLUE_SIZE;
+ attribs[i++] = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ attribs[i++] = EGL_ALPHA_SIZE;
+ attribs[i++] = _this->gl_config.alpha_size;
+ }
+
+ if (_this->gl_config.buffer_size) {
+ attribs[i++] = EGL_BUFFER_SIZE;
+ attribs[i++] = _this->gl_config.buffer_size;
+ }
+
+ attribs[i++] = EGL_DEPTH_SIZE;
+ attribs[i++] = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ attribs[i++] = EGL_STENCIL_SIZE;
+ attribs[i++] = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ attribs[i++] = EGL_SAMPLE_BUFFERS;
+ attribs[i++] = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ attribs[i++] = EGL_SAMPLES;
+ attribs[i++] = _this->gl_config.multisamplesamples;
+ }
+
+ attribs[i++] = EGL_NONE;
+
+ if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
+ attribs,
+ &_this->gles_data->egl_config, 1,
+ &found_configs) == EGL_FALSE ||
+ found_configs == 0) {
+ SDL_SetError("Couldn't find matching EGL config");
+ return NULL;
+ }
+
+ if (_this->gles_data->eglGetConfigAttrib(_this->gles_data->egl_display,
+ _this->gles_data->egl_config,
+ EGL_NATIVE_VISUAL_ID,
+ (EGLint *) & visual_id) ==
+ EGL_FALSE || !visual_id) {
+ /* Use the default visual when all else fails */
+ XVisualInfo vi_in;
+ int out_count;
+ vi_in.screen = screen;
+
+ _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
+ VisualScreenMask,
+ &vi_in, &out_count);
+ } else {
+ XVisualInfo vi_in;
+ int out_count;
+
+ vi_in.screen = screen;
+ vi_in.visualid = visual_id;
+ _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
+ VisualScreenMask |
+ VisualIDMask,
+ &vi_in, &out_count);
+ }
+
+ return _this->gles_data->egl_visualinfo;
+}
+
+SDL_GLContext
+X11_GLES_CreateContext(_THIS, SDL_Window * window)
+{
+ int retval;
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ XSync(display, False);
+
+
+ _this->gles_data->egl_context =
+ _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
+ _this->gles_data->egl_config,
+ EGL_NO_CONTEXT, NULL);
+ XSync(display, False);
+
+ if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
+ SDL_SetError("Could not create EGL context");
+ return NULL;
+ }
+
+ _this->gles_data->egl_active = 1;
+
+ if (_this->gles_data->egl_active)
+ retval = 1;
+ else
+ retval = 0;
+
+ return (retval);
+}
+
+int
+X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ int retval;
+
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+ Display *display = data->videodata->display;
+
+ retval = 1;
+ if (!_this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
+ _this->gles_data->egl_surface,
+ _this->gles_data->egl_surface,
+ _this->gles_data->egl_context)) {
+ SDL_SetError("Unable to make EGL context current");
+ retval = -1;
+ }
+ XSync(display, False);
+
+ return (retval);
+}
+
+static int swapinterval = -1;
+int
+X11_GLES_SetSwapInterval(_THIS, int interval)
+{
+ return 0;
+}
+
+int
+X11_GLES_GetSwapInterval(_THIS)
+{
+ return 0;
+}
+
+void
+X11_GLES_SwapWindow(_THIS, SDL_Window * window)
+{
+ _this->gles_data->eglSwapBuffers(_this->gles_data->egl_display,
+ _this->gles_data->egl_surface);
+}
+
+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->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;
+ }
+ }
+ _this->gles_data->egl_active = 0;
+}
+
+#endif /* SDL_VIDEO_OPENGL_ES */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/x11/SDL_x11opengles.h Wed Jun 10 13:54:13 2009 +0000
@@ -0,0 +1,95 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2004 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+
+ Open Pandora SDL driver
+ Copyright (C) 2009 David Carré
+ (cpasjuste@gmail.com)
+*/
+
+#include <GLES/gl.h>
+#include <GLES/egl.h>
+#include <dlfcn.h>
+#if defined(__OpenBSD__) && !defined(__ELF__)
+#define dlsym(x,y) dlsym(x, "_" y)
+#endif
+
+#include "../SDL_sysvideo.h"
+
+typedef struct SDL_PrivateGLESData
+{
+ int egl_active; /* to stop switching drivers while we have a valid context */
+ XVisualInfo *egl_visualinfo;
+ EGLDisplay egl_display;
+ EGLContext egl_context; /* Current GLES context */
+ EGLSurface egl_surface;
+ EGLConfig egl_config;
+
+ EGLDisplay(*eglGetDisplay) (NativeDisplayType display);
+ EGLBoolean(*eglInitialize) (EGLDisplay dpy, EGLint * major,
+ EGLint * minor);
+ EGLBoolean(*eglTerminate) (EGLDisplay dpy);
+
+ void *(*eglGetProcAddress) (const GLubyte * procName);
+
+ EGLBoolean(*eglChooseConfig) (EGLDisplay dpy,
+ const EGLint * attrib_list,
+ EGLConfig * configs,
+ EGLint config_size, EGLint * num_config);
+
+ EGLContext(*eglCreateContext) (EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_list,
+ const EGLint * attrib_list);
+
+ EGLBoolean(*eglDestroyContext) (EGLDisplay dpy, EGLContext ctx);
+
+ EGLSurface(*eglCreateWindowSurface) (EGLDisplay dpy,
+ EGLConfig config,
+ NativeWindowType window,
+ const EGLint * attrib_list);
+ EGLBoolean(*eglDestroySurface) (EGLDisplay dpy, EGLSurface surface);
+
+ EGLBoolean(*eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
+
+ EGLBoolean(*eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw);
+
+ const char *(*eglQueryString) (EGLDisplay dpy, EGLint name);
+
+ EGLBoolean(*eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint * value);
+
+} SDL_PrivateGLESData;
+
+/* OpenGLES functions */
+extern SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window * window);
+extern XVisualInfo *X11_GLES_GetVisual(_THIS, Display * display, int screen);
+extern int X11_GLES_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern int X11_GLES_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
+extern int X11_GLES_LoadLibrary(_THIS, const char *path);
+extern void *X11_GLES_GetProcAddress(_THIS, const char *proc);
+extern void X11_GLES_UnloadLibrary(_THIS);
+
+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);