21#include "../../SDL_internal.h"
23#if SDL_VIDEO_DRIVER_X11
31#if SDL_VIDEO_OPENGL_GLX
37#define DEFAULT_OPENGL "libGL.so"
38#elif defined(__MACOSX__)
39#define DEFAULT_OPENGL "/usr/X11R6/lib/libGL.1.dylib"
40#elif defined(__QNXNTO__)
41#define DEFAULT_OPENGL "libGL.so.3"
43#define DEFAULT_OPENGL "libGL.so.1"
47#define GLX_NONE_EXT 0x8000
50#ifndef GLX_ARB_multisample
51#define GLX_ARB_multisample
52#define GLX_SAMPLE_BUFFERS_ARB 100000
53#define GLX_SAMPLES_ARB 100001
56#ifndef GLX_EXT_visual_rating
57#define GLX_EXT_visual_rating
58#define GLX_VISUAL_CAVEAT_EXT 0x20
59#define GLX_NONE_EXT 0x8000
60#define GLX_SLOW_VISUAL_EXT 0x8001
61#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
64#ifndef GLX_EXT_visual_info
65#define GLX_EXT_visual_info
66#define GLX_X_VISUAL_TYPE_EXT 0x22
67#define GLX_DIRECT_COLOR_EXT 0x8003
70#ifndef GLX_ARB_create_context
71#define GLX_ARB_create_context
72#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
73#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
74#define GLX_CONTEXT_FLAGS_ARB 0x2094
75#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001
76#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
79typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *
dpy,
88#ifndef GLX_ARB_create_context_profile
89#define GLX_ARB_create_context_profile
90#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
91#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
92#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
95#ifndef GLX_ARB_create_context_robustness
96#define GLX_ARB_create_context_robustness
97#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
98#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
99#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261
100#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252
103#ifndef GLX_EXT_create_context_es2_profile
104#define GLX_EXT_create_context_es2_profile
105#ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT
106#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002
110#ifndef GLX_ARB_framebuffer_sRGB
111#define GLX_ARB_framebuffer_sRGB
112#ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB
113#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
117#ifndef GLX_ARB_create_context_no_error
118#define GLX_ARB_create_context_no_error
119#ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
120#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3
124#ifndef GLX_EXT_swap_control
125#define GLX_SWAP_INTERVAL_EXT 0x20F1
126#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
129#ifndef GLX_EXT_swap_control_tear
130#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
133#ifndef GLX_ARB_context_flush_control
134#define GLX_ARB_context_flush_control
135#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
136#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
137#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
140#define OPENGL_REQUIRES_DLOPEN
141#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
143#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
144#define GL_LoadFunction dlsym
145#define GL_UnloadObject dlclose
147#define GL_LoadObject SDL_LoadObject
148#define GL_LoadFunction SDL_LoadFunction
149#define GL_UnloadObject SDL_UnloadObject
152static void X11_GL_InitExtensions(
_THIS);
155X11_GL_LoadLibrary(
_THIS,
const char *
path)
169 path = DEFAULT_OPENGL;
173#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
193 (Bool (*)(Display *,
int *,
int *))
194 GL_LoadFunction(
handle,
"glXQueryExtension");
197 GL_LoadFunction(
handle,
"glXGetProcAddressARB");
199 (XVisualInfo * (*)(Display *,
int,
int *))
200 X11_GL_GetProcAddress(
_this,
"glXChooseVisual");
202 (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
203 X11_GL_GetProcAddress(
_this,
"glXCreateContext");
205 (
void (*)(Display *, GLXContext))
206 X11_GL_GetProcAddress(
_this,
"glXDestroyContext");
208 (int (*)(Display *, GLXDrawable, GLXContext))
209 X11_GL_GetProcAddress(
_this,
"glXMakeCurrent");
211 (
void (*)(Display *, GLXDrawable))
212 X11_GL_GetProcAddress(
_this,
"glXSwapBuffers");
214 (
void (*)(Display*,GLXDrawable,int,
unsigned int*))
215 X11_GL_GetProcAddress(
_this,
"glXQueryDrawable");
223 return SDL_SetError(
"Could not retrieve OpenGL functions");
235 X11_GL_InitExtensions(
_this);
242 X11_GL_UseEGL(
_this) ) {
243#if SDL_VIDEO_OPENGL_EGL
244 X11_GL_UnloadLibrary(
_this);
259 return X11_GLES_LoadLibrary(
_this,
NULL);
261 return SDL_SetError(
"SDL not configured with EGL support");
269X11_GL_GetProcAddress(
_THIS,
const char *proc)
278X11_GL_UnloadLibrary(
_THIS)
295HasExtension(
const char *extension,
const char *extensions)
298 const char *where, *terminator;
305 if (where || *extension ==
'\0')
320 if (where ==
start || *(where - 1) ==
' ')
321 if (*terminator ==
' ' || *terminator ==
'\0')
330X11_GL_InitExtensions(
_THIS)
334 XVisualInfo *vinfo =
NULL;
336 GLXContext prev_ctx = 0;
337 GLXDrawable prev_drawable = 0;
339 const char *(*glXQueryExtensionsStringFunc) (Display *, int);
340 const char *extensions;
344 GLXContext (*glXGetCurrentContextFunc) (
void) =
345 (GLXContext(*)(
void))
346 X11_GL_GetProcAddress(
_this,
"glXGetCurrentContext");
348 GLXDrawable (*glXGetCurrentDrawableFunc) (
void) =
349 (GLXDrawable(*)(
void))
350 X11_GL_GetProcAddress(
_this,
"glXGetCurrentDrawable");
352 if (glXGetCurrentContextFunc && glXGetCurrentDrawableFunc) {
353 XSetWindowAttributes xattr;
354 prev_ctx = glXGetCurrentContextFunc();
355 prev_drawable = glXGetCurrentDrawableFunc();
357 xattr.background_pixel = 0;
358 xattr.border_pixel = 0;
361 vinfo->visual, AllocNone);
363 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual,
364 (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
376 glXQueryExtensionsStringFunc =
377 (
const char *(*)(Display *,
int)) X11_GL_GetProcAddress(
_this,
378 "glXQueryExtensionsString");
379 if (glXQueryExtensionsStringFunc) {
387 if (HasExtension(
"GLX_EXT_swap_control", extensions)) {
389 (
void (*)(Display*,GLXDrawable,int))
390 X11_GL_GetProcAddress(
_this,
"glXSwapIntervalEXT");
391 if (HasExtension(
"GLX_EXT_swap_control_tear", extensions)) {
397 if (HasExtension(
"GLX_MESA_swap_control", extensions)) {
399 (int(*)(int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalMESA");
401 (int(*)(
void)) X11_GL_GetProcAddress(
_this,
402 "glXGetSwapIntervalMESA");
406 if (HasExtension(
"GLX_SGI_swap_control", extensions)) {
408 (int (*)(int)) X11_GL_GetProcAddress(
_this,
"glXSwapIntervalSGI");
412 if (HasExtension(
"GLX_ARB_create_context", extensions)) {
414 (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,
const int *))
415 X11_GL_GetProcAddress(
_this,
"glXCreateContextAttribsARB");
417 (GLXFBConfig *(*)(Display *,
int,
const int *,
int *))
418 X11_GL_GetProcAddress(
_this,
"glXChooseFBConfig");
422 if (HasExtension(
"GLX_EXT_visual_rating", extensions)) {
427 if (HasExtension(
"GLX_EXT_visual_info", extensions)) {
432 if (HasExtension(
"GLX_EXT_create_context_es2_profile", extensions)) {
437 &
_this->
gl_data->es_profile_max_supported_version.major,
444 if (HasExtension(
"GLX_ARB_context_flush_control", extensions)) {
449 if (HasExtension(
"GLX_ARB_create_context_robustness", extensions)) {
454 if (HasExtension(
"GLX_ARB_create_context_no_error", extensions)) {
461 if (prev_ctx && prev_drawable) {
483 const int MAX_ATTRIBUTES = 64;
484 int *pvistypeattr =
NULL;
529 attribs[
i++] = GLX_ACCUM_GREEN_SIZE;
539 attribs[
i++] = GLX_ACCUM_ALPHA_SIZE;
551 attribs[
i++] = GLX_SAMPLE_BUFFERS_ARB;
561 attribs[
i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
567 attribs[
i++] = GLX_VISUAL_CAVEAT_EXT;
577 attribs[
i++] = GLX_X_VISUAL_TYPE_EXT;
578 attribs[
i++] = GLX_DIRECT_COLOR_EXT;
586 *_pvistypeattr = pvistypeattr;
598 int *pvistypeattr =
NULL;
608 if (!vinfo && (pvistypeattr !=
NULL)) {
609 *pvistypeattr = None;
619static int (*handler) (Display *, XErrorEvent *) =
NULL;
620static const char *errorHandlerOperation =
NULL;
621static int errorBase = 0;
622static int errorCode = 0;
624X11_GL_ErrorHandler(Display *
d, XErrorEvent *
e)
626 char *x11_error =
NULL;
627 char x11_error_locale[256];
629 errorCode =
e->error_code;
630 if (X11_XGetErrorText(
d, errorCode, x11_error_locale,
sizeof(x11_error_locale)) == Success)
637 SDL_SetError(
"Could not %s: %s", errorHandlerOperation, x11_error);
642 SDL_SetError(
"Could not %s: %i (Base %i)", errorHandlerOperation, errorCode, errorBase);
668 XWindowAttributes xattr;
669 XVisualInfo
v, *vinfo;
676 share_context =
NULL;
681 errorHandlerOperation =
"create GL context";
684 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
685 X11_XGetWindowAttributes(
display,
data->xwindow, &xattr);
687 v.visualid = X11_XVisualIDFromVisual(xattr.visual);
688 vinfo = X11_XGetVisualInfo(
display, VisualScreenMask | VisualIDMask, &
v, &
n);
699 GLX_CONTEXT_MAJOR_VERSION_ARB,
701 GLX_CONTEXT_MINOR_VERSION_ARB,
709 attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
715 attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
720 if(
_this->
gl_data->HAS_GLX_ARB_context_flush_control ) {
721 attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
724 GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
725 GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
729 if(
_this->
gl_data->HAS_GLX_ARB_create_context_robustness ) {
730 attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
733 GLX_LOSE_CONTEXT_ON_RESET_ARB :
734 GLX_NO_RESET_NOTIFICATION_ARB;
738 if(
_this->
gl_data->HAS_GLX_ARB_create_context_no_error ) {
739 attribs[iattr++] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB;
747 SDL_SetError(
"OpenGL 3.0 and later are not supported by this system");
752 GLXFBConfig *framebuffer_config =
NULL;
754 int *pvistypeattr =
NULL;
760 DefaultScreen(
display), glxAttribs,
763 if (!framebuffer_config && (pvistypeattr !=
NULL)) {
764 *pvistypeattr = None;
766 DefaultScreen(
display), glxAttribs,
770 if (framebuffer_config) {
772 framebuffer_config[0],
774 X11_XFree(framebuffer_config);
782 X11_XSetErrorHandler(handler);
785 if (errorCode == Success) {
805 GLXContext glx_context = (GLXContext)
context;
814 errorHandlerOperation =
"make GL context current";
817 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
819 X11_XSetErrorHandler(handler);
821 if (errorCode != Success) {
824 return SDL_SetError(
"Unable to make GL context current");
840X11_GL_SetSwapInterval(
_THIS,
int interval)
844 if ((interval < 0) && (!
_this->
gl_data->HAS_GLX_EXT_swap_control_tear)) {
845 SDL_SetError(
"Negative swap interval unsupported in this GL");
851 Window drawable = windowdata->
xwindow;
861 int currentInterval = X11_GL_GetSwapInterval(
_this);
888X11_GL_GetSwapInterval(
_THIS)
894 Window drawable = windowdata->
xwindow;
895 unsigned int allow_late_swap_tearing = 0;
896 unsigned int interval = 0;
900 GLX_LATE_SWAPS_TEAR_EXT,
901 &allow_late_swap_tearing);
905 GLX_SWAP_INTERVAL_EXT, &interval);
907 if ((allow_late_swap_tearing) && (interval > 0)) {
908 return -((int) interval);
911 return (
int) interval;
933 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_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 dpy)
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)
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)
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
int(* GL_SetSwapInterval)(_THIS, int interval)
void(* GL_UnloadLibrary)(_THIS)
int(* GL_GetSwapInterval)(_THIS)
int(* GL_LoadLibrary)(_THIS, const char *path)
int(* GL_SwapWindow)(_THIS, SDL_Window *window)
struct SDL_VideoDevice::@262 gl_config
void *(* GL_GetProcAddress)(_THIS, const char *proc)
struct SDL_GLDriverData * gl_data
int share_with_current_context
The type used to identify a window.
static screen_context_t context