src/video/directfb/SDL_DirectFB_opengl.c
changeset 2737 140a7edcf2bd
child 2859 99210400e8b9
     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, &region, 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: */