1 /* xscreensaver, Copyright (c) 1999-2011 by Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* This file contains code for picking the best visual for GL programs by
13 actually asking the GL library to figure it out for us. The code in
14 visual.c might do a good job of this on most systems, but not on most
15 high end 3D cards (e.g., Silicon Graphics or nVidia.)
17 There exists information about visuals which is available to GL, but
18 which is not available via Xlib calls. So the only way to know
19 which visual to use (other than impirically) is to actually call
25 #include "resources.h"
32 extern char *progname;
35 get_gl_visual (Screen *screen)
38 Display *dpy = DisplayOfScreen (screen);
39 int screen_num = screen_number (screen);
41 # define R GLX_RED_SIZE
42 # define G GLX_GREEN_SIZE
43 # define B GLX_BLUE_SIZE
44 # define A GLX_ALPHA_SIZE
45 # define D GLX_DEPTH_SIZE
46 # define I GLX_BUFFER_SIZE
47 # define DB GLX_DOUBLEBUFFER
48 # define ST GLX_STENCIL_SIZE
50 # if defined(GL_SAMPLE_BUFFERS)
51 # define SB GL_SAMPLE_BUFFERS
52 # define SM GL_SAMPLES
53 # elif defined(GLX_SAMPLE_BUFFERS)
54 # define SB GLX_SAMPLE_BUFFERS
55 # define SM GLX_SAMPLES
56 # elif defined(GLX_SAMPLE_BUFFERS_ARB)
57 # define SB GLX_SAMPLE_BUFFERS_ARB
58 # define SM GLX_SAMPLES_ARB
59 # elif defined(GLX_SAMPLE_BUFFERS_SGIS)
60 # define SB GLX_SAMPLE_BUFFERS_SGIS
61 # define SM GLX_SAMPLES_SGIS
65 # ifdef SB /* rgba double stencil multisample */
66 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,8, 0 },
67 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,6, 0 },
68 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,4, 0 },
69 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,2, 0 },
70 # define SB_COUNT 4 /* #### Kludgey count of preceeding lines! */
72 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, 0 }, /* rgba double stencil */
73 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, ST,1, 0 }, /* rgb double stencil */
74 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, ST,1, 0 },
75 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, ST,1, 0 },
76 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, 0 }, /* rgba double */
77 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, 0 }, /* rgb double */
78 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, 0 },
79 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, 0 },
80 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, 0 }, /* rgba single */
81 { GLX_RGBA, R,8, G,8, B,8, D,8, 0 }, /* rgb single */
82 { GLX_RGBA, R,4, G,4, B,4, D,4, 0 },
83 { GLX_RGBA, R,2, G,2, B,2, D,2, 0 },
84 { I, 8, D,8, DB, 0 }, /* cmap double */
86 { I, 8, D,8, 0 }, /* cmap single */
88 { GLX_RGBA, R,1, G,1, B,1, D,1, 0 } /* monochrome */
94 if (! get_boolean_resource (dpy, "multiSample", "MultiSample"))
95 i = SB_COUNT; /* skip over the multibuffer entries in 'attrs' */
98 for (; i < sizeof(attrs)/sizeof(*attrs); i++)
100 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
103 Visual *v = vi->visual;
105 /* describe_gl_visual (stderr, screen, v, False); */
109 #endif /* !HAVE_GL */
116 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
119 describe_visual (f, screen, visual, private_cmap_p);
126 Display *dpy = DisplayOfScreen (screen);
127 XVisualInfo vi_in, *vi_out;
130 vi_in.screen = screen_number (screen);
131 vi_in.visualid = XVisualIDFromVisual (visual);
132 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
134 if (! vi_out) abort ();
136 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
138 if (status == GLX_NO_EXTENSION)
139 /* dpy does not support the GLX extension. */
142 if (status == GLX_BAD_VISUAL || value == False)
143 /* this visual does not support GLX. */
146 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
148 printf (" GLX level: %d\n", value);
150 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
152 int r=0, g=0, b=0, a=0;
153 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
154 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
155 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
156 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
157 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
161 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
162 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
163 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
164 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
165 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
171 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
172 printf (" GLX type: indexed (%d)\n", value);
175 # ifndef GLX_NONE_EXT /* Hooray for gratuitious name changes. */
176 # define GLX_NONE_EXT GLX_NONE
177 # define GLX_TRANSPARENT_TYPE_EXT GLX_TRANSPARENT_TYPE
178 # define GLX_TRANSPARENT_INDEX_EXT GLX_TRANSPARENT_INDEX
179 # define GLX_TRANSPARENT_INDEX_VALUE_EXT GLX_TRANSPARENT_INDEX_VALUE
180 # define GLX_TRANSPARENT_RGB_EXT GLX_TRANSPARENT_RGB
181 # define GLX_TRANSPARENT_RED_VALUE_EXT GLX_TRANSPARENT_RED_VALUE
182 # define GLX_TRANSPARENT_GREEN_VALUE_EXT GLX_TRANSPARENT_GREEN_VALUE
183 # define GLX_TRANSPARENT_BLUE_VALUE_EXT GLX_TRANSPARENT_BLUE_VALUE
184 # define GLX_TRANSPARENT_ALPHA_VALUE_EXT GLX_TRANSPARENT_ALPHA_VALUE
187 # ifdef GLX_VISUAL_CAVEAT_EXT
188 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
189 value != GLX_NONE_EXT)
190 # ifdef GLX_NON_CONFORMANT_EXT
191 printf (" GLX rating: %s\n",
192 (value == GLX_NONE_EXT ? "none" :
193 value == GLX_SLOW_VISUAL_EXT ? "slow" :
194 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
197 printf (" GLX rating: %s\n",
198 (value == GLX_NONE_EXT ? "none" :
199 value == GLX_SLOW_VISUAL_EXT ? "slow" :
201 # endif /* GLX_NON_CONFORMANT_EXT */
202 # endif /* GLX_VISUAL_CAVEAT_EXT */
204 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
205 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
207 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
209 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
211 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
213 printf (" GLX aux buffers: %d\n", value);
215 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
216 printf (" GLX depth size: %d\n", value);
218 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
220 printf (" GLX stencil size: %d\n", value);
222 # ifdef SB /* GL_SAMPLE_BUFFERS || GLX_SAMPLE_BUFFERS_* */
223 if (!glXGetConfig (dpy, vi_out, SB, &value) &&
227 if (!glXGetConfig (dpy, vi_out, SM, &value))
228 printf (" GLX multisample: %d, %d\n", bufs, value);
230 # endif /* GL_SAMPLE_BUFFERS || GLX_SAMPLE_BUFFERS_* */
232 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
233 value != GLX_NONE_EXT)
235 if (value == GLX_NONE_EXT)
236 printf (" GLX transparency: none\n");
237 else if (value == GLX_TRANSPARENT_INDEX_EXT)
239 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
241 printf (" GLX transparency: indexed (%d)\n", value);
243 else if (value == GLX_TRANSPARENT_RGB_EXT)
245 int r=0, g=0, b=0, a=0;
246 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
247 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
248 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
249 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
250 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
260 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
267 Display *dpy = DisplayOfScreen (screen);
268 XVisualInfo vi_in, *vi_out;
272 vi_in.screen = screen_number (screen);
273 vi_in.visualid = XVisualIDFromVisual (visual);
274 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
276 if (! vi_out) abort ();
278 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
280 id = (unsigned int) vi_out->visualid;
281 XFree ((char *) vi_out);
283 if (status == GLX_NO_EXTENSION)
285 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
286 progname, DisplayString (dpy));
289 else if (status == GLX_BAD_VISUAL || value == False)
292 "%s: %s's visual 0x%x does not support the GLX extension.\n",
293 progname, window_desc, id);
303 fprintf (out, "%s: GL support was not compiled in to this program.\n",
307 #endif /* !HAVE_GL */