From b174a1ae720cb404738cd57c431f5769d677957d Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 28 Aug 2017 11:23:58 -0400 Subject: [PATCH] egl: Simplify the "driver" interface "Driver" isn't a great word for what this layer is, it's effectively a build-time choice about what OS you're targeting. Despite that both of the extant backends totally ignore the display argument, the old code would only set up the backend relative to a display. That causes problems! One problem is it means eglGetProcAddress can generate X or Wayland protocol when it tries to connect to a default display so it can call into the backend, which is, you know, completely bonkers. Any other EGL API that doesn't reference a display, like EGL_EXT_device_query, would have the same issue. Fortunately this is a problem that can be solved with the delete key. Reviewed-by: Eric Anholt Signed-off-by: Adam Jackson --- docs/egl.html | 10 -- src/egl/drivers/dri2/egl_dri2.c | 4 +- src/egl/drivers/haiku/egl_haiku.cpp | 2 +- src/egl/main/egldriver.c | 262 ++-------------------------- src/egl/main/egldriver.h | 6 +- 5 files changed, 22 insertions(+), 262 deletions(-) diff --git a/docs/egl.html b/docs/egl.html index e752a707a3b..3d8a85b4e7e 100644 --- a/docs/egl.html +++ b/docs/egl.html @@ -130,16 +130,6 @@ mesa/demos repository.

runtime

-
EGL_DRIVER
-
- -

This variable specifies a full path to or the name of an EGL driver. It -forces the specified EGL driver to be loaded. It comes in handy when one wants -to test a specific driver. This variable is ignored for setuid/setgid -binaries.

