/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 VMware, Inc.
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
* Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#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))
/**
* 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;
conf->TransparentType = EGL_NONE;
conf->NativeVisualType = EGL_NONE;
conf->ColorBufferType = EGL_RGB_BUFFER;
+ conf->ComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
}
+/*
+ * Wipe the configs list and return the old list
+ */
+_EGLArray *
+_eglWipeConfigs(_EGLDisplay *disp)
+{
+ _EGLArray *configs = disp->Configs;
+ disp->Configs = NULL;
+ return configs;
+}
/**
* Link a config to its display and return the handle of the link.
*
* 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;
}
* 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,
/* 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[] =
{
/* 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 },
+ { EGL_CONFIG_SELECT_GROUP_MESA, ATTRIB_TYPE_INTEGER,
+ ATTRIB_CRITERION_IGNORE,
+ 0 },
};
EGLBoolean
_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
{
+ _EGLDisplay *disp = conf->Display;
EGLint i, attr, val;
EGLBoolean valid = EGL_TRUE;
if (val > 1 || val < 0)
valid = EGL_FALSE;
break;
+ case EGL_CONFIG_SELECT_GROUP_MESA:
+ break;
default:
if (val < 0)
valid = EGL_FALSE;
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;
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 != 0)
valid = EGL_FALSE;
break;
- default:
- assert(0);
- break;
}
if (!valid && for_matching) {
case ATTRIB_CRITERION_SPECIAL:
/* ignored here */
break;
- default:
- assert(0);
+ case ATTRIB_CRITERION_IGNORE:
+ unreachable("already handled above");
break;
}
return matched;
}
-static INLINE EGLBoolean
+static inline EGLBoolean
_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
{
if (_eglOffsetOfConfig(attr) < 0)
switch (attr) {
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;
}
* 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++) {
val = attrib_list[i + 1];
if (!_eglIsConfigAttribValid(conf, attr))
- return EGL_FALSE;
+ return EGL_FALSE;
_eglSetConfigKey(conf, attr, val);
}
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 */
if (conf1 == conf2)
return 0;
+ val1 = conf1->ConfigSelectGroup - conf2->ConfigSelectGroup;
+ if (val1)
+ return val1;
+
/* 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;
}
-static INLINE
+static inline
void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2)
{
const _EGLConfig *tmp = *conf1;
_EGLConfig **configList;
EGLint i, count;
- if (!num_configs)
- return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
-
/* get the number of matched configs */
count = _eglFilterArray(array, NULL, 0,
(_EGLArrayForEach) match, priv_data);
* 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))
_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
EGLint config_size, EGLint *num_config)
{
- if (!num_config)
- return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
-
*num_config = _eglFlattenArray(disp->Configs, (void *) configs,
sizeof(configs[0]), config_size, _eglFlattenConfig);