src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 05 Feb 2011 16:07:10 -0800
changeset 5199 164f20ba08eb
parent 4636 b196d2758026
child 5262 b530ef003506
permissions -rw-r--r--
Updated the DirectFB support, from Couriersud

attached is a working directfb driver diff which works with the current
changes. There are a number of changes around it as well, e.g.
configure.in.

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