X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglconfig.c;h=72cd73d5179a4584362e1f19437d0dc7d0dcdb07;hb=ec12316489380564ed242118d7cb035c7997e044;hp=fec94fb20cd52f70086e39f27fa65d99961aa260;hpb=4926c5748028d33da4808f8a5473aa7b2f2bdc62;p=mesa.git diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index fec94fb20cd..72cd73d5179 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -1,3 +1,33 @@ +/************************************************************************** + * + * Copyright 2008 VMware, Inc. + * Copyright 2009-2010 Chia-I Wu + * Copyright 2010-2011 LunarG, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /** * EGL Configuration (pixel format) functions. */ @@ -6,13 +36,15 @@ #include #include #include +#include "c99_compat.h" +#include "util/macros.h" + #include "eglconfig.h" #include "egldisplay.h" #include "eglcurrent.h" #include "egllog.h" -#define MIN2(A, B) (((A) < (B)) ? (A) : (B)) /** @@ -24,11 +56,11 @@ * IDs are from 1 to N respectively. */ void -_eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id) +_eglInitConfig(_EGLConfig *conf, _EGLDisplay *disp, EGLint id) { memset(conf, 0, sizeof(*conf)); - conf->Display = dpy; + conf->Display = disp; /* some attributes take non-zero default values */ conf->ConfigID = id; @@ -36,6 +68,7 @@ _eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id) conf->TransparentType = EGL_NONE; conf->NativeVisualType = EGL_NONE; conf->ColorBufferType = EGL_RGB_BUFFER; + conf->ComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT; } @@ -45,21 +78,22 @@ _eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id) * * Note that we just save the ptr to the config (we don't copy the config). */ -PUBLIC EGLConfig +EGLConfig _eglLinkConfig(_EGLConfig *conf) { - _EGLDisplay *dpy = conf->Display; + _EGLDisplay *disp = conf->Display; /* sanity check */ - assert(dpy && conf->ConfigID > 0); + assert(disp); + assert(conf->ConfigID > 0); - if (!dpy->Configs) { - dpy->Configs = _eglCreateArray("Config", 16); - if (!dpy->Configs) + if (!disp->Configs) { + disp->Configs = _eglCreateArray("Config", 16); + if (!disp->Configs) return (EGLConfig) NULL; } - _eglAppendArray(dpy->Configs, (void *) conf); + _eglAppendArray(disp->Configs, (void *) conf); return (EGLConfig) conf; } @@ -70,30 +104,31 @@ _eglLinkConfig(_EGLConfig *conf) * Return NULL if the handle has no corresponding linked config. */ _EGLConfig * -_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy) +_eglLookupConfig(EGLConfig config, _EGLDisplay *disp) { _EGLConfig *conf; - if (!dpy) + if (!disp) return NULL; - conf = (_EGLConfig *) _eglFindArray(dpy->Configs, (void *) config); + conf = (_EGLConfig *) _eglFindArray(disp->Configs, (void *) config); if (conf) - assert(conf->Display == dpy); + assert(conf->Display == disp); return conf; } -enum { - /* types */ +enum type { ATTRIB_TYPE_INTEGER, ATTRIB_TYPE_BOOLEAN, ATTRIB_TYPE_BITMASK, ATTRIB_TYPE_ENUM, ATTRIB_TYPE_PSEUDO, /* non-queryable */ ATTRIB_TYPE_PLATFORM, /* platform-dependent */ - /* criteria */ +}; + +enum criterion { ATTRIB_CRITERION_EXACT, ATTRIB_CRITERION_ATLEAST, ATTRIB_CRITERION_MASK, @@ -105,8 +140,8 @@ enum { /* EGL spec Table 3.1 and 3.4 */ static const struct { EGLint attr; - EGLint type; - EGLint criterion; + enum type type; + enum criterion criterion; EGLint default_value; } _eglValidationTable[] = { @@ -213,7 +248,16 @@ static const struct { /* extensions */ { EGL_Y_INVERTED_NOK, ATTRIB_TYPE_BOOLEAN, ATTRIB_CRITERION_EXACT, - EGL_DONT_CARE } + EGL_DONT_CARE }, + { EGL_FRAMEBUFFER_TARGET_ANDROID, ATTRIB_TYPE_BOOLEAN, + ATTRIB_CRITERION_EXACT, + EGL_DONT_CARE }, + { EGL_RECORDABLE_ANDROID, ATTRIB_TYPE_BOOLEAN, + ATTRIB_CRITERION_EXACT, + EGL_DONT_CARE }, + { EGL_COLOR_COMPONENT_TYPE_EXT, ATTRIB_TYPE_ENUM, + ATTRIB_CRITERION_EXACT, + EGL_COLOR_COMPONENT_TYPE_FIXED_EXT }, }; @@ -228,6 +272,7 @@ static const struct { EGLBoolean _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) { + _EGLDisplay *disp = conf->Display; EGLint i, attr, val; EGLBoolean valid = EGL_TRUE; @@ -276,8 +321,13 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER) valid = EGL_FALSE; break; + case EGL_COLOR_COMPONENT_TYPE_EXT: + if (val != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT && + val != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) + valid = EGL_FALSE; + break; default: - assert(0); + unreachable("check _eglValidationTable[]"); break; } break; @@ -291,20 +341,20 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; -#ifdef EGL_MESA_screen_surface - if (conf->Display->Extensions.MESA_screen_surface) - mask |= EGL_SCREEN_BIT_MESA; -#endif + if (disp->Extensions.KHR_mutable_render_buffer) + mask |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR; break; case EGL_RENDERABLE_TYPE: case EGL_CONFORMANT: mask = EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT | + EGL_OPENGL_ES3_BIT_KHR | EGL_OPENGL_BIT; break; default: - assert(0); + unreachable("check _eglValidationTable[]"); + mask = 0; break; } if (val & ~mask) @@ -318,9 +368,6 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) if (val != 0) valid = EGL_FALSE; break; - default: - assert(0); - break; } if (!valid && for_matching) { @@ -428,8 +475,8 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) case ATTRIB_CRITERION_SPECIAL: /* ignored here */ break; - default: - assert(0); + case ATTRIB_CRITERION_IGNORE: + unreachable("already handled above"); break; } @@ -449,17 +496,19 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria) return matched; } -static INLINE EGLBoolean +static inline EGLBoolean _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr) { if (_eglOffsetOfConfig(attr) < 0) return EGL_FALSE; switch (attr) { - case EGL_MATCH_NATIVE_PIXMAP: - return EGL_FALSE; case EGL_Y_INVERTED_NOK: return conf->Display->Extensions.NOK_texture_from_pixmap; + case EGL_FRAMEBUFFER_TARGET_ANDROID: + return conf->Display->Extensions.ANDROID_framebuffer_target; + case EGL_RECORDABLE_ANDROID: + return conf->Display->Extensions.ANDROID_recordable; default: break; } @@ -472,12 +521,12 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr) * Return EGL_FALSE if any of the attribute is invalid. */ EGLBoolean -_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy, +_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *disp, const EGLint *attrib_list) { EGLint attr, val, i; - _eglInitConfig(conf, dpy, EGL_DONT_CARE); + _eglInitConfig(conf, disp, EGL_DONT_CARE); /* reset to default values */ for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) { @@ -492,7 +541,7 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy, val = attrib_list[i + 1]; if (!_eglIsConfigAttribValid(conf, attr)) - return EGL_FALSE; + return EGL_FALSE; _eglSetConfigKey(conf, attr, val); } @@ -500,8 +549,9 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy, if (!_eglValidateConfig(conf, EGL_TRUE)) return EGL_FALSE; - /* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */ - if (conf->Level == EGL_DONT_CARE) + /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */ + if (conf->Level == EGL_DONT_CARE || + conf->MatchNativePixmap == EGL_DONT_CARE) return EGL_FALSE; /* ignore other attributes when EGL_CONFIG_ID is given */ @@ -559,14 +609,14 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, return 0; /* the enum values have the desired ordering */ - assert(EGL_NONE < EGL_SLOW_CONFIG); - assert(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); + STATIC_ASSERT(EGL_NONE < EGL_SLOW_CONFIG); + STATIC_ASSERT(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); val1 = conf1->ConfigCaveat - conf2->ConfigCaveat; if (val1) return val1; /* the enum values have the desired ordering */ - assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); + STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER); val1 = conf1->ColorBufferType - conf2->ColorBufferType; if (val1) return val1; @@ -620,7 +670,7 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, } -static INLINE +static inline void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2) { const _EGLConfig *tmp = *conf1; @@ -634,7 +684,7 @@ void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2) * qsort() in that the compare function accepts an additional * argument. */ -void +static void _eglSortConfigs(const _EGLConfig **configs, EGLint count, EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, void *), @@ -672,40 +722,44 @@ _eglSortConfigs(const _EGLConfig **configs, EGLint count, } -static int -_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2, - void *priv_data) -{ - const _EGLConfig *criteria = (const _EGLConfig *) priv_data; - return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE); -} - - /** - * Typical fallback routine for eglChooseConfig + * A helper function for implementing eglChooseConfig. See _eglFilterArray and + * _eglSortConfigs for the meanings of match and compare. */ EGLBoolean -_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, - EGLConfig *configs, EGLint config_size, EGLint *num_configs) +_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs, + EGLint config_size, EGLint *num_configs, + EGLBoolean (*match)(const _EGLConfig *, void *), + EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, + void *), + void *priv_data) { - _EGLConfig **configList, criteria; + _EGLConfig **configList; EGLint i, count; if (!num_configs) - return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); - - if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) - return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); + return _eglError(EGL_BAD_PARAMETER, "eglChooseConfig"); + + /* get the number of matched configs */ + count = _eglFilterArray(array, NULL, 0, + (_EGLArrayForEach) match, priv_data); + if (!count) { + *num_configs = count; + return EGL_TRUE; + } - configList = (_EGLConfig **) _eglFilterArray(disp->Configs, &count, - (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria); + configList = malloc(sizeof(*configList) * count); if (!configList) return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); + /* get the matched configs */ + _eglFilterArray(array, (void **) configList, count, + (_EGLArrayForEach) match, priv_data); + /* perform sorting of configs */ if (configs && count) { _eglSortConfigs((const _EGLConfig **) configList, count, - _eglFallbackCompare, (void *) &criteria); + compare, priv_data); count = MIN2(count, config_size); for (i = 0; i < count; i++) configs[i] = _eglGetConfigHandle(configList[i]); @@ -719,15 +773,60 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, } +static EGLBoolean +_eglFallbackMatch(const _EGLConfig *conf, void *priv_data) +{ + return _eglMatchConfig(conf, (const _EGLConfig *) priv_data); +} + + +static EGLint +_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2, + void *priv_data) +{ + return _eglCompareConfigs(conf1, conf2, + (const _EGLConfig *) priv_data, EGL_TRUE); +} + + +/** + * Typical fallback routine for eglChooseConfig + */ +EGLBoolean +_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, + EGLConfig *configs, EGLint config_size, EGLint *num_configs) +{ + _EGLConfig criteria; + + if (!_eglParseConfigAttribList(&criteria, disp, attrib_list)) + return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); + + return _eglFilterConfigArray(disp->Configs, + configs, config_size, num_configs, + _eglFallbackMatch, _eglFallbackCompare, + (void *) &criteria); +} + + /** * Fallback for eglGetConfigAttrib. */ EGLBoolean -_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, +_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, EGLint attribute, EGLint *value) { if (!_eglIsConfigAttribValid(conf, attribute)) return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); + + /* nonqueryable attributes */ + switch (attribute) { + case EGL_MATCH_NATIVE_PIXMAP: + return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib"); + break; + default: + break; + } + if (!value) return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib");