egl: Simplify driver matching.
Add initialization options that drv->API.Initialize should support. Replace drv->Probe by TestOnly initialization option and simplify _eglMatchDriver.
This commit is contained in:
@@ -1472,10 +1472,14 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
{
|
{
|
||||||
switch (disp->Platform) {
|
switch (disp->Platform) {
|
||||||
case _EGL_PLATFORM_X11:
|
case _EGL_PLATFORM_X11:
|
||||||
|
if (disp->Options.TestOnly)
|
||||||
|
return EGL_TRUE;
|
||||||
return dri2_initialize_x11(drv, disp);
|
return dri2_initialize_x11(drv, disp);
|
||||||
|
|
||||||
#ifdef HAVE_LIBUDEV
|
#ifdef HAVE_LIBUDEV
|
||||||
case _EGL_PLATFORM_DRM:
|
case _EGL_PLATFORM_DRM:
|
||||||
|
if (disp->Options.TestOnly)
|
||||||
|
return EGL_TRUE;
|
||||||
return dri2_initialize_drm(drv, disp);
|
return dri2_initialize_drm(drv, disp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -589,6 +589,9 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
if (disp->Platform != _EGL_PLATFORM_X11)
|
if (disp->Platform != _EGL_PLATFORM_X11)
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
|
|
||||||
|
if (disp->Options.TestOnly)
|
||||||
|
return EGL_TRUE;
|
||||||
|
|
||||||
GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
|
GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
|
||||||
if (!GLX_dpy)
|
if (!GLX_dpy)
|
||||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||||
|
@@ -90,6 +90,11 @@ struct _egl_display
|
|||||||
_EGLDriver *Driver; /**< Matched driver of the display */
|
_EGLDriver *Driver; /**< Matched driver of the display */
|
||||||
EGLBoolean Initialized; /**< True if the display is initialized */
|
EGLBoolean Initialized; /**< True if the display is initialized */
|
||||||
|
|
||||||
|
/* options that affect how the driver initializes the display */
|
||||||
|
struct {
|
||||||
|
EGLBoolean TestOnly; /**< Driver should not set fields when true */
|
||||||
|
} Options;
|
||||||
|
|
||||||
/* these fields are set by the driver during init */
|
/* these fields are set by the driver during init */
|
||||||
void *DriverData; /**< Driver private data */
|
void *DriverData; /**< Driver private data */
|
||||||
EGLint VersionMajor; /**< EGL major version */
|
EGLint VersionMajor; /**< EGL major version */
|
||||||
|
@@ -525,100 +525,75 @@ _eglAddDrivers(void)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match a display to a driver. The display is initialized unless use_probe is
|
* A helper function for _eglMatchDriver. It finds the first driver that can
|
||||||
* true.
|
* initialize the display and return.
|
||||||
*
|
*/
|
||||||
* The matching is done by finding the first driver that can initialize the
|
static _EGLDriver *
|
||||||
* display, or when use_probe is true, the driver with highest score.
|
_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 (mod->Driver->API.Initialize(mod->Driver, dpy)) {
|
||||||
|
drv = mod->Driver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return drv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* the display.
|
||||||
*/
|
*/
|
||||||
_EGLDriver *
|
_EGLDriver *
|
||||||
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean use_probe)
|
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
|
||||||
{
|
{
|
||||||
_EGLModule *mod;
|
_EGLDriver *best_drv;
|
||||||
_EGLDriver *best_drv = NULL;
|
|
||||||
EGLint best_score = 0;
|
assert(!dpy->Initialized);
|
||||||
EGLint i;
|
|
||||||
|
|
||||||
_eglLockMutex(&_eglModuleMutex);
|
_eglLockMutex(&_eglModuleMutex);
|
||||||
|
|
||||||
if (!_eglAddDrivers()) {
|
/* set options */
|
||||||
_eglUnlockMutex(&_eglModuleMutex);
|
dpy->Options.TestOnly = test_only;
|
||||||
_eglLog(_EGL_WARNING, "failed to find any driver");
|
|
||||||
return EGL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* match the loaded modules */
|
best_drv = _eglMatchAndInitialize(dpy);
|
||||||
for (i = 0; i < _eglModules->Size; i++) {
|
|
||||||
mod = (_EGLModule *) _eglModules->Elements[i];
|
|
||||||
if (!mod->Driver)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (use_probe) {
|
|
||||||
EGLint score = (mod->Driver->Probe) ?
|
|
||||||
mod->Driver->Probe(mod->Driver, dpy) : 1;
|
|
||||||
if (score > best_score) {
|
|
||||||
best_drv = mod->Driver;
|
|
||||||
best_score = score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
|
|
||||||
best_drv = mod->Driver;
|
|
||||||
best_score = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* perfect match */
|
|
||||||
if (best_score >= 100)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* load more modules */
|
|
||||||
if (!best_drv) {
|
|
||||||
EGLint first_unloaded = i;
|
|
||||||
|
|
||||||
while (i < _eglModules->Size) {
|
|
||||||
mod = (_EGLModule *) _eglModules->Elements[i];
|
|
||||||
assert(!mod->Driver);
|
|
||||||
|
|
||||||
if (!_eglLoadModule(mod)) {
|
|
||||||
/* remove invalid modules */
|
|
||||||
_eglEraseArray(_eglModules, i, _eglFreeModule);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_probe) {
|
|
||||||
best_score = (mod->Driver->Probe) ?
|
|
||||||
mod->Driver->Probe(mod->Driver, dpy) : 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mod->Driver->API.Initialize(mod->Driver, dpy))
|
|
||||||
best_score = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best_score > 0) {
|
|
||||||
best_drv = mod->Driver;
|
|
||||||
/* loaded modules come before unloaded ones */
|
|
||||||
if (first_unloaded != i) {
|
|
||||||
void *tmp = _eglModules->Elements[i];
|
|
||||||
_eglModules->Elements[i] =
|
|
||||||
_eglModules->Elements[first_unloaded];
|
|
||||||
_eglModules->Elements[first_unloaded] = tmp;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_eglUnloadModule(mod);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_eglUnlockMutex(&_eglModuleMutex);
|
_eglUnlockMutex(&_eglModuleMutex);
|
||||||
|
|
||||||
if (best_drv) {
|
if (best_drv) {
|
||||||
_eglLog(_EGL_DEBUG, "the best driver is %s (score %d)",
|
_eglLog(_EGL_DEBUG, "the best driver is %s%s",
|
||||||
best_drv->Name, best_score);
|
best_drv->Name, (test_only) ? " (test only) " : "");
|
||||||
if (!use_probe) {
|
if (!test_only) {
|
||||||
dpy->Driver = best_drv;
|
dpy->Driver = best_drv;
|
||||||
dpy->Initialized = EGL_TRUE;
|
dpy->Initialized = EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -43,16 +43,6 @@ struct _egl_driver
|
|||||||
{
|
{
|
||||||
const char *Name; /**< name of this driver */
|
const char *Name; /**< name of this driver */
|
||||||
|
|
||||||
/**
|
|
||||||
* Probe a display and return a score.
|
|
||||||
*
|
|
||||||
* Roughly,
|
|
||||||
* 50 means the driver supports the display;
|
|
||||||
* 90 means the driver can accelerate the display;
|
|
||||||
* 100 means a perfect match.
|
|
||||||
*/
|
|
||||||
EGLint (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release the driver resource.
|
* Release the driver resource.
|
||||||
*
|
*
|
||||||
@@ -81,7 +71,7 @@ _eglMain(const char *args);
|
|||||||
|
|
||||||
|
|
||||||
extern _EGLDriver *
|
extern _EGLDriver *
|
||||||
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean probe_only);
|
_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only);
|
||||||
|
|
||||||
|
|
||||||
extern __eglMustCastToProperFunctionPointerType
|
extern __eglMustCastToProperFunctionPointerType
|
||||||
|
@@ -484,6 +484,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
|
|||||||
if (!nplat)
|
if (!nplat)
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
|
|
||||||
|
if (dpy->Options.TestOnly)
|
||||||
|
return EGL_TRUE;
|
||||||
|
|
||||||
gdpy = CALLOC_STRUCT(egl_g3d_display);
|
gdpy = CALLOC_STRUCT(egl_g3d_display);
|
||||||
if (!gdpy) {
|
if (!gdpy) {
|
||||||
_eglError(EGL_BAD_ALLOC, "eglInitialize");
|
_eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||||
@@ -572,12 +575,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
|
|||||||
stapi->get_proc_address(stapi, procname) : NULL);
|
stapi->get_proc_address(stapi, procname) : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGLint
|
|
||||||
egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
|
|
||||||
{
|
|
||||||
return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_EGLDriver *
|
_EGLDriver *
|
||||||
egl_g3d_create_driver(const struct egl_g3d_loader *loader)
|
egl_g3d_create_driver(const struct egl_g3d_loader *loader)
|
||||||
{
|
{
|
||||||
@@ -594,8 +591,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader)
|
|||||||
gdrv->base.API.Terminate = egl_g3d_terminate;
|
gdrv->base.API.Terminate = egl_g3d_terminate;
|
||||||
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
|
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
|
||||||
|
|
||||||
gdrv->base.Probe = egl_g3d_probe;
|
|
||||||
|
|
||||||
/* to be filled by the caller */
|
/* to be filled by the caller */
|
||||||
gdrv->base.Name = NULL;
|
gdrv->base.Name = NULL;
|
||||||
gdrv->base.Unload = NULL;
|
gdrv->base.Unload = NULL;
|
||||||
|
Reference in New Issue
Block a user