src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga
Fri, 08 Apr 2011 13:03:26 -0700
changeset 5535 96594ac5fd1a
parent 5488 c20436fd5627
child 6044 35448a5ea044
permissions -rw-r--r--
SDL 1.3 is now under the zlib license.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 #include "SDL_DirectFB_video.h"
    23 
    24 #if SDL_DIRECTFB_OPENGL
    25 
    26 #include "SDL_DirectFB_opengl.h"
    27 #include "SDL_DirectFB_window.h"
    28 
    29 #include <directfbgl.h>
    30 #include "SDL_loadso.h"
    31 #endif
    32 
    33 #if SDL_DIRECTFB_OPENGL
    34 
    35 struct SDL_GLDriverData
    36 {
    37     int gl_active;              /* to stop switching drivers while we have a valid context */
    38     int initialized;
    39     DirectFB_GLContext *firstgl;        /* linked list */
    40     
    41     /* OpenGL */
    42     void (*glFinish) (void);
    43     void (*glFlush) (void);
    44 };
    45 
    46 #define OPENGL_REQUIRS_DLOPEN
    47 #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
    48 #include <dlfcn.h>
    49 #define GL_LoadObject(X)	dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
    50 #define GL_LoadFunction		dlsym
    51 #define GL_UnloadObject		dlclose
    52 #else
    53 #define GL_LoadObject	SDL_LoadObject
    54 #define GL_LoadFunction	SDL_LoadFunction
    55 #define GL_UnloadObject	SDL_UnloadObject
    56 #endif
    57 
    58 static void DirectFB_GL_UnloadLibrary(_THIS);
    59 
    60 int
    61 DirectFB_GL_Initialize(_THIS)
    62 {
    63     if (_this->gl_data) {
    64         return 0;
    65     }
    66 
    67     _this->gl_data =
    68         (struct SDL_GLDriverData *) SDL_calloc(1,
    69                                                sizeof(struct
    70                                                       SDL_GLDriverData));
    71     if (!_this->gl_data) {
    72         SDL_OutOfMemory();
    73         return -1;
    74     }
    75     _this->gl_data->initialized = 0;
    76 
    77     ++_this->gl_data->initialized;
    78     _this->gl_data->firstgl = NULL;
    79 
    80     if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
    81         return -1;
    82     }
    83 
    84     /* Initialize extensions */
    85     /* FIXME needed?
    86      * X11_GL_InitExtensions(_this);
    87      */
    88 
    89     return 0;
    90 }
    91 
    92 void
    93 DirectFB_GL_Shutdown(_THIS)
    94 {
    95     if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
    96         return;
    97     }
    98 
    99     DirectFB_GL_UnloadLibrary(_this);
   100 
   101     SDL_free(_this->gl_data);
   102     _this->gl_data = NULL;
   103 }
   104 
   105 int
   106 DirectFB_GL_LoadLibrary(_THIS, const char *path)
   107 {
   108     //SDL_DFB_DEVICEDATA(_this);
   109 
   110     void *handle = NULL;
   111 
   112     SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
   113 
   114     if (_this->gl_data->gl_active) {
   115         SDL_SetError("OpenGL context already created");
   116         return -1;
   117     }
   118 
   119 
   120     if (path == NULL) {
   121         path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   122         if (path == NULL) {
   123             path = "libGL.so";
   124         }
   125     }
   126 
   127     handle = GL_LoadObject(path);
   128     if (handle == NULL) {
   129         SDL_DFB_ERR("Library not found: %s\n", path);
   130         /* SDL_LoadObject() will call SDL_SetError() for us. */
   131         return -1;
   132     }
   133 
   134     SDL_DFB_DEBUG("Loaded library: %s\n", path);
   135 
   136     _this->gl_config.dll_handle = handle;
   137     _this->gl_config.driver_loaded = 1;
   138     if (path) {
   139         SDL_strlcpy(_this->gl_config.driver_path, path,
   140                     SDL_arraysize(_this->gl_config.driver_path));
   141     } else {
   142         *_this->gl_config.driver_path = '\0';
   143     }
   144 
   145     _this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
   146     _this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
   147 
   148     return 0;
   149 }
   150 
   151 static void
   152 DirectFB_GL_UnloadLibrary(_THIS)
   153 {
   154  #if 0
   155     int ret;
   156 
   157     if (_this->gl_config.driver_loaded) {
   158 
   159         ret = GL_UnloadObject(_this->gl_config.dll_handle);
   160         if (ret)
   161             SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
   162         _this->gl_config.dll_handle = NULL;
   163         _this->gl_config.driver_loaded = 0;
   164     }
   165 #endif
   166     /* Free OpenGL memory */
   167     SDL_free(_this->gl_data);
   168     _this->gl_data = NULL;
   169 }
   170 
   171 void *
   172 DirectFB_GL_GetProcAddress(_THIS, const char *proc)
   173 {
   174     void *handle;
   175 
   176     handle = _this->gl_config.dll_handle;
   177     return GL_LoadFunction(handle, proc);
   178 }
   179 
   180 SDL_GLContext
   181 DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
   182 {
   183     //SDL_DFB_DEVICEDATA(_this);
   184     SDL_DFB_WINDOWDATA(window);
   185     DirectFB_GLContext *context;
   186 
   187     SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));
   188 
   189     SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
   190                                              &context->context));
   191 
   192     if (!context->context)
   193         return NULL;
   194 
   195     context->is_locked = 0;
   196     context->sdl_window = window;
   197     
   198     context->next = _this->gl_data->firstgl;
   199     _this->gl_data->firstgl = context;
   200 
   201     SDL_DFB_CHECK(context->context->Unlock(context->context));
   202 
   203     if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
   204         DirectFB_GL_DeleteContext(_this, context);
   205         return NULL;
   206     }
   207 
   208     return context;
   209 
   210   error:
   211     return NULL;
   212 }
   213 
   214 int
   215 DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   216 {
   217     //SDL_DFB_WINDOWDATA(window);
   218     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   219     DirectFB_GLContext *p;
   220 
   221     for (p = _this->gl_data->firstgl; p; p = p->next)
   222     {
   223        if (p->is_locked) {
   224          SDL_DFB_CHECKERR(p->context->Unlock(p->context));
   225          p->is_locked = 0;
   226        }
   227         
   228     }
   229 
   230     if (ctx != NULL) {
   231         SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
   232         ctx->is_locked = 1;
   233     }
   234 
   235     return 0;
   236   error:
   237     return -1;
   238 }
   239 
   240 int
   241 DirectFB_GL_SetSwapInterval(_THIS, int interval)
   242 {
   243     SDL_Unsupported();
   244     return -1;
   245 }
   246 
   247 int
   248 DirectFB_GL_GetSwapInterval(_THIS)
   249 {
   250     SDL_Unsupported();
   251     return -1;
   252 }
   253 
   254 void
   255 DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
   256 {
   257     //SDL_DFB_DEVICEDATA(_this);
   258     SDL_DFB_WINDOWDATA(window);
   259     DFBRegion region;
   260     DirectFB_GLContext *p;
   261 
   262     region.x1 = 0;
   263     region.y1 = 0;
   264     region.x2 = window->w;
   265     region.y2 = window->h;
   266 
   267 #if 0
   268     if (devdata->glFinish)
   269         devdata->glFinish();
   270     else if (devdata->glFlush)
   271         devdata->glFlush();
   272 #endif
   273 
   274   	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   275         if (p->sdl_window == window && p->is_locked)
   276         {
   277             SDL_DFB_CHECKERR(p->context->Unlock(p->context));
   278             p->is_locked = 0;
   279         }            
   280 
   281     SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL,  DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
   282 
   283     //if (windata->gl_context) {
   284         //SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface,NULL, DSFLIP_ONSYNC)); 
   285         //SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context));
   286     //}
   287 
   288     return;
   289   error:
   290     return;
   291 }
   292 
   293 void
   294 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
   295 {
   296     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   297     DirectFB_GLContext *p;
   298 
   299     if (ctx->is_locked)
   300         SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
   301     SDL_DFB_RELEASE(ctx->context);
   302 
   303     for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
   304         ;
   305     if (p)
   306         p->next = ctx->next;
   307     else
   308         _this->gl_data->firstgl = ctx->next;
   309 
   310     SDL_DFB_FREE(ctx);
   311 }
   312 
   313 void
   314 DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
   315 {
   316     DirectFB_GLContext *p;
   317     
   318 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   319 	    if (p->sdl_window == window)
   320 	    {
   321 	    	if (p->is_locked)
   322 	        	SDL_DFB_CHECK(p->context->Unlock(p->context));
   323 	        SDL_DFB_RELEASE(p->context);
   324 	    }
   325 }
   326 
   327 void
   328 DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
   329 {
   330     DirectFB_GLContext *p;
   331 
   332 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   333 	    if (p->sdl_window == window)
   334 	    {
   335             SDL_DFB_WINDOWDATA(window);
   336 			SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
   337 	                                         &p->context));
   338     		if (p->is_locked)
   339             	SDL_DFB_CHECK(p->context->Lock(p->context));
   340 	        }
   341 }
   342 
   343 void
   344 DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
   345 {
   346     DirectFB_GLContext *p;
   347 
   348 	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   349 		if (p->sdl_window == window)
   350 			DirectFB_GL_DeleteContext(_this, p);
   351 }
   352 
   353 #endif
   354 
   355 /* vi: set ts=4 sw=4 expandtab: */