diff options
author | Adam Jackson <[email protected]> | 2017-08-28 11:23:58 -0400 |
---|---|---|
committer | Adam Jackson <[email protected]> | 2017-10-05 13:43:34 -0400 |
commit | b174a1ae720cb404738cd57c431f5769d677957d (patch) | |
tree | a8dc8f91976382a93d387cc1d8247cdbf0a1b9c5 /src/egl/main | |
parent | 15e208c4ccdd94582a459d0066b587f91caf270c (diff) |
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 <[email protected]>
Signed-off-by: Adam Jackson <[email protected]>
Diffstat (limited to 'src/egl/main')
-rw-r--r-- | src/egl/main/egldriver.c | 262 | ||||
-rw-r--r-- | src/egl/main/egldriver.h | 6 |
2 files changed, 20 insertions, 248 deletions
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 * |