21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_X11
30 #if SDL_VIDEO_OPENGL_GLX
34 #if defined(__IRIX__) || defined(__NetBSD__) || defined(__OpenBSD__)
40 #define DEFAULT_OPENGL "libGL.so"
41 #elif defined(__MACOSX__)
42 #define DEFAULT_OPENGL "/opt/X11/lib/libGL.1.dylib"
43 #elif defined(__QNXNTO__)
44 #define DEFAULT_OPENGL "libGL.so.3"
46 #define DEFAULT_OPENGL "libGL.so.1"
50 #define GLX_NONE_EXT 0x8000
53 #ifndef GLX_ARB_multisample
54 #define GLX_ARB_multisample
55 #define GLX_SAMPLE_BUFFERS_ARB 100000
56 #define GLX_SAMPLES_ARB 100001
59 #ifndef GLX_EXT_visual_rating
60 #define GLX_EXT_visual_rating
61 #define GLX_VISUAL_CAVEAT_EXT 0x20
62 #define GLX_NONE_EXT 0x8000
63 #define GLX_SLOW_VISUAL_EXT 0x8001
64 #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
67 #ifndef GLX_EXT_visual_info
68 #define GLX_EXT_visual_info
69 #define GLX_X_VISUAL_TYPE_EXT 0x22
70 #define GLX_DIRECT_COLOR_EXT 0x8003
73 #ifndef GLX_ARB_create_context
74 #define GLX_ARB_create_context
75 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
76 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
77 #define GLX_CONTEXT_FLAGS_ARB 0x2094
78 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
79 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
82 typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *
dpy,
91 #ifndef GLX_ARB_create_context_profile
92 #define GLX_ARB_create_context_profile
93 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
94 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
95 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
98 #ifndef GLX_ARB_create_context_robustness
99 #define GLX_ARB_create_context_robustness
100 #define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
101 #define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
102 #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
103 #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
106 #ifndef GLX_EXT_create_context_es2_profile
107 #define GLX_EXT_create_context_es2_profile
108 #ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT
109 #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002
113 #ifndef GLX_ARB_framebuffer_sRGB
114 #define GLX_ARB_framebuffer_sRGB
115 #ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
116 #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
120 #ifndef GLX_ARB_create_context_no_error
121 #define GLX_ARB_create_context_no_error
122 #ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
123 #define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
127 #ifndef GLX_EXT_swap_control
128 #define GLX_SWAP_INTERVAL_EXT 0x20F1
129 #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
132 #ifndef GLX_EXT_swap_control_tear
133 #define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
136 #ifndef GLX_ARB_context_flush_control
137 #define GLX_ARB_context_flush_control
138 #define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
139 #define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
140 #define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
143 #define OPENGL_REQUIRES_DLOPEN
144 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
146 #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
147 #define GL_LoadFunction dlsym
148 #define GL_UnloadObject dlclose
150 #define GL_LoadObject SDL_LoadObject
151 #define GL_LoadFunction SDL_LoadFunction
152 #define GL_UnloadObject SDL_UnloadObject
155 static void X11_GL_InitExtensions(
_THIS);
158 X11_GL_LoadLibrary(
_THIS,
const char *
path)
172 path = DEFAULT_OPENGL;
176 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
196 (Bool (*)(Display *,
int *,
int *))
197 GL_LoadFunction(
handle,
"glXQueryExtension");
200 GL_LoadFunction(
handle,
"glXGetProcAddressARB");
202 (XVisualInfo * (*)(Display *,
int,
int *))
203 X11_GL_GetProcAddress(
_this,
"glXChooseVisual");
205 (GLXContext(*)(Display *, XVisualInfo *, GLXContext,
int))
206 X11_GL_GetProcAddress(
_this,
"glXCreateContext");
208 (
void (*)(Display *, GLXContext))
209 X11_GL_GetProcAddress(
_this,
"glXDestroyContext");
211 (
int (*)(Display *, GLXDrawable, GLXContext))
212 X11_GL_GetProcAddress(
_this,
"glXMakeCurrent");
214 (
void (*)(Display *, GLXDrawable))
215 X11_GL_GetProcAddress(
_this,
"glXSwapBuffers");
217 (
void (*)(Display*,GLXDrawable,
int,
unsigned int*))
218 X11_GL_GetProcAddress(
_this,
"glXQueryDrawable");
226 return SDL_SetError(
"Could not retrieve OpenGL functions");
238 X11_GL_InitExtensions(
_this);
246 X11_GL_UseEGL(
_this) ) {
247 #if SDL_VIDEO_OPENGL_EGL
248 X11_GL_UnloadLibrary(
_this);
263 return X11_GLES_LoadLibrary(
_this,
NULL);
265 return SDL_SetError(
"SDL not configured with EGL support");
273 X11_GL_GetProcAddress(
_THIS,
const char *proc)
282 X11_GL_UnloadLibrary(
_THIS)
299 HasExtension(
const char *extension,
const char *extensions)
302 const char *where, *terminator;
309 if (where || *extension ==
'\0')
324 if (where ==
start || *(where - 1) ==
' ')
325 if (*terminator ==
' ' || *terminator ==
'\0')
334 X11_GL_InitExtensions(
_THIS)
338 XVisualInfo *vinfo =
NULL;
340 GLXContext prev_ctx = 0;
341 GLXDrawable prev_drawable = 0;
343 const char *(*glXQueryExtensionsStringFunc) (Display *,
int);
344 const char *extensions;
348 GLXContext (*glXGetCurrentContextFunc) (
void) =
349 (GLXContext(*)(
void))
350 X11_GL_GetProcAddress(
_this,
"glXGetCurrentContext");
352 GLXDrawable (*glXGetCurrentDrawableFunc) (
void) =
353 (GLXDrawable(*)(
void))
354 X11_GL_GetProcAddress(
_this,
"glXGetCurrentDrawable");
356 if (glXGetCurrentContextFunc && glXGetCurrentDrawableFunc) {
357 XSetWindowAttributes xattr;
358 prev_ctx = glXGetCurrentContextFunc();
359 prev_drawable = glXGetCurrentDrawableFunc();
361 xattr.background_pixel = 0;
362 xattr.border_pixel = 0;
365 vinfo->visual, AllocNone);
367 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual,
368 (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
380 glXQueryExtensionsStringFunc =
381 (
const char *(*)(Display *,
int)) X11_GL_GetProcAddress(
_this,
382 "glXQueryExtensionsString");
383 if (glXQueryExtensionsStringFunc) {
391 if (HasExtension(
"GLX_EXT_swap_control", extensions)) {
393 (
void (*)(Display*,GLXDrawable,
int))
394 X11_GL_GetProcAddress(
_this,
"glXSwapIntervalEXT");
395 if (HasExtension(
"GLX_EXT_swap_control_tear", extensions)) {
401 if (HasExtension(
"GLX_MESA_swap_control", extensions)) {
403 (
int(*)(
int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalMESA");
406 "glXGetSwapIntervalMESA");
410 if (HasExtension(
"GLX_SGI_swap_control", extensions)) {
412 (
int (*)(
int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalSGI");
416 if (HasExtension(
"GLX_ARB_create_context", extensions)) {
418 (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,
const int *))
419 X11_GL_GetProcAddress(
_this,
"glXCreateContextAttribsARB");
421 (GLXFBConfig *(*)(Display *,
int,
const int *,
int *))
422 X11_GL_GetProcAddress(
_this,
"glXChooseFBConfig");
426 if (HasExtension(
"GLX_EXT_visual_rating", extensions)) {
431 if (HasExtension(
"GLX_EXT_visual_info", extensions)) {
436 if (HasExtension(
"GLX_EXT_create_context_es2_profile", extensions)) {
441 &
_this->
gl_data->es_profile_max_supported_version.major,
448 if (HasExtension(
"GLX_ARB_context_flush_control", extensions)) {
453 if (HasExtension(
"GLX_ARB_create_context_robustness", extensions)) {
458 if (HasExtension(
"GLX_ARB_create_context_no_error", extensions)) {
465 if (prev_ctx && prev_drawable) {
487 const int MAX_ATTRIBUTES = 64;
488 int *pvistypeattr =
NULL;
533 attribs[
i++] = GLX_ACCUM_GREEN_SIZE;
543 attribs[
i++] = GLX_ACCUM_ALPHA_SIZE;
555 attribs[
i++] = GLX_SAMPLE_BUFFERS_ARB;
565 attribs[
i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
571 attribs[
i++] = GLX_VISUAL_CAVEAT_EXT;
581 attribs[
i++] = GLX_X_VISUAL_TYPE_EXT;
582 attribs[
i++] = GLX_DIRECT_COLOR_EXT;
590 *_pvistypeattr = pvistypeattr;
602 int *pvistypeattr =
NULL;
612 if (!vinfo && (pvistypeattr !=
NULL)) {
613 *pvistypeattr = None;
623 static int (*handler) (Display *, XErrorEvent *) =
NULL;
624 static const char *errorHandlerOperation =
NULL;
625 static int errorBase = 0;
626 static int errorCode = 0;
628 X11_GL_ErrorHandler(Display *
d, XErrorEvent *
e)
630 char *x11_error =
NULL;
631 char x11_error_locale[256];
633 errorCode =
e->error_code;
634 if (X11_XGetErrorText(
d, errorCode, x11_error_locale,
sizeof(x11_error_locale)) == Success)
641 SDL_SetError(
"Could not %s: %s", errorHandlerOperation, x11_error);
646 SDL_SetError(
"Could not %s: %i (Base %i)", errorHandlerOperation, errorCode, errorBase);
677 XWindowAttributes xattr;
678 XVisualInfo
v, *vinfo;
685 share_context =
NULL;
690 errorHandlerOperation =
"create GL context";
693 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
694 X11_XGetWindowAttributes(
display,
data->xwindow, &xattr);
696 v.visualid = X11_XVisualIDFromVisual(xattr.visual);
697 vinfo = X11_XGetVisualInfo(
display, VisualScreenMask | VisualIDMask, &
v, &
n);
708 GLX_CONTEXT_MAJOR_VERSION_ARB,
710 GLX_CONTEXT_MINOR_VERSION_ARB,
718 attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
724 attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
729 if(
_this->
gl_data->HAS_GLX_ARB_context_flush_control ) {
730 attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
733 GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
734 GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
738 if(
_this->
gl_data->HAS_GLX_ARB_create_context_robustness ) {
739 attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
742 GLX_LOSE_CONTEXT_ON_RESET_ARB :
743 GLX_NO_RESET_NOTIFICATION_ARB;
747 if(
_this->
gl_data->HAS_GLX_ARB_create_context_no_error ) {
748 attribs[iattr++] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB;
756 SDL_SetError(
"OpenGL 3.0 and later are not supported by this system");
761 GLXFBConfig *framebuffer_config =
NULL;
763 int *pvistypeattr =
NULL;
769 DefaultScreen(
display), glxAttribs,
772 if (!framebuffer_config && (pvistypeattr !=
NULL)) {
773 *pvistypeattr = None;
775 DefaultScreen(
display), glxAttribs,
779 if (framebuffer_config) {
781 framebuffer_config[0],
783 X11_XFree(framebuffer_config);
791 X11_XSetErrorHandler(handler);
794 if (errorCode == Success) {
814 GLXContext glx_context = (GLXContext)
context;
823 errorHandlerOperation =
"make GL context current";
826 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
828 X11_XSetErrorHandler(handler);
830 if (errorCode != Success) {
833 return SDL_SetError(
"Unable to make GL context current");
849 X11_GL_SetSwapInterval(
_THIS,
int interval)
853 if ((interval < 0) && (!
_this->
gl_data->HAS_GLX_EXT_swap_control_tear)) {
854 SDL_SetError(
"Negative swap interval unsupported in this GL");
860 Window drawable = windowdata->
xwindow;
870 int currentInterval = X11_GL_GetSwapInterval(
_this);
897 X11_GL_GetSwapInterval(
_THIS)
903 Window drawable = windowdata->
xwindow;
904 unsigned int allow_late_swap_tearing = 0;
905 unsigned int interval = 0;
909 GLX_LATE_SWAPS_TEAR_EXT,
910 &allow_late_swap_tearing);
914 GLX_SWAP_INTERVAL_EXT, &interval);
916 if ((allow_late_swap_tearing) && (interval > 0)) {
917 return -((
int) interval);
920 return (
int) interval;
942 GLXContext glx_context = (GLXContext)
context;
#define SDL_assert(condition)
#define SDL_GL_GetCurrentWindow
#define SDL_GetHintBoolean
#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
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
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
#define SDL_OutOfMemory()
#define SDL_Unsupported()
#define SDL_HINT_VIDEO_X11_FORCE_EGL
A variable controlling whether X11 should use GLX or EGL by default.
#define SDL_HINT_OPENGL_ES_DRIVER
A variable controlling what driver to use for OpenGL ES contexts.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLsizei const GLchar *const * path
GLubyte GLubyte GLubyte GLubyte w
#define SDL_arraysize(array)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor)
static SDL_VideoDevice * _this
void * SDL_GLContext
An opaque handle to an OpenGL context.
@ SDL_GL_CONTEXT_PROFILE_ES
void X11_PumpEvents(_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)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display dpy)
SDL_bool X11_UseDirectColorVisuals(void)
EGLImageKHR EGLint EGLint * handle
EGLSurface EGLNativeWindowType * window
EGLenum const EGLAttribKHR * attrib_list
int framebuffer_srgb_capable
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
struct SDL_VideoDevice::@440 gl_config
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
int(* GL_SetSwapInterval)(_THIS, int interval)
void(* GL_UnloadLibrary)(_THIS)
void *(* GL_GetProcAddress)(_THIS, const char *proc)
int(* GL_GetSwapInterval)(_THIS)
int(* GL_LoadLibrary)(_THIS, const char *path)
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
struct SDL_GLDriverData * gl_data
int share_with_current_context
The type used to identify a window.
static screen_context_t context
typedef int(__stdcall *FARPROC)()