src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga
Sat, 31 Dec 2011 09:28:07 -0500
changeset 6138 4c64952a58fb
parent 6044 35448a5ea044
child 6382 64d54101773a
permissions -rwxr-xr-x
Happy New Year!
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 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 #include "SDL_config.h"
    22 
    23 #if SDL_VIDEO_DRIVER_DIRECTFB
    24 
    25 #include "SDL_DirectFB_video.h"
    26 
    27 #if SDL_DIRECTFB_OPENGL
    28 
    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 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
   359 
   360 /* vi: set ts=4 sw=4 expandtab: */