/** * Free a module. */ static void _eglFreeModule(void *module) { _EGLModule *mod = (_EGLModule *) module; _eglUnloadModule(mod); free(mod->Path); free(mod); }
/** * Match a display to a driver. The display is initialized unless use_probe is * true. * * The matching is done by finding the first driver that can initialize the * display, or when use_probe is true, the driver with highest score. */ _EGLDriver * _eglMatchDriver(_EGLDisplay *dpy, EGLBoolean use_probe) { _EGLModule *mod; _EGLDriver *best_drv = NULL; EGLint best_score = 0; EGLint major, minor, i; _eglLockMutex(&_eglModuleMutex); if (!_eglAddDrivers()) { _eglUnlockMutex(&_eglModuleMutex); return EGL_FALSE; } /* match the loaded modules */ 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, &major, &minor)) { 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, &major, &minor)) 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); if (best_drv) { _eglLog(_EGL_DEBUG, "the best driver is %s (score %d)", best_drv->Name, best_score); if (!use_probe) { dpy->Driver = best_drv; dpy->Initialized = EGL_TRUE; dpy->APImajor = major; dpy->APIminor = minor; } } return best_drv; }