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);
467 X11_XDestroyWindow(display, w);
480 X11_GL_GetAttributes(
_THIS, Display * display,
int screen,
int *
attribs,
int size, Bool for_FBConfig,
int **_pvistypeattr)
483 const int MAX_ATTRIBUTES = 64;
484 int *pvistypeattr =
NULL;
491 attribs[i++] = GLX_RENDER_TYPE;
492 attribs[i++] = GLX_RGBA_BIT;
494 attribs[i++] = GLX_RGBA;
496 attribs[i++] = GLX_RED_SIZE;
498 attribs[i++] = GLX_GREEN_SIZE;
500 attribs[i++] = GLX_BLUE_SIZE;
504 attribs[i++] = GLX_ALPHA_SIZE;
509 attribs[i++] = GLX_DOUBLEBUFFER;
515 attribs[i++] = GLX_DEPTH_SIZE;
519 attribs[i++] = GLX_STENCIL_SIZE;
524 attribs[i++] = GLX_ACCUM_RED_SIZE;
529 attribs[i++] = GLX_ACCUM_GREEN_SIZE;
534 attribs[i++] = GLX_ACCUM_BLUE_SIZE;
539 attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
544 attribs[i++] = GLX_STEREO;
551 attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
556 attribs[i++] = GLX_SAMPLES_ARB;
561 attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
567 attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
576 pvistypeattr = &attribs[
i];
577 attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
578 attribs[i++] = GLX_DIRECT_COLOR_EXT;
586 *_pvistypeattr = pvistypeattr;
593 X11_GL_GetVisual(
_THIS, Display * display,
int screen)
598 int *pvistypeattr =
NULL;
605 X11_GL_GetAttributes(
_this, display, screen, attribs, 64,
SDL_FALSE, &pvistypeattr);
606 vinfo =
_this->
gl_data->glXChooseVisual(display, screen, attribs);
608 if (!vinfo && (pvistypeattr !=
NULL)) {
609 *pvistypeattr = None;
610 vinfo =
_this->
gl_data->glXChooseVisual(display, screen, attribs);
619 static int (*handler) (Display *, XErrorEvent *) =
NULL;
620 static const char *errorHandlerOperation =
NULL;
621 static int errorBase = 0;
622 static int errorCode = 0;
624 X11_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;
671 GLXContext context =
NULL, share_context;
676 share_context =
NULL;
680 X11_XSync(display, False);
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);
695 _this->
gl_data->glXCreateContext(display, vinfo, share_context, True);
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;
743 attribs[iattr++] = 0;
747 SDL_SetError(
"OpenGL 3.0 and later are not supported by this system");
752 GLXFBConfig *framebuffer_config =
NULL;
754 int *pvistypeattr =
NULL;
756 X11_GL_GetAttributes(
_this,display,screen,glxAttribs,64,
SDL_TRUE,&pvistypeattr);
759 framebuffer_config =
_this->
gl_data->glXChooseFBConfig(display,
760 DefaultScreen(display), glxAttribs,
763 if (!framebuffer_config && (pvistypeattr !=
NULL)) {
764 *pvistypeattr = None;
765 framebuffer_config =
_this->
gl_data->glXChooseFBConfig(display,
766 DefaultScreen(display), glxAttribs,
770 if (framebuffer_config) {
771 context =
_this->
gl_data->glXCreateContextAttribsARB(display,
772 framebuffer_config[0],
773 share_context, True, attribs);
774 X11_XFree(framebuffer_config);
781 X11_XSync(display, False);
782 X11_XSetErrorHandler(handler);
785 if (errorCode == Success) {
791 if (X11_GL_MakeCurrent(
_this, window, context) < 0) {
792 X11_GL_DeleteContext(
_this, context);
805 GLXContext glx_context = (GLXContext) context;
813 X11_XSync(display, False);
814 errorHandlerOperation =
"make GL context current";
817 handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
818 rc =
_this->
gl_data->glXMakeCurrent(display, drawable, glx_context);
819 X11_XSetErrorHandler(handler);
821 if (errorCode != Success) {
824 return SDL_SetError(
"Unable to make GL context current");
840 X11_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);
862 _this->
gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
863 _this->
gl_data->glXSwapIntervalEXT(display, drawable, interval);
866 swapinterval = interval;
872 swapinterval = interval;
879 swapinterval = interval;
888 X11_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;
938 _this->
gl_data->glXDestroyContext(display, glx_context);
939 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
#define SDL_HINT_OPENGL_ES_DRIVER
A variable controlling what driver to use for OpenGL ES contexts.
static SDL_VideoDevice * _this
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
struct SDL_VideoDevice::@34 gl_config
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
int(* GL_GetSwapInterval)(_THIS)
#define SDL_Unsupported()
void *(* GL_GetProcAddress)(_THIS, const char *proc)