src/video/directfb/SDL_DirectFB_opengl.c
author Ryan C. Gordon
Sun, 31 Mar 2013 12:48:50 -0400
changeset 7037 3fedf1f25b94
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Make SDL_SetError and friends unconditionally return -1.

This lets us change things like this...

if (Failed) {
SDL_SetError("We failed");
return -1;
}

...into this...

if (Failed) {
return SDL_SetError("We failed");
}


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