egldriver.c revision f36cba6cf3d51a3937d3bb429609d258399751a0
16052af172f0241e6678cd16efac0a0f14f40146cBrian Paul/** 26052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Functions for choosing and opening/loading device drivers. 36052af172f0241e6678cd16efac0a0f14f40146cBrian Paul */ 46052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 56052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 6adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <assert.h> 711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include <string.h> 8adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <stdio.h> 90c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include <stdlib.h> 101e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu 111e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu#include "eglstring.h" 12e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h" 13adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h" 14adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h" 15b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h" 16f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#include "eglmutex.h" 17adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 186f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 196b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#include <dlfcn.h> 20b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <sys/types.h> 21b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <dirent.h> 225d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu#include <unistd.h> 23b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#endif 24adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 255541988578054345ca70b7ed7972710396e61b44Chia-I Wu 26f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wutypedef struct _egl_module { 27f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu char *Path; 28c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t BuiltIn; 29f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu void *Handle; 30f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *Driver; 31f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} _EGLModule; 32f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 33f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGL_DECLARE_MUTEX(_eglModuleMutex); 34f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLArray *_eglModules; 35f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 36c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wuconst struct { 37c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu const char *name; 38c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t main; 39c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu} _eglBuiltInDrivers[] = { 40a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GALLIUM 41a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu { "egl_gallium", _eglBuiltInDriverGALLIUM }, 42a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#endif 43c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_DRI2 44c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { "egl_dri2", _eglBuiltInDriverDRI2 }, 45c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif 46c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GLX 47c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { "egl_glx", _eglBuiltInDriverGLX }, 48c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif 49c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { NULL, NULL } 50c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu}; 51f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 52a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/** 53a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * Wrappers for dlopen/dlclose() 54a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul */ 556f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS) 56a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 575541988578054345ca70b7ed7972710396e61b44Chia-I Wu 585541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef HMODULE lib_handle; 595541988578054345ca70b7ed7972710396e61b44Chia-I Wu 605541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic HMODULE 615541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename) 625541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 635541988578054345ca70b7ed7972710396e61b44Chia-I Wu return LoadLibrary(filename); 645541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 655541988578054345ca70b7ed7972710396e61b44Chia-I Wu 665541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void 675541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(HMODULE lib) 685541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 695541988578054345ca70b7ed7972710396e61b44Chia-I Wu FreeLibrary(lib); 705541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 715541988578054345ca70b7ed7972710396e61b44Chia-I Wu 72ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White 73b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char * 74b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void) 75b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 765d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return ".dll"; 7721b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu} 7821b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 7921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 806f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX) 81a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 82a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 835541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef void * lib_handle; 845541988578054345ca70b7ed7972710396e61b44Chia-I Wu 855541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void * 865541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename) 875541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 885541988578054345ca70b7ed7972710396e61b44Chia-I Wu return dlopen(filename, RTLD_LAZY); 895541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 905541988578054345ca70b7ed7972710396e61b44Chia-I Wu 915541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void 925541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(void *lib) 935541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 945541988578054345ca70b7ed7972710396e61b44Chia-I Wu dlclose(lib); 955541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 965541988578054345ca70b7ed7972710396e61b44Chia-I Wu 97b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 98b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char * 99b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void) 100b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 1015d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return ".so"; 10221b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu} 10321b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 10421b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 105a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#endif 106a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 1070eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 108adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/** 1090eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu * Open the named driver and find its bootstrap function: _eglMain(). 110adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */ 1110eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wustatic _EGLMain_t 112b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu_eglOpenLibrary(const char *driverPath, lib_handle *handle) 113adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{ 114a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul lib_handle lib; 1155541988578054345ca70b7ed7972710396e61b44Chia-I Wu _EGLMain_t mainFunc = NULL; 1165541988578054345ca70b7ed7972710396e61b44Chia-I Wu const char *error = "unknown error"; 117adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 118b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu assert(driverPath); 1196052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 120b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); 121b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu lib = open_library(driverPath); 1225541988578054345ca70b7ed7972710396e61b44Chia-I Wu 1236f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS) 1245541988578054345ca70b7ed7972710396e61b44Chia-I Wu /* XXX untested */ 1255541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (lib) 1265541988578054345ca70b7ed7972710396e61b44Chia-I Wu mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); 1276f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX) 1285541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (lib) { 129496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu union { 130496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu _EGLMain_t func; 131496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu void *ptr; 132496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu } tmp = { NULL }; 133496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu /* direct cast gives a warning when compiled with -pedantic */ 134496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu tmp.ptr = dlsym(lib, "_eglMain"); 135496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu mainFunc = tmp.func; 1365541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (!mainFunc) 1375541988578054345ca70b7ed7972710396e61b44Chia-I Wu error = dlerror(); 1385541988578054345ca70b7ed7972710396e61b44Chia-I Wu } 1395541988578054345ca70b7ed7972710396e61b44Chia-I Wu else { 1405541988578054345ca70b7ed7972710396e61b44Chia-I Wu error = dlerror(); 141ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White } 142ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White#endif 1435541988578054345ca70b7ed7972710396e61b44Chia-I Wu 144485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!lib) { 1455541988578054345ca70b7ed7972710396e61b44Chia-I Wu _eglLog(_EGL_WARNING, "Could not open driver %s (%s)", 1465541988578054345ca70b7ed7972710396e61b44Chia-I Wu driverPath, error); 147485528f2acb69940a7c757638127f716c0cb2654Jon Smirl return NULL; 148485528f2acb69940a7c757638127f716c0cb2654Jon Smirl } 1496b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul 150485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!mainFunc) { 1515541988578054345ca70b7ed7972710396e61b44Chia-I Wu _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)", 1525541988578054345ca70b7ed7972710396e61b44Chia-I Wu driverPath, error); 1530eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (lib) 1540eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu close_library(lib); 155485528f2acb69940a7c757638127f716c0cb2654Jon Smirl return NULL; 156adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul } 157485528f2acb69940a7c757638127f716c0cb2654Jon Smirl 1580eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu *handle = lib; 1590eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu return mainFunc; 1600eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1610eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1620eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 164f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Load a module and create the driver object. 1650eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 166f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 167f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglLoadModule(_EGLModule *mod) 1680eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 1690eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu _EGLMain_t mainFunc; 1700eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu lib_handle lib; 171f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *drv; 1720eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 173c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod->Driver) 174c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_TRUE; 175c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 176c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod->BuiltIn) { 177c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu lib = (lib_handle) NULL; 178c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mainFunc = mod->BuiltIn; 179c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 180c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu else { 181c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mainFunc = _eglOpenLibrary(mod->Path, &lib); 182c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (!mainFunc) 183c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_FALSE; 184c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 1850eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 186f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu drv = mainFunc(NULL); 187485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!drv) { 1880eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (lib) 1890eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu close_library(lib); 190f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_FALSE; 191adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul } 1926b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul 1930eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (!drv->Name) { 194f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path); 1950eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu drv->Name = "UNNAMED"; 1966b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul } 1970eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 198f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Handle = (void *) lib; 199f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = drv; 200f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 201f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 202f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 203b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 2040eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 205f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 206f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload a module. 207f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 208f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 209f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadModule(_EGLModule *mod) 210f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 211d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if defined(_EGL_OS_UNIX) 212f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* destroy the driver */ 213f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Driver && mod->Driver->Unload) 214f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver->Unload(mod->Driver); 215d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu 216d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu /* 217d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu * XXX At this point (atexit), the module might be the last reference to 218d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu * libEGL. Closing the module might unmap libEGL and give problems. 219d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu */ 220d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if 0 221f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Handle) 222f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu close_library(mod->Handle); 223d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif 224d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#elif defined(_EGL_OS_WINDOWS) 225d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu /* XXX Windows unloads DLLs before atexit */ 226d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif 227f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 228f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = NULL; 229f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Handle = NULL; 2300eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 2310eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2320eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2330eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 234f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array. 2350eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 236f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule * 237f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddModule(const char *path) 2380eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 239f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod; 240f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 2410eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 242f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 243f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = _eglCreateArray("Module", 8); 244f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) 245f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 246f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 247cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu 248f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* find duplicates */ 249f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 250f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = _eglModules->Elements[i]; 251f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (strcmp(mod->Path, path) == 0) 252f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 253f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 254f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 255f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* allocate a new one */ 256f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = calloc(1, sizeof(*mod)); 257f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 258f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Path = _eglstrdup(path); 259f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Path) { 260f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 261f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = NULL; 2620eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 2630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 264f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 265f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAppendArray(_eglModules, (void *) mod); 266f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path); 267f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 2680eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 269f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 270f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 271f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 272f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 273f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 274f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module. 275f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 276f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 277f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module) 278f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 279f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) module; 280f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 281f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnloadModule(mod); 282f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod->Path); 283f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 2840eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 2850eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2860eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2870eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 2880d089cbb48d099b833768556266114d537c91299Chia-I Wu * A loader function for use with _eglPreloadForEach. The loader data is the 2895d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * filename of the driver. This function stops on the first valid driver. 2905d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 2915d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic EGLBoolean 2920d089cbb48d099b833768556266114d537c91299Chia-I Wu_eglLoaderFile(const char *dir, size_t len, void *loader_data) 2935d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 2945d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu char path[1024]; 2950d089cbb48d099b833768556266114d537c91299Chia-I Wu const char *filename = (const char *) loader_data; 2965d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t flen = strlen(filename); 2975d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 2985d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu /* make a full path */ 2995d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu if (len + flen + 2 > sizeof(path)) 3005d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return EGL_TRUE; 3015d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu if (len) { 3025d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu memcpy(path, dir, len); 3035d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu path[len++] = '/'; 3045d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3055d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu memcpy(path + len, filename, flen); 3065d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu len += flen; 3075d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu path[len] = '\0'; 3085d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (library_suffix()) { 3105d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *suffix = library_suffix(); 3115d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t slen = strlen(suffix); 3125d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *p; 3135d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu EGLBoolean need_suffix; 3145d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3155d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu p = filename + flen - slen; 3165d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu need_suffix = (p < filename || strcmp(p, suffix) != 0); 317f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (need_suffix) { 318f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* overflow */ 319f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (len + slen + 1 > sizeof(path)) 320f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 3215d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu strcpy(path + len, suffix); 3225d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3235d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 324f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 325f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#if defined(_EGL_OS_UNIX) 326f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* check if the file exists */ 327f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (access(path, F_OK)) 3285d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return EGL_TRUE; 329f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#endif 330f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 331f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAddModule(path); 332f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 333f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 334f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 335f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 3365d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 337f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 338f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Run the callback function on each driver directory. 3395d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * 3405d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * The process may end prematurely if the callback function returns false. 3415d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 342f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 3435d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglPreloadForEach(const char *search_path, 3440d089cbb48d099b833768556266114d537c91299Chia-I Wu EGLBoolean (*loader)(const char *, size_t, void *), 3450d089cbb48d099b833768556266114d537c91299Chia-I Wu void *loader_data) 3465d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 3475d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *cur, *next; 3485d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t len; 3495d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3505d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu cur = search_path; 3515d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu while (cur) { 3525d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu next = strchr(cur, ':'); 3535d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu len = (next) ? next - cur : strlen(cur); 3545d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 35588af76ce94834d795c11445b1c82b7aa874b87d5Igor Oliveira if (!loader(cur, len, loader_data)) 3565d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu break; 3575d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3585d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu cur = (next) ? next + 1 : NULL; 3595d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3605d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu} 3615d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3625d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3635d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/** 3645d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * Return a list of colon-separated driver directories. 3655d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 3665d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic const char * 3675d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglGetSearchPath(void) 3685d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 369ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu static char search_path[1024]; 3705d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3716f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) 372ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (search_path[0] == '\0') { 373ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char *buf = search_path; 374ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu size_t len = sizeof(search_path); 375ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu EGLBoolean use_env; 376ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char dir_sep; 3775d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu int ret; 3785d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3796f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 380ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu use_env = (geteuid() == getuid() && getegid() == getgid()); 381ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu dir_sep = '/'; 382ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#else 383ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu use_env = EGL_TRUE; 384ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu dir_sep = '\\'; 385ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif 386ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 387ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (use_env) { 388ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char *p; 389ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 390ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu /* extract the dirname from EGL_DRIVER */ 391ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = getenv("EGL_DRIVER"); 392ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (p && strchr(p, dir_sep)) { 393ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s", p); 394ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret > 0 && ret < len) { 395ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = strrchr(buf, dir_sep); 396ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu *p++ = ':'; 397ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 398ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu len -= p - buf; 399ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu buf = p; 400ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 401ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 402ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 403ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu /* append EGL_DRIVERS_PATH */ 404ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = getenv("EGL_DRIVERS_PATH"); 405ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (p) { 406ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s:", p); 407ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret > 0 && ret < len) { 408ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu buf += ret; 409ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu len -= ret; 410ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 411ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 412ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 413ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu else { 4146fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu _eglLog(_EGL_DEBUG, 4156fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu "ignore EGL_DRIVERS_PATH for setuid/setgid binaries"); 4166fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 4176fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu 418ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR); 419ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret < 0 || ret >= len) 420ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu search_path[0] = '\0'; 421ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 422ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path); 4235d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 424ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */ 4255d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4265d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return search_path; 4275d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu} 4285d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4295d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4305d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/** 431f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array. 432b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu * 433f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER. 434b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 4351e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean 436f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void) 437b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 4385d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *search_path = _eglGetSearchPath(); 43921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu char *env; 440f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu size_t name_len = 0; 441b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 442b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu env = getenv("EGL_DRIVER"); 4436f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 4446fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu if (env && strchr(env, '/')) { 4455d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu search_path = ""; 4466fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu if ((geteuid() != getuid() || getegid() != getgid())) { 4476fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu _eglLog(_EGL_DEBUG, 4486fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu "ignore EGL_DRIVER for setuid/setgid binaries"); 4496fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu env = NULL; 4506fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 4516fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 452f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu else if (env) { 453f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu char *suffix = strchr(env, '.'); 454f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu name_len = (suffix) ? suffix - env : strlen(env); 455f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 456f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu#else 457f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (env) 458f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu name_len = strlen(env); 4596f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#endif /* _EGL_OS_UNIX */ 460f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 461f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu /* 462f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * Try built-in drivers first if we know the driver name. This makes sure 463f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * we do not load the outdated external driver that is still on the 464f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * filesystem. 465f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu */ 466f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (name_len) { 467c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 468c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu EGLint i; 469c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 470c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 471f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (strlen(_eglBuiltInDrivers[i].name) == name_len && 472f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) { 473c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(env); 474c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 475c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 476f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 477f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu return EGL_TRUE; 478c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 479c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 480f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 481f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 482f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu /* otherwise, treat env as a path */ 483f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (env) { 484f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env); 4851e4f412242391000eea3fd28452865c3d27f987dChia-I Wu 4861e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_TRUE; 487c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 4881e4f412242391000eea3fd28452865c3d27f987dChia-I Wu 4891e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_FALSE; 490f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 491b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 492f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 493f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 49449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu * Add egl_gallium to the module array. 49549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu */ 49649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic void 49749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu_eglAddGalliumDriver(void) 49849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu{ 49949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#ifndef _EGL_BUILT_IN_DRIVER_GALLIUM 50049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu void *external = (void *) "egl_gallium"; 50149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu _eglPreloadForEach(_eglGetSearchPath(), _eglLoaderFile, external); 50249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#endif 50349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu} 50449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu 50549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu 50649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu/** 507c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array. 508f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 509f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 510c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void) 511f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 512c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 513f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 514f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 515c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 516c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(_eglBuiltInDrivers[i].name); 517c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 518c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 51921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu } 520f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 521b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 522f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 523f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 524f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array. Drivers will be loaded as they are matched 525f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays. 526f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 527f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 528f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void) 529f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 530f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) 531f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 532f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 5331e4f412242391000eea3fd28452865c3d27f987dChia-I Wu if (!_eglAddUserDriver()) { 5341e4f412242391000eea3fd28452865c3d27f987dChia-I Wu /* 5351e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * Add other drivers only when EGL_DRIVER is not set. The order here 5361e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * decides the priorities. 5371e4f412242391000eea3fd28452865c3d27f987dChia-I Wu */ 5381e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddGalliumDriver(); 5391e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddBuiltInDrivers(); 5401e4f412242391000eea3fd28452865c3d27f987dChia-I Wu } 541f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 542f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return (_eglModules != NULL); 543b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu} 544b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 545b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 546b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/** 547655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver. It finds the first driver that can 548655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return. 549b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 550655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver * 551655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy) 552b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 553655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *drv = NULL; 554655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu EGLint i = 0; 5554afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 556f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglAddDrivers()) { 5571e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglLog(_EGL_WARNING, "failed to find any driver"); 558655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return NULL; 5594afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu } 560b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 561655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (dpy->Driver) { 562655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = dpy->Driver; 563655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* no re-matching? */ 564655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!drv->API.Initialize(drv, dpy)) 565655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = NULL; 566655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 567655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 568b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 569655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu while (i < _eglModules->Size) { 570655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 571655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 572655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!_eglLoadModule(mod)) { 573655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* remove invalid modules */ 574655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglEraseArray(_eglModules, i, _eglFreeModule); 575655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu continue; 576655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 577655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 578655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (mod->Driver->API.Initialize(mod->Driver, dpy)) { 579655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = mod->Driver; 580655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu break; 581f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 582f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu else { 583655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu i++; 584f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 585f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 5864afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 587655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 588655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu} 589b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 5904afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 591655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/** 592655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver. The display is initialized unless test_only is 593655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true. The matching is done by finding the first driver that can initialize 594655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display. 595655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */ 596655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver * 597655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) 598655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{ 599655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *best_drv; 600f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 601655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu assert(!dpy->Initialized); 602f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 603655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLockMutex(&_eglModuleMutex); 604655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 605655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* set options */ 606655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu dpy->Options.TestOnly = test_only; 607a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_FALSE; 608655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 609655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv = _eglMatchAndInitialize(dpy); 610a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu if (!best_drv) { 611a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_TRUE; 612a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu best_drv = _eglMatchAndInitialize(dpy); 613a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu } 6140eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 615f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnlockMutex(&_eglModuleMutex); 616f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 617f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (best_drv) { 618655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLog(_EGL_DEBUG, "the best driver is %s%s", 619655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv->Name, (test_only) ? " (test only) " : ""); 620655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!test_only) { 621f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Driver = best_drv; 622f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Initialized = EGL_TRUE; 623f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 624f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 625f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 626f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return best_drv; 627e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul} 628e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 629f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 630f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType 631f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname) 632681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{ 633f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 634f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLProc proc = NULL; 635f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 636f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 637f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* load the driver for the default display */ 638f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 639f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDisplay *dpy = _eglLookupDisplay(egldpy); 640f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) 641f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 642f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 643681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 644f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 645f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 646681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 647f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Driver) 648f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu break; 649f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); 650f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (proc) 651afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu break; 652afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu } 653681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 654f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return proc; 655f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 656f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 657681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 658f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 659f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers. 660f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 661f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid 662f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void) 663f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 664f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* this is called at atexit time */ 665f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) { 666f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglDestroyArray(_eglModules, _eglFreeModule); 667f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = NULL; 668f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 669681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg} 670681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 671e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 672e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul/** 673e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * Invoke a callback function on each EGL search path. 674e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * 675e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The first argument of the callback function is the name of the search path. 676e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The second argument is the length of the name. 677e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu */ 678e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wuvoid 679e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *), 680e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu void *callback_data) 681e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu{ 682e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu const char *search_path = _eglGetSearchPath(); 683e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu _eglPreloadForEach(search_path, callback, callback_data); 684e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu} 685