diff -r 5a924aac594c build-scripts/config.guess --- a/build-scripts/config.guess mar ago 06 18:19:34 2013 -0700 +++ b/build-scripts/config.guess mié ago 07 23:09:51 2013 -0300 @@ -896,12 +896,16 @@ then echo ${UNAME_MACHINE}-unknown-linux-gnu else + case `sed -n '/^Hardware/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + BCM2708) MANUFACTURER=raspberry;; + *) MANUFACTURER=unknown;; + esac if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-${MANUFACTURER}-linux-gnueabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-${MANUFACTURER}-linux-gnueabihf fi fi exit ;; diff -r 5a924aac594c configure --- a/configure mar ago 06 18:19:34 2013 -0700 +++ b/configure mié ago 07 23:09:51 2013 -0300 @@ -22192,6 +22192,21 @@ case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*) case "$host" in + *-raspberry-linux*) + # Raspberry Pi + ARCH=linux + RPI_CFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux" + RPI_LDFLAGS="-L/opt/vc/lib -lbcm_host" + CFLAGS="$CFLAGS $RPI_CFLAGS" + SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" + EXTRA_CFLAGS="$EXTRA_CFLAGS $RPI_CFLAGS" + SDL_LIBS="$SDL_LIBS $RPI_LDFLAGS" + + if test x$enable_video = xyes; then + SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" +$as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h + fi + ;; *-*-linux*) ARCH=linux ;; *-*-uclinux*) ARCH=linux ;; *-*-kfreebsd*-gnu) ARCH=kfreebsd-gnu ;; diff -r 5a924aac594c configure.in --- a/configure.in mar ago 06 18:19:34 2013 -0700 +++ b/configure.in mié ago 07 23:09:51 2013 -0300 @@ -2333,6 +2333,21 @@ case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*) case "$host" in + *-raspberry-linux*) + # Raspberry Pi + ARCH=linux + RPI_CFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux" + RPI_LDFLAGS="-L/opt/vc/lib -lbcm_host" + CFLAGS="$CFLAGS $RPI_CFLAGS" + SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" + EXTRA_CFLAGS="$EXTRA_CFLAGS $RPI_CFLAGS" + SDL_LIBS="$SDL_LIBS $RPI_LDFLAGS" + + if test x$enable_video = xyes; then + SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" +$as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h + fi + ;; *-*-linux*) ARCH=linux ;; *-*-uclinux*) ARCH=linux ;; *-*-kfreebsd*-gnu) ARCH=kfreebsd-gnu ;; diff -r 5a924aac594c include/SDL_config.h.in --- a/include/SDL_config.h.in mar ago 06 18:19:34 2013 -0700 +++ b/include/SDL_config.h.in mié ago 07 23:09:51 2013 -0300 @@ -278,6 +278,7 @@ #undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XDATA32 #undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_OGL diff -r 5a924aac594c src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h mar ago 06 18:19:34 2013 -0700 +++ b/src/video/SDL_sysvideo.h mié ago 07 23:09:51 2013 -0300 @@ -358,6 +358,9 @@ #if SDL_VIDEO_DRIVER_PSP extern VideoBootStrap PSP_bootstrap; #endif +#if SDL_VIDEO_DRIVER_RPI +extern VideoBootStrap RPI_bootstrap; +#endif #if SDL_VIDEO_DRIVER_DUMMY extern VideoBootStrap DUMMY_bootstrap; #endif diff -r 5a924aac594c src/video/SDL_video.c --- a/src/video/SDL_video.c mar ago 06 18:19:34 2013 -0700 +++ b/src/video/SDL_video.c mié ago 07 23:09:51 2013 -0300 @@ -79,6 +79,9 @@ #if SDL_VIDEO_DRIVER_PSP &PSP_bootstrap, #endif +#if SDL_VIDEO_DRIVER_RPI + &RPI_bootstrap, +#endif #if SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, #endif diff -r 5a924aac594c src/video/raspberry/SDL_rpievents.c --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpievents.c mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "SDL_config.h" + +#if SDL_VIDEO_DRIVER_RPI + +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "SDL_rpivideo.h" +#include "SDL_rpievents_c.h" + +void RPI_PumpEvents(_THIS) +{ +} + +void RPI_EventInit(_THIS) +{ +} + +void RPI_EventQuit(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_RPI */ + diff -r 5a924aac594c src/video/raspberry/SDL_rpievents_c.h --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpievents_c.h mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_rpievents_c_h +#define _SDL_rpievents_c_h + +#include "SDL_rpivideo.h" + +void RPI_PumpEvents(_THIS); +void RPI_EventInit(_THIS); +void RPI_EventQuit(_THIS); + +#endif /* _SDL_rpievents_c_h */ \ No newline at end of file diff -r 5a924aac594c src/video/raspberry/SDL_rpiopengles.c --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpiopengles.c mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,424 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +/* This is an almost exact copy of SDL_x11opengles.c (minus the XVisual stuff) */ +/* TODO: Consolidate all EGL code in a single code base that can be shared among X11/PSP/Raspberry/etc */ + +#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_ES + +#include "SDL_rpivideo.h" +#include "SDL_rpiopengles.h" + +#define DEFAULT_EGL "/opt/vc/lib/libEGL.so" +#define DEFAULT_OGL_ES2 "/opt/vc/lib/libGLESv2.so" +//#define DEFAULT_OGL_ES_PVR "/opt/vc/lib/libGLES_CM.so" +#define DEFAULT_OGL_ES "/opt/vc/lib/libGLESv1_CM.so" + +#define LOAD_FUNC(NAME) \ + *((void**)&_this->gles_data->NAME) = dlsym(dll_handle, #NAME); \ + if (!_this->gles_data->NAME) \ + { \ + return SDL_SetError("Could not retrieve EGL function " #NAME); \ + } + +/* GLES implementation of SDL OpenGL support */ + +void * +RPI_GLES_GetProcAddress(_THIS, const char *proc) +{ + static char procname[1024]; + void *handle; + void *retval; + + handle = _this->gles_data->egl_dll_handle; + if (_this->gles_data->eglGetProcAddress) { + retval = _this->gles_data->eglGetProcAddress(proc); + if (retval) { + return retval; + } + } + + handle = _this->gl_config.dll_handle; +#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 +RPI_GLES_UnloadLibrary(_THIS) +{ + 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); + + SDL_free(_this->gles_data); + _this->gles_data = NULL; + + _this->gl_config.dll_handle = NULL; + _this->gl_config.driver_loaded = 0; + } +} + +int +RPI_GLES_LoadLibrary(_THIS, const char *egl_path) +{ + void *dll_handle, *egl_dll_handle; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */ + char *path; + int dlopen_flags; + + if (_this->gles_data) { + return SDL_SetError("OpenGL ES context already created"); + } + + /* Unload the old driver and reset the pointers */ + RPI_GLES_UnloadLibrary(_this); + + /* If SDL_GL_CONTEXT_EGL has been changed to 0, switch over to RPI_GL functions */ +/* if (_this->gl_config.use_egl == 0) { +#if SDL_VIDEO_OPENGL_GLX + _this->GL_LoadLibrary = RPI_GL_LoadLibrary; + _this->GL_GetProcAddress = RPI_GL_GetProcAddress; + _this->GL_UnloadLibrary = RPI_GL_UnloadLibrary; + _this->GL_CreateContext = RPI_GL_CreateContext; + _this->GL_MakeCurrent = RPI_GL_MakeCurrent; + _this->GL_SetSwapInterval = RPI_GL_SetSwapInterval; + _this->GL_GetSwapInterval = RPI_GL_GetSwapInterval; + _this->GL_SwapWindow = RPI_GL_SwapWindow; + _this->GL_DeleteContext = RPI_GL_DeleteContext; + return RPI_GL_LoadLibrary(_this, path); +#else + return SDL_SetError("SDL not configured with OpenGL/GLX support"); +#endif + }*/ + +#ifdef RTLD_GLOBAL + dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; +#else + dlopen_flags = RTLD_LAZY; +#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); + if ((path == NULL) | (egl_dll_handle == NULL)) { + if (_this->gl_config.major_version > 1) { + path = DEFAULT_OGL_ES2; + egl_dll_handle = dlopen(path, dlopen_flags); + } else { + path = DEFAULT_OGL_ES; + egl_dll_handle = dlopen(path, dlopen_flags); + /*if (egl_dll_handle == NULL) { + path = DEFAULT_OGL_ES_PVR; + egl_dll_handle = dlopen(path, dlopen_flags); + }*/ + } + } + + if (egl_dll_handle == NULL) { + return SDL_SetError("Could not initialize OpenGL ES library: %s", dlerror()); + } + + + + /* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */ + dll_handle = dlopen(egl_path, dlopen_flags); + /* Catch the case where the application isn't linked with EGL */ + if ((dlsym(dll_handle, "eglChooseConfig") == NULL) && (egl_path == NULL)) { + + dlclose(dll_handle); + path = getenv("SDL_VIDEO_EGL_DRIVER"); + if (path == NULL) { + path = DEFAULT_EGL; + } + dll_handle = dlopen(path, dlopen_flags); + } + + if (dll_handle == NULL) { + return SDL_SetError("Could not load EGL library: %s", dlerror()); + } + + + _this->gles_data = (struct SDL_PrivateGLESData *) SDL_calloc(1, sizeof(SDL_PrivateGLESData)); + if (!_this->gles_data) { + return SDL_OutOfMemory(); + } + + /* 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); + LOAD_FUNC(eglSwapInterval); + + _this->gles_data->egl_display = _this->gles_data->eglGetDisplay(EGL_DEFAULT_DISPLAY); + + if (!_this->gles_data->egl_display) { + return SDL_SetError("Could not get EGL display"); + } + + if (_this->gles_data-> + eglInitialize(_this->gles_data->egl_display, NULL, + NULL) != EGL_TRUE) { + return SDL_SetError("Could not initialize EGL"); + } + + _this->gl_config.dll_handle = dll_handle; + _this->gles_data->egl_dll_handle = egl_dll_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; +} + +SDL_GLContext +RPI_GLES_CreateContext(_THIS, SDL_Window * window) +{ + EGLint context_attrib_list[] = { + EGL_CONTEXT_CLIENT_VERSION, + 1, + EGL_NONE + }; + + + /* 64 seems nice. */ + EGLint attribs[64]; + EGLint found_configs = 0; + int i; + SDL_WindowData *wdata; + + if (!_this->gles_data && RPI_GLES_LoadLibrary(_this, NULL) != 0) { + SDL_SetError("Could not load EGL or GLES libraries"); + 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_RENDERABLE_TYPE; + if (_this->gl_config.major_version == 2) { + attribs[i++] = EGL_OPENGL_ES2_BIT; + } else { + attribs[i++] = EGL_OPENGL_ES_BIT; + } + + 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; + } + + /*_this->gles_data->eglGetConfigAttrib(display, config, EGL_WIDTH, &width); + _this->gles_data->eglGetConfigAttrib(display, config, EGL_HEIGHT, &height);*/ + + SDL_GLContext context = (SDL_GLContext)1; + + if (_this->gl_config.major_version) { + context_attrib_list[1] = _this->gl_config.major_version; + } + + _this->gles_data->egl_context = + _this->gles_data->eglCreateContext(_this->gles_data->egl_display, + _this->gles_data->egl_config, + EGL_NO_CONTEXT, context_attrib_list); + + if (_this->gles_data->egl_context == EGL_NO_CONTEXT) { + SDL_SetError("Could not create EGL context"); + return NULL; + } + + _this->gles_data->egl_swapinterval = 0; + + /* Create the GLES window surface */ + wdata = (SDL_WindowData *) window->driverdata; + _this->gles_data->egl_surface = _this->gles_data->eglCreateWindowSurface(_this->gles_data->egl_display, _this->gles_data->egl_config, (NativeWindowType) &wdata->dispman_window, NULL); + + if (_this->gles_data->egl_surface == EGL_NO_SURFACE) { + SDL_SetError("Could not create GLES window surface"); + return NULL; + } + + if (RPI_GLES_MakeCurrent(_this, window, context) < 0) { + RPI_GLES_DeleteContext(_this, context); + return NULL; + } + + return context; +} + +int +RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ +/* + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; +*/ + + if (!_this->gles_data) { + return SDL_SetError("OpenGL not initialized"); + } + + 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)) { + return SDL_SetError("Unable to make EGL context current"); + } + +/* + XSync(display, False); +*/ + + return 1; +} + +int +RPI_GLES_SetSwapInterval(_THIS, int interval) +{ + if (_this->gles_data) { + return SDL_SetError("OpenGL ES context not active"); + } + + EGLBoolean status; + status = _this->gles_data->eglSwapInterval(_this->gles_data->egl_display, interval); + if (status == EGL_TRUE) { + _this->gles_data->egl_swapinterval = interval; + return 0; + } + + return SDL_SetError("Unable to set the EGL swap interval"); +} + +int +RPI_GLES_GetSwapInterval(_THIS) +{ + if (_this->gles_data) { + return SDL_SetError("OpenGL ES context not active"); + } + + return _this->gles_data->egl_swapinterval; +} + +void +RPI_GLES_SwapWindow(_THIS, SDL_Window * window) +{ + _this->gles_data->eglSwapBuffers(_this->gles_data->egl_display, + _this->gles_data->egl_surface); +} + +void +RPI_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ + /* Clean up GLES and EGL */ + if (!_this->gles_data) { + return; + } + + 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; + } + } + + /* crappy fix */ + RPI_GLES_UnloadLibrary(_this); +} + +#endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_ES */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 5a924aac594c src/video/raspberry/SDL_rpiopengles.h --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpiopengles.h mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,106 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +/* This is an almost exact copy of SDL_x11opengles.h (minus the XVisual stuff) */ +/* TODO: Consolidate all EGL code in a single code base that can be shared among X11/PSP/Raspberry/etc */ + +#ifndef _SDL_rpiopengles_h +#define _SDL_rpiopengles_h + +#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#include +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include +#if defined(__OpenBSD__) && !defined(__ELF__) +#define dlsym(x,y) dlsym(x, "_" y) +#endif + +#include "../SDL_sysvideo.h" + +typedef struct SDL_PrivateGLESData +{ + void *egl_dll_handle; + EGLDisplay egl_display; + EGLContext egl_context; /* Current GLES context */ + EGLSurface egl_surface; + EGLConfig egl_config; + int egl_swapinterval; + + EGLDisplay(*eglGetDisplay) (NativeDisplayType display); + EGLBoolean(*eglInitialize) (EGLDisplay dpy, EGLint * major, + EGLint * minor); + EGLBoolean(*eglTerminate) (EGLDisplay dpy); + + void *(*eglGetProcAddress) (const char * 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); + + EGLBoolean(*eglSwapInterval) (EGLDisplay dpy, EGLint interval); + + const char *(*eglQueryString) (EGLDisplay dpy, EGLint name); + + EGLBoolean(*eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint * value); + +} SDL_PrivateGLESData; + +/* OpenGLES functions */ +extern SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window); +extern int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, + SDL_GLContext context); +extern int RPI_GLES_GetAttribute(_THIS, SDL_GLattr attrib, int *value); +extern int RPI_GLES_LoadLibrary(_THIS, const char *path); +extern void *RPI_GLES_GetProcAddress(_THIS, const char *proc); +extern void RPI_GLES_UnloadLibrary(_THIS); + +extern int RPI_GLES_SetSwapInterval(_THIS, int interval); +extern int RPI_GLES_GetSwapInterval(_THIS); +extern void RPI_GLES_SwapWindow(_THIS, SDL_Window * window); +extern void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context); + +#endif /* SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 */ + +#endif /* _SDL_rpiopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 5a924aac594c src/video/raspberry/SDL_rpivideo.c --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpivideo.c mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,325 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#if SDL_VIDEO_DRIVER_RPI + +/* References + * http://elinux.org/RPi_VideoCore_APIs + * https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c + */ + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_loadso.h" +#include "SDL_events.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" + +/* RPI declarations */ +#include "SDL_rpivideo.h" +#include "SDL_rpievents_c.h" +#include "SDL_rpiopengles.h" + +static int +RPI_Available(void) +{ + return 1; +} + +static void +RPI_Destroy(SDL_VideoDevice * device) +{ +/* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ + + if (device->driverdata != NULL) { + device->driverdata = NULL; + } +} + +static SDL_VideoDevice * +RPI_Create() +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + /* Initialize SDL_VideoDevice structure */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize internal data */ + phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + if (phdata == NULL) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = phdata; + + /* Setup amount of available displays and current display */ + device->num_displays = 0; + + /* Set device free function */ + device->free = RPI_Destroy; + + /* Setup all functions which we can handle */ + device->VideoInit = RPI_VideoInit; + device->VideoQuit = RPI_VideoQuit; + device->GetDisplayModes = RPI_GetDisplayModes; + device->SetDisplayMode = RPI_SetDisplayMode; + device->CreateWindow = RPI_CreateWindow; + device->CreateWindowFrom = RPI_CreateWindowFrom; + device->SetWindowTitle = RPI_SetWindowTitle; + device->SetWindowIcon = RPI_SetWindowIcon; + device->SetWindowPosition = RPI_SetWindowPosition; + device->SetWindowSize = RPI_SetWindowSize; + device->ShowWindow = RPI_ShowWindow; + device->HideWindow = RPI_HideWindow; + device->RaiseWindow = RPI_RaiseWindow; + device->MaximizeWindow = RPI_MaximizeWindow; + device->MinimizeWindow = RPI_MinimizeWindow; + device->RestoreWindow = RPI_RestoreWindow; + device->SetWindowGrab = RPI_SetWindowGrab; + device->DestroyWindow = RPI_DestroyWindow; + device->GetWindowWMInfo = RPI_GetWindowWMInfo; + device->GL_LoadLibrary = RPI_GLES_LoadLibrary; + device->GL_GetProcAddress = RPI_GLES_GetProcAddress; + device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary; + device->GL_CreateContext = RPI_GLES_CreateContext; + device->GL_MakeCurrent = RPI_GLES_MakeCurrent; + device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval; + device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval; + device->GL_SwapWindow = RPI_GLES_SwapWindow; + device->GL_DeleteContext = RPI_GLES_DeleteContext; + + device->PumpEvents = RPI_PumpEvents; + + return device; +} + +VideoBootStrap RPI_bootstrap = { + "RPI", + "RPI Video Driver", + RPI_Available, + RPI_Create +}; + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/*****************************************************************************/ +int +RPI_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + uint32_t w,h; + + /* Initialize BCM Host */ + bcm_host_init(); + + SDL_zero(current_mode); + + if (graphics_get_display_size( 0, &w, &h) < 0) { + return -1; + } + + printf("Graphics Display size: %dx%d\n", w, h); + + current_mode.w = w; + current_mode.h = h; + /* FIXME: Is there a way to tell the actual refresh rate? */ + current_mode.refresh_rate = 60; + /* 32 bpp for default */ + current_mode.format = SDL_PIXELFORMAT_ABGR8888; + + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + + SDL_DisplayData *data; + + /* Allocate display internal data */ + data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); + if (data == NULL) { + return SDL_OutOfMemory(); + } + + data->dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + data->dispman_update = vc_dispmanx_update_start( 0 ); + + display.driverdata = data; + + SDL_AddVideoDisplay(&display); + + return 1; +} + +void +RPI_VideoQuit(_THIS) +{ +} + +void +RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +{ + +} + +int +RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +int +RPI_CreateWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wdata; + SDL_VideoDisplay *display; + SDL_DisplayData *displaydata; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + + /* Allocate window internal data */ + wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); + if (wdata == NULL) { + return SDL_OutOfMemory(); + } + display = SDL_GetDisplayForWindow(window); + displaydata = (SDL_DisplayData *) display->driverdata; + + /* Windows have one size for now */ + window->w = display->desktop_mode.w; + window->h = display->desktop_mode.h; + + /* OpenGL ES is the law here, buddy */ + window->flags |= SDL_WINDOW_OPENGL; + + /* Create a dispman element and associate a window to it */ + dst_rect.x = 0; + dst_rect.y = 0; + dst_rect.width = window->w; + dst_rect.height = window->h; + + printf("Window size: %dx%d\n", window->w, window->h); + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = window->w << 16; + src_rect.height = window->h << 16; + + wdata->dispman_window.element = vc_dispmanx_element_add ( displaydata->dispman_update, displaydata->dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); + wdata->dispman_window.width = window->w; + wdata->dispman_window.height = window->h; + vc_dispmanx_update_submit_sync( displaydata->dispman_update ); + + /* Setup driver data for this window */ + window->driverdata = wdata; + + /* Window has been successfully created */ + return 0; +} + +int +RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + return -1; +} + +void +RPI_SetWindowTitle(_THIS, SDL_Window * window) +{ +} +void +RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +{ +} +void +RPI_SetWindowPosition(_THIS, SDL_Window * window) +{ +} +void +RPI_SetWindowSize(_THIS, SDL_Window * window) +{ +} +void +RPI_ShowWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_HideWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_RaiseWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_MaximizeWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_MinimizeWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_RestoreWindow(_THIS, SDL_Window * window) +{ +} +void +RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + +} +void +RPI_DestroyWindow(_THIS, SDL_Window * window) +{ +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool +RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major <= SDL_MAJOR_VERSION) { + return SDL_TRUE; + } else { + SDL_SetError("application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } + + /* Failed to get window manager information */ + return SDL_FALSE; +} + +#endif /* SDL_VIDEO_DRIVER_RPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 5a924aac594c src/video/raspberry/SDL_rpivideo.h --- /dev/null jue ene 01 00:00:00 1970 +0000 +++ b/src/video/raspberry/SDL_rpivideo.h mié ago 07 23:09:51 2013 -0300 @@ -0,0 +1,95 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __SDL_RPIVIDEO_H__ +#define __SDL_RPIVIDEO_H__ + +#include "SDL_config.h" +#include "../SDL_sysvideo.h" + +#include "bcm_host.h" +#include "GLES/gl.h" +#include "EGL/egl.h" +#include "EGL/eglext.h" + +typedef struct SDL_VideoData +{ + uint32_t egl_refcount; /* OpenGL ES reference count */ +} SDL_VideoData; + + +typedef struct SDL_DisplayData +{ + DISPMANX_DISPLAY_HANDLE_T dispman_display; + DISPMANX_UPDATE_HANDLE_T dispman_update; +} SDL_DisplayData; + + +typedef struct SDL_WindowData +{ + EGL_DISPMANX_WINDOW_T dispman_window; +} SDL_WindowData; + + + + +/****************************************************************************/ +/* SDL_VideoDevice functions declaration */ +/****************************************************************************/ + +/* Display and window functions */ +int RPI_VideoInit(_THIS); +void RPI_VideoQuit(_THIS); +void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +int RPI_CreateWindow(_THIS, SDL_Window * window); +int RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +void RPI_SetWindowTitle(_THIS, SDL_Window * window); +void RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); +void RPI_SetWindowPosition(_THIS, SDL_Window * window); +void RPI_SetWindowSize(_THIS, SDL_Window * window); +void RPI_ShowWindow(_THIS, SDL_Window * window); +void RPI_HideWindow(_THIS, SDL_Window * window); +void RPI_RaiseWindow(_THIS, SDL_Window * window); +void RPI_MaximizeWindow(_THIS, SDL_Window * window); +void RPI_MinimizeWindow(_THIS, SDL_Window * window); +void RPI_RestoreWindow(_THIS, SDL_Window * window); +void RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +void RPI_DestroyWindow(_THIS, SDL_Window * window); + +/* Window manager function */ +SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +/* OpenGL/OpenGL ES functions */ +int RPI_GLES_LoadLibrary(_THIS, const char *path); +void *RPI_GLES_GetProcAddress(_THIS, const char *proc); +void RPI_GLES_UnloadLibrary(_THIS); +SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window); +int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +int RPI_GLES_SetSwapInterval(_THIS, int interval); +int RPI_GLES_GetSwapInterval(_THIS); +void RPI_GLES_SwapWindow(_THIS, SDL_Window * window); +void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context); + +#endif /* __SDL_RPIVIDEO_H__ */ + +/* vi: set ts=4 sw=4 expandtab: */