Added missing files for OpenGL ES support
authorSam Lantinga <slouken@libsdl.org>
Wed, 10 Jun 2009 13:54:13 +0000
changeset 3190c68d2ca5970f
parent 3189 ba1e64340565
child 3191 91b335df6fc8
Added missing files for OpenGL ES support
src/video/x11/SDL_x11opengles.c
src/video/x11/SDL_x11opengles.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/x11/SDL_x11opengles.c	Wed Jun 10 13:54:13 2009 +0000
     1.3 @@ -0,0 +1,366 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997-2009 Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Lesser General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2.1 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Lesser General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Lesser General Public
    1.19 +    License along with _this library; if not, write to the Free Software
    1.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@libsdl.org
    1.24 +
    1.25 +    Open Pandora SDL driver
    1.26 +    Copyright (C) 2009 David Carré
    1.27 +    (cpasjuste@gmail.com)
    1.28 +*/
    1.29 +#include "SDL_config.h"
    1.30 +
    1.31 +#if SDL_VIDEO_OPENGL_ES
    1.32 +
    1.33 +#include "SDL_x11video.h"
    1.34 +#include "SDL_x11opengles.h"
    1.35 +
    1.36 +#define DEFAULT_OPENGL	"/usr/lib/libGLES_CM.so"
    1.37 +
    1.38 +#define LOAD_FUNC(NAME) \
    1.39 +	*((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
    1.40 +	if (!_this->gles_data->NAME) \
    1.41 +	{ \
    1.42 +		SDL_SetError("Could not retrieve EGL function " #NAME); \
    1.43 +		return -1; \
    1.44 +	}
    1.45 +
    1.46 +/* GLES implementation of SDL OpenGL support */
    1.47 +
    1.48 +void *
    1.49 +X11_GLES_GetProcAddress(_THIS, const char *proc)
    1.50 +{
    1.51 +    static char procname[1024];
    1.52 +    void *handle;
    1.53 +    void *retval;
    1.54 +
    1.55 +    handle = _this->gl_config.dll_handle;
    1.56 +    if (_this->gles_data->eglGetProcAddress) {
    1.57 +        retval = _this->gles_data->eglGetProcAddress(proc);
    1.58 +        if (retval) {
    1.59 +            return retval;
    1.60 +        }
    1.61 +    }
    1.62 +#if defined(__OpenBSD__) && !defined(__ELF__)
    1.63 +#undef dlsym(x,y);
    1.64 +#endif
    1.65 +    retval = dlsym(handle, proc);
    1.66 +    if (!retval && strlen(proc) <= 1022) {
    1.67 +        procname[0] = '_';
    1.68 +        strcpy(procname + 1, proc);
    1.69 +        retval = dlsym(handle, procname);
    1.70 +    }
    1.71 +    return retval;
    1.72 +}
    1.73 +
    1.74 +void
    1.75 +X11_GLES_UnloadLibrary(_THIS)
    1.76 +{
    1.77 +    if (_this->gl_config.driver_loaded) {
    1.78 +        _this->gles_data->eglTerminate(_this->gles_data->egl_display);
    1.79 +
    1.80 +        dlclose(_this->gl_config.dll_handle);
    1.81 +
    1.82 +        _this->gles_data->eglGetProcAddress = NULL;
    1.83 +        _this->gles_data->eglChooseConfig = NULL;
    1.84 +        _this->gles_data->eglCreateContext = NULL;
    1.85 +        _this->gles_data->eglCreateWindowSurface = NULL;
    1.86 +        _this->gles_data->eglDestroyContext = NULL;
    1.87 +        _this->gles_data->eglDestroySurface = NULL;
    1.88 +        _this->gles_data->eglMakeCurrent = NULL;
    1.89 +        _this->gles_data->eglSwapBuffers = NULL;
    1.90 +        _this->gles_data->eglGetDisplay = NULL;
    1.91 +        _this->gles_data->eglTerminate = NULL;
    1.92 +
    1.93 +        _this->gl_config.dll_handle = NULL;
    1.94 +        _this->gl_config.driver_loaded = 0;
    1.95 +    }
    1.96 +}
    1.97 +
    1.98 +int
    1.99 +X11_GLES_LoadLibrary(_THIS, const char *path)
   1.100 +{
   1.101 +    void *handle;
   1.102 +    int dlopen_flags;
   1.103 +
   1.104 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   1.105 +
   1.106 +    if (_this->gles_data->egl_active) {
   1.107 +        SDL_SetError("OpenGL ES context already created");
   1.108 +        return -1;
   1.109 +    }
   1.110 +#ifdef RTLD_GLOBAL
   1.111 +    dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
   1.112 +#else
   1.113 +    dlopen_flags = RTLD_LAZY;
   1.114 +#endif
   1.115 +    handle = dlopen(path, dlopen_flags);
   1.116 +    /* Catch the case where the application isn't linked with EGL */
   1.117 +    if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) {
   1.118 +
   1.119 +        dlclose(handle);
   1.120 +        path = getenv("SDL_VIDEO_GL_DRIVER");
   1.121 +        if (path == NULL) {
   1.122 +            path = DEFAULT_OPENGL;
   1.123 +        }
   1.124 +        handle = dlopen(path, dlopen_flags);
   1.125 +    }
   1.126 +
   1.127 +    if (handle == NULL) {
   1.128 +        SDL_SetError("Could not load OpenGL ES/EGL library");
   1.129 +        return -1;
   1.130 +    }
   1.131 +
   1.132 +    /* Unload the old driver and reset the pointers */
   1.133 +    X11_GLES_UnloadLibrary(_this);
   1.134 +
   1.135 +    /* Load new function pointers */
   1.136 +    LOAD_FUNC(eglGetDisplay);
   1.137 +    LOAD_FUNC(eglInitialize);
   1.138 +    LOAD_FUNC(eglTerminate);
   1.139 +    LOAD_FUNC(eglGetProcAddress);
   1.140 +    LOAD_FUNC(eglChooseConfig);
   1.141 +    LOAD_FUNC(eglGetConfigAttrib);
   1.142 +    LOAD_FUNC(eglCreateContext);
   1.143 +    LOAD_FUNC(eglDestroyContext);
   1.144 +    LOAD_FUNC(eglCreateWindowSurface);
   1.145 +    LOAD_FUNC(eglDestroySurface);
   1.146 +    LOAD_FUNC(eglMakeCurrent);
   1.147 +    LOAD_FUNC(eglSwapBuffers);
   1.148 +
   1.149 +    _this->gles_data->egl_display =
   1.150 +        _this->gles_data->eglGetDisplay((NativeDisplayType) data->display);
   1.151 +
   1.152 +    if (!_this->gles_data->egl_display) {
   1.153 +        SDL_SetError("Could not get EGL display");
   1.154 +        return -1;
   1.155 +    }
   1.156 +
   1.157 +    if (_this->gles_data->
   1.158 +        eglInitialize(_this->gles_data->egl_display, NULL,
   1.159 +                      NULL) != EGL_TRUE) {
   1.160 +        SDL_SetError("Could not initialize EGL");
   1.161 +        return -1;
   1.162 +    }
   1.163 +
   1.164 +    _this->gl_config.dll_handle = handle;
   1.165 +    _this->gl_config.driver_loaded = 1;
   1.166 +
   1.167 +    if (path) {
   1.168 +        strncpy(_this->gl_config.driver_path, path,
   1.169 +                sizeof(_this->gl_config.driver_path) - 1);
   1.170 +    } else {
   1.171 +        strcpy(_this->gl_config.driver_path, "");
   1.172 +    }
   1.173 +    return 0;
   1.174 +}
   1.175 +
   1.176 +XVisualInfo *
   1.177 +X11_GLES_GetVisual(_THIS, Display * display, int screen)
   1.178 +{
   1.179 +    /* 64 seems nice. */
   1.180 +    EGLint attribs[64];
   1.181 +    EGLint found_configs = 0;
   1.182 +    VisualID visual_id;
   1.183 +    int i;
   1.184 +
   1.185 +    /* load the gl driver from a default path */
   1.186 +    if (!_this->gl_config.driver_loaded) {
   1.187 +        /* no driver has been loaded, use default (ourselves) */
   1.188 +        if (X11_GLES_LoadLibrary(_this, NULL) < 0) {
   1.189 +            return NULL;
   1.190 +        }
   1.191 +    }
   1.192 +
   1.193 +    i = 0;
   1.194 +    attribs[i++] = EGL_RED_SIZE;
   1.195 +    attribs[i++] = _this->gl_config.red_size;
   1.196 +    attribs[i++] = EGL_GREEN_SIZE;
   1.197 +    attribs[i++] = _this->gl_config.green_size;
   1.198 +    attribs[i++] = EGL_BLUE_SIZE;
   1.199 +    attribs[i++] = _this->gl_config.blue_size;
   1.200 +
   1.201 +    if (_this->gl_config.alpha_size) {
   1.202 +        attribs[i++] = EGL_ALPHA_SIZE;
   1.203 +        attribs[i++] = _this->gl_config.alpha_size;
   1.204 +    }
   1.205 +
   1.206 +    if (_this->gl_config.buffer_size) {
   1.207 +        attribs[i++] = EGL_BUFFER_SIZE;
   1.208 +        attribs[i++] = _this->gl_config.buffer_size;
   1.209 +    }
   1.210 +
   1.211 +    attribs[i++] = EGL_DEPTH_SIZE;
   1.212 +    attribs[i++] = _this->gl_config.depth_size;
   1.213 +
   1.214 +    if (_this->gl_config.stencil_size) {
   1.215 +        attribs[i++] = EGL_STENCIL_SIZE;
   1.216 +        attribs[i++] = _this->gl_config.stencil_size;
   1.217 +    }
   1.218 +
   1.219 +    if (_this->gl_config.multisamplebuffers) {
   1.220 +        attribs[i++] = EGL_SAMPLE_BUFFERS;
   1.221 +        attribs[i++] = _this->gl_config.multisamplebuffers;
   1.222 +    }
   1.223 +
   1.224 +    if (_this->gl_config.multisamplesamples) {
   1.225 +        attribs[i++] = EGL_SAMPLES;
   1.226 +        attribs[i++] = _this->gl_config.multisamplesamples;
   1.227 +    }
   1.228 +
   1.229 +    attribs[i++] = EGL_NONE;
   1.230 +
   1.231 +    if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
   1.232 +                                          attribs,
   1.233 +                                          &_this->gles_data->egl_config, 1,
   1.234 +                                          &found_configs) == EGL_FALSE ||
   1.235 +        found_configs == 0) {
   1.236 +        SDL_SetError("Couldn't find matching EGL config");
   1.237 +        return NULL;
   1.238 +    }
   1.239 +
   1.240 +    if (_this->gles_data->eglGetConfigAttrib(_this->gles_data->egl_display,
   1.241 +                                             _this->gles_data->egl_config,
   1.242 +                                             EGL_NATIVE_VISUAL_ID,
   1.243 +                                             (EGLint *) & visual_id) ==
   1.244 +        EGL_FALSE || !visual_id) {
   1.245 +        /* Use the default visual when all else fails */
   1.246 +        XVisualInfo vi_in;
   1.247 +        int out_count;
   1.248 +        vi_in.screen = screen;
   1.249 +
   1.250 +        _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
   1.251 +                                                          VisualScreenMask,
   1.252 +                                                          &vi_in, &out_count);
   1.253 +    } else {
   1.254 +        XVisualInfo vi_in;
   1.255 +        int out_count;
   1.256 +
   1.257 +        vi_in.screen = screen;
   1.258 +        vi_in.visualid = visual_id;
   1.259 +        _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
   1.260 +                                                          VisualScreenMask |
   1.261 +                                                          VisualIDMask,
   1.262 +                                                          &vi_in, &out_count);
   1.263 +    }
   1.264 +
   1.265 +    return _this->gles_data->egl_visualinfo;
   1.266 +}
   1.267 +
   1.268 +SDL_GLContext
   1.269 +X11_GLES_CreateContext(_THIS, SDL_Window * window)
   1.270 +{
   1.271 +    int retval;
   1.272 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   1.273 +    Display *display = data->videodata->display;
   1.274 +
   1.275 +    XSync(display, False);
   1.276 +
   1.277 +
   1.278 +    _this->gles_data->egl_context =
   1.279 +        _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
   1.280 +                                           _this->gles_data->egl_config,
   1.281 +                                           EGL_NO_CONTEXT, NULL);
   1.282 +    XSync(display, False);
   1.283 +
   1.284 +    if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
   1.285 +        SDL_SetError("Could not create EGL context");
   1.286 +        return NULL;
   1.287 +    }
   1.288 +
   1.289 +    _this->gles_data->egl_active = 1;
   1.290 +
   1.291 +    if (_this->gles_data->egl_active)
   1.292 +        retval = 1;
   1.293 +    else
   1.294 +        retval = 0;
   1.295 +
   1.296 +    return (retval);
   1.297 +}
   1.298 +
   1.299 +int
   1.300 +X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   1.301 +{
   1.302 +    int retval;
   1.303 +
   1.304 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   1.305 +    Display *display = data->videodata->display;
   1.306 +
   1.307 +    retval = 1;
   1.308 +    if (!_this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
   1.309 +                                          _this->gles_data->egl_surface,
   1.310 +                                          _this->gles_data->egl_surface,
   1.311 +                                          _this->gles_data->egl_context)) {
   1.312 +        SDL_SetError("Unable to make EGL context current");
   1.313 +        retval = -1;
   1.314 +    }
   1.315 +    XSync(display, False);
   1.316 +
   1.317 +    return (retval);
   1.318 +}
   1.319 +
   1.320 +static int swapinterval = -1;
   1.321 +int
   1.322 +X11_GLES_SetSwapInterval(_THIS, int interval)
   1.323 +{
   1.324 +    return 0;
   1.325 +}
   1.326 +
   1.327 +int
   1.328 +X11_GLES_GetSwapInterval(_THIS)
   1.329 +{
   1.330 +    return 0;
   1.331 +}
   1.332 +
   1.333 +void
   1.334 +X11_GLES_SwapWindow(_THIS, SDL_Window * window)
   1.335 +{
   1.336 +    _this->gles_data->eglSwapBuffers(_this->gles_data->egl_display,
   1.337 +                                     _this->gles_data->egl_surface);
   1.338 +}
   1.339 +
   1.340 +void
   1.341 +X11_GLES_DeleteContext(_THIS, SDL_GLContext context)
   1.342 +{
   1.343 +    /* Clean up GLES and EGL */
   1.344 +    if (_this->gles_data->egl_context != EGL_NO_CONTEXT ||
   1.345 +        _this->gles_data->egl_surface != EGL_NO_SURFACE) {
   1.346 +        _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
   1.347 +                                         EGL_NO_SURFACE, EGL_NO_SURFACE,
   1.348 +                                         EGL_NO_CONTEXT);
   1.349 +
   1.350 +        if (_this->gles_data->egl_context != EGL_NO_CONTEXT) {
   1.351 +            _this->gles_data->eglDestroyContext(_this->gles_data->egl_display,
   1.352 +                                                _this->gles_data->
   1.353 +                                                egl_context);
   1.354 +            _this->gles_data->egl_context = EGL_NO_CONTEXT;
   1.355 +        }
   1.356 +
   1.357 +        if (_this->gles_data->egl_surface != EGL_NO_SURFACE) {
   1.358 +            _this->gles_data->eglDestroySurface(_this->gles_data->egl_display,
   1.359 +                                                _this->gles_data->
   1.360 +                                                egl_surface);
   1.361 +            _this->gles_data->egl_surface = EGL_NO_SURFACE;
   1.362 +        }
   1.363 +    }
   1.364 +    _this->gles_data->egl_active = 0;
   1.365 +}
   1.366 +
   1.367 +#endif /* SDL_VIDEO_OPENGL_ES */
   1.368 +
   1.369 +/* vi: set ts=4 sw=4 expandtab: */
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/video/x11/SDL_x11opengles.h	Wed Jun 10 13:54:13 2009 +0000
     2.3 @@ -0,0 +1,95 @@
     2.4 +/*
     2.5 +    SDL - Simple DirectMedia Layer
     2.6 +    Copyright (C) 1997-2004 Sam Lantinga
     2.7 +
     2.8 +    This library is free software; you can redistribute it and/or
     2.9 +    modify it under the terms of the GNU Library General Public
    2.10 +    License as published by the Free Software Foundation; either
    2.11 +    version 2 of the License, or (at your option) any later version.
    2.12 +
    2.13 +    This library is distributed in the hope that it will be useful,
    2.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    2.16 +    Library General Public License for more details.
    2.17 +
    2.18 +    You should have received a copy of the GNU Library General Public
    2.19 +    License along with this library; if not, write to the Free
    2.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.21 +
    2.22 +    Sam Lantinga
    2.23 +    slouken@libsdl.org
    2.24 +
    2.25 +    Open Pandora SDL driver
    2.26 +    Copyright (C) 2009 David Carré
    2.27 +    (cpasjuste@gmail.com)
    2.28 +*/
    2.29 +
    2.30 +#include <GLES/gl.h>
    2.31 +#include <GLES/egl.h>
    2.32 +#include <dlfcn.h>
    2.33 +#if defined(__OpenBSD__) && !defined(__ELF__)
    2.34 +#define dlsym(x,y) dlsym(x, "_" y)
    2.35 +#endif
    2.36 +
    2.37 +#include "../SDL_sysvideo.h"
    2.38 +
    2.39 +typedef struct SDL_PrivateGLESData
    2.40 +{
    2.41 +    int egl_active;             /* to stop switching drivers while we have a valid context */
    2.42 +    XVisualInfo *egl_visualinfo;
    2.43 +    EGLDisplay egl_display;
    2.44 +    EGLContext egl_context;     /* Current GLES context */
    2.45 +    EGLSurface egl_surface;
    2.46 +    EGLConfig egl_config;
    2.47 +
    2.48 +      EGLDisplay(*eglGetDisplay) (NativeDisplayType display);
    2.49 +      EGLBoolean(*eglInitialize) (EGLDisplay dpy, EGLint * major,
    2.50 +                                  EGLint * minor);
    2.51 +      EGLBoolean(*eglTerminate) (EGLDisplay dpy);
    2.52 +
    2.53 +    void *(*eglGetProcAddress) (const GLubyte * procName);
    2.54 +
    2.55 +      EGLBoolean(*eglChooseConfig) (EGLDisplay dpy,
    2.56 +                                    const EGLint * attrib_list,
    2.57 +                                    EGLConfig * configs,
    2.58 +                                    EGLint config_size, EGLint * num_config);
    2.59 +
    2.60 +      EGLContext(*eglCreateContext) (EGLDisplay dpy,
    2.61 +                                     EGLConfig config,
    2.62 +                                     EGLContext share_list,
    2.63 +                                     const EGLint * attrib_list);
    2.64 +
    2.65 +      EGLBoolean(*eglDestroyContext) (EGLDisplay dpy, EGLContext ctx);
    2.66 +
    2.67 +      EGLSurface(*eglCreateWindowSurface) (EGLDisplay dpy,
    2.68 +                                           EGLConfig config,
    2.69 +                                           NativeWindowType window,
    2.70 +                                           const EGLint * attrib_list);
    2.71 +      EGLBoolean(*eglDestroySurface) (EGLDisplay dpy, EGLSurface surface);
    2.72 +
    2.73 +      EGLBoolean(*eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw,
    2.74 +                                   EGLSurface read, EGLContext ctx);
    2.75 +
    2.76 +      EGLBoolean(*eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw);
    2.77 +
    2.78 +    const char *(*eglQueryString) (EGLDisplay dpy, EGLint name);
    2.79 +
    2.80 +      EGLBoolean(*eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config,
    2.81 +                                       EGLint attribute, EGLint * value);
    2.82 +
    2.83 +} SDL_PrivateGLESData;
    2.84 +
    2.85 +/* OpenGLES functions */
    2.86 +extern SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window * window);
    2.87 +extern XVisualInfo *X11_GLES_GetVisual(_THIS, Display * display, int screen);
    2.88 +extern int X11_GLES_MakeCurrent(_THIS, SDL_Window * window,
    2.89 +                                SDL_GLContext context);
    2.90 +extern int X11_GLES_GetAttribute(_THIS, SDL_GLattr attrib, int *value);
    2.91 +extern int X11_GLES_LoadLibrary(_THIS, const char *path);
    2.92 +extern void *X11_GLES_GetProcAddress(_THIS, const char *proc);
    2.93 +extern void X11_GLES_UnloadLibrary(_THIS);
    2.94 +
    2.95 +extern int X11_GLES_SetSwapInterval(_THIS, int interval);
    2.96 +extern int X11_GLES_GetSwapInterval(_THIS);
    2.97 +extern void X11_GLES_SwapWindow(_THIS, SDL_Window * window);
    2.98 +extern void X11_GLES_DeleteContext(_THIS, SDL_GLContext context);