zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_x11opengl.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22 
23 #if SDL_VIDEO_DRIVER_X11
24 
25 #include "SDL_x11video.h"
26 #include "SDL_assert.h"
27 
28 /* GLX implementation of SDL OpenGL support */
29 
30 #if SDL_VIDEO_OPENGL_GLX
31 #include "SDL_loadso.h"
32 #include "SDL_x11opengles.h"
33 
34 #if defined(__IRIX__)
35 /* IRIX doesn't have a GL library versioning system */
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"
41 #else
42 #define DEFAULT_OPENGL "libGL.so.1"
43 #endif
44 
45 #ifndef GLX_NONE_EXT
46 #define GLX_NONE_EXT 0x8000
47 #endif
48 
49 #ifndef GLX_ARB_multisample
50 #define GLX_ARB_multisample
51 #define GLX_SAMPLE_BUFFERS_ARB 100000
52 #define GLX_SAMPLES_ARB 100001
53 #endif
54 
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
61 #endif
62 
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
67 #endif
68 
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
76 
77 /* Typedef for the GL 3.0 context creation function */
81  share_context,
82  Bool direct,
83  const int
84  *attrib_list);
85 #endif
86 
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
92 #endif
93 
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
100 #endif
101 
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
106 #endif
107 #endif
108 
109 #ifndef GLX_EXT_swap_control
110 #define GLX_SWAP_INTERVAL_EXT 0x20F1
111 #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
112 #endif
113 
114 #ifndef GLX_EXT_swap_control_tear
115 #define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
116 #endif
117 
118 #define OPENGL_REQUIRES_DLOPEN
119 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
120 #include <dlfcn.h>
121 #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
122 #define GL_LoadFunction dlsym
123 #define GL_UnloadObject dlclose
124 #else
125 #define GL_LoadObject SDL_LoadObject
126 #define GL_LoadFunction SDL_LoadFunction
127 #define GL_UnloadObject SDL_UnloadObject
128 #endif
129 
130 static void X11_GL_InitExtensions(_THIS);
131 
132 
133 int
134 X11_GL_LoadLibrary(_THIS, const char *path)
135 {
136  Display *display;
137  void *handle;
138 
139  if (_this->gl_data) {
140  return SDL_SetError("OpenGL context already created");
141  }
142 
143  /* Load the OpenGL library */
144  if (path == NULL) {
145  path = SDL_getenv("SDL_OPENGL_LIBRARY");
146  }
147  if (path == NULL) {
148  path = DEFAULT_OPENGL;
149  }
150  _this->gl_config.dll_handle = GL_LoadObject(path);
151  if (!_this->gl_config.dll_handle) {
152 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
153  SDL_SetError("Failed loading %s: %s", path, dlerror());
154 #endif
155  return -1;
156  }
159 
160  /* Allocate OpenGL memory */
161  _this->gl_data =
162  (struct SDL_GLDriverData *) SDL_calloc(1,
163  sizeof(struct
165  if (!_this->gl_data) {
166  return SDL_OutOfMemory();
167  }
168 
169  /* Load function pointers */
170  handle = _this->gl_config.dll_handle;
171  _this->gl_data->glXQueryExtension =
172  (Bool (*)(Display *, int *, int *))
173  GL_LoadFunction(handle, "glXQueryExtension");
174  _this->gl_data->glXGetProcAddress =
175  (void *(*)(const GLubyte *))
176  GL_LoadFunction(handle, "glXGetProcAddressARB");
177  _this->gl_data->glXChooseVisual =
178  (XVisualInfo * (*)(Display *, int, int *))
179  X11_GL_GetProcAddress(_this, "glXChooseVisual");
180  _this->gl_data->glXCreateContext =
181  (GLXContext(*)(Display *, XVisualInfo *, GLXContext, int))
182  X11_GL_GetProcAddress(_this, "glXCreateContext");
183  _this->gl_data->glXDestroyContext =
184  (void (*)(Display *, GLXContext))
185  X11_GL_GetProcAddress(_this, "glXDestroyContext");
186  _this->gl_data->glXMakeCurrent =
187  (int (*)(Display *, GLXDrawable, GLXContext))
188  X11_GL_GetProcAddress(_this, "glXMakeCurrent");
189  _this->gl_data->glXSwapBuffers =
190  (void (*)(Display *, GLXDrawable))
191  X11_GL_GetProcAddress(_this, "glXSwapBuffers");
192  _this->gl_data->glXQueryDrawable =
193  (void (*)(Display*,GLXDrawable,int,unsigned int*))
194  X11_GL_GetProcAddress(_this, "glXQueryDrawable");
195 
196  if (!_this->gl_data->glXQueryExtension ||
197  !_this->gl_data->glXChooseVisual ||
198  !_this->gl_data->glXCreateContext ||
199  !_this->gl_data->glXDestroyContext ||
200  !_this->gl_data->glXMakeCurrent ||
201  !_this->gl_data->glXSwapBuffers) {
202  return SDL_SetError("Could not retrieve OpenGL functions");
203  }
204 
205  display = ((SDL_VideoData *) _this->driverdata)->display;
206  if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) {
207  return SDL_SetError("GLX is not supported");
208  }
209 
210  /* Initialize extensions */
211  X11_GL_InitExtensions(_this);
212 
213  /* If we need a GL ES context and there's no
214  * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions
215  */
217  ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) {
218 #if SDL_VIDEO_OPENGL_EGL
219  X11_GL_UnloadLibrary(_this);
220  /* Better avoid conflicts! */
221  if (_this->gl_config.dll_handle != NULL ) {
222  GL_UnloadObject(_this->gl_config.dll_handle);
224  }
225  _this->GL_LoadLibrary = X11_GLES_LoadLibrary;
226  _this->GL_GetProcAddress = X11_GLES_GetProcAddress;
227  _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
228  _this->GL_CreateContext = X11_GLES_CreateContext;
229  _this->GL_MakeCurrent = X11_GLES_MakeCurrent;
230  _this->GL_SetSwapInterval = X11_GLES_SetSwapInterval;
231  _this->GL_GetSwapInterval = X11_GLES_GetSwapInterval;
232  _this->GL_SwapWindow = X11_GLES_SwapWindow;
233  _this->GL_DeleteContext = X11_GLES_DeleteContext;
234  return X11_GLES_LoadLibrary(_this, NULL);
235 #else
236  return SDL_SetError("SDL not configured with EGL support");
237 #endif
238  }
239 
240  return 0;
241 }
242 
243 void *
244 X11_GL_GetProcAddress(_THIS, const char *proc)
245 {
246  if (_this->gl_data->glXGetProcAddress) {
247  return _this->gl_data->glXGetProcAddress((const GLubyte *) proc);
248  }
249  return GL_LoadFunction(_this->gl_config.dll_handle, proc);
250 }
251 
252 void
253 X11_GL_UnloadLibrary(_THIS)
254 {
255  /* Don't actually unload the library, since it may have registered
256  * X11 shutdown hooks, per the notes at:
257  * http://dri.sourceforge.net/doc/DRIuserguide.html
258  */
259 #if 0
260  GL_UnloadObject(_this->gl_config.dll_handle);
262 #endif
263 
264  /* Free OpenGL memory */
266  _this->gl_data = NULL;
267 }
268 
269 static SDL_bool
270 HasExtension(const char *extension, const char *extensions)
271 {
272  const char *start;
273  const char *where, *terminator;
274 
275  /* Extension names should not have spaces. */
276  where = SDL_strchr(extension, ' ');
277  if (where || *extension == '\0')
278  return SDL_FALSE;
279 
280  if (!extensions)
281  return SDL_FALSE;
282 
283  /* It takes a bit of care to be fool-proof about parsing the
284  * OpenGL extensions string. Don't be fooled by sub-strings,
285  * etc. */
286 
287  start = extensions;
288 
289  for (;;) {
290  where = SDL_strstr(start, extension);
291  if (!where)
292  break;
293 
294  terminator = where + SDL_strlen(extension);
295  if (where == start || *(where - 1) == ' ')
296  if (*terminator == ' ' || *terminator == '\0')
297  return SDL_TRUE;
298 
299  start = terminator;
300  }
301  return SDL_FALSE;
302 }
303 
304 static void
305 X11_GL_InitExtensions(_THIS)
306 {
307  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
308  int screen = DefaultScreen(display);
309  XVisualInfo *vinfo;
310  XSetWindowAttributes xattr;
311  Window w;
312  GLXContext context;
313  const char *(*glXQueryExtensionsStringFunc) (Display *, int);
314  const char *extensions;
315 
316  vinfo = X11_GL_GetVisual(_this, display, screen);
317  if (!vinfo) {
318  return;
319  }
320  xattr.background_pixel = 0;
321  xattr.border_pixel = 0;
322  xattr.colormap =
323  XCreateColormap(display, RootWindow(display, screen), vinfo->visual,
324  AllocNone);
325  w = XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0,
326  vinfo->depth, InputOutput, vinfo->visual,
327  (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
328  context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
329  if (context) {
330  _this->gl_data->glXMakeCurrent(display, w, context);
331  }
332  XFree(vinfo);
333 
334  glXQueryExtensionsStringFunc =
335  (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this,
336  "glXQueryExtensionsString");
337  if (glXQueryExtensionsStringFunc) {
338  extensions = glXQueryExtensionsStringFunc(display, screen);
339  } else {
340  extensions = NULL;
341  }
342 
343  /* Check for GLX_EXT_swap_control(_tear) */
344  _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE;
345  if (HasExtension("GLX_EXT_swap_control", extensions)) {
346  _this->gl_data->glXSwapIntervalEXT =
347  (void (*)(Display*,GLXDrawable,int))
348  X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
349  if (HasExtension("GLX_EXT_swap_control_tear", extensions)) {
350  _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE;
351  }
352  }
353 
354  /* Check for GLX_MESA_swap_control */
355  if (HasExtension("GLX_MESA_swap_control", extensions)) {
356  _this->gl_data->glXSwapIntervalMESA =
357  (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA");
358  _this->gl_data->glXGetSwapIntervalMESA =
359  (int(*)(void)) X11_GL_GetProcAddress(_this,
360  "glXGetSwapIntervalMESA");
361  }
362 
363  /* Check for GLX_SGI_swap_control */
364  if (HasExtension("GLX_SGI_swap_control", extensions)) {
365  _this->gl_data->glXSwapIntervalSGI =
366  (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
367  }
368 
369  /* Check for GLX_EXT_visual_rating */
370  if (HasExtension("GLX_EXT_visual_rating", extensions)) {
371  _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE;
372  }
373 
374  /* Check for GLX_EXT_visual_info */
375  if (HasExtension("GLX_EXT_visual_info", extensions)) {
376  _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE;
377  }
378 
379  /* Check for GLX_EXT_create_context_es2_profile */
380  if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) {
381  _this->gl_data->HAS_GLX_EXT_create_context_es2_profile = SDL_TRUE;
382  }
383 
384  if (context) {
385  _this->gl_data->glXMakeCurrent(display, None, NULL);
386  _this->gl_data->glXDestroyContext(display, context);
387  }
388  XDestroyWindow(display, w);
390 }
391 
392 /* glXChooseVisual and glXChooseFBConfig have some small differences in
393  * the attribute encoding, it can be chosen with the for_FBConfig parameter.
394  */
395 int
396 X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig)
397 {
398  int i = 0;
399  const int MAX_ATTRIBUTES = 64;
400 
401  /* assert buffer is large enough to hold all SDL attributes. */
402  SDL_assert(size >= MAX_ATTRIBUTES);
403 
404  /* Setup our GLX attributes according to the gl_config. */
405  if( for_FBConfig ) {
406  attribs[i++] = GLX_RENDER_TYPE;
407  attribs[i++] = GLX_RGBA_BIT;
408  } else {
409  attribs[i++] = GLX_RGBA;
410  }
411  attribs[i++] = GLX_RED_SIZE;
412  attribs[i++] = _this->gl_config.red_size;
413  attribs[i++] = GLX_GREEN_SIZE;
414  attribs[i++] = _this->gl_config.green_size;
415  attribs[i++] = GLX_BLUE_SIZE;
416  attribs[i++] = _this->gl_config.blue_size;
417 
418  if (_this->gl_config.alpha_size) {
419  attribs[i++] = GLX_ALPHA_SIZE;
420  attribs[i++] = _this->gl_config.alpha_size;
421  }
422 
424  attribs[i++] = GLX_DOUBLEBUFFER;
425  if( for_FBConfig ) {
426  attribs[i++] = True;
427  }
428  }
429 
430  attribs[i++] = GLX_DEPTH_SIZE;
431  attribs[i++] = _this->gl_config.depth_size;
432 
434  attribs[i++] = GLX_STENCIL_SIZE;
435  attribs[i++] = _this->gl_config.stencil_size;
436  }
437 
439  attribs[i++] = GLX_ACCUM_RED_SIZE;
440  attribs[i++] = _this->gl_config.accum_red_size;
441  }
442 
444  attribs[i++] = GLX_ACCUM_GREEN_SIZE;
445  attribs[i++] = _this->gl_config.accum_green_size;
446  }
447 
449  attribs[i++] = GLX_ACCUM_BLUE_SIZE;
450  attribs[i++] = _this->gl_config.accum_blue_size;
451  }
452 
454  attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
455  attribs[i++] = _this->gl_config.accum_alpha_size;
456  }
457 
458  if (_this->gl_config.stereo) {
459  attribs[i++] = GLX_STEREO;
460  if( for_FBConfig ) {
461  attribs[i++] = True;
462  }
463  }
464 
466  attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
467  attribs[i++] = _this->gl_config.multisamplebuffers;
468  }
469 
471  attribs[i++] = GLX_SAMPLES_ARB;
472  attribs[i++] = _this->gl_config.multisamplesamples;
473  }
474 
475  if (_this->gl_config.accelerated >= 0 &&
476  _this->gl_data->HAS_GLX_EXT_visual_rating) {
477  attribs[i++] = GLX_VISUAL_CAVEAT_EXT;
478  attribs[i++] = _this->gl_config.accelerated ? GLX_NONE_EXT :
480  }
481 
482  /* If we're supposed to use DirectColor visuals, and we've got the
483  EXT_visual_info extension, then add GLX_X_VISUAL_TYPE_EXT. */
485  _this->gl_data->HAS_GLX_EXT_visual_info) {
486  attribs[i++] = GLX_X_VISUAL_TYPE_EXT;
487  attribs[i++] = GLX_DIRECT_COLOR_EXT;
488  }
489 
490  attribs[i++] = None;
491 
492  SDL_assert(i <= MAX_ATTRIBUTES);
493 
494  return i;
495 }
496 
497 XVisualInfo *
498 X11_GL_GetVisual(_THIS, Display * display, int screen)
499 {
500  XVisualInfo *vinfo;
501 
502  /* 64 seems nice. */
503  int attribs[64];
504  X11_GL_GetAttributes(_this,display,screen,attribs,64,SDL_FALSE);
505 
506  if (!_this->gl_data) {
507  /* The OpenGL library wasn't loaded, SDL_GetError() should have info */
508  return NULL;
509  }
510 
511  vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs);
512  if (!vinfo) {
513  SDL_SetError("Couldn't find matching GLX visual");
514  }
515  return vinfo;
516 }
517 
518 #ifndef GLXBadContext
519 #define GLXBadContext 0
520 #endif
521 #ifndef GLXBadFBConfig
522 #define GLXBadFBConfig 9
523 #endif
524 #ifndef GLXBadProfileARB
525 #define GLXBadProfileARB 13
526 #endif
527 static int (*handler) (Display *, XErrorEvent *) = NULL;
528 static int errorBase = 0;
529 static int
530 X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)
531 {
532  switch (e->error_code) {
533  case BadRequest:
534  case BadMatch:
535  case BadValue:
536  case BadAlloc:
537  return (0);
538  default:
539  if (errorBase &&
540  (e->error_code == errorBase + GLXBadContext ||
541  e->error_code == errorBase + GLXBadFBConfig ||
542  e->error_code == errorBase + GLXBadProfileARB)) {
543  return (0);
544  }
545  return (handler(d, e));
546  }
547 }
548 
550 X11_GL_CreateContext(_THIS, SDL_Window * window)
551 {
553  Display *display = data->videodata->display;
554  int screen =
555  ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen;
556  XWindowAttributes xattr;
557  XVisualInfo v, *vinfo;
558  int n;
559  GLXContext context = NULL, share_context;
560  PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = NULL;
561 
563  share_context = (GLXContext)SDL_GL_GetCurrentContext();
564  } else {
565  share_context = NULL;
566  }
567 
568  /* We do this to create a clean separation between X and GLX errors. */
569  XSync(display, False);
570  errorBase = _this->gl_data->errorBase;
571  handler = XSetErrorHandler(X11_GL_CreateContextErrorHandler);
572  XGetWindowAttributes(display, data->xwindow, &xattr);
573  v.screen = screen;
574  v.visualid = XVisualIDFromVisual(xattr.visual);
575  vinfo = XGetVisualInfo(display, VisualScreenMask | VisualIDMask, &v, &n);
576  if (vinfo) {
577  if (_this->gl_config.major_version < 3 &&
578  _this->gl_config.profile_mask == 0 &&
579  _this->gl_config.flags == 0) {
580  /* Create legacy context */
581  context =
582  _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
583  } else {
584  /* If we want a GL 3.0 context or later we need to get a temporary
585  context to grab the new context creation function */
586  GLXContext temp_context =
587  _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
588  if (temp_context) {
589  /* max 8 attributes plus terminator */
590  int attribs[9] = {
595  0
596  };
597  int iattr = 4;
598 
599  /* SDL profile bits match GLX profile bits */
600  if( _this->gl_config.profile_mask != 0 ) {
601  attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
602  attribs[iattr++] = _this->gl_config.profile_mask;
603  }
604 
605  /* SDL flags match GLX flags */
606  if( _this->gl_config.flags != 0 ) {
607  attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
608  attribs[iattr++] = _this->gl_config.flags;
609  }
610 
611  attribs[iattr++] = 0;
612 
613  /* Get a pointer to the context creation function for GL 3.0 */
614  glXCreateContextAttribs =
617  "glXCreateContextAttribsARB");
618  if (!glXCreateContextAttribs) {
619  SDL_SetError("GL 3.x is not supported");
620  context = temp_context;
621  } else {
622  int glxAttribs[64];
623 
624  /* Create a GL 3.x context */
625  GLXFBConfig *framebuffer_config = NULL;
626  int fbcount = 0;
627  GLXFBConfig *(*glXChooseFBConfig) (Display * disp,
628  int screen,
629  const int *attrib_list,
630  int *nelements);
631 
633  (GLXFBConfig *
634  (*)(Display *, int, const int *,
635  int *)) _this->gl_data->
636  glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
637 
638  X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE);
639 
640  if (!glXChooseFBConfig
641  || !(framebuffer_config =
642  glXChooseFBConfig(display,
643  DefaultScreen(display), glxAttribs,
644  &fbcount))) {
646  ("No good framebuffers found. GL 3.x disabled");
647  context = temp_context;
648  } else {
649  context =
650  glXCreateContextAttribs(display,
651  framebuffer_config[0],
652  share_context, True, attribs);
653  _this->gl_data->glXDestroyContext(display,
654  temp_context);
655  }
656  }
657  }
658  }
659  XFree(vinfo);
660  }
661  XSync(display, False);
662  XSetErrorHandler(handler);
663 
664  if (!context) {
665  SDL_SetError("Could not create GL context");
666  return NULL;
667  }
668 
669  if (X11_GL_MakeCurrent(_this, window, context) < 0) {
670  X11_GL_DeleteContext(_this, context);
671  return NULL;
672  }
673 
674  return context;
675 }
676 
677 int
678 X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
679 {
680  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
681  Window drawable =
682  (context ? ((SDL_WindowData *) window->driverdata)->xwindow : None);
683  GLXContext glx_context = (GLXContext) context;
684 
685  if (!_this->gl_data) {
686  return SDL_SetError("OpenGL not initialized");
687  }
688 
689  if (!_this->gl_data->glXMakeCurrent(display, drawable, glx_context)) {
690  return SDL_SetError("Unable to make GL context current");
691  }
692 
693  return 0;
694 }
695 
696 /*
697  0 is a valid argument to glxSwapInterval(MESA|EXT) and setting it to 0
698  will undo the effect of a previous call with a value that is greater
699  than zero (or at least that is what the docs say). OTOH, 0 is an invalid
700  argument to glxSwapIntervalSGI and it returns an error if you call it
701  with 0 as an argument.
702 */
703 
704 static int swapinterval = -1;
705 int
706 X11_GL_SetSwapInterval(_THIS, int interval)
707 {
708  int status = -1;
709 
710  if ((interval < 0) && (!_this->gl_data->HAS_GLX_EXT_swap_control_tear)) {
711  SDL_SetError("Negative swap interval unsupported in this GL");
712  } else if (_this->gl_data->glXSwapIntervalEXT) {
713  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
714  const SDL_WindowData *windowdata = (SDL_WindowData *)
716 
717  Window drawable = windowdata->xwindow;
718 
719  /*
720  * This is a workaround for a bug in NVIDIA drivers. Bug has been reported
721  * and will be fixed in a future release (probably 319.xx).
722  *
723  * There's a bug where glXSetSwapIntervalEXT ignores updates because
724  * it has the wrong value cached. To work around it, we just run a no-op
725  * update to the current value.
726  */
727  int currentInterval = X11_GL_GetSwapInterval(_this);
728  _this->gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
729  _this->gl_data->glXSwapIntervalEXT(display, drawable, interval);
730 
731  status = 0;
732  swapinterval = interval;
733  } else if (_this->gl_data->glXSwapIntervalMESA) {
734  status = _this->gl_data->glXSwapIntervalMESA(interval);
735  if (status != 0) {
736  SDL_SetError("glxSwapIntervalMESA failed");
737  } else {
738  swapinterval = interval;
739  }
740  } else if (_this->gl_data->glXSwapIntervalSGI) {
741  status = _this->gl_data->glXSwapIntervalSGI(interval);
742  if (status != 0) {
743  SDL_SetError("glxSwapIntervalSGI failed");
744  } else {
745  swapinterval = interval;
746  }
747  } else {
748  SDL_Unsupported();
749  }
750  return status;
751 }
752 
753 int
754 X11_GL_GetSwapInterval(_THIS)
755 {
756  if (_this->gl_data->glXSwapIntervalEXT) {
757  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
758  const SDL_WindowData *windowdata = (SDL_WindowData *)
760  Window drawable = windowdata->xwindow;
761  unsigned int allow_late_swap_tearing = 0;
762  unsigned int interval = 0;
763 
764  if (_this->gl_data->HAS_GLX_EXT_swap_control_tear) {
765  _this->gl_data->glXQueryDrawable(display, drawable,
767  &allow_late_swap_tearing);
768  }
769 
770  _this->gl_data->glXQueryDrawable(display, drawable,
771  GLX_SWAP_INTERVAL_EXT, &interval);
772 
773  if ((allow_late_swap_tearing) && (interval > 0)) {
774  return -((int) interval);
775  }
776 
777  return (int) interval;
778  } else if (_this->gl_data->glXGetSwapIntervalMESA) {
779  return _this->gl_data->glXGetSwapIntervalMESA();
780  } else {
781  return swapinterval;
782  }
783 }
784 
785 void
786 X11_GL_SwapWindow(_THIS, SDL_Window * window)
787 {
788  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
789  Display *display = data->videodata->display;
790 
791  _this->gl_data->glXSwapBuffers(display, data->xwindow);
792 }
793 
794 void
795 X11_GL_DeleteContext(_THIS, SDL_GLContext context)
796 {
797  Display *display = ((SDL_VideoData *) _this->driverdata)->display;
798  GLXContext glx_context = (GLXContext) context;
799 
800  if (!_this->gl_data) {
801  return;
802  }
803  _this->gl_data->glXDestroyContext(display, glx_context);
804  XSync(display, False);
805 }
806 
807 #endif /* SDL_VIDEO_OPENGL_GLX */
808 
809 #endif /* SDL_VIDEO_DRIVER_X11 */
810 
811 /* vi: set ts=4 sw=4 expandtab: */
void X11_PumpEvents(_THIS)
GLXContext(* PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list)
Definition: glxew.h:400
#define GLX_SWAP_INTERVAL_EXT
Definition: glxew.h:673
Display * display
Definition: SDL_x11video.h:75
uint32_t swapinterval
Definition: SDL_pspgl_c.h:36
#define GLX_NONE_EXT
Definition: glxew.h:754
#define GLX_SLOW_VISUAL_EXT
Definition: glxew.h:774
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
#define NULL
Definition: ftobjs.h:61
struct __GLXcontextRec * GLXContext
Definition: glxew_head.h:63
GLuint start
Definition: glew.h:1239
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:226
#define GLX_DOUBLEBUFFER
Definition: glxew_head.h:37
#define GLX_ACCUM_GREEN_SIZE
Definition: glxew_head.h:47
SDL_bool
Definition: SDL_stdinc.h:116
GLclampd n
Definition: glew.h:7287
#define glXGetProcAddress
Definition: glx_mangle.h:78
return Display return Display Bool Bool int int e
Definition: SDL_x11sym.h:30
DECLSPEC SDL_Window *SDLCALL SDL_GL_GetCurrentWindow(void)
Get the currently active OpenGL window.
Definition: SDL_video.c:2812
SDL_bool X11_UseDirectColorVisuals(void)
DECLSPEC void SDLCALL SDL_free(void *mem)
#define GLX_GREEN_SIZE
Definition: glxew_head.h:41
GLXFBConfig * glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:161
EGLSurface const EGLint * attrib_list
Definition: eglext.h:74
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
char * display
Definition: visualinfo.c:85
DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c)
Definition: SDL_string.c:575
const GLint * attribs
Definition: glew.h:13064
EGLDisplay display
Definition: SDL_pspgl_c.h:33
GLsizei const GLchar *const * path
Definition: glew.h:5828
#define GLX_VISUAL_CAVEAT_EXT
Definition: glxew.h:773
#define GLX_SAMPLES_ARB
Definition: glxew.h:475
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:315
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:228
#define GLX_X_VISUAL_TYPE_EXT
Definition: glxew.h:747
#define GLX_SAMPLE_BUFFERS_ARB
Definition: glxew.h:474
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:224
#define GLX_RGBA
Definition: glxew_head.h:36
khronos_uint8_t GLubyte
Definition: gl2.h:30
#define GLX_BLUE_SIZE
Definition: glxew_head.h:42
const GLdouble * v
Definition: glew.h:1377
#define GLX_CONTEXT_FLAGS_ARB
Definition: glxew.h:398
int
Definition: SDL_systhread.c:37
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
#define _THIS
struct SDL_VideoData * videodata
#define GLX_DEPTH_SIZE
Definition: glxew_head.h:44
#define GLX_CONTEXT_PROFILE_MASK_ARB
Definition: glxew.h:415
XID GLXDrawable
Definition: glxew_head.h:58
DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle)
Definition: SDL_string.c:612
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
char driver_path[256]
Definition: SDL_sysvideo.h:298
struct __GLXFBConfigRec * GLXFBConfig
Definition: glxew.h:263
#define GLX_DIRECT_COLOR_EXT
Definition: glxew.h:756
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
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 int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom retur XGetWindowAttributes)
Definition: SDL_x11sym.h:70
#define GLX_STEREO
Definition: glxew_head.h:38
#define GLX_ACCUM_BLUE_SIZE
Definition: glxew_head.h:48
int share_with_current_context
Definition: SDL_sysvideo.h:295
#define SDL_assert(condition)
Definition: SDL_assert.h:159
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:229
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
#define GLX_ACCUM_ALPHA_SIZE
Definition: glxew_head.h:49
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:231
#define GLX_CONTEXT_MAJOR_VERSION_ARB
Definition: glxew.h:396
#define GLX_CONTEXT_MINOR_VERSION_ARB
Definition: glxew.h:397
#define GLX_RENDER_TYPE
Definition: glxew.h:238
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
#define GLX_ACCUM_RED_SIZE
Definition: glxew_head.h:46
#define GLX_RED_SIZE
Definition: glxew_head.h:40
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:225
EGLConfig config
Definition: eglext.h:257
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:222
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:230
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 int int return Display Window Cursor retur XDestroyWindow)
Definition: SDL_x11sym.h:46
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
void * driverdata
Definition: SDL_sysvideo.h:99
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:284
TParseContext * context
int i
Definition: pngrutil.c:1377
#define GLX_STENCIL_SIZE
Definition: glxew_head.h:45
char Bool
Definition: ftraster.c:307
#define GLX_RGBA_BIT
Definition: glxew.h:203
struct SDL_VideoDevice::@87 gl_config
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:223
#define GLX_ALPHA_SIZE
Definition: glxew_head.h:43
#define SDL_Unsupported()
Definition: SDL_error.h:53
DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void)
Get the currently active OpenGL context.
Definition: SDL_video.c:2822
#define GLX_LATE_SWAPS_TEAR_EXT
Definition: glxew.h:689
Display * dpy
GLsizei size
Definition: gl2ext.h:1467