src/video/directfb/SDL_DirectFB_opengl.c
author Sam Lantinga
Wed, 18 Jan 2017 12:19:57 -0800
changeset 10821 b0b8395f5cf9
parent 10741 a32fd6b7412b
child 10998 cedca11e9b61
permissions -rw-r--r--
Removed unused variable
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2017 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     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     DFBRegion region;
   247     DirectFB_GLContext *p;
   248 
   249     region.x1 = 0;
   250     region.y1 = 0;
   251     region.x2 = window->w;
   252     region.y2 = window->h;
   253 
   254 #if 0
   255     if (devdata->glFinish)
   256         devdata->glFinish();
   257     else if (devdata->glFlush)
   258         devdata->glFlush();
   259 #endif
   260 
   261     for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   262         if (p->sdl_window == window && p->is_locked)
   263         {
   264             SDL_DFB_CHECKERR(p->context->Unlock(p->context));
   265             p->is_locked = 0;
   266         }
   267 
   268     SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL,  DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
   269     return 0;
   270   error:
   271     return -1;
   272 }
   273 
   274 void
   275 DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
   276 {
   277     DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
   278     DirectFB_GLContext *p;
   279 
   280     if (ctx->is_locked)
   281         SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
   282     SDL_DFB_RELEASE(ctx->context);
   283 
   284     for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
   285         ;
   286     if (p)
   287         p->next = ctx->next;
   288     else
   289         _this->gl_data->firstgl = ctx->next;
   290 
   291     SDL_DFB_FREE(ctx);
   292 }
   293 
   294 void
   295 DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
   296 {
   297     DirectFB_GLContext *p;
   298 
   299     for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   300         if (p->sdl_window == window)
   301         {
   302             if (p->is_locked)
   303                 SDL_DFB_CHECK(p->context->Unlock(p->context));
   304             SDL_DFB_RELEASE(p->context);
   305         }
   306 }
   307 
   308 void
   309 DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
   310 {
   311     DirectFB_GLContext *p;
   312 
   313     for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   314         if (p->sdl_window == window)
   315         {
   316             SDL_DFB_WINDOWDATA(window);
   317             SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
   318                                              &p->context));
   319             if (p->is_locked)
   320                 SDL_DFB_CHECK(p->context->Lock(p->context));
   321             }
   322 }
   323 
   324 void
   325 DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
   326 {
   327     DirectFB_GLContext *p;
   328 
   329     for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
   330         if (p->sdl_window == window)
   331             DirectFB_GL_DeleteContext(_this, p);
   332 }
   333 
   334 #endif
   335 
   336 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
   337 
   338 /* vi: set ts=4 sw=4 expandtab: */