21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_DRIVER_X11 30 #if SDL_VIDEO_OPENGL_GLX 36 #define DEFAULT_OPENGL "libGL.so" 37 #elif defined(__MACOSX__) 38 #define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib" 39 #elif defined(__QNXNTO__) 40 #define DEFAULT_OPENGL "libGL.so.3" 42 #define DEFAULT_OPENGL "libGL.so.1" 46 #define GLX_NONE_EXT 0x8000 49 #ifndef GLX_ARB_multisample 50 #define GLX_ARB_multisample 51 #define GLX_SAMPLE_BUFFERS_ARB 100000 52 #define GLX_SAMPLES_ARB 100001 55 #ifndef GLX_EXT_visual_rating 56 #define GLX_EXT_visual_rating 57 #define GLX_VISUAL_CAVEAT_EXT 0x20 58 #define GLX_NONE_EXT 0x8000 59 #define GLX_SLOW_VISUAL_EXT 0x8001 60 #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D 63 #ifndef GLX_EXT_visual_info 64 #define GLX_EXT_visual_info 65 #define GLX_X_VISUAL_TYPE_EXT 0x22 66 #define GLX_DIRECT_COLOR_EXT 0x8003 69 #ifndef GLX_ARB_create_context 70 #define GLX_ARB_create_context 71 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 72 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 73 #define GLX_CONTEXT_FLAGS_ARB 0x2094 74 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 75 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 78 typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *
dpy,
87 #ifndef GLX_ARB_create_context_profile 88 #define GLX_ARB_create_context_profile 89 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 90 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 91 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 94 #ifndef GLX_ARB_create_context_robustness 95 #define GLX_ARB_create_context_robustness 96 #define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 97 #define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 98 #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 99 #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 102 #ifndef GLX_EXT_create_context_es2_profile 103 #define GLX_EXT_create_context_es2_profile 104 #ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT 105 #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002 109 #ifndef GLX_ARB_framebuffer_sRGB 110 #define GLX_ARB_framebuffer_sRGB 111 #ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 112 #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 116 #ifndef GLX_EXT_swap_control 117 #define GLX_SWAP_INTERVAL_EXT 0x20F1 118 #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 121 #ifndef GLX_EXT_swap_control_tear 122 #define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 125 #ifndef GLX_ARB_context_flush_control 126 #define GLX_ARB_context_flush_control 127 #define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 128 #define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 129 #define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 132 #define OPENGL_REQUIRES_DLOPEN 133 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) 135 #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) 136 #define GL_LoadFunction dlsym 137 #define GL_UnloadObject dlclose 139 #define GL_LoadObject SDL_LoadObject 140 #define GL_LoadFunction SDL_LoadFunction 141 #define GL_UnloadObject SDL_UnloadObject 144 static void X11_GL_InitExtensions(
_THIS);
148 X11_GL_LoadLibrary(
_THIS,
const char *
path)
162 path = DEFAULT_OPENGL;
166 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) 186 (Bool (*)(Display *,
int *,
int *))
187 GL_LoadFunction(handle,
"glXQueryExtension");
190 GL_LoadFunction(handle,
"glXGetProcAddressARB");
192 (XVisualInfo * (*)(Display *, int,
int *))
193 X11_GL_GetProcAddress(
_this,
"glXChooseVisual");
195 (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
196 X11_GL_GetProcAddress(
_this,
"glXCreateContext");
198 (
void (*)(Display *, GLXContext))
199 X11_GL_GetProcAddress(
_this,
"glXDestroyContext");
201 (int (*)(Display *, GLXDrawable, GLXContext))
202 X11_GL_GetProcAddress(
_this,
"glXMakeCurrent");
204 (
void (*)(Display *, GLXDrawable))
205 X11_GL_GetProcAddress(
_this,
"glXSwapBuffers");
207 (
void (*)(Display*,GLXDrawable,int,
unsigned int*))
208 X11_GL_GetProcAddress(
_this,
"glXQueryDrawable");
216 return SDL_SetError(
"Could not retrieve OpenGL functions");
225 X11_GL_InitExtensions(
_this);
231 !
_this->
gl_data->HAS_GLX_EXT_create_context_es2_profile ) {
232 #if SDL_VIDEO_OPENGL_EGL 233 X11_GL_UnloadLibrary(
_this);
248 return X11_GLES_LoadLibrary(
_this,
NULL);
250 return SDL_SetError(
"SDL not configured with EGL support");
258 X11_GL_GetProcAddress(
_THIS,
const char *proc)
267 X11_GL_UnloadLibrary(
_THIS)
284 HasExtension(
const char *extension,
const char *extensions)
287 const char *where, *terminator;
294 if (where || *extension ==
'\0')
309 if (where == start || *(where - 1) ==
' ')
310 if (*terminator ==
' ' || *terminator ==
'\0')
319 X11_GL_InitExtensions(
_THIS)
322 const int screen = DefaultScreen(display);
323 const char *(*glXQueryExtensionsStringFunc) (Display *, int);
324 const char *extensions;
326 glXQueryExtensionsStringFunc =
327 (
const char *(*)(Display *, int)) X11_GL_GetProcAddress(
_this,
328 "glXQueryExtensionsString");
329 if (glXQueryExtensionsStringFunc) {
330 extensions = glXQueryExtensionsStringFunc(display, screen);
337 if (HasExtension(
"GLX_EXT_swap_control", extensions)) {
339 (
void (*)(Display*,GLXDrawable,int))
340 X11_GL_GetProcAddress(
_this,
"glXSwapIntervalEXT");
341 if (HasExtension(
"GLX_EXT_swap_control_tear", extensions)) {
347 if (HasExtension(
"GLX_MESA_swap_control", extensions)) {
349 (int(*)(int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalMESA");
351 (int(*)(
void)) X11_GL_GetProcAddress(
_this,
352 "glXGetSwapIntervalMESA");
356 if (HasExtension(
"GLX_SGI_swap_control", extensions)) {
358 (int (*)(int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalSGI");
362 if (HasExtension(
"GLX_ARB_create_context", extensions)) {
364 (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,
const int *))
365 X11_GL_GetProcAddress(
_this,
"glXCreateContextAttribsARB");
367 (GLXFBConfig *(*)(Display *, int,
const int *,
int *))
368 X11_GL_GetProcAddress(
_this,
"glXChooseFBConfig");
372 if (HasExtension(
"GLX_EXT_visual_rating", extensions)) {
377 if (HasExtension(
"GLX_EXT_visual_info", extensions)) {
382 if (HasExtension(
"GLX_EXT_create_context_es2_profile", extensions)) {
387 if (HasExtension(
"GLX_ARB_context_flush_control", extensions)) {
396 X11_GL_GetAttributes(
_THIS, Display * display,
int screen,
int *
attribs,
int size, Bool for_FBConfig)
399 const int MAX_ATTRIBUTES = 64;
406 attribs[i++] = GLX_RENDER_TYPE;
407 attribs[i++] = GLX_RGBA_BIT;
409 attribs[i++] = GLX_RGBA;
411 attribs[i++] = GLX_RED_SIZE;
413 attribs[i++] = GLX_GREEN_SIZE;
415 attribs[i++] = GLX_BLUE_SIZE;
419 attribs[i++] = GLX_ALPHA_SIZE;
424 attribs[i++] = GLX_DOUBLEBUFFER;
430 attribs[i++] = GLX_DEPTH_SIZE;
434 attribs[i++] = GLX_STENCIL_SIZE;
439 attribs[i++] = GLX_ACCUM_RED_SIZE;
444 attribs[i++] = GLX_ACCUM_GREEN_SIZE;
449 attribs[i++] = GLX_ACCUM_BLUE_SIZE;
454 attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
459 attribs[i++] = GLX_STEREO;
466 attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
471 attribs[i++] = GLX_SAMPLES_ARB;
476 attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
482 attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
491 attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
492 attribs[i++] = GLX_DIRECT_COLOR_EXT;
503 X11_GL_GetVisual(
_THIS, Display * display,
int screen)
514 X11_GL_GetAttributes(
_this, display, screen, attribs, 64,
SDL_FALSE);
515 vinfo =
_this->
gl_data->glXChooseVisual(display, screen, attribs);
522 #ifndef GLXBadContext 523 #define GLXBadContext 0 525 #ifndef GLXBadFBConfig 526 #define GLXBadFBConfig 9 528 #ifndef GLXBadProfileARB 529 #define GLXBadProfileARB 13 531 static int (*handler) (Display *, XErrorEvent *) =
NULL;
532 static const char *errorHandlerOperation =
NULL;
533 static int errorBase = 0;
534 static int errorCode = 0;
536 X11_GL_ErrorHandler(Display *
d, XErrorEvent *
e)
538 char *x11_error =
NULL;
539 char x11_error_locale[256];
541 errorCode = e->error_code;
542 if (X11_XGetErrorText(d, errorCode, x11_error_locale,
sizeof(x11_error_locale)) == Success)
549 SDL_SetError(
"Could not %s: %s", errorHandlerOperation, x11_error);
554 SDL_SetError(
"Could not %s: %i (Base %i)\n", errorHandlerOperation, errorCode, errorBase);
567 XWindowAttributes xattr;
568 XVisualInfo
v, *vinfo;
575 share_context =
NULL;
579 X11_XSync(display, False);
580 errorHandlerOperation =
"create GL context";
583 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
584 X11_XGetWindowAttributes(display, data->
xwindow, &xattr);
586 v.visualid = X11_XVisualIDFromVisual(xattr.visual);
587 vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
594 _this->
gl_data->glXCreateContext(display, vinfo, share_context, True);
598 GLX_CONTEXT_MAJOR_VERSION_ARB,
600 GLX_CONTEXT_MINOR_VERSION_ARB,
608 attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
614 attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
619 if(
_this->
gl_data->HAS_GLX_ARB_context_flush_control ) {
620 attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
623 GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
624 GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
627 attribs[iattr++] = 0;
631 SDL_SetError(
"OpenGL 3.0 and later are not supported by this system");
636 GLXFBConfig *framebuffer_config =
NULL;
639 X11_GL_GetAttributes(
_this,display,screen,glxAttribs,64,
SDL_TRUE);
642 || !(framebuffer_config =
644 DefaultScreen(display), glxAttribs,
646 SDL_SetError(
"No good framebuffers found. OpenGL 3.0 and later unavailable");
648 context =
_this->
gl_data->glXCreateContextAttribsARB(display,
649 framebuffer_config[0],
650 share_context, True, attribs);
656 X11_XSync(display, False);
657 X11_XSetErrorHandler(handler);
660 if (errorCode == Success) {
666 if (X11_GL_MakeCurrent(
_this, window, context) < 0) {
667 X11_GL_DeleteContext(
_this, context);
680 GLXContext glx_context = (GLXContext) context;
688 X11_XSync(display, False);
689 errorHandlerOperation =
"make GL context current";
692 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
693 rc =
_this->
gl_data->glXMakeCurrent(display, drawable, glx_context);
694 X11_XSetErrorHandler(handler);
696 if (errorCode != Success) {
699 return SDL_SetError(
"Unable to make GL context current");
715 X11_GL_SetSwapInterval(
_THIS,
int interval)
719 if ((interval < 0) && (!
_this->
gl_data->HAS_GLX_EXT_swap_control_tear)) {
720 SDL_SetError(
"Negative swap interval unsupported in this GL");
726 Window drawable = windowdata->
xwindow;
736 int currentInterval = X11_GL_GetSwapInterval(
_this);
737 _this->
gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
738 _this->
gl_data->glXSwapIntervalEXT(display, drawable, interval);
741 swapinterval = interval;
747 swapinterval = interval;
754 swapinterval = interval;
763 X11_GL_GetSwapInterval(
_THIS)
769 Window drawable = windowdata->
xwindow;
770 unsigned int allow_late_swap_tearing = 0;
771 unsigned int interval = 0;
775 GLX_LATE_SWAPS_TEAR_EXT,
776 &allow_late_swap_tearing);
780 GLX_SWAP_INTERVAL_EXT, &interval);
782 if ((allow_late_swap_tearing) && (interval > 0)) {
783 return -((int) interval);
786 return (
int) interval;
807 GLXContext glx_context = (GLXContext) context;
812 _this->
gl_data->glXDestroyContext(display, glx_context);
813 X11_XSync(display, False);
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 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display dpy)
struct wl_display * display
static SDL_Window * window
SDL_bool X11_UseDirectColorVisuals(void)
int(* GL_SetSwapInterval)(_THIS, int interval)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
int(* GL_LoadLibrary)(_THIS, const char *path)
struct SDL_GLDriverData * gl_data
static SDL_VideoDevice * _this
void * SDL_calloc(size_t nmemb, size_t size)
void * SDL_GLContext
An opaque handle to an OpenGL context.
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
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 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
struct SDL_VideoData * videodata
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
int framebuffer_srgb_capable
void(* GL_UnloadLibrary)(_THIS)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int share_with_current_context
#define SDL_assert(condition)
#define SDL_OutOfMemory()
#define SDL_GL_GetCurrentContext
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
#define SDL_GL_GetCurrentWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
The type used to identify a window.
struct SDL_VideoDevice::@28 gl_config
#define SDL_arraysize(array)
GLsizei const GLchar *const * path
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_GetSwapInterval)(_THIS)
#define SDL_Unsupported()
void *(* GL_GetProcAddress)(_THIS, const char *proc)