1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/video/directfb/SDL_DirectFB_opengl.c Sun Aug 31 16:04:32 2008 +0000
1.3 @@ -0,0 +1,299 @@
1.4 +/*
1.5 + SDL - Simple DirectMedia Layer
1.6 + Copyright (C) 1997-2006 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 +#include "SDL_config.h"
1.26 +
1.27 +#include "SDL_DirectFB_video.h"
1.28 +
1.29 +#if SDL_DIRECTFB_OPENGL
1.30 +
1.31 +struct SDL_GLDriverData
1.32 +{
1.33 + int gl_active; /* to stop switching drivers while we have a valid context */
1.34 + int initialized;
1.35 + DirectFB_GLContext *firstgl; /* linked list */
1.36 +};
1.37 +
1.38 +#define OPENGL_REQUIRS_DLOPEN
1.39 +#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
1.40 +#include <dlfcn.h>
1.41 +#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
1.42 +#define GL_LoadFunction dlsym
1.43 +#define GL_UnloadObject dlclose
1.44 +#else
1.45 +#define GL_LoadObject SDL_LoadObject
1.46 +#define GL_LoadFunction SDL_LoadFunction
1.47 +#define GL_UnloadObject SDL_UnloadObject
1.48 +#endif
1.49 +
1.50 +static void DirectFB_GL_UnloadLibrary(_THIS);
1.51 +
1.52 +int
1.53 +DirectFB_GL_Initialize(_THIS)
1.54 +{
1.55 + if (_this->gl_data) {
1.56 + return 0;
1.57 + }
1.58 +
1.59 + _this->gl_data =
1.60 + (struct SDL_GLDriverData *) SDL_calloc(1,
1.61 + sizeof(struct
1.62 + SDL_GLDriverData));
1.63 + if (!_this->gl_data) {
1.64 + SDL_OutOfMemory();
1.65 + return -1;
1.66 + }
1.67 + _this->gl_data->initialized = 0;
1.68 +
1.69 + ++_this->gl_data->initialized;
1.70 + _this->gl_data->firstgl = NULL;
1.71 +
1.72 + if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
1.73 + return -1;
1.74 + }
1.75 +
1.76 + /* Initialize extensions */
1.77 + /* FIXME needed?
1.78 + * X11_GL_InitExtensions(_this);
1.79 + */
1.80 +
1.81 + return 0;
1.82 +}
1.83 +
1.84 +void
1.85 +DirectFB_GL_Shutdown(_THIS)
1.86 +{
1.87 + if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
1.88 + return;
1.89 + }
1.90 +
1.91 + DirectFB_GL_UnloadLibrary(_this);
1.92 +
1.93 + SDL_free(_this->gl_data);
1.94 + _this->gl_data = NULL;
1.95 +}
1.96 +
1.97 +int
1.98 +DirectFB_GL_LoadLibrary(_THIS, const char *path)
1.99 +{
1.100 + SDL_DFB_DEVICEDATA(_this);
1.101 +
1.102 + void *handle = NULL;
1.103 +
1.104 + SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
1.105 +
1.106 + if (_this->gl_data->gl_active) {
1.107 + SDL_SetError("OpenGL context already created");
1.108 + return -1;
1.109 + }
1.110 +
1.111 +
1.112 + if (path == NULL) {
1.113 + path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
1.114 + if (path == NULL) {
1.115 + path = "libGL.so";
1.116 + }
1.117 + }
1.118 +
1.119 + handle = GL_LoadObject(path);
1.120 + if (handle == NULL) {
1.121 + SDL_DFB_ERR("Library not found: %s\n", path);
1.122 + /* SDL_LoadObject() will call SDL_SetError() for us. */
1.123 + return -1;
1.124 + }
1.125 +
1.126 + SDL_DFB_DEBUG("Loaded library: %s\n", path);
1.127 +
1.128 + /* Unload the old driver and reset the pointers */
1.129 + DirectFB_GL_UnloadLibrary(_this);
1.130 +
1.131 + _this->gl_config.dll_handle = handle;
1.132 + _this->gl_config.driver_loaded = 1;
1.133 + if (path) {
1.134 + SDL_strlcpy(_this->gl_config.driver_path, path,
1.135 + SDL_arraysize(_this->gl_config.driver_path));
1.136 + } else {
1.137 + *_this->gl_config.driver_path = '\0';
1.138 + }
1.139 +
1.140 + devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
1.141 + devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
1.142 +
1.143 + return 0;
1.144 +}
1.145 +
1.146 +static void
1.147 +DirectFB_GL_UnloadLibrary(_THIS)
1.148 +{
1.149 + int ret;
1.150 +
1.151 + if (_this->gl_config.driver_loaded) {
1.152 +
1.153 + ret = GL_UnloadObject(_this->gl_config.dll_handle);
1.154 + if (ret)
1.155 + SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
1.156 + _this->gl_config.dll_handle = NULL;
1.157 + _this->gl_config.driver_loaded = 0;
1.158 + }
1.159 +}
1.160 +
1.161 +void *
1.162 +DirectFB_GL_GetProcAddress(_THIS, const char *proc)
1.163 +{
1.164 + void *handle;
1.165 +
1.166 + handle = _this->gl_config.dll_handle;
1.167 + return GL_LoadFunction(handle, proc);
1.168 +}
1.169 +
1.170 +SDL_GLContext
1.171 +DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
1.172 +{
1.173 + SDL_DFB_WINDOWDATA(window);
1.174 + DirectFB_GLContext *context;
1.175 + int ret;
1.176 +
1.177 + SDL_DFB_CALLOC(context, 1, sizeof(*context));
1.178 +
1.179 + SDL_DFB_CHECKERR(windata->surface->
1.180 + GetGL(windata->surface, &context->context));
1.181 + SDL_DFB_CHECKERR(context->context->Unlock(context->context));
1.182 +
1.183 + context->next = _this->gl_data->firstgl;
1.184 + _this->gl_data->firstgl = context;
1.185 +
1.186 + if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
1.187 + DirectFB_GL_DeleteContext(_this, context);
1.188 + return NULL;
1.189 + }
1.190 +
1.191 + return context;
1.192 +
1.193 + error:
1.194 + return NULL;
1.195 +}
1.196 +
1.197 +int
1.198 +DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
1.199 +{
1.200 + SDL_DFB_WINDOWDATA(window);
1.201 + DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
1.202 + DirectFB_GLContext *p;
1.203 +
1.204 + int ret;
1.205 +
1.206 + for (p = _this->gl_data->firstgl; p; p = p->next)
1.207 + p->context->Unlock(p->context);
1.208 +
1.209 + if (windata) {
1.210 + int cw, ch;
1.211 +
1.212 + windata->gl_context = NULL;
1.213 + /* Everything is unlocked, check for a resize */
1.214 + SDL_DFB_CHECKERR(windata->surface->
1.215 + GetSize(windata->surface, &cw, &ch));
1.216 + if (cw != window->w || ch != window->h)
1.217 + SDL_DFB_CHECKERR(windata->window->
1.218 + ResizeSurface(windata->window, window->w,
1.219 + window->h));
1.220 + }
1.221 +
1.222 + if (ctx != NULL) {
1.223 + SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
1.224 + }
1.225 +
1.226 + if (windata)
1.227 + windata->gl_context = ctx;
1.228 +
1.229 + return 0;
1.230 + error:
1.231 + return -1;
1.232 +}
1.233 +
1.234 +int
1.235 +DirectFB_GL_SetSwapInterval(_THIS, int interval)
1.236 +{
1.237 + SDL_Unsupported();
1.238 + return -1;
1.239 +}
1.240 +
1.241 +int
1.242 +DirectFB_GL_GetSwapInterval(_THIS)
1.243 +{
1.244 + SDL_Unsupported();
1.245 + return -1;
1.246 +}
1.247 +
1.248 +void
1.249 +DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
1.250 +{
1.251 + SDL_DFB_DEVICEDATA(_this);
1.252 + SDL_DFB_WINDOWDATA(window);
1.253 + int ret;
1.254 + DFBRegion region;
1.255 +
1.256 + region.x1 = 0;
1.257 + region.y1 = 0;
1.258 + region.x2 = window->w;
1.259 + region.y2 = window->h;
1.260 +
1.261 + if (devdata->glFinish)
1.262 + devdata->glFinish();
1.263 + else if (devdata->glFlush)
1.264 + devdata->glFlush();
1.265 +
1.266 + if (1 || windata->gl_context) {
1.267 + /* SDL_DFB_CHECKERR(windata->gl_context->context->Unlock(windata->gl_context->context)); */
1.268 + SDL_DFB_CHECKERR(windata->surface->
1.269 + Flip(windata->surface, ®ion, DSFLIP_ONSYNC));
1.270 + /* SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context)); */
1.271 +
1.272 + }
1.273 +
1.274 + return;
1.275 + error:
1.276 + return;
1.277 +}
1.278 +
1.279 +void
1.280 +DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
1.281 +{
1.282 + DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
1.283 + DirectFB_GLContext *p;
1.284 +
1.285 + ctx->context->Unlock(ctx->context);
1.286 + ctx->context->Release(ctx->context);
1.287 +
1.288 + p = _this->gl_data->firstgl;
1.289 + while (p && p->next != ctx)
1.290 + p = p->next;
1.291 + if (p)
1.292 + p->next = ctx->next;
1.293 + else
1.294 + _this->gl_data->firstgl = ctx->next;
1.295 +
1.296 + SDL_DFB_FREE(ctx);
1.297 +
1.298 +}
1.299 +
1.300 +#endif
1.301 +
1.302 +/* vi: set ts=4 sw=4 expandtab: */