zenilib: zenilib/jni/external/sdl/src/video/x11/SDL_x11opengl.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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 */
78 typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
79 GLXFBConfig config,
80 GLXContext
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 }
157 SDL_strlcpy(_this->gl_config.driver_path, path,
158 SDL_arraysize(_this->gl_config.driver_path));
159
160 /* Allocate OpenGL memory */
161 _this->gl_data =
162 (struct SDL_GLDriverData *) SDL_calloc(1,
163 sizeof(struct
164 SDL_GLDriverData));
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 */
216 if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES &&
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);
223 _this->gl_config.dll_handle = NULL;
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);
261 _this->gl_config.dll_handle = NULL;
262 #endif
263
264 /* Free OpenGL memory */
265 SDL_free(_this->gl_data);
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);
389 X11_PumpEvents(_this);
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
423 if (_this->gl_config.double_buffer) {
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
433 if (_this->gl_config.stencil_size) {
434 attribs[i++] = GLX_STENCIL_SIZE;
435 attribs[i++] = _this->gl_config.stencil_size;
436 }
437
438 if (_this->gl_config.accum_red_size) {
439 attribs[i++] = GLX_ACCUM_RED_SIZE;
440 attribs[i++] = _this->gl_config.accum_red_size;
441 }
442
443 if (_this->gl_config.accum_green_size) {
444 attribs[i++] = GLX_ACCUM_GREEN_SIZE;
445 attribs[i++] = _this->gl_config.accum_green_size;
446 }
447
448 if (_this->gl_config.accum_blue_size) {
449 attribs[i++] = GLX_ACCUM_BLUE_SIZE;
450 attribs[i++] = _this->gl_config.accum_blue_size;
451 }
452
453 if (_this->gl_config.accum_alpha_size) {
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
465 if (_this->gl_config.multisamplebuffers) {
466 attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
467 attribs[i++] = _this->gl_config.multisamplebuffers;
468 }
469
470 if (_this->gl_config.multisamplesamples) {
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 :
479 GLX_SLOW_VISUAL_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. */
484 if (X11_UseDirectColorVisuals() &&
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
549 SDL_GLContext
550 X11_GL_CreateContext(_THIS, SDL_Window * window)
551 {
552 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
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
562 if (_this->gl_config.share_with_current_context) {
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] = {
591 GLX_CONTEXT_MAJOR_VERSION_ARB,
592 _this->gl_config.major_version,
593 GLX_CONTEXT_MINOR_VERSION_ARB,
594 _this->gl_config.minor_version,
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 =
615 (PFNGLXCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
616 glXGetProcAddress((GLubyte *)
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
632 glXChooseFBConfig =
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))) {
645 SDL_SetError
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 *)
715 SDL_GL_GetCurrentWindow()->driverdata;
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 *)
759 SDL_GL_GetCurrentWindow()->driverdata;
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,
766 GLX_LATE_SWAPS_TEAR_EXT,
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: */
X11_PumpEvents
void X11_PumpEvents(_THIS)
PFNGLXCREATECONTEXTATTRIBSARBPROC
GLXContext(* PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list)
Definition: glxew.h:400
GLX_SWAP_INTERVAL_EXT
#define GLX_SWAP_INTERVAL_EXT
Definition: glxew.h:673
SDL_VideoDevice::accum_alpha_size
int accum_alpha_size
Definition: SDL_sysvideo.h:286
SDL_VideoData::display
Display * display
Definition: SDL_x11video.h:75
SDL_VideoDevice::accum_blue_size
int accum_blue_size
Definition: SDL_sysvideo.h:285
SDL_GLDriverData::swapinterval
uint32_t swapinterval
Definition: SDL_pspgl_c.h:36
GLX_NONE_EXT
#define GLX_NONE_EXT
Definition: glxew.h:754
GLX_SLOW_VISUAL_EXT
#define GLX_SLOW_VISUAL_EXT
Definition: glxew.h:774
void
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
SDL_calloc
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
NULL
#define NULL
Definition: ftobjs.h:61
GLXContext
struct __GLXcontextRec * GLXContext
Definition: glxew_head.h:63
SDL_VideoDevice::minor_version
int minor_version
Definition: SDL_sysvideo.h:292
start
GLuint start
Definition: glew.h:1239
SDL_VideoDevice::GL_MakeCurrent
int(* GL_MakeCurrent)(_THIS, SDL_Window *window, SDL_GLContext context)
Definition: SDL_sysvideo.h:226
SDL_VideoDevice::blue_size
int blue_size
Definition: SDL_sysvideo.h:277
GLX_DOUBLEBUFFER
#define GLX_DOUBLEBUFFER
Definition: glxew_head.h:37
SDL_VideoDevice::accum_red_size
int accum_red_size
Definition: SDL_sysvideo.h:283
GLX_ACCUM_GREEN_SIZE
#define GLX_ACCUM_GREEN_SIZE
Definition: glxew_head.h:47
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
n
GLclampd n
Definition: glew.h:7287
glXGetProcAddress
#define glXGetProcAddress
Definition: glx_mangle.h:78
SDL_WindowData::xwindow
Window xwindow
Definition: SDL_x11window.h:47
SDL_TRUE
Definition: SDL_stdinc.h:119
e
return Display return Display Bool Bool int int e
Definition: SDL_x11sym.h:30
SDL_GL_GetCurrentWindow
DECLSPEC SDL_Window *SDLCALL SDL_GL_GetCurrentWindow(void)
Get the currently active OpenGL window.
Definition: SDL_video.c:2812
X11_UseDirectColorVisuals
SDL_bool X11_UseDirectColorVisuals(void)
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:314
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
GLX_GREEN_SIZE
#define GLX_GREEN_SIZE
Definition: glxew_head.h:41
SDL_VideoDevice::profile_mask
int profile_mask
Definition: SDL_sysvideo.h:294
glXChooseFBConfig
GLXFBConfig * glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
SDL_x11opengles.h
SDL_GLContext
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:161
attrib_list
EGLSurface const EGLint * attrib_list
Definition: eglext.h:74
d
return Display return Display Bool Bool int d
Definition: SDL_x11sym.h:30
display
char * display
Definition: visualinfo.c:85
SDL_strchr
DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c)
Definition: SDL_string.c:575
SDL_FALSE
Definition: SDL_stdinc.h:118
attribs
const GLint * attribs
Definition: glew.h:13064
SDL_GLDriverData::display
EGLDisplay display
Definition: SDL_pspgl_c.h:33
path
GLsizei const GLchar *const * path
Definition: glew.h:5828
SDL_config.h
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
GLX_VISUAL_CAVEAT_EXT
#define GLX_VISUAL_CAVEAT_EXT
Definition: glxew.h:773
SDL_VideoDevice::stereo
int stereo
Definition: SDL_sysvideo.h:287
GLX_SAMPLES_ARB
#define GLX_SAMPLES_ARB
Definition: glxew.h:475
SDL_VideoDevice::gl_data
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:315
SDL_WindowData
Definition: SDL_androidwindow.h:33
SDL_VideoDevice::GL_SetSwapInterval
int(* GL_SetSwapInterval)(_THIS, int interval)
Definition: SDL_sysvideo.h:228
GLX_X_VISUAL_TYPE_EXT
#define GLX_X_VISUAL_TYPE_EXT
Definition: glxew.h:747
GLX_SAMPLE_BUFFERS_ARB
#define GLX_SAMPLE_BUFFERS_ARB
Definition: glxew.h:474
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:92
SDL_VideoDevice::accelerated
int accelerated
Definition: SDL_sysvideo.h:290
SDL_VideoDevice::multisamplebuffers
int multisamplebuffers
Definition: SDL_sysvideo.h:288
SDL_VideoDevice::GL_UnloadLibrary
void(* GL_UnloadLibrary)(_THIS)
Definition: SDL_sysvideo.h:224
SDL_VideoDevice::multisamplesamples
int multisamplesamples
Definition: SDL_sysvideo.h:289
GLX_RGBA
#define GLX_RGBA
Definition: glxew_head.h:36
SDL_VideoDevice::major_version
int major_version
Definition: SDL_sysvideo.h:291
GLubyte
khronos_uint8_t GLubyte
Definition: gl2.h:30
GLX_BLUE_SIZE
#define GLX_BLUE_SIZE
Definition: glxew_head.h:42
v
const GLdouble * v
Definition: glew.h:1377
GLX_CONTEXT_FLAGS_ARB
#define GLX_CONTEXT_FLAGS_ARB
Definition: glxew.h:398
int
int
Definition: SDL_systhread.c:37
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
SDL_VideoDevice::depth_size
int depth_size
Definition: SDL_sysvideo.h:279
SDL_VideoDevice::red_size
int red_size
Definition: SDL_sysvideo.h:275
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_WindowData::videodata
struct SDL_VideoData * videodata
Definition: SDL_cocoawindow.h:90
SDL_VideoDevice::double_buffer
int double_buffer
Definition: SDL_sysvideo.h:282
GLX_DEPTH_SIZE
#define GLX_DEPTH_SIZE
Definition: glxew_head.h:44
GLX_CONTEXT_PROFILE_MASK_ARB
#define GLX_CONTEXT_PROFILE_MASK_ARB
Definition: glxew.h:415
GLXDrawable
XID GLXDrawable
Definition: glxew_head.h:58
SDL_strstr
DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle)
Definition: SDL_string.c:612
SDL_strlcpy
DECLSPEC size_t SDLCALL SDL_strlcpy(char *dst, const char *src, size_t maxlen)
Definition: SDL_string.c:448
SDL_VideoDevice::driver_path
char driver_path[256]
Definition: SDL_sysvideo.h:298
SDL_VideoDevice::dll_handle
void * dll_handle
Definition: SDL_sysvideo.h:299
GLXFBConfig
struct __GLXFBConfigRec * GLXFBConfig
Definition: glxew.h:263
SDL_VideoDevice::green_size
int green_size
Definition: SDL_sysvideo.h:276
GLX_DIRECT_COLOR_EXT
#define GLX_DIRECT_COLOR_EXT
Definition: glxew.h:756
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_VideoDevice::alpha_size
int alpha_size
Definition: SDL_sysvideo.h:278
XGetWindowAttributes
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
GLX_STEREO
#define GLX_STEREO
Definition: glxew_head.h:38
GLX_ACCUM_BLUE_SIZE
#define GLX_ACCUM_BLUE_SIZE
Definition: glxew_head.h:48
SDL_VideoDevice::stencil_size
int stencil_size
Definition: SDL_sysvideo.h:281
SDL_VideoDevice::share_with_current_context
int share_with_current_context
Definition: SDL_sysvideo.h:295
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:159
SDL_strlen
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
SDL_VideoDevice::GL_GetSwapInterval
int(* GL_GetSwapInterval)(_THIS)
Definition: SDL_sysvideo.h:229
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:83
GLX_ACCUM_ALPHA_SIZE
#define GLX_ACCUM_ALPHA_SIZE
Definition: glxew_head.h:49
SDL_VideoDevice::GL_DeleteContext
void(* GL_DeleteContext)(_THIS, SDL_GLContext context)
Definition: SDL_sysvideo.h:231
SDL_VideoDevice::flags
int flags
Definition: SDL_sysvideo.h:293
GLX_CONTEXT_MAJOR_VERSION_ARB
#define GLX_CONTEXT_MAJOR_VERSION_ARB
Definition: glxew.h:396
SDL_loadso.h
GLX_CONTEXT_MINOR_VERSION_ARB
#define GLX_CONTEXT_MINOR_VERSION_ARB
Definition: glxew.h:397
GLX_RENDER_TYPE
#define GLX_RENDER_TYPE
Definition: glxew.h:238
SDL_GLDriverData
Definition: SDL_pspgl_c.h:32
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
SDL_Window
Definition: SDL_sysvideo.h:71
GLX_ACCUM_RED_SIZE
#define GLX_ACCUM_RED_SIZE
Definition: glxew_head.h:46
GLX_RED_SIZE
#define GLX_RED_SIZE
Definition: glxew_head.h:40
SDL_VideoDevice::GL_CreateContext
SDL_GLContext(* GL_CreateContext)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:225
config
EGLConfig config
Definition: eglext.h:257
SDL_VideoDevice::GL_LoadLibrary
int(* GL_LoadLibrary)(_THIS, const char *path)
Definition: SDL_sysvideo.h:222
SDL_VideoDevice::GL_SwapWindow
void(* GL_SwapWindow)(_THIS, SDL_Window *window)
Definition: SDL_sysvideo.h:230
SDL_x11video.h
SDL_VideoData
Definition: SDL_androidvideo.h:35
XDestroyWindow
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
w
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
SDL_getenv
DECLSPEC char *SDLCALL SDL_getenv(const char *name)
Definition: SDL_getenv.c:179
SDL_VideoDevice::accum_green_size
int accum_green_size
Definition: SDL_sysvideo.h:284
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:99
handle
EGLImageKHR EGLint EGLint * handle
Definition: eglext.h:284
context
TParseContext * context
Definition: glslang_tab.cpp:1907
i
int i
Definition: pngrutil.c:1377
GLX_STENCIL_SIZE
#define GLX_STENCIL_SIZE
Definition: glxew_head.h:45
Bool
char Bool
Definition: ftraster.c:307
SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:197
GLX_RGBA_BIT
#define GLX_RGBA_BIT
Definition: glxew.h:203
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@87 gl_config
SDL_VideoDevice::GL_GetProcAddress
void *(* GL_GetProcAddress)(_THIS, const char *proc)
Definition: SDL_sysvideo.h:223
GLX_ALPHA_SIZE
#define GLX_ALPHA_SIZE
Definition: glxew_head.h:43
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_GL_GetCurrentContext
DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void)
Get the currently active OpenGL context.
Definition: SDL_video.c:2822
GLX_LATE_SWAPS_TEAR_EXT
#define GLX_LATE_SWAPS_TEAR_EXT
Definition: glxew.h:689
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:126
dpy
Display * dpy
Definition: glewinfo_tail.c:220
SDL_assert.h
size
GLsizei size
Definition: gl2ext.h:1467