sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_DirectFB_opengl.c (8091B)


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