eglconfig.c revision b711eb793b68bb0c4561e5e345b76453dfac286b
16c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/** 26c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * EGL Configuration (pixel format) functions. 36c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org */ 46c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 56c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 66c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include <stdlib.h> 76c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include <stdio.h> 86c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include <string.h> 96c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include <assert.h> 106c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "eglconfig.h" 116c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "egldisplay.h" 126c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "egldriver.h" 136c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "eglglobals.h" 146c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#include "egllog.h" 15848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon 166c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 176c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org#define MIN2(A, B) (((A) < (B)) ? (A) : (B)) 186c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 196c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 206c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/** 216c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Convert an _EGLConfig to a __GLcontextModes object. 226c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * NOTE: This routine may be incomplete - we're only making sure that 236c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * the fields needed by Mesa (for _mesa_create_context/framebuffer) are 246c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * set correctly. 25d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org */ 26d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.orgvoid 27d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode) 28d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org{ 29d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org memset(mode, 0, sizeof(*mode)); 30d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org 31d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org mode->rgbMode = GL_TRUE; /* no color index */ 32d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org mode->colorIndexMode = GL_FALSE; 33d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org mode->doubleBufferMode = GL_TRUE; /* always DB for now */ 34d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org mode->stereoMode = GL_FALSE; 35d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org 36d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org mode->redBits = GET_CONFIG_ATTRIB(config, EGL_RED_SIZE); 376c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->greenBits = GET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE); 386c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->blueBits = GET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE); 396c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->alphaBits = GET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE); 406c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->rgbBits = GET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE); 416c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 426c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org /* no rgba masks - fix? */ 436c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 449fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed mode->depthBits = GET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE); 456c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->haveDepthBuffer = mode->depthBits > 0; 469fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 479fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed mode->stencilBits = GET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE); 489fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed mode->haveStencilBuffer = mode->stencilBits > 0; 496c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 509fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed /* no accum */ 519fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 526c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->level = GET_CONFIG_ATTRIB(config, EGL_LEVEL); 536c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->samples = GET_CONFIG_ATTRIB(config, EGL_SAMPLES); 549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed mode->sampleBuffers = GET_CONFIG_ATTRIB(config, EGL_SAMPLE_BUFFERS); 559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 560f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org /* surface type - not really needed */ 576c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->visualType = GLX_TRUE_COLOR; 586c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org mode->renderType = GLX_RGBA_BIT; 596c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org} 606c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 616c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 626c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgvoid 636c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val) 646c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org{ 6583d081ae1d731b5039e99823620f5e287542ee39bsalomon assert(attr >= FIRST_ATTRIB); 6655fad7af61c21d502acb9891d631e8aa29e3628cbsalomon assert(attr < FIRST_ATTRIB + MAX_ATTRIBS); 6755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon config->Attrib[attr - FIRST_ATTRIB] = val; 686c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org} 696c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 706c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 716c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/** 726c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Init the given _EGLconfig to default values. 736c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * \param id the configuration's ID. 746c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org */ 756c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.orgvoid 766c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_eglInitConfig(_EGLConfig *config, EGLint id) 776c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org{ 78d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org memset(config, 0, sizeof(*config)); 79d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org config->Handle = id; 80d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org _eglSetConfigAttrib(config, EGL_CONFIG_ID, id); 816c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE); 826c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE); 836c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_CONFIG_CAVEAT, EGL_DONT_CARE); 846c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE); 856c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE); 866c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE); 876c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE); 886c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, 896c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org EGL_SCREEN_BIT_MESA | EGL_PBUFFER_BIT | 9063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon EGL_PIXMAP_BIT | EGL_WINDOW_BIT); 916c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_TRANSPARENT_TYPE, EGL_NONE); 926c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE); 936c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _eglSetConfigAttrib(config, EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE); 9463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon _eglSetConfigAttrib(config, EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE); 956c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org} 966c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 976c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 986c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/** 996c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Given an EGLConfig handle, return the corresponding _EGLConfig object. 100824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org */ 1016c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_EGLConfig * 1026c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config) 1036c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org{ 1046c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org EGLint i; 1056c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _EGLDisplay *disp = _eglLookupDisplay(dpy); 1066c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org for (i = 0; i < disp->NumConfigs; i++) { 1076c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org if (disp->Configs[i].Handle == config) { 108d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org return disp->Configs + i; 109d494b09f554d470fc6411d0924879bbfb0cb0e95commit-bot@chromium.org } 1106c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org } 1116c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org return NULL; 1126c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org} 1136c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 1146c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 1156c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org/** 1166c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org * Add the given _EGLConifg to the given display. 1176c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org */ 1186c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_EGLConfig * 1196c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org_eglAddConfig(_EGLDisplay *display, const _EGLConfig *config) 1206c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org{ 1216c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org _EGLConfig *newConfigs; 1226c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org EGLint n; 12397b9ab72cd5ee0cba4692082737266376425f27cbsalomon 1246c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org n = display->NumConfigs; 1256c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org 1266c1ee2d4e727357451c8a6fcf4a08e75890b5d6dcommit-bot@chromium.org newConfigs = (_EGLConfig *) realloc(display->Configs, 127 (n + 1) * sizeof(_EGLConfig)); 128 if (newConfigs) { 129 display->Configs = newConfigs; 130 display->Configs[n] = *config; /* copy struct */ 131 display->Configs[n].Handle = n; 132 display->NumConfigs++; 133 return display->Configs + n; 134 } 135 else { 136 return NULL; 137 } 138} 139 140 141/** 142 * Parse the attrib_list to fill in the fields of the given _egl_config 143 * Return EGL_FALSE if any errors, EGL_TRUE otherwise. 144 */ 145EGLBoolean 146_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list) 147{ 148 EGLint i; 149 150 /* XXX set all config attribs to EGL_DONT_CARE */ 151 152 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { 153 EGLint k = attrib_list[i] - FIRST_ATTRIB; 154 if (k >= 0 && k < MAX_ATTRIBS) { 155 config->Attrib[k] = attrib_list[++i]; 156 } 157 else { 158 _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); 159 return EGL_FALSE; 160 } 161 } 162 return EGL_TRUE; 163} 164 165 166#define EXACT 1 167#define ATLEAST 2 168#define MASK 3 169#define SMALLER 4 170#define SPECIAL 5 171#define NONE 6 172 173struct sort_info { 174 EGLint Attribute; 175 EGLint MatchCriteria; 176 EGLint SortOrder; 177}; 178 179/* This encodes the info from Table 3.5 of the EGL spec, ordered by 180 * Sort Priority. 181 */ 182static struct sort_info SortInfo[] = { 183 { EGL_CONFIG_CAVEAT, EXACT, SPECIAL }, 184 { EGL_RED_SIZE, ATLEAST, SPECIAL }, 185 { EGL_GREEN_SIZE, ATLEAST, SPECIAL }, 186 { EGL_BLUE_SIZE, ATLEAST, SPECIAL }, 187 { EGL_ALPHA_SIZE, ATLEAST, SPECIAL }, 188 { EGL_BUFFER_SIZE, ATLEAST, SMALLER }, 189 { EGL_SAMPLE_BUFFERS, ATLEAST, SMALLER }, 190 { EGL_SAMPLES, ATLEAST, SMALLER }, 191 { EGL_DEPTH_SIZE, ATLEAST, SMALLER }, 192 { EGL_STENCIL_SIZE, ATLEAST, SMALLER }, 193 { EGL_NATIVE_VISUAL_TYPE, EXACT, SPECIAL }, 194 { EGL_CONFIG_ID, EXACT, SMALLER }, 195 { EGL_BIND_TO_TEXTURE_RGB, EXACT, NONE }, 196 { EGL_BIND_TO_TEXTURE_RGBA, EXACT, NONE }, 197 { EGL_LEVEL, EXACT, NONE }, 198 { EGL_NATIVE_RENDERABLE, EXACT, NONE }, 199 { EGL_MAX_SWAP_INTERVAL, EXACT, NONE }, 200 { EGL_MIN_SWAP_INTERVAL, EXACT, NONE }, 201 { EGL_SURFACE_TYPE, MASK, NONE }, 202 { EGL_TRANSPARENT_TYPE, EXACT, NONE }, 203 { EGL_TRANSPARENT_RED_VALUE, EXACT, NONE }, 204 { EGL_TRANSPARENT_GREEN_VALUE, EXACT, NONE }, 205 { EGL_TRANSPARENT_BLUE_VALUE, EXACT, NONE }, 206 { 0, 0, 0 } 207}; 208 209 210/** 211 * Return EGL_TRUE if the attributes of c meet or exceed the minimums 212 * specified by min. 213 */ 214EGLBoolean 215_eglConfigQualifies(const _EGLConfig *c, const _EGLConfig *min) 216{ 217 EGLint i; 218 for (i = 0; SortInfo[i].Attribute != 0; i++) { 219 const EGLint mv = GET_CONFIG_ATTRIB(min, SortInfo[i].Attribute); 220 if (mv != EGL_DONT_CARE) { 221 const EGLint cv = GET_CONFIG_ATTRIB(c, SortInfo[i].Attribute); 222 if (SortInfo[i].MatchCriteria == EXACT) { 223 if (cv != mv) { 224 return EGL_FALSE; 225 } 226 } 227 else if (SortInfo[i].MatchCriteria == ATLEAST) { 228 if (cv < mv) { 229 return EGL_FALSE; 230 } 231 } 232 else { 233 assert(SortInfo[i].MatchCriteria == MASK); 234 if ((mv & cv) != mv) { 235 return EGL_FALSE; 236 } 237 } 238 } 239 } 240 return EGL_TRUE; 241} 242 243 244/** 245 * Compare configs 'a' and 'b' and return -1 if a belongs before b, 246 * 1 if a belongs after b, or 0 if they're equal. 247 */ 248EGLint 249_eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b) 250{ 251 EGLint i; 252 for (i = 0; SortInfo[i].Attribute != 0; i++) { 253 const EGLint av = GET_CONFIG_ATTRIB(a, SortInfo[i].Attribute); 254 const EGLint bv = GET_CONFIG_ATTRIB(b, SortInfo[i].Attribute); 255 if (SortInfo[i].SortOrder == SMALLER) { 256 if (av < bv) 257 return -1; 258 else if (av > bv) 259 return 1; 260 /* else, continue examining attribute values */ 261 } 262 else if (SortInfo[i].SortOrder == SPECIAL) { 263 if (SortInfo[i].Attribute == EGL_CONFIG_CAVEAT) { 264 /* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */ 265 if (av < bv) 266 return -1; 267 else if (av > bv) 268 return 1; 269 } 270 else if (SortInfo[i].Attribute == EGL_RED_SIZE || 271 SortInfo[i].Attribute == EGL_GREEN_SIZE || 272 SortInfo[i].Attribute == EGL_BLUE_SIZE || 273 SortInfo[i].Attribute == EGL_ALPHA_SIZE) { 274 if (av > bv) 275 return -1; 276 else if (av < bv) 277 return 1; 278 } 279 else { 280 assert(SortInfo[i].Attribute == EGL_NATIVE_VISUAL_TYPE); 281 if (av < bv) 282 return -1; 283 else if (av > bv) 284 return 1; 285 } 286 } 287 else { 288 assert(SortInfo[i].SortOrder == NONE); 289 /* continue examining attribute values */ 290 } 291 } 292 return 0; 293} 294 295 296/** 297 * Typical fallback routine for eglChooseConfig 298 */ 299EGLBoolean 300_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) 301{ 302 _EGLDisplay *disp = _eglLookupDisplay(dpy); 303 _EGLConfig criteria; 304 EGLint i; 305 306 /* parse the attrib_list to initialize criteria */ 307 if (!_eglParseConfigAttribs(&criteria, attrib_list)) { 308 return EGL_FALSE; 309 } 310 311 *num_config = 0; 312 for (i = 0; i < disp->NumConfigs; i++) { 313 const _EGLConfig *conf = disp->Configs + i; 314 if (_eglConfigQualifies(conf, &criteria)) { 315 if (*num_config < config_size) { 316 /* save */ 317 configs[*num_config] = conf->Handle; 318 (*num_config)++; 319 } 320 else { 321 break; 322 } 323 } 324 } 325 326 /* XXX sort the list here */ 327 328 return EGL_TRUE; 329} 330 331 332/** 333 * Fallback for eglGetConfigAttrib. 334 */ 335EGLBoolean 336_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) 337{ 338 const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); 339 const EGLint k = attribute - FIRST_ATTRIB; 340 if (k >= 0 && k < MAX_ATTRIBS) { 341 *value = conf->Attrib[k]; 342 return EGL_TRUE; 343 } 344 else { 345 _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); 346 return EGL_FALSE; 347 } 348} 349 350 351/** 352 * Fallback for eglGetConfigs. 353 */ 354EGLBoolean 355_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) 356{ 357 _EGLDisplay *disp = _eglLookupDisplay(dpy); 358 359 if (!drv->Initialized) { 360 _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs"); 361 return EGL_FALSE; 362 } 363 364 if (configs) { 365 EGLint i; 366 *num_config = MIN2(disp->NumConfigs, config_size); 367 for (i = 0; i < *num_config; i++) { 368 configs[i] = disp->Configs[i].Handle; 369 } 370 } else 371 *num_config = disp->NumConfigs; 372 373 return EGL_TRUE; 374} 375 376 377/** 378 * Creates a set of \c __GLcontextModes that a driver will expose. 379 * 380 * A set of \c __GLcontextModes will be created based on the supplied 381 * parameters. The number of modes processed will be 2 * 382 * \c num_depth_stencil_bits * \c num_db_modes. 383 * 384 * For the most part, data is just copied from \c depth_bits, \c stencil_bits, 385 * \c db_modes, and \c visType into each \c __GLcontextModes element. 386 * However, the meanings of \c fb_format and \c fb_type require further 387 * explanation. The \c fb_format specifies which color components are in 388 * each pixel and what the default order is. For example, \c GL_RGB specifies 389 * that red, green, blue are available and red is in the "most significant" 390 * position and blue is in the "least significant". The \c fb_type specifies 391 * the bit sizes of each component and the actual ordering. For example, if 392 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] 393 * are the blue value, bits [10:5] are the green value, and bits [4:0] are 394 * the red value. 395 * 396 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either 397 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the 398 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or 399 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as 400 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 401 * still uses 32-bits. 402 * 403 * If in doubt, look at the tables used in the function. 404 * 405 * \param ptr_to_modes Pointer to a pointer to a linked list of 406 * \c __GLcontextModes. Upon completion, a pointer to 407 * the next element to be process will be stored here. 408 * If the function fails and returns \c GL_FALSE, this 409 * value will be unmodified, but some elements in the 410 * linked list may be modified. 411 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB, 412 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported. 413 * \param fb_type Type of the pixels in the framebuffer. Currently only 414 * \c GL_UNSIGNED_SHORT_5_6_5, 415 * \c GL_UNSIGNED_SHORT_5_6_5_REV, 416 * \c GL_UNSIGNED_INT_8_8_8_8, and 417 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported. 418 * \param depth_bits Array of depth buffer sizes to be exposed. 419 * \param stencil_bits Array of stencil buffer sizes to be exposed. 420 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and 421 * \c stencil_bits. 422 * \param db_modes Array of buffer swap modes. If an element has a 423 * value of \c GLX_NONE, then it represents a 424 * single-buffered mode. Other valid values are 425 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and 426 * \c GLX_SWAP_UNDEFINED_OML. See the 427 * GLX_OML_swap_method extension spec for more details. 428 * \param num_db_modes Number of entries in \c db_modes. 429 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or 430 * \c GLX_DIRECT_COLOR. 431 * 432 * \returns 433 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only 434 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or 435 * \c fb_type). 436 * 437 * \todo 438 * There is currently no way to support packed RGB modes (i.e., modes with 439 * exactly 3 bytes per pixel) or floating-point modes. This could probably 440 * be done by creating some new, private enums with clever names likes 441 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, 442 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. 443 */ 444GLboolean 445_eglFillInConfigs(_EGLConfig * configs, 446 GLenum fb_format, GLenum fb_type, 447 const u_int8_t * depth_bits, const u_int8_t * stencil_bits, 448 unsigned num_depth_stencil_bits, 449 const GLenum * db_modes, unsigned num_db_modes, 450 int visType) { 451 static const u_int8_t bits_table[3][4] = { 452 /* R G B A */ 453 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ 454 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ 455 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ 456 }; 457 458 /* The following arrays are all indexed by the fb_type masked with 0x07. 459 * Given the four supported fb_type values, this results in valid array 460 * indices of 3, 4, 5, and 7. 461 */ 462 static const u_int32_t masks_table_rgb[8][4] = { 463 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 464 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 465 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 466 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */ 467 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */ 468 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */ 469 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 470 {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */ 471 }; 472 473 static const u_int32_t masks_table_rgba[8][4] = { 474 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 475 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 476 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 477 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */ 478 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */ 479 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */ 480 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 481 {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */ 482 }; 483 484 static const u_int32_t masks_table_bgr[8][4] = { 485 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 486 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 487 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 488 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */ 489 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */ 490 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */ 491 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 492 {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */ 493 }; 494 495 static const u_int32_t masks_table_bgra[8][4] = { 496 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 497 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 498 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 499 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */ 500 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */ 501 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */ 502 {0x00000000, 0x00000000, 0x00000000, 0x00000000}, 503 {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */ 504 }; 505 506 static const u_int8_t bytes_per_pixel[8] = { 507 0, 0, 0, 2, 2, 4, 0, 4 508 }; 509 510 const u_int8_t * bits; 511 const u_int32_t * masks; 512 const int index = fb_type & 0x07; 513 _EGLConfig *config; 514 unsigned i; 515 unsigned j; 516 unsigned k; 517 518 if ( bytes_per_pixel[index] == 0 ) { 519 _eglLog(_EGL_INFO, 520 "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.", 521 __FUNCTION__, __LINE__, fb_type); 522 return GL_FALSE; 523 } 524 525 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and 526 * the _REV versions. 527 * 528 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. 529 */ 530 switch ( fb_format ) { 531 case GL_RGB: 532 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1]; 533 masks = masks_table_rgb[index]; 534 break; 535 536 case GL_RGBA: 537 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2]; 538 masks = masks_table_rgba[index]; 539 break; 540 541 case GL_BGR: 542 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1]; 543 masks = masks_table_bgr[index]; 544 break; 545 546 case GL_BGRA: 547 bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2]; 548 masks = masks_table_bgra[index]; 549 break; 550 551 default: 552 _eglLog(_EGL_WARNING, 553 "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.", 554 __FUNCTION__, __LINE__, fb_format); 555 return GL_FALSE; 556 } 557 558 config = configs; 559 for (k = 0; k < num_depth_stencil_bits; k++) { 560 for (i = 0; i < num_db_modes; i++) { 561 for (j = 0; j < 2; j++) { 562 _eglSetConfigAttrib(config, EGL_RED_SIZE, bits[0]); 563 _eglSetConfigAttrib(config, EGL_GREEN_SIZE, bits[1]); 564 _eglSetConfigAttrib(config, EGL_BLUE_SIZE, bits[2]); 565 _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, bits[3]); 566 _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 567 bits[0] + bits[1] + bits[2] + bits[3]); 568 569 _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, stencil_bits[k]); 570 _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, depth_bits[i]); 571 572 _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_SCREEN_BIT_MESA | 573 EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT); 574 575 config++; 576 } 577 } 578 } 579 return GL_TRUE; 580} 581