glcontextmodes.c (19342B)
1 /* 2 * (C) Copyright IBM Corporation 2003 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 /** 26 * \file glcontextmodes.c 27 * Utility routines for working with \c __GLcontextModes structures. At 28 * some point most or all of these functions will be moved to the Mesa 29 * code base. 30 * 31 * \author Ian Romanick <idr@us.ibm.com> 32 */ 33 34 #if defined(IN_MINI_GLX) 35 #include <GL/gl.h> 36 #else 37 #if defined(HAVE_DIX_CONFIG_H) 38 #include <dix-config.h> 39 #endif 40 #include <X11/X.h> 41 #include <GL/glx.h> 42 #include "GL/glxint.h" 43 #endif 44 45 /* Memory macros */ 46 #if defined(IN_MINI_GLX) 47 #include <stdlib.h> 48 #include <string.h> 49 #define _mesa_malloc(b) malloc(b) 50 #define _mesa_free(m) free(m) 51 #define _mesa_memset memset 52 #else 53 #ifdef XFree86Server 54 #include <os.h> 55 #include <string.h> 56 #define _mesa_malloc(b) malloc(b) 57 #define _mesa_free(m) free(m) 58 #define _mesa_memset memset 59 #else 60 #include <X11/Xlibint.h> 61 #define _mesa_memset memset 62 #define _mesa_malloc(b) Xmalloc(b) 63 #define _mesa_free(m) free(m) 64 #endif /* XFree86Server */ 65 #endif /* !defined(IN_MINI_GLX) */ 66 67 #include "glcontextmodes.h" 68 69 #if !defined(IN_MINI_GLX) 70 #define NUM_VISUAL_TYPES 6 71 72 /** 73 * Convert an X visual type to a GLX visual type. 74 * 75 * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) 76 * to be converted. 77 * \return If \c visualType is a valid X visual type, a GLX visual type will 78 * be returned. Otherwise \c GLX_NONE will be returned. 79 */ 80 GLint 81 _gl_convert_from_x_visual_type(int visualType) 82 { 83 static const int glx_visual_types[NUM_VISUAL_TYPES] = { 84 GLX_STATIC_GRAY, GLX_GRAY_SCALE, 85 GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, 86 GLX_TRUE_COLOR, GLX_DIRECT_COLOR 87 }; 88 89 return ((unsigned)visualType < NUM_VISUAL_TYPES) 90 ? glx_visual_types[visualType] : GLX_NONE; 91 } 92 93 /** 94 * Convert a GLX visual type to an X visual type. 95 * 96 * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, 97 * \c GLX_STATIC_GRAY, etc.) to be converted. 98 * \return If \c visualType is a valid GLX visual type, an X visual type will 99 * be returned. Otherwise -1 will be returned. 100 */ 101 GLint 102 _gl_convert_to_x_visual_type(int visualType) 103 { 104 static const int x_visual_types[NUM_VISUAL_TYPES] = { 105 TrueColor, DirectColor, 106 PseudoColor, StaticColor, 107 GrayScale, StaticGray 108 }; 109 110 return ((unsigned)(visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES) 111 ? x_visual_types[visualType - GLX_TRUE_COLOR] : -1; 112 } 113 114 /** 115 * Copy a GLX visual config structure to a GL context mode structure. All 116 * of the fields in \c config are copied to \c mode. Additional fields in 117 * \c mode that can be derived from the fields of \c config (i.e., 118 * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode 119 * that cannot be derived are set to default values. 120 * 121 * \param mode Destination GL context mode. 122 * \param config Source GLX visual config. 123 * 124 * \note 125 * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes 126 * structure will be set to the \c vid of the \c __GLXvisualConfig structure. 127 */ 128 void 129 _gl_copy_visual_to_context_mode(__GLcontextModes * mode, 130 const __GLXvisualConfig * config) 131 { 132 __GLcontextModes * const next = mode->next; 133 134 (void)_mesa_memset(mode, 0, sizeof(__GLcontextModes)); 135 mode->next = next; 136 137 mode->visualID = config->vid; 138 mode->visualType = _gl_convert_from_x_visual_type(config->class); 139 mode->fbconfigID = config->vid; 140 mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; 141 142 mode->rgbMode = (config->rgba != 0); 143 mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; 144 145 mode->colorIndexMode = !(mode->rgbMode); 146 mode->doubleBufferMode = (config->doubleBuffer != 0); 147 mode->stereoMode = (config->stereo != 0); 148 149 mode->haveAccumBuffer = ((config->accumRedSize + 150 config->accumGreenSize + 151 config->accumBlueSize + 152 config->accumAlphaSize) > 0); 153 mode->haveDepthBuffer = (config->depthSize > 0); 154 mode->haveStencilBuffer = (config->stencilSize > 0); 155 156 mode->redBits = config->redSize; 157 mode->greenBits = config->greenSize; 158 mode->blueBits = config->blueSize; 159 mode->alphaBits = config->alphaSize; 160 mode->redMask = config->redMask; 161 mode->greenMask = config->greenMask; 162 mode->blueMask = config->blueMask; 163 mode->alphaMask = config->alphaMask; 164 mode->rgbBits = mode->rgbMode ? config->bufferSize : 0; 165 mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0; 166 167 mode->accumRedBits = config->accumRedSize; 168 mode->accumGreenBits = config->accumGreenSize; 169 mode->accumBlueBits = config->accumBlueSize; 170 mode->accumAlphaBits = config->accumAlphaSize; 171 mode->depthBits = config->depthSize; 172 mode->stencilBits = config->stencilSize; 173 174 mode->numAuxBuffers = config->auxBuffers; 175 mode->level = config->level; 176 177 mode->visualRating = config->visualRating; 178 mode->transparentPixel = config->transparentPixel; 179 mode->transparentRed = config->transparentRed; 180 mode->transparentGreen = config->transparentGreen; 181 mode->transparentBlue = config->transparentBlue; 182 mode->transparentAlpha = config->transparentAlpha; 183 mode->transparentIndex = config->transparentIndex; 184 mode->samples = config->multiSampleSize; 185 mode->sampleBuffers = config->nMultiSampleBuffers; 186 /* mode->visualSelectGroup = config->visualSelectGroup; ? */ 187 188 mode->swapMethod = GLX_SWAP_UNDEFINED_OML; 189 190 mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE; 191 mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ? 192 GL_TRUE : GL_FALSE; 193 mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE; 194 mode->bindToTextureTargets = mode->rgbMode ? 195 GLX_TEXTURE_1D_BIT_EXT | 196 GLX_TEXTURE_2D_BIT_EXT | 197 GLX_TEXTURE_RECTANGLE_BIT_EXT : 0; 198 mode->yInverted = GL_FALSE; 199 } 200 201 /** 202 * Get data from a GL context mode. 203 * 204 * \param mode GL context mode whose data is to be returned. 205 * \param attribute Attribute of \c mode that is to be returned. 206 * \param value_return Location to store the data member of \c mode. 207 * \return If \c attribute is a valid attribute of \c mode, zero is 208 * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. 209 */ 210 int 211 _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, 212 int *value_return) 213 { 214 switch (attribute) { 215 case GLX_USE_GL: 216 *value_return = GL_TRUE; 217 return 0; 218 219 case GLX_BUFFER_SIZE: 220 *value_return = mode->rgbBits; 221 return 0; 222 223 case GLX_RGBA: 224 *value_return = mode->rgbMode; 225 return 0; 226 227 case GLX_RED_SIZE: 228 *value_return = mode->redBits; 229 return 0; 230 231 case GLX_GREEN_SIZE: 232 *value_return = mode->greenBits; 233 return 0; 234 235 case GLX_BLUE_SIZE: 236 *value_return = mode->blueBits; 237 return 0; 238 239 case GLX_ALPHA_SIZE: 240 *value_return = mode->alphaBits; 241 return 0; 242 243 case GLX_DOUBLEBUFFER: 244 *value_return = mode->doubleBufferMode; 245 return 0; 246 247 case GLX_STEREO: 248 *value_return = mode->stereoMode; 249 return 0; 250 251 case GLX_AUX_BUFFERS: 252 *value_return = mode->numAuxBuffers; 253 return 0; 254 255 case GLX_DEPTH_SIZE: 256 *value_return = mode->depthBits; 257 return 0; 258 259 case GLX_STENCIL_SIZE: 260 *value_return = mode->stencilBits; 261 return 0; 262 263 case GLX_ACCUM_RED_SIZE: 264 *value_return = mode->accumRedBits; 265 return 0; 266 267 case GLX_ACCUM_GREEN_SIZE: 268 *value_return = mode->accumGreenBits; 269 return 0; 270 271 case GLX_ACCUM_BLUE_SIZE: 272 *value_return = mode->accumBlueBits; 273 return 0; 274 275 case GLX_ACCUM_ALPHA_SIZE: 276 *value_return = mode->accumAlphaBits; 277 return 0; 278 279 case GLX_LEVEL: 280 *value_return = mode->level; 281 return 0; 282 283 case GLX_TRANSPARENT_TYPE_EXT: 284 *value_return = mode->transparentPixel; 285 return 0; 286 287 case GLX_TRANSPARENT_RED_VALUE: 288 *value_return = mode->transparentRed; 289 return 0; 290 291 case GLX_TRANSPARENT_GREEN_VALUE: 292 *value_return = mode->transparentGreen; 293 return 0; 294 295 case GLX_TRANSPARENT_BLUE_VALUE: 296 *value_return = mode->transparentBlue; 297 return 0; 298 299 case GLX_TRANSPARENT_ALPHA_VALUE: 300 *value_return = mode->transparentAlpha; 301 return 0; 302 303 case GLX_TRANSPARENT_INDEX_VALUE: 304 *value_return = mode->transparentIndex; 305 return 0; 306 307 case GLX_X_VISUAL_TYPE: 308 *value_return = mode->visualType; 309 return 0; 310 311 case GLX_CONFIG_CAVEAT: 312 *value_return = mode->visualRating; 313 return 0; 314 315 case GLX_VISUAL_ID: 316 *value_return = mode->visualID; 317 return 0; 318 319 case GLX_DRAWABLE_TYPE: 320 *value_return = mode->drawableType; 321 return 0; 322 323 case GLX_RENDER_TYPE: 324 *value_return = mode->renderType; 325 return 0; 326 327 case GLX_X_RENDERABLE: 328 *value_return = mode->xRenderable; 329 return 0; 330 331 case GLX_FBCONFIG_ID: 332 *value_return = mode->fbconfigID; 333 return 0; 334 335 case GLX_MAX_PBUFFER_WIDTH: 336 *value_return = mode->maxPbufferWidth; 337 return 0; 338 339 case GLX_MAX_PBUFFER_HEIGHT: 340 *value_return = mode->maxPbufferHeight; 341 return 0; 342 343 case GLX_MAX_PBUFFER_PIXELS: 344 *value_return = mode->maxPbufferPixels; 345 return 0; 346 347 case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: 348 *value_return = mode->optimalPbufferWidth; 349 return 0; 350 351 case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: 352 *value_return = mode->optimalPbufferHeight; 353 return 0; 354 355 case GLX_SWAP_METHOD_OML: 356 *value_return = mode->swapMethod; 357 return 0; 358 359 case GLX_SAMPLE_BUFFERS_SGIS: 360 *value_return = mode->sampleBuffers; 361 return 0; 362 363 case GLX_SAMPLES_SGIS: 364 *value_return = mode->samples; 365 return 0; 366 367 case GLX_BIND_TO_TEXTURE_RGB_EXT: 368 *value_return = mode->bindToTextureRgb; 369 return 0; 370 371 case GLX_BIND_TO_TEXTURE_RGBA_EXT: 372 *value_return = mode->bindToTextureRgba; 373 return 0; 374 375 case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: 376 *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : 377 GL_FALSE; 378 return 0; 379 380 case GLX_BIND_TO_TEXTURE_TARGETS_EXT: 381 *value_return = mode->bindToTextureTargets; 382 return 0; 383 384 case GLX_Y_INVERTED_EXT: 385 *value_return = mode->yInverted; 386 return 0; 387 388 /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. 389 * It is ONLY for communication between the GLX client and the GLX 390 * server. 391 */ 392 case GLX_VISUAL_SELECT_GROUP_SGIX: 393 default: 394 return GLX_BAD_ATTRIBUTE; 395 } 396 } 397 #endif /* !defined(IN_MINI_GLX) */ 398 399 /** 400 * Allocate a linked list of \c __GLcontextModes structures. The fields of 401 * each structure will be initialized to "reasonable" default values. In 402 * most cases this is the default value defined by table 3.4 of the GLX 403 * 1.3 specification. This means that most values are either initialized to 404 * zero or \c GLX_DONT_CARE (which is -1). As support for additional 405 * extensions is added, the new values will be initialized to appropriate 406 * values from the extension specification. 407 * 408 * \param count Number of structures to allocate. 409 * \param minimum_size Minimum size of a structure to allocate. This allows 410 * for differences in the version of the 411 * \c __GLcontextModes structure used in libGL and in a 412 * DRI-based driver. 413 * \returns A pointer to the first element in a linked list of \c count 414 * structures on success, or \c NULL on failure. 415 * 416 * \warning Use of \c minimum_size does \b not guarantee binary compatibility. 417 * The fundamental assumption is that if the \c minimum_size 418 * specified by the driver and the size of the \c __GLcontextModes 419 * structure in libGL is the same, then the meaning of each byte in 420 * the structure is the same in both places. \b Be \b careful! 421 * Basically this means that fields have to be added in libGL and 422 * then propagated to drivers. Drivers should \b never arbitrarilly 423 * extend the \c __GLcontextModes data-structure. 424 */ 425 __GLcontextModes * 426 _gl_context_modes_create(unsigned count, size_t minimum_size) 427 { 428 const size_t size = (minimum_size > sizeof(__GLcontextModes)) 429 ? minimum_size : sizeof(__GLcontextModes); 430 __GLcontextModes * base = NULL; 431 __GLcontextModes ** next; 432 unsigned i; 433 434 next = &base; 435 for (i = 0; i < count; i++) { 436 *next = (__GLcontextModes *)_mesa_malloc(size); 437 if (*next == NULL) { 438 _gl_context_modes_destroy(base); 439 base = NULL; 440 break; 441 } 442 443 (void)_mesa_memset(*next, 0, size); 444 (*next)->visualID = GLX_DONT_CARE; 445 (*next)->visualType = GLX_DONT_CARE; 446 (*next)->visualRating = GLX_NONE; 447 (*next)->transparentPixel = GLX_NONE; 448 (*next)->transparentRed = GLX_DONT_CARE; 449 (*next)->transparentGreen = GLX_DONT_CARE; 450 (*next)->transparentBlue = GLX_DONT_CARE; 451 (*next)->transparentAlpha = GLX_DONT_CARE; 452 (*next)->transparentIndex = GLX_DONT_CARE; 453 (*next)->xRenderable = GLX_DONT_CARE; 454 (*next)->fbconfigID = GLX_DONT_CARE; 455 (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; 456 (*next)->bindToTextureRgb = GLX_DONT_CARE; 457 (*next)->bindToTextureRgba = GLX_DONT_CARE; 458 (*next)->bindToMipmapTexture = GLX_DONT_CARE; 459 (*next)->bindToTextureTargets = GLX_DONT_CARE; 460 (*next)->yInverted = GLX_DONT_CARE; 461 462 next = &((*next)->next); 463 } 464 465 return base; 466 } 467 468 /** 469 * Destroy a linked list of \c __GLcontextModes structures created by 470 * \c _gl_context_modes_create. 471 * 472 * \param modes Linked list of structures to be destroyed. All structures 473 * in the list will be freed. 474 */ 475 void 476 _gl_context_modes_destroy(__GLcontextModes * modes) 477 { 478 while (modes != NULL) { 479 __GLcontextModes * const next = modes->next; 480 481 _mesa_free(modes); 482 modes = next; 483 } 484 } 485 486 /** 487 * Find a context mode matching a Visual ID. 488 * 489 * \param modes List list of context-mode structures to be searched. 490 * \param vid Visual ID to be found. 491 * \returns A pointer to a context-mode in \c modes if \c vid was found in 492 * the list, or \c NULL if it was not. 493 */ 494 495 __GLcontextModes * 496 _gl_context_modes_find_visual(__GLcontextModes *modes, int vid) 497 { 498 __GLcontextModes *m; 499 500 for (m = modes; m != NULL; m = m->next) 501 if (m->visualID == vid) 502 return m; 503 504 return NULL; 505 } 506 507 __GLcontextModes * 508 _gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid) 509 { 510 __GLcontextModes *m; 511 512 for (m = modes; m != NULL; m = m->next) 513 if (m->fbconfigID == fbid) 514 return m; 515 516 return NULL; 517 } 518 519 /** 520 * Determine if two context-modes are the same. This is intended to be used 521 * by libGL implementations to compare to sets of driver generated FBconfigs. 522 * 523 * \param a Context-mode to be compared. 524 * \param b Context-mode to be compared. 525 * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is 526 * returned otherwise. 527 */ 528 GLboolean 529 _gl_context_modes_are_same(const __GLcontextModes * a, 530 const __GLcontextModes * b) 531 { 532 return ((a->rgbMode == b->rgbMode) && 533 (a->floatMode == b->floatMode) && 534 (a->colorIndexMode == b->colorIndexMode) && 535 (a->doubleBufferMode == b->doubleBufferMode) && 536 (a->stereoMode == b->stereoMode) && 537 (a->redBits == b->redBits) && 538 (a->greenBits == b->greenBits) && 539 (a->blueBits == b->blueBits) && 540 (a->alphaBits == b->alphaBits) && 541 #if 0 /* For some reason these don't get set on the client-side in libGL. */ 542 (a->redMask == b->redMask) && 543 (a->greenMask == b->greenMask) && 544 (a->blueMask == b->blueMask) && 545 (a->alphaMask == b->alphaMask) && 546 #endif 547 (a->rgbBits == b->rgbBits) && 548 (a->indexBits == b->indexBits) && 549 (a->accumRedBits == b->accumRedBits) && 550 (a->accumGreenBits == b->accumGreenBits) && 551 (a->accumBlueBits == b->accumBlueBits) && 552 (a->accumAlphaBits == b->accumAlphaBits) && 553 (a->depthBits == b->depthBits) && 554 (a->stencilBits == b->stencilBits) && 555 (a->numAuxBuffers == b->numAuxBuffers) && 556 (a->level == b->level) && 557 (a->visualRating == b->visualRating) && 558 559 (a->transparentPixel == b->transparentPixel) && 560 561 ((a->transparentPixel != GLX_TRANSPARENT_RGB) || 562 ((a->transparentRed == b->transparentRed) && 563 (a->transparentGreen == b->transparentGreen) && 564 (a->transparentBlue == b->transparentBlue) && 565 (a->transparentAlpha == b->transparentAlpha))) && 566 567 ((a->transparentPixel != GLX_TRANSPARENT_INDEX) || 568 (a->transparentIndex == b->transparentIndex)) && 569 570 (a->sampleBuffers == b->sampleBuffers) && 571 (a->samples == b->samples) && 572 ((a->drawableType & b->drawableType) != 0) && 573 (a->renderType == b->renderType) && 574 (a->maxPbufferWidth == b->maxPbufferWidth) && 575 (a->maxPbufferHeight == b->maxPbufferHeight) && 576 (a->maxPbufferPixels == b->maxPbufferPixels) && 577 (a->optimalPbufferWidth == b->optimalPbufferWidth) && 578 (a->optimalPbufferHeight == b->optimalPbufferHeight) && 579 (a->swapMethod == b->swapMethod) && 580 (a->bindToTextureRgb == b->bindToTextureRgb) && 581 (a->bindToTextureRgba == b->bindToTextureRgba) && 582 (a->bindToMipmapTexture == b->bindToMipmapTexture) && 583 (a->bindToTextureTargets == b->bindToTextureTargets) && 584 (a->yInverted == b->yInverted)); 585 }