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