2
* Copyright © 2004 David Reveman
4
* Permission to use, copy, modify, distribute, and sell this software
5
* and its documentation for any purpose is hereby granted without
6
* fee, provided that the above copyright notice appear in all copies
7
* and that both that copyright notice and this permission notice
8
* appear in supporting documentation, and that the name of
9
* David Reveman not be used in advertising or publicity pertaining to
10
* distribution of the software without specific, written prior permission.
11
* David Reveman makes no representations about the suitability of this
12
* software for any purpose. It is provided "as is" without express or
15
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Author: David Reveman <davidr@novell.com>
27
# include "../config.h"
30
#include "glitz_glxint.h"
36
_glitz_glx_format_compare (const void *elem1,
39
glitz_int_drawable_format_t *format[2];
42
format[0] = (glitz_int_drawable_format_t *) elem1;
43
format[1] = (glitz_int_drawable_format_t *) elem2;
44
i = score[0] = score[1] = 0;
48
if (format[i]->d.color.fourcc != GLITZ_FOURCC_RGB)
51
if (format[i]->d.color.red_size)
53
if (format[i]->d.color.red_size >= 8)
59
if (format[i]->d.color.alpha_size)
61
if (format[i]->d.color.alpha_size >= 8)
67
if (format[i]->d.stencil_size)
70
if (format[i]->d.depth_size)
73
if (format[i]->d.doublebuffer)
76
if (format[i]->d.samples > 1)
77
score[i] -= (20 - format[i]->d.samples);
79
if (format[i]->types & GLITZ_DRAWABLE_TYPE_WINDOW_MASK)
82
if (format[i]->types & GLITZ_DRAWABLE_TYPE_PBUFFER_MASK)
85
if (format[i]->caveat)
89
return score[1] - score[0];
93
_glitz_add_format (glitz_glx_screen_info_t *screen_info,
94
glitz_int_drawable_format_t *format)
96
int n = screen_info->n_formats;
98
screen_info->formats =
99
realloc (screen_info->formats,
100
sizeof (glitz_int_drawable_format_t) * (n + 1));
101
if (screen_info->formats)
103
screen_info->formats[n] = *format;
104
screen_info->formats[n].d.id = n;
105
screen_info->n_formats++;
110
_glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
113
glitz_int_drawable_format_t format;
114
XVisualInfo visual_templ;
115
XVisualInfo *visuals;
118
display = screen_info->display_info->display;
120
visual_templ.screen = screen_info->screen;
121
visuals = XGetVisualInfo (display, VisualScreenMask,
122
&visual_templ, &num_visuals);
124
/* No pbuffers without fbconfigs */
125
format.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
127
format.d.color.fourcc = GLITZ_FOURCC_RGB;
129
for (i = 0; i < num_visuals; i++)
133
if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) ||
137
glXGetConfig (display, &visuals[i], GLX_RGBA, &value);
141
/* Stereo is not supported yet */
142
glXGetConfig (display, &visuals[i], GLX_STEREO, &value);
146
glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value);
147
format.d.color.red_size = (unsigned short) value;
148
glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value);
149
format.d.color.green_size = (unsigned short) value;
150
glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value);
151
format.d.color.blue_size = (unsigned short) value;
152
glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value);
153
format.d.color.alpha_size = (unsigned short) value;
154
glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value);
155
format.d.depth_size = (unsigned short) value;
156
glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value);
157
format.d.stencil_size = (unsigned short) value;
158
glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value);
159
format.d.doublebuffer = (value) ? 1: 0;
161
if (screen_info->glx_feature_mask &
162
GLITZ_GLX_FEATURE_VISUAL_RATING_MASK)
164
glXGetConfig (display, &visuals[i], GLX_VISUAL_CAVEAT_EXT, &value);
166
case GLX_SLOW_VISUAL_EXT:
167
case GLX_NON_CONFORMANT_VISUAL_EXT:
178
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK)
180
glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB,
184
glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value);
185
format.d.samples = (unsigned short) (value > 1)? value: 1;
188
format.d.samples = 1;
191
format.d.samples = 1;
193
format.u.uval = visuals[i].visualid;
195
_glitz_add_format (screen_info, &format);
202
static glitz_status_t
203
_glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info)
205
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
207
glitz_int_drawable_format_t format;
208
GLXFBConfig *fbconfigs;
211
display = screen_info->display_info->display;
213
fbconfigs = glx->get_fbconfigs (display, screen_info->screen,
217
/* fbconfigs are not supported, falling back to visuals */
218
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK;
219
screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK;
221
return GLITZ_STATUS_NOT_SUPPORTED;
224
for (i = 0; i < num_configs; i++)
228
if ((glx->get_fbconfig_attrib (display, fbconfigs[i],
229
GLX_RENDER_TYPE, &value) != 0) ||
230
(!(value & GLX_RGBA_BIT)))
233
/* Stereo is not supported yet */
234
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value);
238
glx->get_fbconfig_attrib (display, fbconfigs[i],
239
GLX_DRAWABLE_TYPE, &value);
240
if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT)))
244
if (value & GLX_WINDOW_BIT)
245
format.types |= GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
247
if (value & GLX_PBUFFER_BIT)
248
format.types |= GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
251
format.d.color.fourcc = GLITZ_FOURCC_RGB;
253
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID,
255
format.u.uval = value;
257
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value);
258
format.d.color.red_size = (unsigned short) value;
259
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE,
261
format.d.color.green_size = (unsigned short) value;
262
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE,
264
format.d.color.blue_size = (unsigned short) value;
265
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE,
267
format.d.color.alpha_size = (unsigned short) value;
268
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE,
270
format.d.depth_size = (unsigned short) value;
271
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE,
273
format.d.stencil_size = (unsigned short) value;
274
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER,
276
format.d.doublebuffer = (value)? 1: 0;
277
glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_CONFIG_CAVEAT,
280
case GLX_SLOW_VISUAL_EXT:
281
case GLX_NON_CONFORMANT_VISUAL_EXT:
289
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK)
291
glx->get_fbconfig_attrib (display, fbconfigs[i],
292
GLX_SAMPLE_BUFFERS_ARB, &value);
295
glx->get_fbconfig_attrib (display, fbconfigs[i],
296
GLX_SAMPLES_ARB, &value);
297
format.d.samples = (unsigned short) (value > 1)? value: 1;
298
if (format.d.samples > 1)
300
if (!(screen_info->glx_feature_mask &
301
GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK))
302
format.types &= ~GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
306
format.d.samples = 1;
309
format.d.samples = 1;
311
_glitz_add_format (screen_info, &format);
317
return GLITZ_STATUS_SUCCESS;
321
glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info)
323
glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED;
326
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
327
status = _glitz_glx_query_formats_using_fbconfigs (screen_info);
330
_glitz_glx_query_formats (screen_info);
332
if (!screen_info->n_formats)
335
qsort (screen_info->formats, screen_info->n_formats,
336
sizeof (glitz_int_drawable_format_t), _glitz_glx_format_compare);
338
for (i = 0; i < screen_info->n_formats; i++)
339
screen_info->formats[i].d.id = i;
342
glitz_drawable_format_t *
343
glitz_glx_find_window_format (Display *display,
346
const glitz_drawable_format_t *templ,
349
glitz_int_drawable_format_t itempl;
350
glitz_glx_screen_info_t *screen_info =
351
glitz_glx_screen_info_get (display, screen);
353
glitz_drawable_format_copy (templ, &itempl.d, mask);
355
itempl.types = GLITZ_DRAWABLE_TYPE_WINDOW_MASK;
356
mask |= GLITZ_INT_FORMAT_WINDOW_MASK;
358
return glitz_drawable_format_find (screen_info->formats,
359
screen_info->n_formats,
360
mask, &itempl, count);
362
slim_hidden_def(glitz_glx_find_window_format);
364
glitz_drawable_format_t *
365
glitz_glx_find_pbuffer_format (Display *display,
368
const glitz_drawable_format_t *templ,
371
glitz_int_drawable_format_t itempl;
372
glitz_glx_screen_info_t *screen_info =
373
glitz_glx_screen_info_get (display, screen);
375
glitz_drawable_format_copy (templ, &itempl.d, mask);
377
itempl.types = GLITZ_DRAWABLE_TYPE_PBUFFER_MASK;
378
mask |= GLITZ_INT_FORMAT_PBUFFER_MASK;
380
return glitz_drawable_format_find (screen_info->formats,
381
screen_info->n_formats,
382
mask, &itempl, count);
384
slim_hidden_def(glitz_glx_find_pbuffer_format);
386
glitz_drawable_format_t *
387
glitz_glx_find_drawable_format_for_visual (Display *display,
391
glitz_drawable_format_t *format = NULL;
392
glitz_glx_screen_info_t *screen_info;
395
screen_info = glitz_glx_screen_info_get (display, screen);
399
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
401
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
402
GLXFBConfig *fbconfigs;
403
int fid, n_fbconfigs;
406
fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs);
407
for (i = 0; i < n_fbconfigs; i++)
409
XVisualInfo *visinfo;
411
visinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]);
412
if (visinfo && visinfo->visualid == visual_id)
416
glx->get_fbconfig_attrib (display, fbconfigs[i],
417
GLX_FBCONFIG_ID, &value);
418
for (fid = 0; fid < screen_info->n_formats; fid++)
420
if (screen_info->formats[fid].u.uval == value)
422
format = &screen_info->formats[fid].d;
437
for (i = 0; i < screen_info->n_formats; i++)
439
if (visual_id == screen_info->formats[i].u.uval)
441
format = &screen_info->formats[i].d;
449
slim_hidden_def(glitz_glx_find_drawable_format_for_visual);
452
glitz_glx_get_visual_info_from_format (Display *display,
454
glitz_drawable_format_t *format)
456
XVisualInfo *vinfo = NULL;
457
glitz_glx_screen_info_t *screen_info =
458
glitz_glx_screen_info_get (display, screen);
459
glitz_glx_static_proc_address_list_t *glx = &screen_info->glx;
461
if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK)
463
GLXFBConfig *fbconfigs;
465
int fbconfigid = screen_info->formats[format->id].u.uval;
467
fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs);
468
for (i = 0; i < n_fbconfigs; i++)
472
glx->get_fbconfig_attrib (display, fbconfigs[i],
473
GLX_FBCONFIG_ID, &value);
474
if (value == fbconfigid)
479
vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]);
490
templ.visualid = screen_info->formats[format->id].u.uval;
492
vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items);
497
slim_hidden_def(glitz_glx_get_visual_info_from_format);