visualConfigs.c revision 4642e01f
1/* 2 * Copyright (c) 2007, 2008 Apple Inc. 3 * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. 4 * Copyright (c) 2002 Greg Parker. All Rights Reserved. 5 * 6 * Portions of this file are copied from Mesa's xf86glx.c, 7 * which contains the following copyright: 8 * 9 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 10 * All Rights Reserved. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included in 20 * all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 * DEALINGS IN THE SOFTWARE. 29 */ 30 31#ifdef HAVE_DIX_CONFIG_H 32#include <dix-config.h> 33#endif 34 35#include "dri.h" 36 37#include <OpenGL/OpenGL.h> 38#include <OpenGL/CGLContext.h> 39 40#include <GL/gl.h> 41#include <GL/glxproto.h> 42#include <windowstr.h> 43#include <resource.h> 44#include <GL/glxint.h> 45#include <GL/glxtokens.h> 46#include <scrnintstr.h> 47#include <glxserver.h> 48#include <glxscreens.h> 49#include <glxdrawable.h> 50#include <glxcontext.h> 51#include <glxext.h> 52#include <glxutil.h> 53#include <glxscreens.h> 54#include <GL/internal/glcore.h> 55 56#include "capabilities.h" 57#include "visualConfigs.h" 58 59/* Based originally on code from indirect.c which was based on code from i830_dri.c. */ 60void setVisualConfigs(void) { 61 int numConfigs = 0; 62 __GLXvisualConfig *visualConfigs = NULL; 63 void **visualPrivates = NULL; 64 struct glCapabilities caps; 65 struct glCapabilitiesConfig *conf = NULL; 66 int stereo, depth, aux, buffers, stencil, accum, color, msample; 67 int i = 0; 68 69 if(getGlCapabilities(&caps)) { 70 ErrorF("error from getGlCapabilities()!\n"); 71 return; 72 } 73 74 /* 75 conf->stereo is 0 or 1, but we need at least 1 iteration of the loop, 76 so we treat a true conf->stereo as 2. 77 78 The depth size is 0 or 24. Thus we do 2 iterations for that. 79 80 conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1. 81 82 conf->buffers indicates whether we have single or double buffering. 83 84 conf->total_stencil_bit_depths 85 86 conf->total_color_buffers indicates the RGB/RGBA color depths. 87 88 conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0) 89 90 conf->total_depth_buffer_depths 91 92 conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1 93 for the 0 multisampling config. 94 95 */ 96 97 assert(NULL != caps.configurations); 98 conf = caps.configurations; 99 100 numConfigs = 0; 101 102 for(conf = caps.configurations; conf; conf = conf->next) { 103 if(conf->total_color_buffers <= 0) 104 continue; 105 106 numConfigs += (conf->stereo ? 2 : 1) 107 * (conf->aux_buffers ? 2 : 1) 108 * conf->buffers 109 * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1) 110 * conf->total_color_buffers 111 * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1) 112 * conf->total_depth_buffer_depths 113 * (conf->multisample_buffers + 1); 114 } 115 116 visualConfigs = xcalloc(sizeof(*visualConfigs), numConfigs); 117 118 if(NULL == visualConfigs) { 119 ErrorF("xcalloc failure when allocating visualConfigs\n"); 120 freeGlCapabilities(&caps); 121 return; 122 } 123 124 visualPrivates = xcalloc(sizeof(void *), numConfigs); 125 126 if(NULL == visualPrivates) { 127 ErrorF("xcalloc failure when allocating visualPrivates"); 128 freeGlCapabilities(&caps); 129 xfree(visualConfigs); 130 return; 131 } 132 133 i = 0; /* current buffer */ 134 for(conf = caps.configurations; conf; conf = conf->next) { 135 for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) { 136 for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) { 137 for(buffers = 0; buffers < conf->buffers; ++buffers) { 138 for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ? 139 conf->total_stencil_bit_depths : 1); ++stencil) { 140 for(color = 0; color < conf->total_color_buffers; ++color) { 141 for(accum = 0; accum < ((conf->total_accum_buffers > 0) ? 142 conf->total_accum_buffers : 1); ++accum) { 143 for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) { 144 for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) { 145 visualConfigs[i].vid = (VisualID)(-1); 146 visualConfigs[i].class = TrueColor; 147 148 visualConfigs[i].rgba = true; 149 visualConfigs[i].redSize = conf->color_buffers[color].r; 150 visualConfigs[i].greenSize = conf->color_buffers[color].g; 151 visualConfigs[i].blueSize = conf->color_buffers[color].b; 152 153 if(GLCAPS_COLOR_BUF_INVALID_VALUE == conf->color_buffers[color].a) { 154 /* This visual has no alpha. */ 155 visualConfigs[i].alphaSize = 0; 156 } else { 157 visualConfigs[i].alphaSize = conf->color_buffers[color].a; 158 } 159 160 /* 161 * If the .a/alpha value is unset, then don't add it to the 162 * bufferSize specification. The INVALID_VALUE indicates that it 163 * was unset. 164 * 165 * This prevents odd bufferSizes, such as 14. 166 */ 167 if(GLCAPS_COLOR_BUF_INVALID_VALUE == conf->color_buffers[color].a) { 168 visualConfigs[i].bufferSize = conf->color_buffers[color].r + 169 conf->color_buffers[color].g + conf->color_buffers[color].b; 170 } else { 171 visualConfigs[i].bufferSize = conf->color_buffers[color].r + 172 conf->color_buffers[color].g + conf->color_buffers[color].b + 173 conf->color_buffers[color].a; 174 } 175 176 /* 177 * I'm uncertain about these masks. 178 * I don't think we actually care what the values are in our 179 * libGL, so it doesn't seem to make a difference. 180 */ 181 visualConfigs[i].redMask = -1; 182 visualConfigs[i].greenMask = -1; 183 visualConfigs[i].blueMask = -1; 184 visualConfigs[i].alphaMask = -1; 185 186 if(conf->total_accum_buffers > 0) { 187 visualConfigs[i].accumRedSize = conf->accum_buffers[accum].r; 188 visualConfigs[i].accumGreenSize = conf->accum_buffers[accum].g; 189 visualConfigs[i].accumBlueSize = conf->accum_buffers[accum].b; 190 if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) { 191 visualConfigs[i].accumAlphaSize = conf->accum_buffers[accum].a; 192 } else { 193 visualConfigs[i].accumAlphaSize = 0; 194 } 195 } else { 196 visualConfigs[i].accumRedSize = 0; 197 visualConfigs[i].accumGreenSize = 0; 198 visualConfigs[i].accumBlueSize = 0; 199 visualConfigs[i].accumAlphaSize = 0; 200 } 201 202 visualConfigs[i].doubleBuffer = buffers ? TRUE : FALSE; 203 visualConfigs[i].stereo = stereo ? TRUE : FALSE; 204 205 visualConfigs[i].depthSize = conf->depth_buffers[depth]; 206 207 if(conf->total_stencil_bit_depths > 0) { 208 visualConfigs[i].stencilSize = conf->stencil_bit_depths[stencil]; 209 } else { 210 visualConfigs[i].stencilSize = 0; 211 } 212 visualConfigs[i].auxBuffers = aux ? conf->aux_buffers : 0; 213 visualConfigs[i].level = 0; 214 215 if(conf->accelerated) { 216 visualConfigs[i].visualRating = GLX_NONE; 217 } else { 218 visualConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; 219 } 220 221 visualConfigs[i].transparentPixel = GLX_NONE; 222 visualConfigs[i].transparentRed = GLX_NONE; 223 visualConfigs[i].transparentGreen = GLX_NONE; 224 visualConfigs[i].transparentBlue = GLX_NONE; 225 visualConfigs[i].transparentAlpha = GLX_NONE; 226 visualConfigs[i].transparentIndex = GLX_NONE; 227 228 if(msample > 0) { 229 visualConfigs[i].multiSampleSize = conf->multisample_samples; 230 visualConfigs[i].nMultiSampleBuffers = conf->multisample_buffers; 231 } else { 232 visualConfigs[i].multiSampleSize = 0; 233 visualConfigs[i].nMultiSampleBuffers = 0; 234 } 235 236 ++i; 237 } 238 } 239 } 240 } 241 } 242 } 243 } 244 } 245 } 246 247 if (i != numConfigs) { 248 ErrorF("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, i); 249 abort(); 250 } 251 252 freeGlCapabilities(&caps); 253 254 GlxSetVisualConfigs(numConfigs, visualConfigs, visualPrivates); 255} 256