1 /* xscreensaver, Copyright (c) 1999-2018 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(GLX_SAMPLE_BUFFERS) /* Needs to come before GL_SAMPLE_BUFFERS */
51 # define SB GLX_SAMPLE_BUFFERS
52 # define SM GLX_SAMPLES
53 # elif defined(GLX_SAMPLE_BUFFERS_ARB)
54 # define SB GLX_SAMPLE_BUFFERS_ARB
55 # define SM GLX_SAMPLES_ARB
56 # elif defined(GLX_SAMPLE_BUFFERS_SGIS)
57 # define SB GLX_SAMPLE_BUFFERS_SGIS
58 # define SM GLX_SAMPLES_SGIS
59 # elif defined(GL_SAMPLE_BUFFERS)
60 # define SB GL_SAMPLE_BUFFERS
61 # define SM GL_SAMPLES
66 # ifdef SB /* rgba double stencil multisample */
67 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,8, 0 },
68 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,6, 0 },
69 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,4, 0 },
70 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, SB,1, SM,2, 0 },
71 # define SB_COUNT 4 /* #### Kludgey count of preceeding lines! */
73 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, 0 }, /* rgba double stencil */
74 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, ST,1, 0 }, /* rgb double stencil */
75 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, ST,1, 0 },
76 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, ST,1, 0 },
77 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, 0 }, /* rgba double */
78 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, 0 }, /* rgb double */
79 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, 0 },
80 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, 0 },
81 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, 0 }, /* rgba single */
82 { GLX_RGBA, R,8, G,8, B,8, D,8, 0 }, /* rgb single */
83 { GLX_RGBA, R,4, G,4, B,4, D,4, 0 },
84 { GLX_RGBA, R,2, G,2, B,2, D,2, 0 },
85 { I, 8, D,8, DB, 0 }, /* cmap double */
87 { I, 8, D,8, 0 }, /* cmap single */
89 { GLX_RGBA, R,1, G,1, B,1, D,1, 0 } /* monochrome */
95 if (! get_boolean_resource (dpy, "multiSample", "MultiSample"))
96 i = SB_COUNT; /* skip over the multibuffer entries in 'attrs' */
99 for (; i < sizeof(attrs)/sizeof(*attrs); i++)
101 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
104 Visual *v = vi->visual;
106 /* describe_gl_visual (stderr, screen, v, False); */
110 #endif /* !HAVE_GL */
117 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
120 describe_visual (f, screen, visual, private_cmap_p);
127 Display *dpy = DisplayOfScreen (screen);
128 XVisualInfo vi_in, *vi_out;
131 vi_in.screen = screen_number (screen);
132 vi_in.visualid = XVisualIDFromVisual (visual);
133 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
135 if (! vi_out) abort ();
137 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
139 if (status == GLX_NO_EXTENSION)
140 /* dpy does not support the GLX extension. */
143 if (status == GLX_BAD_VISUAL || value == False)
144 /* this visual does not support GLX. */
147 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
149 printf (" GLX level: %d\n", value);
151 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
153 int r=0, g=0, b=0, a=0;
154 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
155 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
156 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
157 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
158 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
162 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
163 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
164 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
165 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
166 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
172 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
173 printf (" GLX type: indexed (%d)\n", value);
176 # ifndef GLX_NONE_EXT /* Hooray for gratuitious name changes. */
177 # define GLX_NONE_EXT GLX_NONE
178 # define GLX_TRANSPARENT_TYPE_EXT GLX_TRANSPARENT_TYPE
179 # define GLX_TRANSPARENT_INDEX_EXT GLX_TRANSPARENT_INDEX
180 # define GLX_TRANSPARENT_INDEX_VALUE_EXT GLX_TRANSPARENT_INDEX_VALUE
181 # define GLX_TRANSPARENT_RGB_EXT GLX_TRANSPARENT_RGB
182 # define GLX_TRANSPARENT_RED_VALUE_EXT GLX_TRANSPARENT_RED_VALUE
183 # define GLX_TRANSPARENT_GREEN_VALUE_EXT GLX_TRANSPARENT_GREEN_VALUE
184 # define GLX_TRANSPARENT_BLUE_VALUE_EXT GLX_TRANSPARENT_BLUE_VALUE
185 # define GLX_TRANSPARENT_ALPHA_VALUE_EXT GLX_TRANSPARENT_ALPHA_VALUE
188 # ifdef GLX_VISUAL_CAVEAT_EXT
189 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
190 value != GLX_NONE_EXT)
191 # ifdef GLX_NON_CONFORMANT_EXT
192 printf (" GLX rating: %s\n",
193 (value == GLX_NONE_EXT ? "none" :
194 value == GLX_SLOW_VISUAL_EXT ? "slow" :
195 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
198 printf (" GLX rating: %s\n",
199 (value == GLX_NONE_EXT ? "none" :
200 value == GLX_SLOW_VISUAL_EXT ? "slow" :
202 # endif /* GLX_NON_CONFORMANT_EXT */
203 # endif /* GLX_VISUAL_CAVEAT_EXT */
205 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
206 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
208 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
210 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
212 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
214 printf (" GLX aux buffers: %d\n", value);
216 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
217 printf (" GLX depth size: %d\n", value);
219 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
221 printf (" GLX stencil size: %d\n", value);
223 # ifdef SB /* GL_SAMPLE_BUFFERS || GLX_SAMPLE_BUFFERS_* */
224 if (!glXGetConfig (dpy, vi_out, SB, &value) &&
228 if (!glXGetConfig (dpy, vi_out, SM, &value))
229 printf (" GLX multisample: %d, %d\n", bufs, value);
231 # endif /* GL_SAMPLE_BUFFERS || GLX_SAMPLE_BUFFERS_* */
233 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
234 value != GLX_NONE_EXT)
236 if (value == GLX_NONE_EXT)
237 printf (" GLX transparency: none\n");
238 else if (value == GLX_TRANSPARENT_INDEX_EXT)
240 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
242 printf (" GLX transparency: indexed (%d)\n", value);
244 else if (value == GLX_TRANSPARENT_RGB_EXT)
246 int r=0, g=0, b=0, a=0;
247 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
248 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
249 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
250 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
251 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
261 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
268 Display *dpy = DisplayOfScreen (screen);
269 XVisualInfo vi_in, *vi_out;
273 vi_in.screen = screen_number (screen);
274 vi_in.visualid = XVisualIDFromVisual (visual);
275 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
277 if (! vi_out) abort ();
279 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
281 id = (unsigned int) vi_out->visualid;
282 XFree ((char *) vi_out);
284 if (status == GLX_NO_EXTENSION)
286 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
287 progname, DisplayString (dpy));
290 else if (status == GLX_BAD_VISUAL || value == False)
293 "%s: %s's visual 0x%x does not support the GLX extension.\n",
294 progname, window_desc, id);
304 fprintf (out, "%s: GL support was not compiled in to this program.\n",
308 #endif /* !HAVE_GL */