src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 09 Dec 2016 01:47:43 -0800
changeset 10690 23a825f341e6
parent 9998 f67cf37e9cd4
child 10737 3406a0f8b041
permissions -rw-r--r--
Fixed bug 3513 - SDL_GL_SwapWindow does not return error status

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