src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga
Sun, 31 Aug 2008 16:04:32 +0000
changeset 2737 140a7edcf2bd
child 2859 99210400e8b9
permissions -rw-r--r--
Date: Sun, 31 Aug 2008 17:53:59 +0200
From: Couriersud
Subject: Re: Updated DirectFB driver for SDL1.3

attached is a patch which brings the directfb driver in line with
current svn. In addition:

* driver now is in line with the structure of the X11 driver.
This adds a couple of files.
* driver now supports relative mouse movements
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with _this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_DirectFB_video.h"
    25 
    26 #if SDL_DIRECTFB_OPENGL
    27 
    28 struct SDL_GLDriverData
    29 {
    30     int gl_active;              /* to stop switching drivers while we have a valid context */
    31     int initialized;
    32     DirectFB_GLContext *firstgl;        /* linked list */
    33 };
    34 
    35 #define OPENGL_REQUIRS_DLOPEN
    36 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
    37 #include <dlfcn.h>
    38 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
    39 #define GL_LoadFunction		dlsym
    40 #define GL_UnloadObject		dlclose
    41 #else
    42 #define GL_LoadObject	SDL_LoadObject
    43 #define GL_LoadFunction	SDL_LoadFunction
    44 #define GL_UnloadObject	SDL_UnloadObject
    45 #endif
    46 
    47 static void DirectFB_GL_UnloadLibrary(_THIS);
    48 
    49 int
    50 DirectFB_GL_Initialize(_THIS)
    51 {
    52     if (_this->gl_data) {
    53         return 0;
    54     }
    55 
    56     _this->gl_data =
    57         (struct SDL_GLDriverData *) SDL_calloc(1,
    58                                                sizeof(struct
    59                                                       SDL_GLDriverData));
    60     if (!_this->gl_data) {
    61         SDL_OutOfMemory();
    62         return -1;
    63     }
    64     _this->gl_data->initialized = 0;
    65 
    66     ++_this->gl_data->initialized;
    67     _this->gl_data->firstgl = NULL;
    68 
    69     if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
    70         return -1;
    71     }
    72 
    73     /* Initialize extensions */
    74     /* FIXME needed?
    75      * X11_GL_InitExtensions(_this);
    76      */
    77 
    78     return 0;
    79 }
    80 
    81 void
    82 DirectFB_GL_Shutdown(_THIS)
    83 {
    84     if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
    85         return;
    86     }
    87 
    88     DirectFB_GL_UnloadLibrary(_this);
    89 
    90     SDL_free(_this->gl_data);
    91     _this->gl_data = NULL;
    92 }
    93 
    94 int
    95 DirectFB_GL_LoadLibrary(_THIS, const char *path)
    96 {
    97     SDL_DFB_DEVICEDATA(_this);
    98 
    99     void *handle = NULL;
   100 
   101     SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
   102 
   103     if (_this->gl_data->gl_active) {
   104         SDL_SetError("OpenGL context already created");
   105         return -1;
   106     }
   107 
   108 
   109     if (path == NULL) {
   110         path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   111         if (path == NULL) {
   112             path = "libGL.so";
   113         }
   114     }
   115 
   116     handle = GL_LoadObject(path);
   117     if (handle == NULL) {
   118         SDL_DFB_ERR("Library not found: %s\n", path);
   119         /* SDL_LoadObject() will call SDL_SetError() for us. */
   120         return -1;
   121     }
   122 
   123     SDL_DFB_DEBUG("Loaded library: %s\n", path);
   124 
   125     /* Unload the old driver and reset the pointers */
   126     DirectFB_GL_UnloadLibrary(_this);
   127 
   128     _this->gl_config.dll_handle = handle;
   129     _this->gl_config.driver_loaded = 1;
   130     if (path) {
   131         SDL_strlcpy(_this->gl_config.driver_path, path,
   132                     SDL_arraysize(_this->gl_config.driver_path));
   133     } else {
   134         *_this->gl_config.driver_path = '\0';
   135     }
   136 
   137     devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
   138     devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
   139 
   140     return 0;
   141 }
   142 
   143 static void
   144 DirectFB_GL_UnloadLibrary(_THIS)
   145 {
   146     int ret;
   147 
   148     if (_this->gl_config.driver_loaded) {
   149 
   150         ret = GL_UnloadObject(_this->gl_config.dll_handle);
   151         if (ret)
   152             SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
   153         _this->gl_config.dll_handle = NULL;
   154         _this->gl_config.driver_loaded = 0;
   155     }
   156 }
   157 
   158 void *
   159 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
   160 {
   161     void *handle;
   162 
   163     handle = _this->gl_config.dll_handle;
   164     return GL_LoadFunction(handle, proc);
   165 }
   166 
   167 SDL_GLContext
   168 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
   169 {
   170     SDL_DFB_WINDOWDATA(window);
   171     DirectFB_GLContext *context;
   172     int ret;
   173 
   174     SDL_DFB_CALLOC(context, 1, sizeof(*context));
   175 
   176     SDL_DFB_CHECKERR(windata->surface->
   177                      GetGL(windata->surface, &context->context));
   178     SDL_DFB_CHECKERR(context->context->Unlock(context->context));
   179 
   180     context->next = _this->gl_data->firstgl;
   181     _this->gl_data->firstgl = context;
   182 
   183     if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
   184         DirectFB_GL_DeleteContext(_this, context);
   185         return NULL;
   186     }
   187 
   188     return context;
   189 
   190   error:
   191     return NULL;
   192 }
   193 
   194 int
   195 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   196 {
   197     SDL_DFB_WINDOWDATA(window);
   198     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   199     DirectFB_GLContext *p;
   200 
   201     int ret;
   202 
   203     for (p = _this->gl_data->firstgl; p; p = p->next)
   204         p->context->Unlock(p->context);
   205 
   206     if (windata) {
   207         int cw, ch;
   208 
   209         windata->gl_context = NULL;
   210         /* Everything is unlocked, check for a resize */
   211         SDL_DFB_CHECKERR(windata->surface->
   212                          GetSize(windata->surface, &cw, &ch));
   213         if (cw != window->w || ch != window->h)
   214             SDL_DFB_CHECKERR(windata->window->
   215                              ResizeSurface(windata->window, window->w,
   216                                            window->h));
   217     }
   218 
   219     if (ctx != NULL) {
   220         SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
   221     }
   222 
   223     if (windata)
   224         windata->gl_context = ctx;
   225 
   226     return 0;
   227   error:
   228     return -1;
   229 }
   230 
   231 int
   232 DirectFB_GL_SetSwapInterval(_THIS, int interval)
   233 {
   234     SDL_Unsupported();
   235     return -1;
   236 }
   237 
   238 int
   239 DirectFB_GL_GetSwapInterval(_THIS)
   240 {
   241     SDL_Unsupported();
   242     return -1;
   243 }
   244 
   245 void
   246 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
   247 {
   248     SDL_DFB_DEVICEDATA(_this);
   249     SDL_DFB_WINDOWDATA(window);
   250     int ret;
   251     DFBRegion region;
   252 
   253     region.x1 = 0;
   254     region.y1 = 0;
   255     region.x2 = window->w;
   256     region.y2 = window->h;
   257 
   258     if (devdata->glFinish)
   259         devdata->glFinish();
   260     else if (devdata->glFlush)
   261         devdata->glFlush();
   262 
   263     if (1 || windata->gl_context) {
   264         /* SDL_DFB_CHECKERR(windata->gl_context->context->Unlock(windata->gl_context->context)); */
   265         SDL_DFB_CHECKERR(windata->surface->
   266                          Flip(windata->surface, &region, DSFLIP_ONSYNC));
   267         /* SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context)); */
   268 
   269     }
   270 
   271     return;
   272   error:
   273     return;
   274 }
   275 
   276 void
   277 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
   278 {
   279     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   280     DirectFB_GLContext *p;
   281 
   282     ctx->context->Unlock(ctx->context);
   283     ctx->context->Release(ctx->context);
   284 
   285     p = _this->gl_data->firstgl;
   286     while (p && p->next != ctx)
   287         p = p->next;
   288     if (p)
   289         p->next = ctx->next;
   290     else
   291         _this->gl_data->firstgl = ctx->next;
   292 
   293     SDL_DFB_FREE(ctx);
   294 
   295 }
   296 
   297 #endif
   298 
   299 /* vi: set ts=4 sw=4 expandtab: */