PageRenderTime 39ms CodeModel.GetById 16ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sdl-1.3/src/video/x11/SDL_x11opengles.c

https://github.com/aichunyu/FFPlayer
C | 429 lines | 326 code | 69 blank | 34 comment | 65 complexity | 49d5c1280c41aab63dc7d79c56ad1eb7 MD5 | raw file
  1/*
  2  Simple DirectMedia Layer
  3  Copyright (C) 1997-2012 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_config.h"
 22
 23#if SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_ES
 24
 25#include "SDL_x11video.h"
 26#include "SDL_x11opengles.h"
 27
 28#define DEFAULT_EGL "libEGL.so"
 29#define DEFAULT_OGL_ES2 "libGLESv2.so"
 30#define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
 31#define DEFAULT_OGL_ES "libGLESv1_CM.so"
 32
 33#define LOAD_FUNC(NAME) \
 34	*((void**)&_this->gles_data->NAME) = dlsym(handle, #NAME); \
 35	if (!_this->gles_data->NAME) \
 36	{ \
 37		SDL_SetError("Could not retrieve EGL function " #NAME); \
 38		return -1; \
 39	}
 40
 41/* GLES implementation of SDL OpenGL support */
 42
 43void *
 44X11_GLES_GetProcAddress(_THIS, const char *proc)
 45{
 46    static char procname[1024];
 47    void *handle;
 48    void *retval;
 49
 50    handle = _this->gles_data->egl_dll_handle;
 51    if (_this->gles_data->eglGetProcAddress) {
 52        retval = _this->gles_data->eglGetProcAddress(proc);
 53        if (retval) {
 54            return retval;
 55        }
 56    }
 57    
 58    handle = _this->gl_config.dll_handle;
 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
 71void
 72X11_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        dlclose(_this->gles_data->egl_dll_handle);
 79
 80        _this->gles_data->eglGetProcAddress = NULL;
 81        _this->gles_data->eglChooseConfig = NULL;
 82        _this->gles_data->eglCreateContext = NULL;
 83        _this->gles_data->eglCreateWindowSurface = NULL;
 84        _this->gles_data->eglDestroyContext = NULL;
 85        _this->gles_data->eglDestroySurface = NULL;
 86        _this->gles_data->eglMakeCurrent = NULL;
 87        _this->gles_data->eglSwapBuffers = NULL;
 88        _this->gles_data->eglGetDisplay = NULL;
 89        _this->gles_data->eglTerminate = NULL;
 90
 91        _this->gl_config.dll_handle = NULL;
 92        _this->gl_config.driver_loaded = 0;
 93    }
 94}
 95
 96int
 97X11_GLES_LoadLibrary(_THIS, const char *path)
 98{
 99    void *handle;
100    int dlopen_flags;
101
102    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
103
104    if (_this->gles_data->egl_active) {
105        SDL_SetError("OpenGL ES context already created");
106        return -1;
107    }
108#ifdef RTLD_GLOBAL
109    dlopen_flags = RTLD_LAZY | RTLD_GLOBAL;
110#else
111    dlopen_flags = RTLD_LAZY;
112#endif
113    handle = dlopen(path, dlopen_flags);
114    /* Catch the case where the application isn't linked with EGL */
115    if ((dlsym(handle, "eglChooseConfig") == NULL) && (path == NULL)) {
116
117        dlclose(handle);
118        path = getenv("SDL_VIDEO_GL_DRIVER");
119        if (path == NULL) {
120            path = DEFAULT_EGL;
121        }
122        handle = dlopen(path, dlopen_flags);
123    }
124
125    if (handle == NULL) {
126        SDL_SetError("Could not load OpenGL ES/EGL library");
127        return -1;
128    }
129
130    /* Unload the old driver and reset the pointers */
131    X11_GLES_UnloadLibrary(_this);
132
133    /* Load new function pointers */
134    LOAD_FUNC(eglGetDisplay);
135    LOAD_FUNC(eglInitialize);
136    LOAD_FUNC(eglTerminate);
137    LOAD_FUNC(eglGetProcAddress);
138    LOAD_FUNC(eglChooseConfig);
139    LOAD_FUNC(eglGetConfigAttrib);
140    LOAD_FUNC(eglCreateContext);
141    LOAD_FUNC(eglDestroyContext);
142    LOAD_FUNC(eglCreateWindowSurface);
143    LOAD_FUNC(eglDestroySurface);
144    LOAD_FUNC(eglMakeCurrent);
145    LOAD_FUNC(eglSwapBuffers);
146    LOAD_FUNC(eglSwapInterval);
147
148    _this->gles_data->egl_display =
149        _this->gles_data->eglGetDisplay((NativeDisplayType) data->display);
150
151    if (!_this->gles_data->egl_display) {
152        SDL_SetError("Could not get EGL display");
153        return -1;
154    }
155
156    if (_this->gles_data->
157        eglInitialize(_this->gles_data->egl_display, NULL,
158                      NULL) != EGL_TRUE) {
159        SDL_SetError("Could not initialize EGL");
160        return -1;
161    }
162
163    _this->gles_data->egl_dll_handle = handle;
164
165    path = getenv("SDL_VIDEO_GL_DRIVER");
166    handle = dlopen(path, dlopen_flags);
167    if ((path == NULL) | (handle == NULL)) {
168        if (_this->gl_config.major_version > 1) {
169            path = DEFAULT_OGL_ES2;
170            handle = dlopen(path, dlopen_flags);
171        } else {
172            path = DEFAULT_OGL_ES;
173            handle = dlopen(path, dlopen_flags);
174            if (handle == NULL) {
175                path = DEFAULT_OGL_ES_PVR;
176                handle = dlopen(path, dlopen_flags);
177            }
178        }
179    }
180
181    if (handle == NULL) {
182        SDL_SetError("Could not initialize OpenGL ES library");
183        return -1;
184    }
185
186    _this->gl_config.dll_handle = handle;
187    _this->gl_config.driver_loaded = 1;
188
189    if (path) {
190        strncpy(_this->gl_config.driver_path, path,
191                sizeof(_this->gl_config.driver_path) - 1);
192    } else {
193        strcpy(_this->gl_config.driver_path, "");
194    }
195    return 0;
196}
197
198XVisualInfo *
199X11_GLES_GetVisual(_THIS, Display * display, int screen)
200{
201    /* 64 seems nice. */
202    EGLint attribs[64];
203    EGLint found_configs = 0;
204    VisualID visual_id;
205    int i;
206
207    /* load the gl driver from a default path */
208    if (!_this->gl_config.driver_loaded) {
209        /* no driver has been loaded, use default (ourselves) */
210        if (X11_GLES_LoadLibrary(_this, NULL) < 0) {
211            return NULL;
212        }
213    }
214
215    i = 0;
216    attribs[i++] = EGL_RED_SIZE;
217    attribs[i++] = _this->gl_config.red_size;
218    attribs[i++] = EGL_GREEN_SIZE;
219    attribs[i++] = _this->gl_config.green_size;
220    attribs[i++] = EGL_BLUE_SIZE;
221    attribs[i++] = _this->gl_config.blue_size;
222
223    if (_this->gl_config.alpha_size) {
224        attribs[i++] = EGL_ALPHA_SIZE;
225        attribs[i++] = _this->gl_config.alpha_size;
226    }
227
228    if (_this->gl_config.buffer_size) {
229        attribs[i++] = EGL_BUFFER_SIZE;
230        attribs[i++] = _this->gl_config.buffer_size;
231    }
232
233    attribs[i++] = EGL_DEPTH_SIZE;
234    attribs[i++] = _this->gl_config.depth_size;
235
236    if (_this->gl_config.stencil_size) {
237        attribs[i++] = EGL_STENCIL_SIZE;
238        attribs[i++] = _this->gl_config.stencil_size;
239    }
240
241    if (_this->gl_config.multisamplebuffers) {
242        attribs[i++] = EGL_SAMPLE_BUFFERS;
243        attribs[i++] = _this->gl_config.multisamplebuffers;
244    }
245
246    if (_this->gl_config.multisamplesamples) {
247        attribs[i++] = EGL_SAMPLES;
248        attribs[i++] = _this->gl_config.multisamplesamples;
249    }
250
251    attribs[i++] = EGL_RENDERABLE_TYPE;
252    if (_this->gl_config.major_version == 2) {
253        attribs[i++] = EGL_OPENGL_ES2_BIT;
254    } else {
255        attribs[i++] = EGL_OPENGL_ES_BIT;
256    }
257
258    attribs[i++] = EGL_NONE;
259
260    if (_this->gles_data->eglChooseConfig(_this->gles_data->egl_display,
261                                          attribs,
262                                          &_this->gles_data->egl_config, 1,
263                                          &found_configs) == EGL_FALSE ||
264        found_configs == 0) {
265        SDL_SetError("Couldn't find matching EGL config");
266        return NULL;
267    }
268
269    if (_this->gles_data->eglGetConfigAttrib(_this->gles_data->egl_display,
270                                             _this->gles_data->egl_config,
271                                             EGL_NATIVE_VISUAL_ID,
272                                             (EGLint *) & visual_id) ==
273        EGL_FALSE || !visual_id) {
274        /* Use the default visual when all else fails */
275        XVisualInfo vi_in;
276        int out_count;
277        vi_in.screen = screen;
278
279        _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
280                                                          VisualScreenMask,
281                                                          &vi_in, &out_count);
282    } else {
283        XVisualInfo vi_in;
284        int out_count;
285
286        vi_in.screen = screen;
287        vi_in.visualid = visual_id;
288        _this->gles_data->egl_visualinfo = XGetVisualInfo(display,
289                                                          VisualScreenMask |
290                                                          VisualIDMask,
291                                                          &vi_in, &out_count);
292    }
293
294    return _this->gles_data->egl_visualinfo;
295}
296
297SDL_GLContext
298X11_GLES_CreateContext(_THIS, SDL_Window * window)
299{
300    EGLint context_attrib_list[] = {
301        EGL_CONTEXT_CLIENT_VERSION,
302        1,
303        EGL_NONE
304    };
305
306    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
307    Display *display = data->videodata->display;
308    SDL_GLContext context = 1;
309
310    XSync(display, False);
311
312    if (_this->gl_config.major_version) {
313        context_attrib_list[1] = _this->gl_config.major_version;
314    }
315
316    _this->gles_data->egl_context =
317        _this->gles_data->eglCreateContext(_this->gles_data->egl_display,
318                                           _this->gles_data->egl_config,
319                                           EGL_NO_CONTEXT, context_attrib_list);
320    XSync(display, False);
321
322    if (_this->gles_data->egl_context == EGL_NO_CONTEXT) {
323        SDL_SetError("Could not create EGL context");
324        return NULL;
325    }
326
327    _this->gles_data->egl_active = 1;
328    _this->gles_data->egl_swapinterval = 0;
329
330    if (X11_GLES_MakeCurrent(_this, window, context) < 0) {
331        X11_GLES_DeleteContext(_this, context);
332        return NULL;
333    }
334
335    return context;
336}
337
338int
339X11_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
340{
341    int retval;
342
343//    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
344//    Display *display = data->videodata->display;
345
346    retval = 1;
347    if (!_this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
348                                          _this->gles_data->egl_surface,
349                                          _this->gles_data->egl_surface,
350                                          _this->gles_data->egl_context)) {
351        SDL_SetError("Unable to make EGL context current");
352        retval = -1;
353    }
354//    XSync(display, False);
355
356    return (retval);
357}
358
359int
360X11_GLES_SetSwapInterval(_THIS, int interval)
361{
362    if (_this->gles_data->egl_active != 1) {
363        SDL_SetError("OpenGL ES context not active");
364        return -1;
365    }
366
367    EGLBoolean status;
368    status = _this->gles_data->eglSwapInterval(_this->gles_data->egl_display, interval);
369    if (status == EGL_TRUE) {
370        _this->gles_data->egl_swapinterval = interval;
371        return 0; 
372    }
373
374    SDL_SetError("Unable to set the EGL swap interval");
375    return -1;
376}
377
378int
379X11_GLES_GetSwapInterval(_THIS)
380{
381    if (_this->gles_data->egl_active != 1) {
382        SDL_SetError("OpenGL ES context not active");
383        return -1;
384    }
385
386    return _this->gles_data->egl_swapinterval;
387}
388
389void
390X11_GLES_SwapWindow(_THIS, SDL_Window * window)
391{
392    _this->gles_data->eglSwapBuffers(_this->gles_data->egl_display,
393                                     _this->gles_data->egl_surface);
394}
395
396void
397X11_GLES_DeleteContext(_THIS, SDL_GLContext context)
398{
399    /* Clean up GLES and EGL */
400    if (_this->gles_data->egl_context != EGL_NO_CONTEXT ||
401        _this->gles_data->egl_surface != EGL_NO_SURFACE) {
402        _this->gles_data->eglMakeCurrent(_this->gles_data->egl_display,
403                                         EGL_NO_SURFACE, EGL_NO_SURFACE,
404                                         EGL_NO_CONTEXT);
405
406        if (_this->gles_data->egl_context != EGL_NO_CONTEXT) {
407            _this->gles_data->eglDestroyContext(_this->gles_data->egl_display,
408                                                _this->gles_data->
409                                                egl_context);
410            _this->gles_data->egl_context = EGL_NO_CONTEXT;
411        }
412
413        if (_this->gles_data->egl_surface != EGL_NO_SURFACE) {
414            _this->gles_data->eglDestroySurface(_this->gles_data->egl_display,
415                                                _this->gles_data->
416                                                egl_surface);
417            _this->gles_data->egl_surface = EGL_NO_SURFACE;
418        }
419    }
420    _this->gles_data->egl_active = 0;
421
422/* crappy fix */
423    X11_GLES_UnloadLibrary(_this);
424
425}
426
427#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_ES */
428
429/* vi: set ts=4 sw=4 expandtab: */