First attempt at getting egl support up on dumb framebuffer.
[mesa.git] / src / egl / main / eglconfig.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "eglconfig.h"
6 #include "egldisplay.h"
7 #include "egldriver.h"
8 #include "eglglobals.h"
9
10
11 #define MIN2(A, B) (((A) < (B)) ? (A) : (B))
12
13
14 /**
15 * Init the given _EGLconfig to default values.
16 * \param id the configuration's ID.
17 */
18 void
19 _eglInitConfig(_EGLConfig *config, EGLint id)
20 {
21 memset(config, 0, sizeof(*config));
22 config->Handle = id;
23 _eglSetConfigAtrib(config, EGL_CONFIG_ID, id);
24 _eglSetConfigAtrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
25 _eglSetConfigAtrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
26 _eglSetConfigAtrib(config, EGL_CONFIG_CAVEAT, EGL_DONT_CARE);
27 _eglSetConfigAtrib(config, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE);
28 _eglSetConfigAtrib(config, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE);
29 _eglSetConfigAtrib(config, EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE);
30 _eglSetConfigAtrib(config, EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE);
31 _eglSetConfigAtrib(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
32 _eglSetConfigAtrib(config, EGL_TRANSPARENT_TYPE, EGL_NONE);
33 _eglSetConfigAtrib(config, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE);
34 _eglSetConfigAtrib(config, EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE);
35 _eglSetConfigAtrib(config, EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE);
36 }
37
38
39 /**
40 * Given an EGLConfig handle, return the corresponding _EGLConfig object.
41 */
42 _EGLConfig *
43 _eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
44 {
45 EGLint i;
46 _EGLDisplay *disp = _eglLookupDisplay(dpy);
47 for (i = 0; i < disp->NumConfigs; i++) {
48 if (disp->Configs[i].Handle == config) {
49 return disp->Configs + i;
50 }
51 }
52 return NULL;
53 }
54
55
56 /**
57 * Add the given _EGLConifg to the given display.
58 */
59 _EGLConfig *
60 _eglAddConfig(_EGLDisplay *display, const _EGLConfig *config)
61 {
62 _EGLConfig *newConfigs;
63 EGLint n;
64
65 n = display->NumConfigs;
66
67 newConfigs = (_EGLConfig *) realloc(display->Configs,
68 (n + 1) * sizeof(_EGLConfig));
69 if (newConfigs) {
70 display->Configs = newConfigs;
71 display->Configs[n] = *config; /* copy struct */
72 display->NumConfigs++;
73 return display->Configs + n;
74 }
75 else {
76 return NULL;
77 }
78 }
79
80
81 extern void
82 _eglSetConfigAtrib(_EGLConfig *config, EGLint attr, EGLint val)
83 {
84 config->Attrib[attr - FIRST_ATTRIB] = val;
85
86 switch (attr) {
87 case EGL_BUFFER_SIZE:
88 config->glmode.rgbBits = val;
89 break;
90 case EGL_ALPHA_SIZE:
91 config->glmode.alphaBits = val;
92 break;
93 case EGL_BLUE_SIZE:
94 config->glmode.blueBits = val;
95 break;
96 case EGL_GREEN_SIZE:
97 config->glmode.greenBits = val;
98 break;
99 case EGL_RED_SIZE:
100 config->glmode.redBits = val;
101 break;
102 case EGL_DEPTH_SIZE:
103 config->glmode.depthBits = val;
104 break;
105 case EGL_STENCIL_SIZE:
106 config->glmode.stencilBits = val;
107 break;
108 case EGL_CONFIG_CAVEAT:
109 break;
110 case EGL_CONFIG_ID:
111 break;
112 case EGL_LEVEL:
113 break;
114 case EGL_MAX_PBUFFER_HEIGHT:
115 break;
116 case EGL_MAX_PBUFFER_PIXELS:
117 break;
118 case EGL_MAX_PBUFFER_WIDTH:
119 break;
120 case EGL_NATIVE_RENDERABLE:
121 break;
122 case EGL_NATIVE_VISUAL_ID:
123 break;
124 case EGL_NATIVE_VISUAL_TYPE:
125 break;
126 case EGL_SAMPLES:
127 break;
128 case EGL_SAMPLE_BUFFERS:
129 break;
130 case EGL_SURFACE_TYPE:
131 break;
132 case EGL_TRANSPARENT_TYPE:
133 break;
134 case EGL_TRANSPARENT_BLUE_VALUE:
135 break;
136 case EGL_TRANSPARENT_GREEN_VALUE:
137 break;
138 case EGL_TRANSPARENT_RED_VALUE:
139 break;
140 case EGL_NONE:
141 break;
142 case EGL_BIND_TO_TEXTURE_RGB:
143 break;
144 case EGL_BIND_TO_TEXTURE_RGBA:
145 break;
146 case EGL_MIN_SWAP_INTERVAL:
147 break;
148 case EGL_MAX_SWAP_INTERVAL:
149 break;
150 default:
151 break;
152 }
153 }
154
155 /**
156 * Parse the attrib_list to fill in the fields of the given _egl_config
157 * Return EGL_FALSE if any errors, EGL_TRUE otherwise.
158 */
159 EGLBoolean
160 _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list)
161 {
162 EGLint i;
163
164 /* XXX set all config attribs to EGL_DONT_CARE */
165
166 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
167 EGLint k = attrib_list[i] - FIRST_ATTRIB;
168 if (k >= 0 && k < MAX_ATTRIBS) {
169 config->Attrib[k] = attrib_list[++i];
170 }
171 else {
172 _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
173 return EGL_FALSE;
174 }
175 }
176 return EGL_TRUE;
177 }
178
179
180 #define EXACT 1
181 #define ATLEAST 2
182 #define MASK 3
183 #define SMALLER 4
184 #define SPECIAL 5
185 #define NONE 6
186
187 struct sort_info {
188 EGLint Attribute;
189 EGLint MatchCriteria;
190 EGLint SortOrder;
191 };
192
193 /* This encodes the info from Table 3.5 of the EGL spec, ordered by
194 * Sort Priority.
195 */
196 static struct sort_info SortInfo[] = {
197 { EGL_CONFIG_CAVEAT, EXACT, SPECIAL },
198 { EGL_RED_SIZE, ATLEAST, SPECIAL },
199 { EGL_GREEN_SIZE, ATLEAST, SPECIAL },
200 { EGL_BLUE_SIZE, ATLEAST, SPECIAL },
201 { EGL_ALPHA_SIZE, ATLEAST, SPECIAL },
202 { EGL_BUFFER_SIZE, ATLEAST, SMALLER },
203 { EGL_SAMPLE_BUFFERS, ATLEAST, SMALLER },
204 { EGL_SAMPLES, ATLEAST, SMALLER },
205 { EGL_DEPTH_SIZE, ATLEAST, SMALLER },
206 { EGL_STENCIL_SIZE, ATLEAST, SMALLER },
207 { EGL_NATIVE_VISUAL_TYPE, EXACT, SPECIAL },
208 { EGL_CONFIG_ID, EXACT, SMALLER },
209 { EGL_BIND_TO_TEXTURE_RGB, EXACT, NONE },
210 { EGL_BIND_TO_TEXTURE_RGBA, EXACT, NONE },
211 { EGL_LEVEL, EXACT, NONE },
212 { EGL_NATIVE_RENDERABLE, EXACT, NONE },
213 { EGL_MAX_SWAP_INTERVAL, EXACT, NONE },
214 { EGL_MIN_SWAP_INTERVAL, EXACT, NONE },
215 { EGL_SURFACE_TYPE, MASK, NONE },
216 { EGL_TRANSPARENT_TYPE, EXACT, NONE },
217 { EGL_TRANSPARENT_RED_VALUE, EXACT, NONE },
218 { EGL_TRANSPARENT_GREEN_VALUE, EXACT, NONE },
219 { EGL_TRANSPARENT_BLUE_VALUE, EXACT, NONE },
220 { 0, 0, 0 }
221 };
222
223
224 /**
225 * Return EGL_TRUE if the attributes of c meet or exceed the minimums
226 * specified by min.
227 */
228 EGLBoolean
229 _eglConfigQualifies(const _EGLConfig *c, const _EGLConfig *min)
230 {
231 EGLint i;
232 for (i = 0; SortInfo[i].Attribute != 0; i++) {
233 const EGLint mv = GET_CONFIG_ATTRIB(min, SortInfo[i].Attribute);
234 if (mv != EGL_DONT_CARE) {
235 const EGLint cv = GET_CONFIG_ATTRIB(c, SortInfo[i].Attribute);
236 if (SortInfo[i].MatchCriteria == EXACT) {
237 if (cv != mv) {
238 return EGL_FALSE;
239 }
240 }
241 else if (SortInfo[i].MatchCriteria == ATLEAST) {
242 if (cv < mv) {
243 return EGL_FALSE;
244 }
245 }
246 else {
247 assert(SortInfo[i].MatchCriteria == MASK);
248 if ((mv & cv) != mv) {
249 return EGL_FALSE;
250 }
251 }
252 }
253 }
254 return EGL_TRUE;
255 }
256
257
258 /**
259 * Compare configs 'a' and 'b' and return -1 if a belongs before b,
260 * 1 if a belongs after b, or 0 if they're equal.
261 */
262 EGLint
263 _eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b)
264 {
265 EGLint i;
266 for (i = 0; SortInfo[i].Attribute != 0; i++) {
267 const EGLint av = GET_CONFIG_ATTRIB(a, SortInfo[i].Attribute);
268 const EGLint bv = GET_CONFIG_ATTRIB(b, SortInfo[i].Attribute);
269 if (SortInfo[i].SortOrder == SMALLER) {
270 if (av < bv)
271 return -1;
272 else if (av > bv)
273 return 1;
274 /* else, continue examining attribute values */
275 }
276 else if (SortInfo[i].SortOrder == SPECIAL) {
277 if (SortInfo[i].Attribute == EGL_CONFIG_CAVEAT) {
278 /* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
279 if (av < bv)
280 return -1;
281 else if (av > bv)
282 return 1;
283 }
284 else if (SortInfo[i].Attribute == EGL_RED_SIZE ||
285 SortInfo[i].Attribute == EGL_GREEN_SIZE ||
286 SortInfo[i].Attribute == EGL_BLUE_SIZE ||
287 SortInfo[i].Attribute == EGL_ALPHA_SIZE) {
288 if (av > bv)
289 return -1;
290 else if (av < bv)
291 return 1;
292 }
293 else {
294 assert(SortInfo[i].Attribute == EGL_NATIVE_VISUAL_TYPE);
295 if (av < bv)
296 return -1;
297 else if (av > bv)
298 return 1;
299 }
300 }
301 else {
302 assert(SortInfo[i].SortOrder == NONE);
303 /* continue examining attribute values */
304 }
305 }
306 return 0;
307 }
308
309
310 /**
311 * Typical fallback routine for eglChooseConfig
312 */
313 EGLBoolean
314 _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
315 {
316 _EGLDisplay *disp = _eglLookupDisplay(dpy);
317 _EGLConfig criteria;
318 EGLint i;
319
320 /* parse the attrib_list to initialize criteria */
321 if (!_eglParseConfigAttribs(&criteria, attrib_list)) {
322 return EGL_FALSE;
323 }
324
325 *num_config = 0;
326 for (i = 0; i < disp->NumConfigs; i++) {
327 const _EGLConfig *conf = disp->Configs + i;
328 if (_eglConfigQualifies(conf, &criteria)) {
329 if (*num_config < config_size) {
330 /* save */
331 configs[*num_config] = conf->Handle;
332 (*num_config)++;
333 }
334 else {
335 break;
336 }
337 }
338 }
339
340 /* XXX sort the list here */
341
342 return EGL_TRUE;
343 }
344
345
346 /**
347 * Fallback for eglGetConfigAttrib.
348 */
349 EGLBoolean
350 _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
351 {
352 const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
353 const EGLint k = attribute - FIRST_ATTRIB;
354 if (k >= 0 && k < MAX_ATTRIBS) {
355 *value = conf->Attrib[k];
356 return EGL_TRUE;
357 }
358 else {
359 _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
360 return EGL_FALSE;
361 }
362 }
363
364
365 /**
366 * Fallback for eglGetConfigs.
367 */
368 EGLBoolean
369 _eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
370 {
371 _EGLDisplay *disp = _eglLookupDisplay(dpy);
372
373 if (!drv->Initialized) {
374 _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
375 return EGL_FALSE;
376 }
377
378 *num_config = MIN2(disp->NumConfigs, config_size);
379 if (configs) {
380 EGLint i;
381 for (i = 0; i < *num_config; i++) {
382 configs[i] = disp->Configs[i].Handle;
383 }
384 }
385 return EGL_TRUE;
386 }
387
388
389 /**
390 * Creates a set of \c __GLcontextModes that a driver will expose.
391 *
392 * A set of \c __GLcontextModes will be created based on the supplied
393 * parameters. The number of modes processed will be 2 *
394 * \c num_depth_stencil_bits * \c num_db_modes.
395 *
396 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
397 * \c db_modes, and \c visType into each \c __GLcontextModes element.
398 * However, the meanings of \c fb_format and \c fb_type require further
399 * explanation. The \c fb_format specifies which color components are in
400 * each pixel and what the default order is. For example, \c GL_RGB specifies
401 * that red, green, blue are available and red is in the "most significant"
402 * position and blue is in the "least significant". The \c fb_type specifies
403 * the bit sizes of each component and the actual ordering. For example, if
404 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
405 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
406 * the red value.
407 *
408 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
409 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
410 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
411 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
412 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
413 * still uses 32-bits.
414 *
415 * If in doubt, look at the tables used in the function.
416 *
417 * \param ptr_to_modes Pointer to a pointer to a linked list of
418 * \c __GLcontextModes. Upon completion, a pointer to
419 * the next element to be process will be stored here.
420 * If the function fails and returns \c GL_FALSE, this
421 * value will be unmodified, but some elements in the
422 * linked list may be modified.
423 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
424 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
425 * \param fb_type Type of the pixels in the framebuffer. Currently only
426 * \c GL_UNSIGNED_SHORT_5_6_5,
427 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
428 * \c GL_UNSIGNED_INT_8_8_8_8, and
429 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
430 * \param depth_bits Array of depth buffer sizes to be exposed.
431 * \param stencil_bits Array of stencil buffer sizes to be exposed.
432 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
433 * \c stencil_bits.
434 * \param db_modes Array of buffer swap modes. If an element has a
435 * value of \c GLX_NONE, then it represents a
436 * single-buffered mode. Other valid values are
437 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
438 * \c GLX_SWAP_UNDEFINED_OML. See the
439 * GLX_OML_swap_method extension spec for more details.
440 * \param num_db_modes Number of entries in \c db_modes.
441 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
442 * \c GLX_DIRECT_COLOR.
443 *
444 * \returns
445 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
446 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
447 * \c fb_type).
448 *
449 * \todo
450 * There is currently no way to support packed RGB modes (i.e., modes with
451 * exactly 3 bytes per pixel) or floating-point modes. This could probably
452 * be done by creating some new, private enums with clever names likes
453 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
454 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
455 */
456 GLboolean
457 _eglFillInConfigs(_EGLConfig * configs,
458 GLenum fb_format, GLenum fb_type,
459 const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
460 unsigned num_depth_stencil_bits,
461 const GLenum * db_modes, unsigned num_db_modes,
462 int visType) {
463 static const u_int8_t bits_table[3][4] = {
464 /* R G B A */
465 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
466 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
467 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
468 };
469
470 /* The following arrays are all indexed by the fb_type masked with 0x07.
471 * Given the four supported fb_type values, this results in valid array
472 * indices of 3, 4, 5, and 7.
473 */
474 static const u_int32_t masks_table_rgb[8][4] = {
475 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
476 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
477 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
478 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
479 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
480 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
481 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
482 {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
483 };
484
485 static const u_int32_t masks_table_rgba[8][4] = {
486 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
487 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
488 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
489 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
490 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
491 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
492 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
493 {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
494 };
495
496 static const u_int32_t masks_table_bgr[8][4] = {
497 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
498 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
499 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
500 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
501 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
502 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
503 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
504 {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
505 };
506
507 static const u_int32_t masks_table_bgra[8][4] = {
508 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
509 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
510 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
511 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
512 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
513 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
514 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
515 {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
516 };
517
518 static const u_int8_t bytes_per_pixel[8] = {
519 0, 0, 0, 2, 2, 4, 0, 4
520 };
521
522 const u_int8_t * bits;
523 const u_int32_t * masks;
524 const int index = fb_type & 0x07;
525 _EGLConfig *config;
526 unsigned i;
527 unsigned j;
528 unsigned k;
529
530 if ( bytes_per_pixel[index] == 0 ) {
531 fprintf(stderr, "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.\n",
532 __FUNCTION__, __LINE__, fb_type);
533 return GL_FALSE;
534 }
535
536 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
537 * the _REV versions.
538 *
539 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
540 */
541 switch ( fb_format ) {
542 case GL_RGB:
543 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
544 masks = masks_table_rgb[index];
545 break;
546
547 case GL_RGBA:
548 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
549 masks = masks_table_rgba[index];
550 break;
551
552 case GL_BGR:
553 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
554 masks = masks_table_bgr[index];
555 break;
556
557 case GL_BGRA:
558 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
559 masks = masks_table_bgra[index];
560 break;
561
562 default:
563 fprintf(stderr, "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.\n",
564 __FUNCTION__, __LINE__, fb_format);
565 return GL_FALSE;
566 }
567
568 config = configs;
569 for (k = 0; k < num_depth_stencil_bits; k++) {
570 for (i = 0; i < num_db_modes; i++) {
571 for (j = 0; j < 2; j++) {
572
573 _eglSetConfigAtrib(config, EGL_RED_SIZE, bits[0]);
574 _eglSetConfigAtrib(config, EGL_GREEN_SIZE, bits[1]);
575 _eglSetConfigAtrib(config, EGL_BLUE_SIZE, bits[2]);
576 _eglSetConfigAtrib(config, EGL_ALPHA_SIZE, bits[3]);
577 config->glmode.redMask = masks[0];
578 config->glmode.greenMask = masks[1];
579 config->glmode.blueMask = masks[2];
580 config->glmode.alphaMask = masks[3];
581 _eglSetConfigAtrib(config, EGL_BUFFER_SIZE, config->glmode.redBits + config->glmode.greenBits
582 + config->glmode.blueBits + config->glmode.alphaBits);
583
584 config->glmode.accumRedBits = 16 * j;
585 config->glmode.accumGreenBits = 16 * j;
586 config->glmode.accumBlueBits = 16 * j;
587 config->glmode.accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
588 config->glmode.visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
589
590 _eglSetConfigAtrib(config, EGL_STENCIL_SIZE, stencil_bits[k]);
591 _eglSetConfigAtrib(config, EGL_DEPTH_SIZE, depth_bits[k]);
592
593 config->glmode.visualType = visType;
594 config->glmode.renderType = GLX_RGBA_BIT;
595 config->glmode.drawableType = GLX_WINDOW_BIT;
596 config->glmode.rgbMode = GL_TRUE;
597
598 if (db_modes[i] == GLX_NONE) {
599 config->glmode.doubleBufferMode = GL_FALSE;
600 } else {
601 config->glmode.doubleBufferMode = GL_TRUE;
602 config->glmode.swapMethod = db_modes[i];
603 }
604
605 config->glmode.haveAccumBuffer = ((config->glmode.accumRedBits +
606 config->glmode.accumGreenBits +
607 config->glmode.accumBlueBits +
608 config->glmode.accumAlphaBits) > 0);
609 config->glmode.haveDepthBuffer = (config->glmode.depthBits > 0);
610 config->glmode.haveStencilBuffer = (config->glmode.stencilBits > 0);
611
612 config++;
613 }
614 }
615 }
616 return GL_TRUE;
617 }