Mercurial > sdl-ios-xcode
comparison src/video/x11/SDL_x11gl.c @ 1191:2bd4cec0de63
Seperate glX from HAVE_OPENGL, for platforms that have both an X server and
a more official way to do OpenGL, explicitly check for glX on Mac OS X, and
use SDL_LoadObject for platforms that have glX but don't have dlopen().
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Wed, 23 Nov 2005 11:46:36 +0000 |
parents | e8e8dcb68e7a |
children | b81f54c3963f |
comparison
equal
deleted
inserted
replaced
1190:173c063d4f55 | 1191:2bd4cec0de63 |
---|---|
35 #include "SDL_x11gl_c.h" | 35 #include "SDL_x11gl_c.h" |
36 | 36 |
37 #if defined(sgi) | 37 #if defined(sgi) |
38 /* IRIX doesn't have a GL library versioning system */ | 38 /* IRIX doesn't have a GL library versioning system */ |
39 #define DEFAULT_OPENGL "libGL.so" | 39 #define DEFAULT_OPENGL "libGL.so" |
40 #elif defined(MACOSX) | |
41 #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib" | |
40 #else | 42 #else |
41 #define DEFAULT_OPENGL "libGL.so.1" | 43 #define DEFAULT_OPENGL "libGL.so.1" |
42 #endif | 44 #endif |
43 | 45 |
44 #ifndef GLX_ARB_multisample | 46 #ifndef GLX_ARB_multisample |
48 #endif | 50 #endif |
49 | 51 |
50 /* return the preferred visual to use for openGL graphics */ | 52 /* return the preferred visual to use for openGL graphics */ |
51 XVisualInfo *X11_GL_GetVisual(_THIS) | 53 XVisualInfo *X11_GL_GetVisual(_THIS) |
52 { | 54 { |
53 #ifdef HAVE_OPENGL | 55 #ifdef HAVE_OPENGL_X11 |
54 /* 64 seems nice. */ | 56 /* 64 seems nice. */ |
55 int attribs[64]; | 57 int attribs[64]; |
56 int i; | 58 int i; |
57 | 59 |
58 /* load the gl driver from a default path */ | 60 /* load the gl driver from a default path */ |
173 } | 175 } |
174 | 176 |
175 int X11_GL_CreateWindow(_THIS, int w, int h) | 177 int X11_GL_CreateWindow(_THIS, int w, int h) |
176 { | 178 { |
177 int retval; | 179 int retval; |
178 #ifdef HAVE_OPENGL | 180 #ifdef HAVE_OPENGL_X11 |
179 XSetWindowAttributes attributes; | 181 XSetWindowAttributes attributes; |
180 unsigned long mask; | 182 unsigned long mask; |
181 unsigned long black; | 183 unsigned long black; |
182 | 184 |
183 black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, | 185 black = (glx_visualinfo->visual == DefaultVisual(SDL_Display, |
205 } | 207 } |
206 | 208 |
207 int X11_GL_CreateContext(_THIS) | 209 int X11_GL_CreateContext(_THIS) |
208 { | 210 { |
209 int retval; | 211 int retval; |
210 #ifdef HAVE_OPENGL | 212 #ifdef HAVE_OPENGL_X11 |
211 /* We do this to create a clean separation between X and GLX errors. */ | 213 /* We do this to create a clean separation between X and GLX errors. */ |
212 pXSync( SDL_Display, False ); | 214 pXSync( SDL_Display, False ); |
213 glx_context = this->gl_data->glXCreateContext(GFX_Display, | 215 glx_context = this->gl_data->glXCreateContext(GFX_Display, |
214 glx_visualinfo, NULL, True); | 216 glx_visualinfo, NULL, True); |
215 pXSync( GFX_Display, False ); | 217 pXSync( GFX_Display, False ); |
231 return(retval); | 233 return(retval); |
232 } | 234 } |
233 | 235 |
234 void X11_GL_Shutdown(_THIS) | 236 void X11_GL_Shutdown(_THIS) |
235 { | 237 { |
236 #ifdef HAVE_OPENGL | 238 #ifdef HAVE_OPENGL_X11 |
237 /* Clean up OpenGL */ | 239 /* Clean up OpenGL */ |
238 if( glx_context ) { | 240 if( glx_context ) { |
239 this->gl_data->glXMakeCurrent(GFX_Display, None, NULL); | 241 this->gl_data->glXMakeCurrent(GFX_Display, None, NULL); |
240 | 242 |
241 if (glx_context != NULL) | 243 if (glx_context != NULL) |
245 this->gl_data->glXReleaseBuffersMESA(GFX_Display,SDL_Window); | 247 this->gl_data->glXReleaseBuffersMESA(GFX_Display,SDL_Window); |
246 } | 248 } |
247 glx_context = NULL; | 249 glx_context = NULL; |
248 } | 250 } |
249 gl_active = 0; | 251 gl_active = 0; |
250 #endif /* HAVE_OPENGL */ | 252 #endif /* HAVE_OPENGL_X11 */ |
251 } | 253 } |
252 | 254 |
253 #ifdef HAVE_OPENGL | 255 #ifdef HAVE_OPENGL_X11 |
254 | 256 |
255 static int ExtensionSupported(const char *extension) | 257 static int ExtensionSupported(const char *extension) |
256 { | 258 { |
257 const GLubyte *extensions = NULL; | 259 const GLubyte *extensions = NULL; |
258 const GLubyte *start; | 260 const GLubyte *start; |
393 void X11_GL_SwapBuffers(_THIS) | 395 void X11_GL_SwapBuffers(_THIS) |
394 { | 396 { |
395 this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window); | 397 this->gl_data->glXSwapBuffers(GFX_Display, SDL_Window); |
396 } | 398 } |
397 | 399 |
398 #endif /* HAVE_OPENGL */ | 400 #endif /* HAVE_OPENGL_X11 */ |
399 | 401 |
400 void X11_GL_UnloadLibrary(_THIS) | 402 void X11_GL_UnloadLibrary(_THIS) |
401 { | 403 { |
402 #ifdef HAVE_OPENGL | 404 #ifdef HAVE_OPENGL_X11 |
403 if ( this->gl_config.driver_loaded ) { | 405 if ( this->gl_config.driver_loaded ) { |
406 | |
407 /* !!! FIXME: Can we just use SDL_UnloadObject() everywhere? */ | |
408 #ifdef USE_DLOPEN | |
404 dlclose(this->gl_config.dll_handle); | 409 dlclose(this->gl_config.dll_handle); |
410 #else | |
411 SDL_UnloadObject(this->gl_config.dll_handle); | |
412 #endif | |
405 | 413 |
406 this->gl_data->glXGetProcAddress = NULL; | 414 this->gl_data->glXGetProcAddress = NULL; |
407 this->gl_data->glXChooseVisual = NULL; | 415 this->gl_data->glXChooseVisual = NULL; |
408 this->gl_data->glXCreateContext = NULL; | 416 this->gl_data->glXCreateContext = NULL; |
409 this->gl_data->glXDestroyContext = NULL; | 417 this->gl_data->glXDestroyContext = NULL; |
414 this->gl_config.driver_loaded = 0; | 422 this->gl_config.driver_loaded = 0; |
415 } | 423 } |
416 #endif | 424 #endif |
417 } | 425 } |
418 | 426 |
419 #ifdef HAVE_OPENGL | 427 #ifdef HAVE_OPENGL_X11 |
420 | 428 |
421 /* If this is wrong, please put some #ifdefs for your platform! */ | 429 static void *do_dlsym(void *handle, const char *name) |
422 #define DEFAULT_GL_DRIVER_PATH "libGL.so.1" | 430 { |
431 /* !!! FIXME: Can we just use SDL_LoadFunction() everywhere? */ | |
432 #ifdef USE_DLOPEN | |
433 return dlsym(handle, name); | |
434 #else | |
435 return SDL_LoadFunction(handle, name); | |
436 #endif | |
437 } | |
438 | |
439 #if defined(__OpenBSD__) && !defined(__ELF__) | |
440 #define do_dlsym(x,y) do_dlsym(x, "_" y) | |
441 #endif | |
423 | 442 |
424 /* Passing a NULL path means load pointers from the application */ | 443 /* Passing a NULL path means load pointers from the application */ |
425 int X11_GL_LoadLibrary(_THIS, const char* path) | 444 int X11_GL_LoadLibrary(_THIS, const char* path) |
426 { | 445 { |
427 void* handle; | 446 void* handle = NULL; |
428 int dlopen_flags; | |
429 | 447 |
430 if ( gl_active ) { | 448 if ( gl_active ) { |
431 SDL_SetError("OpenGL context already created"); | 449 SDL_SetError("OpenGL context already created"); |
432 return -1; | 450 return -1; |
433 } | 451 } |
434 | 452 |
435 if ( path == NULL ) { | 453 if ( path == NULL ) { |
436 path = DEFAULT_GL_DRIVER_PATH; | |
437 } | |
438 | |
439 #ifdef RTLD_GLOBAL | |
440 dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; | |
441 #else | |
442 dlopen_flags = RTLD_LAZY; | |
443 #endif | |
444 handle = dlopen(path, dlopen_flags); | |
445 /* Catch the case where the application isn't linked with GL */ | |
446 if ( (dlsym(handle, "glXChooseVisual") == NULL) && (path == NULL) ) { | |
447 dlclose(handle); | |
448 path = getenv("SDL_VIDEO_GL_DRIVER"); | 454 path = getenv("SDL_VIDEO_GL_DRIVER"); |
449 if ( path == NULL ) { | 455 if ( path == NULL ) { |
450 path = DEFAULT_OPENGL; | 456 path = DEFAULT_OPENGL; |
451 } | 457 } |
458 } | |
459 | |
460 /* !!! FIXME: Can we just use SDL_LoadObject() everywhere? */ | |
461 #ifdef USE_DLOPEN | |
462 { | |
463 #ifdef RTLD_GLOBAL | |
464 int dlopen_flags = RTLD_LAZY | RTLD_GLOBAL; | |
465 #else | |
466 int dlopen_flags = RTLD_LAZY; | |
467 #endif | |
452 handle = dlopen(path, dlopen_flags); | 468 handle = dlopen(path, dlopen_flags); |
453 } | 469 } |
470 #else | |
471 handle = SDL_LoadObject(path); | |
472 #endif | |
473 | |
454 if ( handle == NULL ) { | 474 if ( handle == NULL ) { |
455 SDL_SetError("Could not load OpenGL library"); | 475 SDL_SetError("Could not load OpenGL library"); |
456 return -1; | 476 return -1; |
457 } | 477 } |
458 | 478 |
459 /* Unload the old driver and reset the pointers */ | 479 /* Unload the old driver and reset the pointers */ |
460 X11_GL_UnloadLibrary(this); | 480 X11_GL_UnloadLibrary(this); |
461 | 481 |
462 /* Load new function pointers */ | 482 /* Load new function pointers */ |
463 this->gl_data->glXGetProcAddress = | 483 this->gl_data->glXGetProcAddress = |
464 (void *(*)(const GLubyte *)) dlsym(handle, "glXGetProcAddressARB"); | 484 (void *(*)(const GLubyte *)) do_dlsym(handle, "glXGetProcAddressARB"); |
465 this->gl_data->glXChooseVisual = | 485 this->gl_data->glXChooseVisual = |
466 (XVisualInfo *(*)(Display *, int, int *)) dlsym(handle, "glXChooseVisual"); | 486 (XVisualInfo *(*)(Display *, int, int *)) do_dlsym(handle, "glXChooseVisual"); |
467 this->gl_data->glXCreateContext = | 487 this->gl_data->glXCreateContext = |
468 (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) dlsym(handle, "glXCreateContext"); | 488 (GLXContext (*)(Display *, XVisualInfo *, GLXContext, int)) do_dlsym(handle, "glXCreateContext"); |
469 this->gl_data->glXDestroyContext = | 489 this->gl_data->glXDestroyContext = |
470 (void (*)(Display *, GLXContext)) dlsym(handle, "glXDestroyContext"); | 490 (void (*)(Display *, GLXContext)) do_dlsym(handle, "glXDestroyContext"); |
471 this->gl_data->glXMakeCurrent = | 491 this->gl_data->glXMakeCurrent = |
472 (int (*)(Display *, GLXDrawable, GLXContext)) dlsym(handle, "glXMakeCurrent"); | 492 (int (*)(Display *, GLXDrawable, GLXContext)) do_dlsym(handle, "glXMakeCurrent"); |
473 this->gl_data->glXSwapBuffers = | 493 this->gl_data->glXSwapBuffers = |
474 (void (*)(Display *, GLXDrawable)) dlsym(handle, "glXSwapBuffers"); | 494 (void (*)(Display *, GLXDrawable)) do_dlsym(handle, "glXSwapBuffers"); |
475 this->gl_data->glXGetConfig = | 495 this->gl_data->glXGetConfig = |
476 (int (*)(Display *, XVisualInfo *, int, int *)) dlsym(handle, "glXGetConfig"); | 496 (int (*)(Display *, XVisualInfo *, int, int *)) do_dlsym(handle, "glXGetConfig"); |
477 this->gl_data->glXQueryExtensionsString = | 497 this->gl_data->glXQueryExtensionsString = |
478 (const char *(*)(Display *, int)) dlsym(handle, "glXQueryExtensionsString"); | 498 (const char *(*)(Display *, int)) do_dlsym(handle, "glXQueryExtensionsString"); |
479 | 499 |
480 /* We don't compare below for this in case we're not using Mesa. */ | 500 /* We don't compare below for this in case we're not using Mesa. */ |
481 this->gl_data->glXReleaseBuffersMESA = | 501 this->gl_data->glXReleaseBuffersMESA = |
482 (void (*)(Display *, GLXDrawable)) dlsym( handle, "glXReleaseBuffersMESA" ); | 502 (void (*)(Display *, GLXDrawable)) do_dlsym( handle, "glXReleaseBuffersMESA" ); |
483 | 503 |
484 | 504 |
485 if ( (this->gl_data->glXChooseVisual == NULL) || | 505 if ( (this->gl_data->glXChooseVisual == NULL) || |
486 (this->gl_data->glXCreateContext == NULL) || | 506 (this->gl_data->glXCreateContext == NULL) || |
487 (this->gl_data->glXDestroyContext == NULL) || | 507 (this->gl_data->glXDestroyContext == NULL) || |
513 handle = this->gl_config.dll_handle; | 533 handle = this->gl_config.dll_handle; |
514 if ( this->gl_data->glXGetProcAddress ) { | 534 if ( this->gl_data->glXGetProcAddress ) { |
515 return this->gl_data->glXGetProcAddress(proc); | 535 return this->gl_data->glXGetProcAddress(proc); |
516 } | 536 } |
517 #if defined(__OpenBSD__) && !defined(__ELF__) | 537 #if defined(__OpenBSD__) && !defined(__ELF__) |
518 #undef dlsym(x,y); | 538 #undef do_dlsym |
519 #endif | 539 #endif |
520 retval = dlsym(handle, proc); | 540 retval = do_dlsym(handle, proc); |
521 if (!retval && strlen(proc) <= 1022) { | 541 if (!retval && strlen(proc) <= 1022) { |
522 procname[0] = '_'; | 542 procname[0] = '_'; |
523 strcpy(procname + 1, proc); | 543 strcpy(procname + 1, proc); |
524 retval = dlsym(handle, procname); | 544 retval = do_dlsym(handle, procname); |
525 } | 545 } |
526 return retval; | 546 return retval; |
527 } | 547 } |
528 | 548 |
529 #endif /* HAVE_OPENGL */ | 549 #endif /* HAVE_OPENGL_X11 */ |