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 79 typedef 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 152 static void X11_GL_InitExtensions(
_THIS);
155 X11_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");
269 X11_GL_GetProcAddress(
_THIS,
const char *proc)
278 X11_GL_UnloadLibrary(
_THIS)
295 HasExtension(
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')
330 X11_GL_InitExtensions(
_THIS)
333 const int screen = DefaultScreen(display);
334 XVisualInfo *vinfo =
NULL;
336 GLXContext prev_ctx = 0;
337 GLXDrawable prev_drawable = 0;
339 const char *(*glXQueryExtensionsStringFunc) (Display *, int);
340 const char *extensions;
342 vinfo = X11_GL_GetVisual(
_this, display, screen);
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;
360 X11_XCreateColormap(display, RootWindow(display, screen),
361 vinfo->visual, AllocNone);
362 w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0,
363 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual,
364 (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
366 context =
_this->
gl_data->glXCreateContext(display, vinfo,
376 glXQueryExtensionsStringFunc =
377 (
const char *(*)(Display *, int)) X11_GL_GetProcAddress(
_this,
378 "glXQueryExtensionsString");
379 if (glXQueryExtensionsStringFunc) {
380 extensions = glXQueryExtensionsStringFunc(display, screen);
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) {
462 _this->
gl_data->glXMakeCurrent(display, prev_drawable, prev_ctx);
466 X11_XDestroyWindow(display, w);
478 X11_GL_GetAttributes(
_THIS, Display * display,
int screen,
int *
attribs,
int size, Bool for_FBConfig,
int **_pvistypeattr)
481 const int MAX_ATTRIBUTES = 64;
482 int *pvistypeattr =
NULL;
489 attribs[i++] = GLX_RENDER_TYPE;
490 attribs[i++] = GLX_RGBA_BIT;
492 attribs[i++] = GLX_RGBA;
494 attribs[i++] = GLX_RED_SIZE;
496 attribs[i++] = GLX_GREEN_SIZE;
498 attribs[i++] = GLX_BLUE_SIZE;
502 attribs[i++] = GLX_ALPHA_SIZE;
507 attribs[i++] = GLX_DOUBLEBUFFER;
513 attribs[i++] = GLX_DEPTH_SIZE;
517 attribs[i++] = GLX_STENCIL_SIZE;
522 attribs[i++] = GLX_ACCUM_RED_SIZE;
527 attribs[i++] = GLX_ACCUM_GREEN_SIZE;
532 attribs[i++] = GLX_ACCUM_BLUE_SIZE;
537 attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
542 attribs[i++] = GLX_STEREO;
549 attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
554 attribs[i++] = GLX_SAMPLES_ARB;
559 attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
565 attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
574 pvistypeattr = &attribs[
i];
575 attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
576 attribs[i++] = GLX_DIRECT_COLOR_EXT;
584 *_pvistypeattr = pvistypeattr;
591 X11_GL_GetVisual(
_THIS, Display * display,
int screen)
596 int *pvistypeattr =
NULL;
603 X11_GL_GetAttributes(
_this, display, screen, attribs, 64,
SDL_FALSE, &pvistypeattr);
604 vinfo =
_this->
gl_data->glXChooseVisual(display, screen, attribs);
606 if (!vinfo && (pvistypeattr !=
NULL)) {
607 *pvistypeattr = None;
608 vinfo =
_this->
gl_data->glXChooseVisual(display, screen, attribs);
617 static int (*handler) (Display *, XErrorEvent *) =
NULL;
618 static const char *errorHandlerOperation =
NULL;
619 static int errorBase = 0;
620 static int errorCode = 0;
622 X11_GL_ErrorHandler(Display *
d, XErrorEvent *
e)
624 char *x11_error =
NULL;
625 char x11_error_locale[256];
627 errorCode = e->error_code;
628 if (X11_XGetErrorText(d, errorCode, x11_error_locale,
sizeof(x11_error_locale)) == Success)
635 SDL_SetError(
"Could not %s: %s", errorHandlerOperation, x11_error);
640 SDL_SetError(
"Could not %s: %i (Base %i)", errorHandlerOperation, errorCode, errorBase);
666 XWindowAttributes xattr;
667 XVisualInfo
v, *vinfo;
669 GLXContext context =
NULL, share_context;
674 share_context =
NULL;
678 X11_XSync(display, False);
679 errorHandlerOperation =
"create GL context";
682 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
683 X11_XGetWindowAttributes(display, data->
xwindow, &xattr);
685 v.visualid = X11_XVisualIDFromVisual(xattr.visual);
686 vinfo = X11_XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
693 _this->
gl_data->glXCreateContext(display, vinfo, share_context, True);
697 GLX_CONTEXT_MAJOR_VERSION_ARB,
699 GLX_CONTEXT_MINOR_VERSION_ARB,
707 attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
713 attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
718 if(
_this->
gl_data->HAS_GLX_ARB_context_flush_control ) {
719 attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
722 GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
723 GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
727 if(
_this->
gl_data->HAS_GLX_ARB_create_context_robustness ) {
728 attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB;
731 GLX_LOSE_CONTEXT_ON_RESET_ARB :
732 GLX_NO_RESET_NOTIFICATION_ARB;
736 if(
_this->
gl_data->HAS_GLX_ARB_create_context_no_error ) {
737 attribs[iattr++] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB;
741 attribs[iattr++] = 0;
745 SDL_SetError(
"OpenGL 3.0 and later are not supported by this system");
750 GLXFBConfig *framebuffer_config =
NULL;
752 int *pvistypeattr =
NULL;
754 X11_GL_GetAttributes(
_this,display,screen,glxAttribs,64,
SDL_TRUE,&pvistypeattr);
757 framebuffer_config =
_this->
gl_data->glXChooseFBConfig(display,
758 DefaultScreen(display), glxAttribs,
761 if (!framebuffer_config && (pvistypeattr !=
NULL)) {
762 *pvistypeattr = None;
763 framebuffer_config =
_this->
gl_data->glXChooseFBConfig(display,
764 DefaultScreen(display), glxAttribs,
768 if (framebuffer_config) {
769 context =
_this->
gl_data->glXCreateContextAttribsARB(display,
770 framebuffer_config[0],
771 share_context, True, attribs);
772 X11_XFree(framebuffer_config);
779 X11_XSync(display, False);
780 X11_XSetErrorHandler(handler);
783 if (errorCode == Success) {
789 if (X11_GL_MakeCurrent(
_this, window, context) < 0) {
790 X11_GL_DeleteContext(
_this, context);
803 GLXContext glx_context = (GLXContext) context;
811 X11_XSync(display, False);
812 errorHandlerOperation =
"make GL context current";
815 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
816 rc =
_this->
gl_data->glXMakeCurrent(display, drawable, glx_context);
817 X11_XSetErrorHandler(handler);
819 if (errorCode != Success) {
822 return SDL_SetError(
"Unable to make GL context current");
838 X11_GL_SetSwapInterval(
_THIS,
int interval)
842 if ((interval < 0) && (!
_this->
gl_data->HAS_GLX_EXT_swap_control_tear)) {
843 SDL_SetError(
"Negative swap interval unsupported in this GL");
849 Window drawable = windowdata->
xwindow;
859 int currentInterval = X11_GL_GetSwapInterval(
_this);
860 _this->
gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
861 _this->
gl_data->glXSwapIntervalEXT(display, drawable, interval);
864 swapinterval = interval;
870 swapinterval = interval;
877 swapinterval = interval;
886 X11_GL_GetSwapInterval(
_THIS)
892 Window drawable = windowdata->
xwindow;
893 unsigned int allow_late_swap_tearing = 0;
894 unsigned int interval = 0;
898 GLX_LATE_SWAPS_TEAR_EXT,
899 &allow_late_swap_tearing);
903 GLX_SWAP_INTERVAL_EXT, &interval);
905 if ((allow_late_swap_tearing) && (interval > 0)) {
906 return -((int) interval);
909 return (
int) interval;
931 GLXContext glx_context = (GLXContext) context;
936 _this->
gl_data->glXDestroyContext(display, glx_context);
937 X11_XSync(display, False);
void X11_PumpEvents(_THIS)
EGLenum const EGLAttribKHR * attrib_list
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
SDL_bool X11_UseDirectColorVisuals(void)
int(* GL_SetSwapInterval)(_THIS, int interval)
static screen_context_t context
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int(* GL_LoadLibrary)(_THIS, const char *path)
struct SDL_GLDriverData * gl_data
#define SDL_GetHintBoolean
struct SDL_VideoDevice::@32 gl_config
#define SDL_HINT_OPENGL_ES_DRIVER
A variable controlling what driver to use for OpenGL ES contexts.
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)
EGLImageKHR EGLint EGLint * handle
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)
void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor)
GLubyte GLubyte GLubyte GLubyte w
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
#define SDL_GL_GetCurrentWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
EGLSurface EGLNativeWindowType * window
int(* GL_SwapWindow)(_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 void
The type used to identify a window.
#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)