cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_DirectFB_opengl.c (8360B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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
     38struct 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
     61static void DirectFB_GL_UnloadLibrary(_THIS);
     62
     63int
     64DirectFB_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
     94void
     95DirectFB_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
    107int
    108DirectFB_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
    150static void
    151DirectFB_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
    170void *
    171DirectFB_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
    179SDL_GLContext
    180DirectFB_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
    212int
    213DirectFB_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
    237int
    238DirectFB_GL_SetSwapInterval(_THIS, int interval)
    239{
    240    return SDL_Unsupported();
    241}
    242
    243int
    244DirectFB_GL_GetSwapInterval(_THIS)
    245{
    246    return 0;
    247}
    248
    249void
    250DirectFB_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;
    277  error:
    278    return;
    279}
    280
    281void
    282DirectFB_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
    301void
    302DirectFB_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
    315void
    316DirectFB_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
    331void
    332DirectFB_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: */