SDL  2.0
SDL_DirectFB_opengl.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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
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 
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 
136  if (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);
157 #endif
158  /* Free OpenGL memory */
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 
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: */
#define SDL_strlcpy
#define SDL_DFB_FREE(x)
GLfloat GLfloat p
GLAPI void GLAPIENTRY glFinish(void)
#define SDL_DFB_RELEASE(x)
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:378
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:175
GLAPI void GLAPIENTRY glFlush(void)
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:937
#define _THIS
#define SDL_free
char driver_path[256]
Definition: SDL_sysvideo.h:350
#define SDL_getenv
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_DFB_ALLOC_CLEAR(r, s)
#define SDL_DFB_ERR(x...)
#define SDL_DFB_CHECKERR(x...)
#define SDL_SetError
#define SDL_calloc
#define SDL_DFB_WINDOWDATA(win)
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
#define SDL_DFB_CHECK(x...)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_DFB_DEBUG(x...)
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
GLsizei const GLchar *const * path
struct SDL_VideoDevice::@34 gl_config
EGLContext context
Definition: SDL_pspgl_c.h:34
#define SDL_Unsupported()
Definition: SDL_error.h:53
EGLContext ctx
Definition: eglext.h:208