From 56822b0812cd500bd54bb7c4b573c54547efb657 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 25 Sep 2009 23:43:49 +0800 Subject: [PATCH] egl: Rework config lookup. Make it similiar to how contexts and surfaces are looked up. It should be slightly faster, and work better with multiple displays. Signed-off-by: Chia-I Wu --- src/egl/main/eglconfig.c | 92 +++++++++++++++++++-------------------- src/egl/main/eglconfig.h | 49 ++++++++++++++++++--- src/egl/main/egldisplay.h | 1 + 3 files changed, 89 insertions(+), 53 deletions(-) diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index b342aae33e8..2c8d1c4055b 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -30,7 +30,6 @@ void _eglInitConfig(_EGLConfig *config, EGLint id) { memset(config, 0, sizeof(*config)); - config->Handle = (EGLConfig) _eglUIntToPointer((unsigned int) id); /* some attributes take non-zero default values */ SET_CONFIG_ATTRIB(config, EGL_CONFIG_ID, id); @@ -44,63 +43,63 @@ _eglInitConfig(_EGLConfig *config, EGLint id) /** - * Return the public handle for an internal _EGLConfig. - * This is the inverse of _eglLookupConfig(). + * Link a config to a display and return the handle of the link. + * The handle can be passed to client directly. + * + * Note that we just save the ptr to the config (we don't copy the config). */ EGLConfig -_eglGetConfigHandle(_EGLConfig *config) +_eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf) { - return config ? config->Handle : 0; -} + _EGLConfig **configs; + /* sanity check */ + assert(GET_CONFIG_ATTRIB(conf, EGL_CONFIG_ID) > 0); -/** - * Given an EGLConfig handle, return the corresponding _EGLConfig object. - * This is the inverse of _eglGetConfigHandle(). - */ -_EGLConfig * -_eglLookupConfig(EGLConfig config, _EGLDisplay *disp) -{ - EGLint i; - for (i = 0; i < disp->NumConfigs; i++) { - if (disp->Configs[i]->Handle == config) { - return disp->Configs[i]; - } + configs = dpy->Configs; + if (dpy->NumConfigs >= dpy->MaxConfigs) { + EGLint new_size = dpy->MaxConfigs + 16; + assert(dpy->NumConfigs < new_size); + + configs = realloc(dpy->Configs, new_size * sizeof(dpy->Configs[0])); + if (!configs) + return (EGLConfig) NULL; + + dpy->Configs = configs; + dpy->MaxConfigs = new_size; } - return NULL; + + conf->Display = dpy; + dpy->Configs[dpy->NumConfigs++] = conf; + + return (EGLConfig) conf; } -/** - * Add the given _EGLConfig to the given display. - * Note that we just save the ptr to the config (we don't copy the config). - */ -_EGLConfig * -_eglAddConfig(_EGLDisplay *display, _EGLConfig *config) +#ifndef _EGL_SKIP_HANDLE_CHECK + + +EGLBoolean +_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy) { - _EGLConfig **newConfigs; - EGLint n; + _EGLConfig *conf = NULL; + EGLint i; - /* sanity check */ - assert(GET_CONFIG_ATTRIB(config, EGL_CONFIG_ID) > 0); - - n = display->NumConfigs; - - /* realloc array of ptrs */ - newConfigs = (_EGLConfig **) realloc(display->Configs, - (n + 1) * sizeof(_EGLConfig *)); - if (newConfigs) { - display->Configs = newConfigs; - display->Configs[n] = config; - display->NumConfigs++; - return config; - } - else { - return NULL; + for (i = 0; dpy && i < dpy->NumConfigs; i++) { + conf = dpy->Configs[i]; + if (conf == (_EGLConfig *) config) { + assert(conf->Display == dpy); + break; + } } + + return (conf != NULL); } +#endif /* _EGL_SKIP_HANDLE_CHECK */ + + enum { /* types */ ATTRIB_TYPE_INTEGER, @@ -755,7 +754,7 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list, _eglFallbackCompare, (void *) &criteria); count = MIN2(count, config_size); for (i = 0; i < count; i++) - configs[i] = configList[i]->Handle; + configs[i] = _eglGetConfigHandle(configList[i]); } free(configList); @@ -818,9 +817,8 @@ _eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs, if (configs) { EGLint i; *num_config = MIN2(disp->NumConfigs, config_size); - for (i = 0; i < *num_config; i++) { - configs[i] = disp->Configs[i]->Handle; - } + for (i = 0; i < *num_config; i++) + configs[i] = _eglGetConfigHandle(disp->Configs[i]); } else { /* just return total number of supported configs */ diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index e09d58980d0..6b8a259984e 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -16,7 +16,7 @@ struct _egl_config { - EGLConfig Handle; /* the public/opaque handle which names this config */ + _EGLDisplay *Display; EGLint Storage[_EGL_CONFIG_STORAGE_SIZE]; }; @@ -96,15 +96,52 @@ _eglInitConfig(_EGLConfig *config, EGLint id); extern EGLConfig -_eglGetConfigHandle(_EGLConfig *config); +_eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf); -extern _EGLConfig * -_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy); +#ifndef _EGL_SKIP_HANDLE_CHECK -extern _EGLConfig * -_eglAddConfig(_EGLDisplay *display, _EGLConfig *config); +extern EGLBoolean +_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy); + + +#else + + +static INLINE EGLBoolean +_eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy) +{ + _EGLConfig *conf = (_EGLConfig *) config; + return (dpy && conf && conf->Display == dpy); +} + + +#endif /* _EGL_SKIP_HANDLE_CHECK */ + + +/** + * Lookup a handle to find the linked config. + * Return NULL if the handle has no corresponding linked config. + */ +static INLINE _EGLConfig * +_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy) +{ + _EGLConfig *conf = (_EGLConfig *) config; + if (!_eglCheckConfigHandle(config, dpy)) + conf = NULL; + return conf; +} + + +/** + * Return the handle of a linked config, or NULL. + */ +static INLINE EGLConfig +_eglGetConfigHandle(_EGLConfig *conf) +{ + return (EGLConfig) ((conf && conf->Display) ? conf : NULL); +} extern EGLBoolean diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 6575fdf198f..ea4e35a8b3f 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -44,6 +44,7 @@ struct _egl_display EGLint NumScreens; _EGLScreen **Screens; /* array [NumScreens] */ + EGLint MaxConfigs; EGLint NumConfigs; _EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */ -- 2.30.2