src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga
Mon, 14 Mar 2011 23:13:33 -0700
changeset 5488 c20436fd5627
parent 5262 b530ef003506
child 5535 96594ac5fd1a
permissions -rw-r--r--
DirectFB driver update

Couriersud to Sam

the attached patch brings the DirectFB driver back in line with recent
SDL 1.3 developments.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2011 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     SDL1.3 DirectFB driver by couriersud@arcor.de
    23 	
    24 */
    25 
    26 #include "SDL_DirectFB_video.h"
    27 
    28 #if SDL_DIRECTFB_OPENGL
    29 
    30 #include "SDL_DirectFB_opengl.h"
    31 #include "SDL_DirectFB_window.h"
    32 
    33 #include <directfbgl.h>
    34 #include "SDL_loadso.h"
    35 #endif
    36 
    37 #if SDL_DIRECTFB_OPENGL
    38 
    39 struct SDL_GLDriverData
    40 {
    41     int gl_active;              /* to stop switching drivers while we have a valid context */
    42     int initialized;
    43     DirectFB_GLContext *firstgl;        /* linked list */
    44     
    45     /* OpenGL */
    46     void (*glFinish) (void);
    47     void (*glFlush) (void);
    48 };
    49 
    50 #define OPENGL_REQUIRS_DLOPEN
    51 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
    52 #include <dlfcn.h>
    53 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
    54 #define GL_LoadFunction		dlsym
    55 #define GL_UnloadObject		dlclose
    56 #else
    57 #define GL_LoadObject	SDL_LoadObject
    58 #define GL_LoadFunction	SDL_LoadFunction
    59 #define GL_UnloadObject	SDL_UnloadObject
    60 #endif
    61 
    62 static void DirectFB_GL_UnloadLibrary(_THIS);
    63 
    64 int
    65 DirectFB_GL_Initialize(_THIS)
    66 {
    67     if (_this->gl_data) {
    68         return 0;
    69     }
    70 
    71     _this->gl_data =
    72         (struct SDL_GLDriverData *) SDL_calloc(1,
    73                                                sizeof(struct
    74                                                       SDL_GLDriverData));
    75     if (!_this->gl_data) {
    76         SDL_OutOfMemory();
    77         return -1;
    78     }
    79     _this->gl_data->initialized = 0;
    80 
    81     ++_this->gl_data->initialized;
    82     _this->gl_data->firstgl = NULL;
    83 
    84     if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
    85         return -1;
    86     }
    87 
    88     /* Initialize extensions */
    89     /* FIXME needed?
    90      * X11_GL_InitExtensions(_this);
    91      */
    92 
    93     return 0;
    94 }
    95 
    96 void
    97 DirectFB_GL_Shutdown(_THIS)
    98 {
    99     if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
   100         return;
   101     }
   102 
   103     DirectFB_GL_UnloadLibrary(_this);
   104 
   105     SDL_free(_this->gl_data);
   106     _this->gl_data = NULL;
   107 }
   108 
   109 int
   110 DirectFB_GL_LoadLibrary(_THIS, const char *path)
   111 {
   112     //SDL_DFB_DEVICEDATA(_this);
   113 
   114     void *handle = NULL;
   115 
   116     SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
   117 
   118     if (_this->gl_data->gl_active) {
   119         SDL_SetError("OpenGL context already created");
   120         return -1;
   121     }
   122 
   123 
   124     if (path == NULL) {
   125         path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   126         if (path == NULL) {
   127             path = "libGL.so";
   128         }
   129     }
   130 
   131     handle = GL_LoadObject(path);
   132     if (handle == NULL) {
   133         SDL_DFB_ERR("Library not found: %s\n", path);
   134         /* SDL_LoadObject() will call SDL_SetError() for us. */
   135         return -1;
   136     }
   137 
   138     SDL_DFB_DEBUG("Loaded library: %s\n", path);
   139 
   140     _this->gl_config.dll_handle = handle;
   141     _this->gl_config.driver_loaded = 1;
   142     if (path) {
   143         SDL_strlcpy(_this->gl_config.driver_path, path,
   144                     SDL_arraysize(_this->gl_config.driver_path));
   145     } else {
   146         *_this->gl_config.driver_path = '\0';
   147     }
   148 
   149     _this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
   150     _this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
   151 
   152     return 0;
   153 }
   154 
   155 static void
   156 DirectFB_GL_UnloadLibrary(_THIS)
   157 {
   158  #if 0
   159     int ret;
   160 
   161     if (_this->gl_config.driver_loaded) {
   162 
   163         ret = GL_UnloadObject(_this->gl_config.dll_handle);
   164         if (ret)
   165             SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
   166         _this->gl_config.dll_handle = NULL;
   167         _this->gl_config.driver_loaded = 0;
   168     }
   169 #endif
   170     /* Free OpenGL memory */
   171     SDL_free(_this->gl_data);
   172     _this->gl_data = NULL;
   173 }
   174 
   175 void *
   176 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
   177 {
   178     void *handle;
   179 
   180     handle = _this->gl_config.dll_handle;
   181     return GL_LoadFunction(handle, proc);
   182 }
   183 
   184 SDL_GLContext
   185 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
   186 {
   187     //SDL_DFB_DEVICEDATA(_this);
   188     SDL_DFB_WINDOWDATA(window);
   189     DirectFB_GLContext *context;
   190 
   191     SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));
   192 
   193     SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
   194                                              &context->context));
   195 
   196     if (!context->context)
   197         return NULL;
   198 
   199     context->is_locked = 0;
   200     context->sdl_window = window;
   201     
   202     context->next = _this->gl_data->firstgl;
   203     _this->gl_data->firstgl = context;
   204 
   205     SDL_DFB_CHECK(context->context->Unlock(context->context));
   206 
   207     if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
   208         DirectFB_GL_DeleteContext(_this, context);
   209         return NULL;
   210     }
   211 
   212     return context;
   213 
   214   error:
   215     return NULL;
   216 }
   217 
   218 int
   219 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   220 {
   221     //SDL_DFB_WINDOWDATA(window);
   222     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   223     DirectFB_GLContext *p;
   224 
   225     for (p = _this->gl_data->firstgl; p; p = p->next)
   226     {
   227        if (p->is_locked) {
   228          SDL_DFB_CHECKERR(p->context->Unlock(p->context));
   229          p->is_locked = 0;
   230        }
   231         
   232     }
   233 
   234     if (ctx != NULL) {
   235         SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
   236         ctx->is_locked = 1;
   237     }
   238 
   239     return 0;
   240   error:
   241     return -1;
   242 }
   243 
   244 int
   245 DirectFB_GL_SetSwapInterval(_THIS, int interval)
   246 {
   247     SDL_Unsupported();
   248     return -1;
   249 }
   250 
   251 int
   252 DirectFB_GL_GetSwapInterval(_THIS)
   253 {
   254     SDL_Unsupported();
   255     return -1;
   256 }
   257 
   258 void
   259 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
   260 {
   261     //SDL_DFB_DEVICEDATA(_this);
   262     SDL_DFB_WINDOWDATA(window);
   263     DFBRegion region;
   264     DirectFB_GLContext *p;
   265 
   266     region.x1 = 0;
   267     region.y1 = 0;
   268     region.x2 = window->w;
   269     region.y2 = window->h;
   270 
   271 #if 0
   272     if (devdata->glFinish)
   273         devdata->glFinish();
   274     else if (devdata->glFlush)
   275         devdata->glFlush();
   276 #endif
   277 
   278   	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   279         if (p->sdl_window == window && p->is_locked)
   280         {
   281             SDL_DFB_CHECKERR(p->context->Unlock(p->context));
   282             p->is_locked = 0;
   283         }            
   284 
   285     SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL,  DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
   286 
   287     //if (windata->gl_context) {
   288         //SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface,NULL, DSFLIP_ONSYNC)); 
   289         //SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context));
   290     //}
   291 
   292     return;
   293   error:
   294     return;
   295 }
   296 
   297 void
   298 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
   299 {
   300     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   301     DirectFB_GLContext *p;
   302 
   303     if (ctx->is_locked)
   304         SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
   305     SDL_DFB_RELEASE(ctx->context);
   306 
   307     for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
   308         ;
   309     if (p)
   310         p->next = ctx->next;
   311     else
   312         _this->gl_data->firstgl = ctx->next;
   313 
   314     SDL_DFB_FREE(ctx);
   315 }
   316 
   317 void
   318 DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
   319 {
   320     DirectFB_GLContext *p;
   321     
   322 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   323 	    if (p->sdl_window == window)
   324 	    {
   325 	    	if (p->is_locked)
   326 	        	SDL_DFB_CHECK(p->context->Unlock(p->context));
   327 	        SDL_DFB_RELEASE(p->context);
   328 	    }
   329 }
   330 
   331 void
   332 DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
   333 {
   334     DirectFB_GLContext *p;
   335 
   336 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   337 	    if (p->sdl_window == window)
   338 	    {
   339             SDL_DFB_WINDOWDATA(window);
   340 			SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
   341 	                                         &p->context));
   342     		if (p->is_locked)
   343             	SDL_DFB_CHECK(p->context->Lock(p->context));
   344 	        }
   345 }
   346 
   347 void
   348 DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
   349 {
   350     DirectFB_GLContext *p;
   351 
   352 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   353 		if (p->sdl_window == window)
   354 			DirectFB_GL_DeleteContext(_this, p);
   355 }
   356 
   357 #endif
   358 
   359 /* vi: set ts=4 sw=4 expandtab: */