comparison src/video/x11/SDL_x11opengles.c @ 3190:c68d2ca5970f

Added missing files for OpenGL ES support
author Sam Lantinga <slouken@libsdl.org>
date Wed, 10 Jun 2009 13:54:13 +0000
parents
children 81773a1eac83
comparison
equal deleted inserted replaced
3189:ba1e64340565 3190:c68d2ca5970f
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with _this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21
22 Open Pandora SDL driver
23 Copyright (C) 2009 David Carré
24 (cpasjuste@gmail.com)
25 */
26 #include "SDL_config.h"
27
28 #if SDL_VIDEO_OPENGL_ES
29
30 #include "SDL_x11video.h"
31 #include "SDL_x11opengles.h"
32
33 #define DEFAULT_OPENGL "/usr/lib/libGLES_CM.so"
34
35 #define LOAD_FUNC(NAME) \
36 *((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
37 if (!_this->gles_data->NAME) \
38 { \
39 SDL_SetError("Could not retrieve EGL function " #NAME); \
40 return -1; \
41 }
42
43 /* GLES implementation of SDL OpenGL support */
44
45 void *
46 X11_GLES_GetProcAddress(_THIS, const char *proc)
47 {
48 static char procname[1024];
49 void *handle;
50 void *retval;
51
52 handle = _this->gl_config.dll_handle;
53 if (_this->gles_data->eglGetProcAddress) {
54 retval = _this->gles_data->eglGetProcAddress(proc);
55 if (retval) {
56 return retval;
57 }
58 }
59 #if defined(__OpenBSD__) && !defined(__ELF__)
60 #undef dlsym(x,y);
61 #endif
62 retval = dlsym(handle, proc);
63 if (!retval && strlen(proc) <= 1022) {
64 procname[0] = '_';
65 strcpy(procname + 1, proc);
66 retval = dlsym(handle, procname);
67 }
68 return retval;
69 }
70
71 void
72 X11_GLES_UnloadLibrary(_THIS)
73 {
74 if (_this->gl_config.driver_loaded) {
75 _this->gles_data->eglTerminate(_this->gles_data->egl_display);
76
77 dlclose(_this->gl_config.dll_handle);
78
79 _this->gles_data->eglGetProcAddress = NULL;
80 _this->gles_data->eglChooseConfig = NULL;
81 _this->gles_data->eglCreateContext = NULL;
82 _this->gles_data->eglCreateWindowSurface = NULL;
83 _this->gles_data->eglDestroyContext = NULL;
84 _this->gles_data->eglDestroySurface = NULL;
85 _this->gles_data->eglMakeCurrent = NULL;
86 _this->gles_data->eglSwapBuffers = NULL;
87 _this->gles_data->eglGetDisplay = NULL;
88 _this->gles_data->eglTerminate = NULL;
89
90 _this->gl_config.dll_handle = NULL;
91 _this->gl_config.driver_loaded = 0;
92 }
93 }
94
95 int
96 X11_GLES_LoadLibrary(_THIS, const char *path)
97 {
98 void *handle;
99 int dlopen_flags;
100
101 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
102
103 if (_this->gles_data->egl_active) {
104 SDL_SetError("OpenGL ES context already created");
105 return -1;
106 }
107 #ifdef RTLD_GLOBAL
108 dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
109 #else
110 dlopen_flags = RTLD_LAZY;
111 #endif
112 handle = dlopen(path, dlopen_flags);
113 /* Catch the case where the application isn't linked with EGL */
114 if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) {
115
116 dlclose(handle);
117 path = getenv("SDL_VIDEO_GL_DRIVER");
118 if (path == NULL) {
119 path = DEFAULT_OPENGL;
120 }
121 handle = dlopen(path, dlopen_flags);
122 }
123
124 if (handle == NULL) {
125 SDL_SetError("Could not load OpenGL ES/EGL library");
126 return -1;
127 }
128
129 /* Unload the old driver and reset the pointers */
130 X11_GLES_UnloadLibrary(_this);
131
132 /* Load new function pointers */
133 LOAD_FUNC(eglGetDisplay);
134 LOAD_FUNC(eglInitialize);
135 LOAD_FUNC(eglTerminate);
136 LOAD_FUNC(eglGetProcAddress);
137 LOAD_FUNC(eglChooseConfig);
138 LOAD_FUNC(eglGetConfigAttrib);
139 LOAD_FUNC(eglCreateContext);
140 LOAD_FUNC(eglDestroyContext);
141 LOAD_FUNC(eglCreateWindowSurface);
142 LOAD_FUNC(eglDestroySurface);
143 LOAD_FUNC(eglMakeCurrent);
144 LOAD_FUNC(eglSwapBuffers);
145
146 _this->gles_data->egl_display =
147 _this->gles_data->eglGetDisplay((NativeDisplayType) data->display);
148
149 if (!_this->gles_data->egl_display) {
150 SDL_SetError("Could not get EGL display");
151 return -1;
152 }
153
154 if (_this->gles_data->
155 eglInitialize(_this->gles_data->egl_display, NULL,
156 NULL) != EGL_TRUE) {
157 SDL_SetError("Could not initialize EGL");
158 return -1;
159 }
160
161 _this->gl_config.dll_handle = handle;
162 _this->gl_config.driver_loaded = 1;
163
164 if (path) {
165 strncpy(_this->gl_config.driver_path, path,
166 sizeof(_this->gl_config.driver_path) - 1);
167 } else {
168 strcpy(_this->gl_config.driver_path, "");
169 }
170 return 0;
171 }
172
173 XVisualInfo *
174 X11_GLES_GetVisual(_THIS, Display * display, int screen)
175 {
176 /* 64 seems nice. */
177 EGLint attribs[64];
178 EGLint found_configs = 0;
179 VisualID visual_id;
180 int i;
181
182 /* load the gl driver from a default path */
183 if (!_this->gl_config.driver_loaded) {
184 /* no driver has been loaded, use default (ourselves) */
185 if (X11_GLES_LoadLibrary(_this, NULL) < 0) {
186 return NULL;
187 }
188 }
189
190 i = 0;
191 attribs[i++] = EGL_RED_SIZE;
192 attribs[i++] = _this->gl_config.red_size;
193 attribs[i++] = EGL_GREEN_SIZE;
194 attribs[i++] = _this->gl_config.green_size;
195 attribs[i++] = EGL_BLUE_SIZE;
196 attribs[i++] = _this->gl_config.blue_size;
197
198 if (_this->gl_config.alpha_size) {
199 attribs[i++] = EGL_ALPHA_SIZE;
200 attribs[i++] = _this->gl_config.alpha_size;
201 }
202
203 if (_this->gl_config.buffer_size) {
204 attribs[i++] = EGL_BUFFER_SIZE;
205 attribs[i++] = _this->gl_config.buffer_size;
206 }
207
208 attribs[i++] = EGL_DEPTH_SIZE;
209 attribs[i++] = _this->gl_config.depth_size;
210
211 if (_this->gl_config.stencil_size) {
212 attribs[i++] = EGL_STENCIL_SIZE;
213 attribs[i++] = _this->gl_config.stencil_size;
214 }
215
216 if (_this->gl_config.multisamplebuffers) {
217 attribs[i++] = EGL_SAMPLE_BUFFERS;
218 attribs[i++] = _this->gl_config.multisamplebuffers;
219 }
220
221 if (_this->gl_config.multisamplesamples) {
222 attribs[i++] = EGL_SAMPLES;
223 attribs[i++] = _this->gl_config.multisamplesamples;
224 }
225
226 attribs[i++] = EGL_NONE;
227
228 if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
229 attribs,
230 &_this->gles_data->egl_config, 1,
231 &found_configs) == EGL_FALSE ||
232 found_configs == 0) {
233 SDL_SetError("Couldn't find matching EGL config");
234 return NULL;
235 }
236
237 if (_this->gles_data->eglGetConfigAttrib(_this->gles_data->egl_display,
238 _this->gles_data->egl_config,
239 EGL_NATIVE_VISUAL_ID,
240 (EGLint *) & visual_id) ==
241 EGL_FALSE || !visual_id) {
242 /* Use the default visual when all else fails */
243 XVisualInfo vi_in;
244 int out_count;
245 vi_in.screen = screen;
246
247 _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
248 VisualScreenMask,
249 &vi_in, &out_count);
250 } else {
251 XVisualInfo vi_in;
252 int out_count;
253
254 vi_in.screen = screen;
255 vi_in.visualid = visual_id;
256 _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
257 VisualScreenMask |
258 VisualIDMask,
259 &vi_in, &out_count);
260 }
261
262 return _this->gles_data->egl_visualinfo;
263 }
264
265 SDL_GLContext
266 X11_GLES_CreateContext(_THIS, SDL_Window * window)
267 {
268 int retval;
269 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
270 Display *display = data->videodata->display;
271
272 XSync(display, False);
273
274
275 _this->gles_data->egl_context =
276 _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
277 _this->gles_data->egl_config,
278 EGL_NO_CONTEXT, NULL);
279 XSync(display, False);
280
281 if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
282 SDL_SetError("Could not create EGL context");
283 return NULL;
284 }
285
286 _this->gles_data->egl_active = 1;
287
288 if (_this->gles_data->egl_active)
289 retval = 1;
290 else
291 retval = 0;
292
293 return (retval);
294 }
295
296 int
297 X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
298 {
299 int retval;
300
301 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
302 Display *display = data->videodata->display;
303
304 retval = 1;
305 if (!_this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
306 _this->gles_data->egl_surface,
307 _this->gles_data->egl_surface,
308 _this->gles_data->egl_context)) {
309 SDL_SetError("Unable to make EGL context current");
310 retval = -1;
311 }
312 XSync(display, False);
313
314 return (retval);
315 }
316
317 static int swapinterval = -1;
318 int
319 X11_GLES_SetSwapInterval(_THIS, int interval)
320 {
321 return 0;
322 }
323
324 int
325 X11_GLES_GetSwapInterval(_THIS)
326 {
327 return 0;
328 }
329
330 void
331 X11_GLES_SwapWindow(_THIS, SDL_Window * window)
332 {
333 _this->gles_data->eglSwapBuffers(_this->gles_data->egl_display,
334 _this->gles_data->egl_surface);
335 }
336
337 void
338 X11_GLES_DeleteContext(_THIS, SDL_GLContext context)
339 {
340 /* Clean up GLES and EGL */
341 if (_this->gles_data->egl_context != EGL_NO_CONTEXT ||
342 _this->gles_data->egl_surface != EGL_NO_SURFACE) {
343 _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
344 EGL_NO_SURFACE, EGL_NO_SURFACE,
345 EGL_NO_CONTEXT);
346
347 if (_this->gles_data->egl_context != EGL_NO_CONTEXT) {
348 _this->gles_data->eglDestroyContext(_this->gles_data->egl_display,
349 _this->gles_data->
350 egl_context);
351 _this->gles_data->egl_context = EGL_NO_CONTEXT;
352 }
353
354 if (_this->gles_data->egl_surface != EGL_NO_SURFACE) {
355 _this->gles_data->eglDestroySurface(_this->gles_data->egl_display,
356 _this->gles_data->
357 egl_surface);
358 _this->gles_data->egl_surface = EGL_NO_SURFACE;
359 }
360 }
361 _this->gles_data->egl_active = 0;
362 }
363
364 #endif /* SDL_VIDEO_OPENGL_ES */
365
366 /* vi: set ts=4 sw=4 expandtab: */