- -
-
EGL_PLATFORM
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index c2b16d11732..0db80a091f8 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -3193,12 +3193,10 @@ dri2_load(_EGLDriver *drv) * Create a new _EGLDriver object and init its dispatch table. */ _EGLDriver * -_eglBuiltInDriverDRI2(const char *args) +_eglBuiltInDriver(void) { struct dri2_egl_driver *dri2_drv; - (void) args; - dri2_drv = calloc(1, sizeof *dri2_drv); if (!dri2_drv) return NULL; diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp index 10f3abc070a..c17198d6dd8 100644 --- a/src/egl/drivers/haiku/egl_haiku.cpp +++ b/src/egl/drivers/haiku/egl_haiku.cpp @@ -322,7 +322,7 @@ haiku_unload(_EGLDriver* drv) */ extern "C" _EGLDriver* -_eglBuiltInDriverHaiku(const char *args) +_eglBuiltInDriver(void) { CALLED(); diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 60753bb22e9..1ede95ea6f4 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -44,232 +44,32 @@ #include "egldriver.h" #include "egllog.h" -typedef struct _egl_module { - char *Name; - _EGLMain_t BuiltIn; - _EGLDriver *Driver; -} _EGLModule; - static mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP; -static _EGLArray *_eglModules; - -const struct { - const char *name; - _EGLMain_t main; -} _eglBuiltInDrivers[] = { -#ifdef _EGL_BUILT_IN_DRIVER_DRI2 - { "egl_dri2", _eglBuiltInDriverDRI2 }, -#endif -#ifdef _EGL_BUILT_IN_DRIVER_HAIKU - { "egl_haiku", _eglBuiltInDriverHaiku }, -#endif -}; - -/** - * Load a module and create the driver object. - */ -static EGLBoolean -_eglLoadModule(_EGLModule *mod) -{ - _EGLDriver *drv; - - if (mod->Driver) - return EGL_TRUE; - - if (!mod->BuiltIn) - return EGL_FALSE; - - drv = mod->BuiltIn(NULL); - if (!drv || !drv->Name) - return EGL_FALSE; - - mod->Driver = drv; - - return EGL_TRUE; -} - - -/** - * Unload a module. - */ -static void -_eglUnloadModule(_EGLModule *mod) -{ - /* destroy the driver */ - if (mod->Driver && mod->Driver->Unload) - mod->Driver->Unload(mod->Driver); - - mod->Driver = NULL; -} - - -/** - * Add a module to the module array. - */ -static _EGLModule * -_eglAddModule(const char *name) -{ - _EGLModule *mod; - EGLint i; - - if (!_eglModules) { - _eglModules = _eglCreateArray("Module", 8); - if (!_eglModules) - return NULL; - } - - /* find duplicates */ - for (i = 0; i < _eglModules->Size; i++) { - mod = _eglModules->Elements[i]; - if (strcmp(mod->Name, name) == 0) - return mod; - } - - /* allocate a new one */ - mod = calloc(1, sizeof(*mod)); - if (mod) { - mod->Name = strdup(name); - if (!mod->Name) { - free(mod); - mod = NULL; - } - } - if (mod) { - _eglAppendArray(_eglModules, (void *) mod); - _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name); - } - - return mod; -} - - -/** - * Free a module. - */ -static void -_eglFreeModule(void *module) -{ - _EGLModule *mod = (_EGLModule *) module; - - _eglUnloadModule(mod); - free(mod->Name); - free(mod); -} - - -/** - * Add the user driver to the module array. - * - * The user driver is specified by EGL_DRIVER. - */ -static EGLBoolean -_eglAddUserDriver(void) -{ - char *env; - - env = getenv("EGL_DRIVER"); - if (env) { - EGLint i; +static _EGLDriver *_eglDriver; - for (i = 0; i < ARRAY_SIZE(_eglBuiltInDrivers); i++) { - if (!strcmp(_eglBuiltInDrivers[i].name, env)) { - _EGLModule *mod = _eglAddModule(env); - if (mod) - mod->BuiltIn = _eglBuiltInDrivers[i].main; - - return EGL_TRUE; - } - } - } - - return EGL_FALSE; -} - - -/** - * Add built-in drivers to the module array. - */ -static void -_eglAddBuiltInDrivers(void) +static _EGLDriver * +_eglGetDriver(void) { - _EGLModule *mod; - EGLint i; - - for (i = 0; i < ARRAY_SIZE(_eglBuiltInDrivers); i++) { - mod = _eglAddModule(_eglBuiltInDrivers[i].name); - if (mod) - mod->BuiltIn = _eglBuiltInDrivers[i].main; - } -} - + mtx_lock(&_eglModuleMutex); -/** - * Add drivers to the module array. Drivers will be loaded as they are matched - * to displays. - */ -static EGLBoolean -_eglAddDrivers(void) -{ - if (_eglModules) - return EGL_TRUE; + if (!_eglDriver) + _eglDriver = _eglBuiltInDriver(); - if (!_eglAddUserDriver()) { - /* - * Add other drivers only when EGL_DRIVER is not set. The order here - * decides the priorities. - */ - _eglAddBuiltInDrivers(); - } + mtx_unlock(&_eglModuleMutex); - return (_eglModules != NULL); + return _eglDriver; } - -/** - * A helper function for _eglMatchDriver. It finds the first driver that can - * initialize the display and return. - */ static _EGLDriver * _eglMatchAndInitialize(_EGLDisplay *dpy) { - _EGLDriver *drv = NULL; - EGLint i = 0; - - if (!_eglAddDrivers()) { - _eglLog(_EGL_WARNING, "failed to find any driver"); - return NULL; - } - - if (dpy->Driver) { - drv = dpy->Driver; - /* no re-matching? */ - if (!drv->API.Initialize(drv, dpy)) - drv = NULL; - return drv; - } - - while (i < _eglModules->Size) { - _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; - - if (!_eglLoadModule(mod)) { - /* remove invalid modules */ - _eglEraseArray(_eglModules, i, _eglFreeModule); - continue; - } + if (_eglGetDriver()) + if (_eglDriver->API.Initialize(_eglDriver, dpy)) + return _eglDriver; - if (mod->Driver->API.Initialize(mod->Driver, dpy)) { - drv = mod->Driver; - break; - } - else { - i++; - } - } - - return drv; + return NULL; } - /** * Match a display to a driver. The display is initialized unless test_only is * true. The matching is done by finding the first driver that can initialize @@ -282,8 +82,6 @@ _eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) assert(!dpy->Initialized); - mtx_lock(&_eglModuleMutex); - /* set options */ dpy->Options.TestOnly = test_only; dpy->Options.UseFallback = EGL_FALSE; @@ -294,8 +92,6 @@ _eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) best_drv = _eglMatchAndInitialize(dpy); } - mtx_unlock(&_eglModuleMutex); - if (best_drv) { _eglLog(_EGL_DEBUG, "the best driver is %s%s", best_drv->Name, (test_only) ? " (test only) " : ""); @@ -308,35 +104,15 @@ _eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) return best_drv; } - __eglMustCastToProperFunctionPointerType _eglGetDriverProc(const char *procname) { - EGLint i; - _EGLProc proc = NULL; - - if (!_eglModules) { - /* load the driver for the default display */ - EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); - _EGLDisplay *dpy = _eglLookupDisplay(egldpy); - if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) - return NULL; - } + if (_eglGetDriver()) + return _eglDriver->API.GetProcAddress(_eglDriver, procname); - for (i = 0; i < _eglModules->Size; i++) { - _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; - - if (!mod->Driver) - break; - proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); - if (proc) - break; - } - - return proc; + return NULL; } - /** * Unload all drivers. */ @@ -344,8 +120,8 @@ void _eglUnloadDrivers(void) { /* this is called at atexit time */ - if (_eglModules) { - _eglDestroyArray(_eglModules, _eglFreeModule); - _eglModules = NULL; - } + if (_eglDriver && _eglDriver->Unload) + _eglDriver->Unload(_eglDriver); + + _eglDriver = NULL; } diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 1cf6628446b..a8b0cab2b1a 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -91,12 +91,8 @@ struct _egl_driver }; -extern _EGLDriver * -_eglBuiltInDriverDRI2(const char *args); - - extern _EGLDriver* -_eglBuiltInDriverHaiku(const char* args); +_eglBuiltInDriver(void); extern _EGLDriver * -- 2.30.2